[jboss-svn-commits] JBL Code SVN: r28530 - in labs/jbosstm/trunk/common: classes/com/arjuna/common/internal/util/propertyservice and 1 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Jul 28 06:00:31 EDT 2009
Author: jhalliday
Date: 2009-07-28 06:00:29 -0400 (Tue, 28 Jul 2009)
New Revision: 28530
Added:
labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/BeanPopulator.java
labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/FullPropertyName.java
labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/PropertyPrefix.java
labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/DummyEnvironmentBean.java
labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/DummyPropertyManager.java
labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/EnvironmentBeanTest.java
Modified:
labs/jbosstm/trunk/common/build.xml
Log:
Framework for bean based property configuration. JBTM-596
Modified: labs/jbosstm/trunk/common/build.xml
===================================================================
--- labs/jbosstm/trunk/common/build.xml 2009-07-28 09:09:20 UTC (rev 28529)
+++ labs/jbosstm/trunk/common/build.xml 2009-07-28 10:00:29 UTC (rev 28530)
@@ -72,6 +72,9 @@
<run.tests.macro>
<tests><fileset dir="tests" includes="**/IOTest.java"/></tests>
</run.tests.macro>
+ <run.tests.macro>
+ <tests><fileset dir="tests" includes="**/EnvironmentBeanTest.java"/></tests>
+ </run.tests.macro>
</target>
Added: labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/BeanPopulator.java
===================================================================
--- labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/BeanPopulator.java (rev 0)
+++ labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/BeanPopulator.java 2009-07-28 10:00:29 UTC (rev 28530)
@@ -0,0 +1,150 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2009,
+ * @author JBoss, a division of Red Hat.
+ */
+package com.arjuna.common.internal.util.propertyservice;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import com.arjuna.common.util.propertyservice.PropertyManager;
+
+/**
+ * Utility class that configures *EnvironmentBean objects using a PropertyManager, which is usually
+ * backed by a -properties.xml file.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com)
+ */
+public class BeanPopulator
+{
+ /**
+ * Examine the properties of the provided bean and update them to match the values of the corresponding
+ * properties in the PropertyManager.
+ * This will normally be used to configure a freshly created default bean to match the configuration
+ * read from a properties file.
+ *
+ * The algorithm is as follows: for each field in the bean, which must have a getter and setter method
+ * matching according to the JavaBeans naming conventions, determine the corresponding property key.
+ * The key name is constructed by taking the bean classes' PropertyPrefix annotation value and adding to it the
+ * name of the field, except in cases where the field has a FullPropertyName annotation, in which case
+ * its value is used instead. This allows for the convention that all properties in a given bean will share
+ * the same prefix e.g. com.arjuna.ats.arjuna.foo. whilst still allowing for changing of the property
+ * name in cases where this makes for more readable code.
+ * Obtain the value of the property from the PropertyManager and if it's not null, type convert it to match
+ * the bean's property field type. Obtain the value of the property from the bean and if it's different
+ * from the value read from the propertyManager, use the setter to update the bean.
+ *
+ * @param bean a JavaBean, the target of the property updates and source for defaults.
+ * @param propertyManager a PropertyManager, the source of the configuration overrides.
+ * @throws Exception if the configuration of the bean fails.
+ */
+ public static void configureFromPropertyManager(Object bean, PropertyManager propertyManager) throws Exception {
+
+ if(!bean.getClass().isAnnotationPresent(PropertyPrefix.class)) {
+ throw new Exception("no PropertyPrefix found on "+bean.getClass().getName());
+ }
+
+ PropertyPrefix prefixAnnotation = bean.getClass().getAnnotation(PropertyPrefix.class);
+
+ String prefix = prefixAnnotation.prefix();
+
+ for(Field field : bean.getClass().getDeclaredFields()) {
+ Class type = field.getType();
+
+ String setterMethodName = "set"+capitalizeFirstLetter(field.getName());
+ Method setter = bean.getClass().getMethod(setterMethodName, new Class[] {field.getType()});
+
+ String getterMethodName;
+ Method getter = null;
+ if(field.getType().equals(Boolean.TYPE)) {
+ getterMethodName = "is"+capitalizeFirstLetter(field.getName());
+ try {
+ getter = bean.getClass().getMethod(getterMethodName, new Class[] {});
+ } catch (NoSuchMethodException e) {}
+ }
+
+ if(getter == null) {
+ getterMethodName = "get"+capitalizeFirstLetter(field.getName());
+ getter = bean.getClass().getMethod(getterMethodName, new Class[] {});
+ }
+
+ String propertyFileKey = prefix+field.getName();
+
+ if(field.isAnnotationPresent(FullPropertyName.class)) {
+ FullPropertyName fullPropertyName = field.getAnnotation(FullPropertyName.class);
+ propertyFileKey = fullPropertyName.name();
+ }
+
+ String valueFromPropertyManager = propertyManager.getProperty(propertyFileKey);
+
+ if(valueFromPropertyManager != null) {
+
+ Object valueFromBean = getter.invoke(bean, new Object[] {});
+
+ if(field.getType().equals(Boolean.TYPE)) {
+
+ if(!((Boolean)valueFromBean).booleanValue() && isPositive(valueFromPropertyManager)) {
+ setter.invoke(bean, new Object[]{ Boolean.TRUE });
+ }
+
+ if(((Boolean)valueFromBean).booleanValue() && isNegative(valueFromPropertyManager)) {
+ setter.invoke(bean, new Object[] { Boolean.FALSE});
+ }
+
+ } else if(field.getType().equals(String.class)) {
+
+ if(!valueFromPropertyManager.equals(valueFromBean)) {
+ setter.invoke(bean, new Object[] {valueFromPropertyManager});
+ }
+
+ } else if(field.getType().equals(Long.TYPE)) {
+
+ Long longValue = Long.valueOf(valueFromPropertyManager);
+ if(!longValue.equals(valueFromBean)) {
+ setter.invoke(bean, new Object[] {longValue});
+ }
+
+ } else if(field.getType().equals(Integer.TYPE)) {
+
+ Integer intValue = Integer.valueOf(valueFromPropertyManager);
+ if(!intValue.equals(valueFromBean)) {
+ setter.invoke(bean, new Object[] {intValue});
+ }
+
+ } else {
+
+ throw new Exception("unknown field type "+field.getType());
+
+ }
+ }
+ }
+ }
+
+ private static String capitalizeFirstLetter(String string) {
+ return (string.length()>0) ? (Character.toUpperCase(string.charAt(0))+string.substring(1)) : string;
+ }
+
+ private static boolean isPositive(String value) {
+ return "YES".equalsIgnoreCase(value) || "ON".equalsIgnoreCase(value) || "TRUE".equalsIgnoreCase(value);
+ }
+
+ private static boolean isNegative(String value) {
+ return "NO".equalsIgnoreCase(value) || "OFF".equalsIgnoreCase(value) || "FALSE".equalsIgnoreCase(value);
+ }
+}
Added: labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/FullPropertyName.java
===================================================================
--- labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/FullPropertyName.java (rev 0)
+++ labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/FullPropertyName.java 2009-07-28 10:00:29 UTC (rev 28530)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2009,
+ * @author JBoss, a division of Red Hat.
+ */
+package com.arjuna.common.internal.util.propertyservice;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Annotation used to set the name of a property corresponding to a bean field.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com)
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target(ElementType.FIELD)
+public @interface FullPropertyName
+{
+ String name();
+}
Added: labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/PropertyPrefix.java
===================================================================
--- labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/PropertyPrefix.java (rev 0)
+++ labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/PropertyPrefix.java 2009-07-28 10:00:29 UTC (rev 28530)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2009,
+ * @author JBoss, a division of Red Hat.
+ */
+package com.arjuna.common.internal.util.propertyservice;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Annotation used to set the default property name prefix for EnvironmentBean classes
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com)
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target(ElementType.TYPE)
+public @interface PropertyPrefix
+{
+ String prefix();
+}
Added: labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/DummyEnvironmentBean.java
===================================================================
--- labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/DummyEnvironmentBean.java (rev 0)
+++ labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/DummyEnvironmentBean.java 2009-07-28 10:00:29 UTC (rev 28530)
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2009,
+ * @author JBoss, a division of Red Hat.
+ */
+package com.arjuna.common.tests.simple;
+
+import com.arjuna.common.internal.util.propertyservice.PropertyPrefix;
+import com.arjuna.common.internal.util.propertyservice.FullPropertyName;
+
+import java.util.Properties;
+
+/**
+ * Basic EnvironmentBean for test purposes
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com)
+ */
+ at PropertyPrefix(prefix = "myprefix.")
+public class DummyEnvironmentBean {
+ private int myInt = -1;
+ private long myLong = -1;
+ @FullPropertyName(name = "my_custom_name")
+ private String myString = "default";
+ private boolean myBoolean = false;
+
+ public Properties getProperties() {
+ Properties properties = new Properties();
+ properties.setProperty("myprefix.myInt", "1");
+ properties.setProperty("myprefix.myLong", "1");
+ properties.setProperty("my_custom_name", "not_the_default");
+ properties.setProperty("myprefix.myBoolean", "NO");
+ return properties;
+ }
+
+ public int getMyInt()
+ {
+ return myInt;
+ }
+
+ public void setMyInt(int myInt)
+ {
+ this.myInt = myInt;
+ }
+
+ public long getMyLong()
+ {
+ return myLong;
+ }
+
+ public void setMyLong(long myLong)
+ {
+ this.myLong = myLong;
+ }
+
+ public String getMyString()
+ {
+ return myString;
+ }
+
+ public void setMyString(String myString)
+ {
+ this.myString = myString;
+ }
+
+ public boolean isMyBoolean()
+ {
+ return myBoolean;
+ }
+
+ public void setMyBoolean(boolean myBoolean)
+ {
+ this.myBoolean = myBoolean;
+ }
+}
\ No newline at end of file
Added: labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/DummyPropertyManager.java
===================================================================
--- labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/DummyPropertyManager.java (rev 0)
+++ labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/DummyPropertyManager.java 2009-07-28 10:00:29 UTC (rev 28530)
@@ -0,0 +1,127 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2009,
+ * @author JBoss, a division of Red Hat.
+ */
+package com.arjuna.common.tests.simple;
+
+import com.arjuna.common.util.propertyservice.PropertyManager;
+import com.arjuna.common.util.propertyservice.plugins.PropertyManagementPlugin;
+import com.arjuna.common.util.exceptions.LoadPropertiesException;
+import com.arjuna.common.util.exceptions.SavePropertiesException;
+import com.arjuna.common.util.exceptions.ManagementPluginException;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Enumeration;
+import java.lang.reflect.Field;
+import java.io.IOException;
+
+/**
+ * Basic PropertyManager impl for BeanPopulator for test purposes
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com)
+ */
+public class DummyPropertyManager implements PropertyManager
+{
+ public static Set<String> extractKeys(Class environment) throws IllegalAccessException {
+
+ Set<String> keys = new HashSet<String>();
+
+ for(Field field : environment.getDeclaredFields()) {
+ String key = (String)field.get(null);
+
+ if(field.isAnnotationPresent(Deprecated.class)) {
+ continue;
+ }
+
+ keys.add(key);
+ }
+
+ return keys;
+ }
+
+ public Set<String> usedKeys = new HashSet<String>();
+ Properties properties = null;
+
+ public DummyPropertyManager(Properties properties) {
+ this.properties = properties;
+ }
+
+ public String getProperty(String key)
+ {
+ usedKeys.add(key);
+
+ if(properties != null) {
+ return properties.getProperty(key);
+ } else {
+ return null;
+ }
+ }
+
+ public String getProperty(String s, String s1)
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+
+ public String setProperty(String s, String s1, boolean b)
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+
+ public String setProperty(String s, String s1)
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+
+ public String removeProperty(String s)
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+
+ public Properties getProperties()
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+
+ public Enumeration propertyNames()
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+
+ public void load(String s, String s1) throws IOException, ClassNotFoundException, LoadPropertiesException
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+
+ public void save(String s, String s1) throws IOException, ClassNotFoundException, SavePropertiesException
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+
+ public void addManagementPlugin(PropertyManagementPlugin propertyManagementPlugin) throws IOException, ManagementPluginException
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+
+ public boolean verbose()
+ {
+ throw new RuntimeException("this is not expected to be called during the test");
+ }
+}
\ No newline at end of file
Added: labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/EnvironmentBeanTest.java
===================================================================
--- labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/EnvironmentBeanTest.java (rev 0)
+++ labs/jbosstm/trunk/common/tests/com/arjuna/common/tests/simple/EnvironmentBeanTest.java 2009-07-28 10:00:29 UTC (rev 28530)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2009,
+ * @author JBoss, a division of Red Hat.
+ */
+package com.arjuna.common.tests.simple;
+
+import org.junit.Test;
+import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
+
+import java.util.Set;
+
+import static org.junit.Assert.*;
+
+/**
+ * EnvironmentBean tests
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com)
+ */
+public class EnvironmentBeanTest
+{
+ @Test
+ public void beanPopulatorTestWithDummies() throws Exception {
+
+ // check that a bean is populated correctly by the BeanPopulator
+
+ DummyEnvironmentBean testBean = new DummyEnvironmentBean();
+ DummyPropertyManager testManager = new DummyPropertyManager(testBean.getProperties());
+ BeanPopulator.configureFromPropertyManager(testBean, testManager);
+ Set<String> expectedKeys = testBean.getProperties().stringPropertyNames();
+
+ assertEquals(expectedKeys, testManager.usedKeys);
+ }
+}
More information about the jboss-svn-commits
mailing list