[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