Author: oheger
Date: Fri Nov 24 11:13:10 2006
New Revision: 478947

URL: http://svn.apache.org/viewvc?view=rev&rev=478947
Log:
Updated DefaultConfigurationBuilder to use the standard hierarchical expression 
engine; so the dependency to JXPath is no longer needed when working with this 
class

Modified:
    
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java
    
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java
    jakarta/commons/proper/configuration/trunk/xdocs/changes.xml

Modified: 
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java?view=diff&rev=478947&r1=478946&r2=478947
==============================================================================
--- 
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
 Fri Nov 24 11:13:10 2006
@@ -18,6 +18,8 @@
 
 import java.io.File;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -34,7 +36,6 @@
 import org.apache.commons.configuration.tree.DefaultExpressionEngine;
 import org.apache.commons.configuration.tree.OverrideCombiner;
 import org.apache.commons.configuration.tree.UnionCombiner;
-import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
 
 /**
  * <p>
@@ -180,9 +181,6 @@
             .getName()
             + "/ADDITIONAL_CONFIG";
 
-    /** Constant for the expression engine used by this builder. */
-    static final XPathExpressionEngine EXPRESSION_ENGINE = new 
XPathExpressionEngine();
-
     /** Constant for the name of the configuration bean factory. */
     static final String CONFIG_BEAN_FACTORY_NAME = 
DefaultConfigurationBuilder.class
             .getName()
@@ -228,42 +226,42 @@
     static final String SEC_HEADER = "header";
 
     /** Constant for an expression that selects the union configurations. */
-    static final String KEY_UNION = "/additional/*";
+    static final String KEY_UNION = "additional";
 
-    /** Constant for an expression that selects override configurations. */
-    static final String KEY_OVERRIDE1 = "/*[local-name() != 'additional' and "
-            + "local-name() != 'override' and local-name() != '"
-            + SEC_HEADER + "']";
+    /** An array with the names of top level configuration sections.*/
+    static final String[] CONFIG_SECTIONS = {
+        "additional", "override", SEC_HEADER
+    };
 
     /**
      * Constant for an expression that selects override configurations in the
      * override section.
      */
-    static final String KEY_OVERRIDE2 = "/override/*";
+    static final String KEY_OVERRIDE = "override";
 
     /**
      * Constant for the key that points to the list nodes definition of the
      * override combiner.
      */
     static final String KEY_OVERRIDE_LIST = SEC_HEADER
-            + "/combiner/override/list-nodes/node";
+            + ".combiner.override.list-nodes.node";
 
     /**
      * Constant for the key that points to the list nodes definition of the
      * additional combiner.
      */
     static final String KEY_ADDITIONAL_LIST = SEC_HEADER
-            + "/combiner/additional/list-nodes/node";
+            + ".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";
+    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";
+    static final String KEY_COMBINER = KEY_RESULT + ".nodeCombiner";
 
     /** Constant for the XML file extension. */
     static final String EXT_XML = ".xml";
@@ -326,7 +324,6 @@
     {
         super();
         providers = new HashMap();
-        setExpressionEngine(EXPRESSION_ENGINE);
         registerDefaultProviders();
     }
 
@@ -481,11 +478,11 @@
         CombinedConfiguration result = createResultConfiguration();
         constructedConfiguration = result;
 
-        List overrides = configurationsAt(KEY_OVERRIDE1);
-        overrides.addAll(configurationsAt(KEY_OVERRIDE2));
+        List overrides = fetchTopLevelOverrideConfigs();
+        overrides.addAll(fetchChildConfigs(KEY_OVERRIDE));
         initCombinedConfiguration(result, overrides, KEY_OVERRIDE_LIST);
 
-        List additionals = configurationsAt(KEY_UNION);
+        List additionals = fetchChildConfigs(KEY_UNION);
         if (!additionals.isEmpty())
         {
             CombinedConfiguration addConfig = new CombinedConfiguration(
@@ -613,6 +610,73 @@
             // redirect to configuration exceptions
             throw new ConfigurationException(ex);
         }
+    }
+
+    /**
+     * Returns a list with <code>SubnodeConfiguration</code> objects for the
+     * child nodes of the specified configuration node.
+     *
+     * @param node the start node
+     * @return a list with subnode configurations for the node's children
+     */
+    private List fetchChildConfigs(ConfigurationNode node)
+    {
+        List children = node.getChildren();
+        List result = new ArrayList(children.size());
+        for (Iterator it = children.iterator(); it.hasNext();)
+        {
+            result.add(createSubnodeConfiguration((Node) it.next()));
+        }
+        return result;
+    }
+
+    /**
+     * Returns a list with <code>SubnodeConfiguration</code> objects for the
+     * child nodes of the node specified by the given key.
+     *
+     * @param key the key (must define exactly one node)
+     * @return a list with subnode configurations for the node's children
+     */
+    private List fetchChildConfigs(String key)
+    {
+        List nodes = fetchNodeList(key);
+        if (nodes.size() > 0)
+        {
+            return fetchChildConfigs((ConfigurationNode) nodes.get(0));
+        }
+        else
+        {
+            return Collections.EMPTY_LIST;
+        }
+    }
+
+    /**
+     * Finds the override configurations that are defined as top level elements
+     * in the configuration definition file. This method will fetch the child
+     * elements of the root node and remove the nodes that represent other
+     * configuration sections. The remaining nodes are treated as definitions
+     * for override configurations.
+     *
+     * @return a list with subnode configurations for the top level override
+     * configurations
+     */
+    private List fetchTopLevelOverrideConfigs()
+    {
+        List configs = fetchChildConfigs(getRootNode());
+        for (Iterator it = configs.iterator(); it.hasNext();)
+        {
+            String nodeName = ((SubnodeConfiguration) it.next()).getRootNode()
+                    .getName();
+            for (int i = 0; i < CONFIG_SECTIONS.length; i++)
+            {
+                if (CONFIG_SECTIONS[i].equals(nodeName))
+                {
+                    it.remove();
+                    break;
+                }
+            }
+        }
+        return configs;
     }
 
     /**

Modified: 
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java?view=diff&rev=478947&r1=478946&r2=478947
==============================================================================
--- 
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
 Fri Nov 24 11:13:10 2006
@@ -144,25 +144,25 @@
      */
     public void testConfigurationDeclarationGetAttributes()
     {
-        factory.addProperty("/ xml/fileName", "test.xml");
+        factory.addProperty("xml.fileName", "test.xml");
         DefaultConfigurationBuilder.ConfigurationDeclaration decl = new 
DefaultConfigurationBuilder.ConfigurationDeclaration(
                 factory, factory.configurationAt("xml"));
         assertNull("Found an at attribute", decl.getAt());
         assertFalse("Found an optional attribute", decl.isOptional());
-        factory.addProperty("/xml @config-at", "test1");
+        factory.addProperty("[EMAIL PROTECTED]", "test1");
         assertEquals("Wrong value of at attribute", "test1", decl.getAt());
-        factory.addProperty("/xml @at", "test2");
+        factory.addProperty("[EMAIL PROTECTED]", "test2");
         assertEquals("Wrong value of config-at attribute", "test1", 
decl.getAt());
-        factory.clearProperty("/xml/@config-at");
+        factory.clearProperty("[EMAIL PROTECTED]");
         assertEquals("Old at attribute not detected", "test2", decl.getAt());
-        factory.addProperty("/xml @config-optional", "true");
+        factory.addProperty("[EMAIL PROTECTED]", "true");
         assertTrue("Wrong value of optional attribute", decl.isOptional());
-        factory.addProperty("/xml @optional", "false");
+        factory.addProperty("[EMAIL PROTECTED]", "false");
         assertTrue("Wrong value of config-optional attribute", 
decl.isOptional());
-        factory.clearProperty("/xml/@config-optional");
-        factory.setProperty("/xml/@optional", Boolean.TRUE);
+        factory.clearProperty("[EMAIL PROTECTED]");
+        factory.setProperty("[EMAIL PROTECTED]", Boolean.TRUE);
         assertTrue("Old optional attribute not detected", decl.isOptional());
-        factory.setProperty("/xml/@optional", "invalid value");
+        factory.setProperty("[EMAIL PROTECTED]", "invalid value");
         try
         {
             decl.isOptional();
@@ -246,7 +246,7 @@
         factory.addConfigurationProvider("test",
                 new DefaultConfigurationBuilder.ConfigurationProvider(
                         PropertiesConfiguration.class));
-        factory.addProperty("/ [EMAIL PROTECTED]", "true");
+        factory.addProperty("[EMAIL PROTECTED]", "true");
         DefaultConfigurationBuilder.ConfigurationDeclaration decl = new 
DefaultConfigurationBuilder.ConfigurationDeclaration(
                 factory, factory.configurationAt("test"));
         PropertiesConfiguration conf = (PropertiesConfiguration) BeanHelper
@@ -261,7 +261,7 @@
      */
     public void testConfigurationBeanFactoryCreateUnknownTag()
     {
-        factory.addProperty("/ [EMAIL PROTECTED]", "true");
+        factory.addProperty("[EMAIL PROTECTED]", "true");
         DefaultConfigurationBuilder.ConfigurationDeclaration decl = new 
DefaultConfigurationBuilder.ConfigurationDeclaration(
                 factory, factory.configurationAt("test"));
         try
@@ -434,11 +434,11 @@
      */
     public void testLoadOptionalNonFileBased() throws ConfigurationException
     {
-        factory.addProperty("/ override/[EMAIL PROTECTED]",
+        factory.addProperty("[EMAIL PROTECTED]",
                 "nonExisting.xml");
-        factory.addProperty("/override/configuration[1] @config-optional",
+        factory.addProperty("[EMAIL PROTECTED]",
                 Boolean.TRUE);
-        factory.addProperty("/override/configuration[1] @config-name",
+        factory.addProperty("[EMAIL PROTECTED]",
                 "optionalConfig");
         CombinedConfiguration config = factory.getConfiguration(false);
         assertTrue("Configuration not empty", config.isEmpty());
@@ -485,7 +485,7 @@
      */
     public void testSetConfigurationBasePath() throws ConfigurationException
     {
-        factory.addProperty("/ [EMAIL PROTECTED]", "test.properties");
+        factory.addProperty("[EMAIL PROTECTED]", "test.properties");
         File deepDir = new File("conf/config/deep");
         factory.setConfigurationBasePath(deepDir.getAbsolutePath());
 
@@ -593,7 +593,7 @@
     public void testConfigurationBuilderProvider()
             throws ConfigurationException
     {
-        factory.addProperty("/ override/[EMAIL PROTECTED]", TEST_FILE
+        factory.addProperty("[EMAIL PROTECTED]", TEST_FILE
                 .getAbsolutePath());
         CombinedConfiguration cc = factory.getConfiguration(false);
         assertEquals("Wrong number of configurations", 1, cc

Modified: jakarta/commons/proper/configuration/trunk/xdocs/changes.xml
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/xdocs/changes.xml?view=diff&rev=478947&r1=478946&r2=478947
==============================================================================
--- jakarta/commons/proper/configuration/trunk/xdocs/changes.xml (original)
+++ jakarta/commons/proper/configuration/trunk/xdocs/changes.xml Fri Nov 24 
11:13:10 2006
@@ -23,9 +23,17 @@
 
   <body>
     <release version="1.4-dev" date="in SVN">
+      <action dev="oheger" type="update" issue="CONFIGURATION-234">
+        DefaultConfigurationBuilder now internally uses the standard expression
+        engine for hierarchical configurations. So the dependency to Commons
+        JXPath is no more needed when this class is used. Note that this change
+        has some impact on existing code that manually sets properties before
+        the combined configuration is created; this code must now be adapted to
+        the changed syntax of property keys.
+      </action>
       <action dev="oheger" type="add" issue="CONFIGURATION-236">
         HierarchicalConfiguration and some of its sub classes now define a
-       copy constructor.
+        copy constructor.
       </action>
       <action dev="oheger" type="add" issue="CONFIGURATION-197" due-to="Trevor 
Charles Miller">
         A new configuration class for windows ini files was added.



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to