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]