You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by oh...@apache.org on 2006/04/30 18:19:52 UTC

svn commit: r398368 - in /jakarta/commons/proper/configuration/trunk: conf/ src/java/org/apache/commons/configuration/ src/java/org/apache/commons/configuration/beanutils/ src/test/org/apache/commons/configuration/ src/test/org/apache/commons/configura...

Author: oheger
Date: Sun Apr 30 09:19:51 2006
New Revision: 398368

URL: http://svn.apache.org/viewcvs?rev=398368&view=rev
Log:
Updated DefaultConfigurationBuilder to deal with an extended header section

Modified:
    jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java
    jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java
    jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java

Modified: jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml?rev=398368&r1=398367&r2=398368&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml (original)
+++ jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml Sun Apr 30 09:19:51 2006
@@ -2,6 +2,10 @@
 <!-- Test configuration definition file that demonstrates complex initialization -->
 <configuration>
   <header>
+    <result delimiterParsingDisabled="true">
+      <nodeCombiner config-class="org.apache.commons.configuration.tree.OverrideCombiner"/>
+      <expressionEngine config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
+    </result>
     <combiner>
       <override>
         <list-nodes>

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java?rev=398368&r1=398367&r2=398368&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java Sun Apr 30 09:19:51 2006
@@ -30,7 +30,6 @@
 import org.apache.commons.configuration.plist.PropertyListConfiguration;
 import org.apache.commons.configuration.plist.XMLPropertyListConfiguration;
 import org.apache.commons.configuration.tree.ConfigurationNode;
-import org.apache.commons.configuration.tree.NodeCombiner;
 import org.apache.commons.configuration.tree.OverrideCombiner;
 import org.apache.commons.configuration.tree.UnionCombiner;
 import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
@@ -119,8 +118,8 @@
  * </tr>
  * <tr>
  * <td valign="top"><code>config-optional</code></td>
- * <td>Declares a configuration as optional. This means that errors when
- * creating the configuration are silently ignored.</td>
+ * <td>Declares a configuration as optional. This means that errors that occur
+ * when creating the configuration are silently ignored.</td>
  * </tr>
  * </table>
  * </p>
@@ -222,6 +221,16 @@
     static final String KEY_ADDITIONAL_LIST = SEC_HEADER
             + "/combiner/additional/list-nodes/node";
 
+    /**
+     * Constant for the key of the result declaration. This key can point to a
+     * bean declaration, which defines properties of the resulting combined
+     * configuration.
+     */
+    static final String KEY_RESULT = SEC_HEADER + "/result";
+
+    /** Constant for the key of the combiner in the result declaration.*/
+    static final String KEY_COMBINER = KEY_RESULT + "/nodeCombiner";
+
     /** Constant for the XML file extension. */
     static final String EXT_XML = ".xml";
 
@@ -424,54 +433,82 @@
             load();
         }
 
-        List overrides = configurationsAt(KEY_OVERRIDE1);
-        overrides.addAll(configurationsAt(KEY_OVERRIDE2));
-        CombinedConfiguration result = createCombinedConfiguration(overrides,
-                new OverrideCombiner(), KEY_OVERRIDE_LIST);
+        CombinedConfiguration result = createOverrideConfiguration();
         List additionals = configurationsAt(KEY_UNION);
         if (!additionals.isEmpty())
         {
-            result.addConfiguration(createCombinedConfiguration(additionals,
-                    new UnionCombiner(), KEY_ADDITIONAL_LIST), ADDITIONAL_NAME);
+            CombinedConfiguration addConfig = new CombinedConfiguration(
+                    new UnionCombiner());
+            initCombinedConfiguration(addConfig, additionals,
+                    KEY_ADDITIONAL_LIST);
+            result.addConfiguration(addConfig, ADDITIONAL_NAME);
         }
 
         return result;
     }
 
     /**
-     * Creates a combined configuration for the configurations of a specific
+     * Creates the resulting combined configuration. This method is called by
+     * <code>getConfiguration()</code>. Its task is to construct the
+     * resulting (override) combined configuration and to add all declared
+     * override configurations to it. This implementation checks whether the
+     * <code>header</code> section of the configuration definition file
+     * contains a <code>result</code> element. If this is the case, it will be
+     * used to initialize the properties of the newly created configuration
+     * object.
+     *
+     * @return the override configuration object
+     * @throws ConfigurationException if an error occurs
+     */
+    protected CombinedConfiguration createOverrideConfiguration()
+            throws ConfigurationException
+    {
+        XMLBeanDeclaration decl = new XMLBeanDeclaration(this, KEY_RESULT, true);
+        CombinedConfiguration result = (CombinedConfiguration) BeanHelper
+                .createBean(decl, CombinedConfiguration.class);
+
+        if (getMaxIndex(KEY_COMBINER) < 0)
+        {
+            // No combiner defined => set default
+            result.setNodeCombiner(new OverrideCombiner());
+        }
+
+        List overrides = configurationsAt(KEY_OVERRIDE1);
+        overrides.addAll(configurationsAt(KEY_OVERRIDE2));
+        initCombinedConfiguration(result, overrides, KEY_OVERRIDE_LIST);
+        return result;
+    }
+
+    /**
+     * Initializes a combined configuration for the configurations of a specific
      * section. This method is called for the override and for the additional
      * section (if it exists).
      *
+     * @param config the configuration to be initialized
      * @param containedConfigs the list with the declaratinos of the contained
      * configurations
-     * @param combiner the node combiner to use
      * @param keyListNodes a list with the declaration of list nodes
-     * @return the new combined configuration
      * @throws ConfigurationException if an error occurs
      */
-    protected CombinedConfiguration createCombinedConfiguration(
-            List containedConfigs, NodeCombiner combiner, String keyListNodes)
+    protected void initCombinedConfiguration(CombinedConfiguration config,
+            List containedConfigs, String keyListNodes)
             throws ConfigurationException
     {
         List listNodes = getList(keyListNodes);
         for (Iterator it = listNodes.iterator(); it.hasNext();)
         {
-            combiner.addListNode((String) it.next());
+            config.getNodeCombiner().addListNode((String) it.next());
         }
 
-        CombinedConfiguration result = new CombinedConfiguration(combiner);
         for (Iterator it = containedConfigs.iterator(); it.hasNext();)
         {
             HierarchicalConfiguration conf = (HierarchicalConfiguration) it
                     .next();
             ConfigurationDeclaration decl = new ConfigurationDeclaration(this,
                     conf);
-            result.addConfiguration(createConfigurationAt(decl), decl
+            config.addConfiguration(createConfigurationAt(decl), decl
                     .attributeValueStr(ATTR_NAME), decl.getAt());
         }
-
-        return result;
     }
 
     /**
@@ -792,7 +829,7 @@
      * configurations. Ensures that the base path is correctly set and that the
      * load() method gets called.
      */
-    static class FileConfigurationProvider extends ConfigurationProvider
+    public static class FileConfigurationProvider extends ConfigurationProvider
     {
         /**
          * Creates a new instance of <code>FileConfigurationProvider</code>.

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java?rev=398368&r1=398367&r2=398368&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java Sun Apr 30 09:19:51 2006
@@ -23,6 +23,7 @@
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.commons.configuration.PropertyConverter;
 import org.apache.commons.configuration.tree.ConfigurationNode;
+import org.apache.commons.configuration.tree.DefaultConfigurationNode;
 
 /**
  * <p>
@@ -117,18 +118,53 @@
      *
      * @param config the configuration
      * @param key the key to the bean declaration (this key must point to
-     * exactly one bean declaration)
+     * exactly one bean declaration or a <code>IllegalArgumentException</code>
+     * exception will be thrown)
      */
     public XMLBeanDeclaration(HierarchicalConfiguration config, String key)
     {
+        this(config, key, false);
+    }
+
+    /**
+     * Creates a new instance of <code>XMLBeanDeclaration</code> and
+     * initializes it from the given configuration. The passed in key points to
+     * the bean declaration. If the key does not exist and the boolean argument
+     * is <b>true</b>, the declaration is initialized with an empty
+     * configuration. It is possible to create objects from such an empty
+     * 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
+     * <b>true</b>, no exception will be thrown if the passed in key is
+     * undefined
+     */
+    public XMLBeanDeclaration(HierarchicalConfiguration config, String key,
+            boolean optional)
+    {
         if (config == null)
         {
             throw new IllegalArgumentException(
                     "Configuration must not be null!");
         }
 
-        node = (key == null) ? config.getRoot() : config.configurationAt(key)
-                .getRoot();
+        try
+        {
+            node = (key == null) ? config.getRoot() : config.configurationAt(
+                    key).getRoot();
+        }
+        catch (IllegalArgumentException iex)
+        {
+            // If we reach this block, the key does not have exactly one value
+            if (!optional || config.getMaxIndex(key) > 0)
+            {
+                throw iex;
+            }
+            node = new DefaultConfigurationNode();
+        }
         configuration = config;
     }
 

Modified: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java?rev=398368&r1=398367&r2=398368&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java Sun Apr 30 09:19:51 2006
@@ -23,6 +23,7 @@
 import org.apache.commons.configuration.beanutils.XMLBeanDeclaration;
 import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
 import org.apache.commons.configuration.tree.DefaultConfigurationNode;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
 
 import junit.framework.TestCase;
 
@@ -480,6 +481,11 @@
                 .getString("element2/subelement/subsubelement"));
         assertEquals("List index not found", "two", xmlConf
                 .getString("list[0]/item[1]"));
+
+        assertTrue("Delimiter flag was not set", cc
+                .isDelimiterParsingDisabled());
+        assertTrue("Expression engine was not set",
+                cc.getExpressionEngine() instanceof XPathExpressionEngine);
     }
 
     /**

Modified: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java?rev=398368&r1=398367&r2=398368&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java Sun Apr 30 09:19:51 2006
@@ -304,6 +304,59 @@
     }
 
     /**
+     * Tests constructing a bean declaration from an undefined key. This should
+     * cause an exception.
+     */
+    public void testInitFromUndefinedKey()
+    {
+        HierarchicalConfiguration config = new HierarchicalConfiguration();
+        setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
+        try
+        {
+            decl = new XMLBeanDeclaration(config, "undefined_key");
+            fail("Could create declaration from an undefined key!");
+        }
+        catch (IllegalArgumentException iex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tests constructing a bean declaration from a key, which is undefined when
+     * the optional flag is set. In this case an empty declaration should be
+     * created, which can be used for creating beans as long as a default class
+     * is provided.
+     */
+    public void testInitFromUndefinedKeyOptional()
+    {
+        HierarchicalConfiguration config = new HierarchicalConfiguration();
+        setupBeanDeclaration(config, KEY, TEST_PROPS, TEST_VALUES);
+        decl = new XMLBeanDeclaration(config, "undefined_key", true);
+        assertNull("Found a bean class", decl.getBeanClassName());
+    }
+
+    /**
+     * Tests constructing a bean declaration from a key with multiple values.
+     * This should cause an exception because keys must be unique.
+     */
+    public void testInitFromMultiValueKey()
+    {
+        HierarchicalConfiguration config = new HierarchicalConfiguration();
+        config.addProperty(KEY, "myFirstKey");
+        config.addProperty(KEY, "mySecondKey");
+        try
+        {
+            decl = new XMLBeanDeclaration(config, KEY);
+            fail("Could create declaration from multi-valued property!");
+        }
+        catch (IllegalArgumentException iex)
+        {
+            // ok
+        }
+    }
+
+    /**
      * Initializes a configuration object with a bean declaration. Under the
      * specified key the given properties will be added.
      *



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org