Author: oheger
Date: Mon Jun 23 13:37:59 2008
New Revision: 670741

URL: http://svn.apache.org/viewvc?rev=670741&view=rev
Log:
CONFIGURATION-331: Added a factory method to XMLBeanDeclaration for creating 
the declarations for complex nested properties. Ported changes from trunk to 
this branch.

Modified:
    
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/XMLBeanDeclaration.java
    
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/beanutils/TestXMLBeanDeclaration.java
    
commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml

Modified: 
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/XMLBeanDeclaration.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/XMLBeanDeclaration.java?rev=670741&r1=670740&r2=670741&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/XMLBeanDeclaration.java
 (original)
+++ 
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/XMLBeanDeclaration.java
 Mon Jun 23 13:37:59 2008
@@ -36,7 +36,7 @@
  * fragment:
  * </p>
  * <p>
- * 
+ *
  * <pre>
  *   ...
  *   &lt;personBean config-class=&quot;my.model.PersonBean&quot;
@@ -46,7 +46,7 @@
  *           city=&quot;TestCity&quot;/&gt;
  *   &lt;/personBean&gt;
  * </pre>
- * 
+ *
  * </p>
  * <p>
  * The bean declaration can be contained in an arbitrary element. Here it is 
the
@@ -95,7 +95,7 @@
  * class are understood by the configuration, the default expression engine 
will
  * be set.
  * </p>
- * 
+ *
  * @since 1.3
  * @author Oliver Heger
  * @version $Id$
@@ -129,7 +129,7 @@
      * Creates a new instance of <code>XMLBeanDeclaration</code> and
      * initializes it from the given configuration. The passed in key points to
      * the bean declaration.
-     * 
+     *
      * @param config the configuration
      * @param key the key to the bean declaration (this key must point to
      *        exactly one bean declaration or a
@@ -150,7 +150,7 @@
      * declaration if a default class is provided. If the key on the other hand
      * has multiple values or is undefined and the boolean argument is 
<b>false</b>,
      * a <code>IllegalArgumentException</code> exception will be thrown.
-     * 
+     *
      * @param config the configuration
      * @param key the key to the bean declaration
      * @param optional a flag whether this declaration is optional; if set to
@@ -188,7 +188,7 @@
      * Creates a new instance of <code>XMLBeanDeclaration</code> and
      * initializes it from the given configuration. The configuration's root
      * node must contain the bean declaration.
-     * 
+     *
      * @param config the configuration with the bean declaration
      */
     public XMLBeanDeclaration(AbstractHierarchicalConfiguration<T> config)
@@ -200,7 +200,7 @@
      * Creates a new instance of <code>XMLBeanDeclaration</code> and
      * initializes it with the configuration node that contains the bean
      * declaration.
-     * 
+     *
      * @param config the configuration
      * @param node the node with the bean declaration.
      */
@@ -223,7 +223,7 @@
 
     /**
      * Returns the configuration object this bean declaration is based on.
-     * 
+     *
      * @return the associated configuration
      */
     public SubConfiguration<T> getConfiguration()
@@ -233,7 +233,7 @@
 
     /**
      * Returns the node that contains the bean declaration.
-     * 
+     *
      * @return the configuration node this bean declaration is based on
      */
     public T getNode()
@@ -244,7 +244,7 @@
     /**
      * Returns the name of the bean factory. This information is fetched from
      * the <code>config-factory</code> attribute.
-     * 
+     *
      * @return the name of the bean factory
      */
     public String getBeanFactoryName()
@@ -255,7 +255,7 @@
     /**
      * Returns a parameter for the bean factory. This information is fetched
      * from the <code>config-factoryParam</code> attribute.
-     * 
+     *
      * @return the parameter for the bean factory
      */
     public Object getBeanFactoryParameter()
@@ -266,7 +266,7 @@
     /**
      * Returns the name of the class of the bean to be created. This 
information
      * is obtained from the <code>config-class</code> attribute.
-     * 
+     *
      * @return the name of the bean's class
      */
     public String getBeanClassName()
@@ -277,7 +277,7 @@
     /**
      * Returns a map with the bean's (simple) properties. The properties are
      * collected from all attribute nodes, which are not reserved.
-     * 
+     *
      * @return a map with the bean's properties
      */
     public Map<String, Object> getBeanProperties()
@@ -302,7 +302,7 @@
      * Returns a map with bean declarations for the complex properties of the
      * bean to be created. These declarations are obtained from the child nodes
      * of this declaration's root node.
-     * 
+     *
      * @return a map with bean declarations for complex properties
      */
     public Map<String, BeanDeclaration> getNestedBeanDeclarations()
@@ -315,9 +315,7 @@
                 if (!isReservedNode(child))
                 {
                     String nodeName = getNodeHandler().nodeName(child);
-                    nested.put(nodeName,
-                            new XMLBeanDeclaration<T>(getConfiguration()
-                                    .configurationAt(nodeName), child));
+                    nested.put(nodeName, createBeanDeclaration(child));
                 }
             }
         }
@@ -330,7 +328,7 @@
      * interpolate against the current subnode configuration's parent. If sub
      * classes need a different interpolation mechanism, they should override
      * this method.
-     * 
+     *
      * @param value the value that is to be interpolated
      * @return the interpolated value
      */
@@ -346,7 +344,7 @@
      * properties are collected. Per default there are no reserved nodes, so
      * this implementation always returns <b>false</b>. Derived classes may
      * change this.
-     * 
+     *
      * @param nd the node to be checked
      * @return a flag whether this node is reserved (and does not point to a
      *         property)
@@ -361,7 +359,7 @@
      * This method is called when the maps for the bean's properties and 
complex
      * properties are collected. It checks whether the name of the given
      * attribute starts with the reserved prefix.
-     * 
+     *
      * @param parent the node to which the attribute belongs
      * @param name the name of the attribute in question
      * @return a flag whether this attribute is reserved (and does not point to
@@ -375,7 +373,7 @@
 
     /**
      * Convenience method for obtaining the node handler.
-     * 
+     *
      * @return the node handler
      * @since 2.0
      */
@@ -385,9 +383,29 @@
     }
 
     /**
+     * Creates a new <code>BeanDeclaration</code> for a child node of the
+     * current configuration node. This method is called by
+     * <code>getNestedBeanDeclarations()</code> for all complex sub properties
+     * detected by this method. Derived classes can hook in if they need a
+     * specific initialization. This base implementation creates a
+     * <code>XMLBeanDeclaration</code> that is properly initialized from the
+     * passed in node.
+     *
+     * @param node the child node, for which a <code>BeanDeclaration</code> is
+     *        to be created
+     * @return the <code>BeanDeclaration</code> for this child node
+     * @since 1.6
+     */
+    protected BeanDeclaration createBeanDeclaration(T node)
+    {
+        return new XMLBeanDeclaration<T>(getConfiguration().configurationAt(
+                getNodeHandler().nodeName(node)), node);
+    }
+
+    /**
      * Initializes the internally managed subnode configuration. This method
      * will set some default values for some properties.
-     * 
+     *
      * @param conf the configuration to initialize
      */
     private void initSubnodeConfiguration(

Modified: 
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/beanutils/TestXMLBeanDeclaration.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/beanutils/TestXMLBeanDeclaration.java?rev=670741&r1=670740&r2=670741&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/beanutils/TestXMLBeanDeclaration.java
 (original)
+++ 
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/beanutils/TestXMLBeanDeclaration.java
 Mon Jun 23 13:37:59 2008
@@ -21,6 +21,7 @@
 import junit.framework.TestCase;
 
 import org.apache.commons.configuration2.InMemoryConfiguration;
+import org.apache.commons.configuration2.SubConfiguration;
 import org.apache.commons.configuration2.tree.ConfigurationNode;
 
 /**
@@ -243,10 +244,10 @@
     }
 
     /**
-     * Tests fetching nested bean declarations.
+     * Creates a configuration with data for testing nested bean declarations.
+     * @return the initialized test configuration
      */
-    @SuppressWarnings("unchecked")
-    public void testGetNestedBeanDeclarations()
+    private InMemoryConfiguration prepareNestedBeanDeclarations()
     {
         InMemoryConfiguration config = new InMemoryConfiguration();
         setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
@@ -258,7 +259,16 @@
                     KEY + '.' + COMPLEX_PROPS[i] + "[EMAIL PROTECTED]",
                     COMPLEX_CLASSES[i]);
         }
+        return config;
+    }
 
+    /**
+     * Tests fetching nested bean declarations.
+     */
+    @SuppressWarnings("unchecked")
+    public void testGetNestedBeanDeclarations()
+    {
+        InMemoryConfiguration config = prepareNestedBeanDeclarations();
         decl = new XMLBeanDeclaration<ConfigurationNode>(config, KEY);
         checkProperties(decl, TEST_PROPS, TEST_VALUES);
 
@@ -277,6 +287,35 @@
     }
 
     /**
+     * Tests whether the factory method for creating nested bean declarations
+     * gets called.
+     */
+    public void testGetNestedBeanDeclarationsFactoryMethod()
+    {
+        InMemoryConfiguration config = prepareNestedBeanDeclarations();
+        decl = new XMLBeanDeclaration<ConfigurationNode>(config, KEY)
+        {
+            @Override
+            protected BeanDeclaration createBeanDeclaration(
+                    ConfigurationNode node)
+            {
+                return new XMLBeanDeclarationTestImpl(getConfiguration()
+                        .configurationAt(node.getName()), node);
+            }
+        };
+
+        Map<String, BeanDeclaration> nested = decl.getNestedBeanDeclarations();
+        assertEquals("Wrong number of nested declarations",
+                COMPLEX_PROPS.length, nested.size());
+        for (int i = 0; i < COMPLEX_PROPS.length; i++)
+        {
+            BeanDeclaration d = nested.get(COMPLEX_PROPS[i]);
+            assertTrue("Wrong declaration class: " + d,
+                    d instanceof XMLBeanDeclarationTestImpl);
+        }
+    }
+
+    /**
      * Tests fetching nested bean declarations if none are defined.
      */
     public void testGetNestedBeanDeclarationsEmpty()
@@ -397,4 +436,19 @@
                     props.get(names[i]));
         }
     }
+
+    /**
+     * A helper class used for testing the createBeanDeclaration() factory
+     * method.
+     */
+    private static class XMLBeanDeclarationTestImpl extends
+            XMLBeanDeclaration<ConfigurationNode>
+    {
+        public XMLBeanDeclarationTestImpl(
+                SubConfiguration<ConfigurationNode> config,
+                ConfigurationNode node)
+        {
+            super(config, node);
+        }
+    }
 }

Modified: 
commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml?rev=670741&r1=670740&r2=670741&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml
 (original)
+++ 
commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml
 Mon Jun 23 13:37:59 2008
@@ -79,6 +79,12 @@
     </release>
 
     <release version="1.6" date="in SVN" description="">
+      <action dev="oheger" type="add" issue="CONFIGURATION-331">
+        XMLBeanDeclaration now defines a factory method createBeanDeclaration()
+        for creating the declarations for complex nested properties. This
+        method can be overridden by derived classes for injecting custom
+        BeanDeclaration implementations.
+      </action>
       <action dev="oheger" type="fix" issue="CONFIGURATION-307">
         XMLConfiguration now supports the xml:space attribute. This attribute
         can be used to preserve whitespace in the content of XML elements.


Reply via email to