Author: oheger Date: Thu Jun 8 13:11:29 2006 New Revision: 412848 URL: http://svn.apache.org/viewvc?rev=412848&view=rev Log: Enabled support for variable interpolation in DefaultConfigurationBuilder
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/HierarchicalConfiguration.java jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.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 jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml Modified: jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml?rev=412848&r1=412847&r2=412848&view=diff ============================================================================== --- jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml (original) +++ jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml Thu Jun 8 13:11:29 2006 @@ -15,17 +15,19 @@ </override> </combiner> </header> + <system/> <properties fileName="test.properties" throwExceptionOnMissing="true" config-name="properties"> <reloadingStrategy config-class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy" refreshDelay="10000"/> </properties> - <xml fileName="test.xml" config-name="xml"> + <!-- Fetch the file name from a variable --> + <xml fileName="${test_file_xml}" config-name="xml"> <expressionEngine config-class="org.apache.commons.configuration.tree.DefaultExpressionEngine" propertyDelimiter="/" indexStart="[" indexEnd="]"/> </xml> <additional> - <xml config-name="combiner1" fileName="testcombine1.xml"/> + <xml config-name="combiner1" fileName="${test_file_combine}"/> --> <xml config-name="combiner2" fileName="testcombine2.xml"/> </additional> </configuration> 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?rev=412848&r1=412847&r2=412848&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 Thu Jun 8 13:11:29 2006 @@ -30,6 +30,7 @@ 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.DefaultExpressionEngine; import org.apache.commons.configuration.tree.OverrideCombiner; import org.apache.commons.configuration.tree.UnionCombiner; import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine; @@ -152,6 +153,11 @@ * configuration under the name defined by the <code>ADDITIONAL_NAME</code> * constant. * </p> + * <p> + * Implementation note: This class is not thread-safe. Especially the + * <code>getConfiguration()</code> methods should be called by a single thread + * only. + * </p> * * @since 1.3 * @author Oliver Heger @@ -180,16 +186,40 @@ + ".CONFIG_BEAN_FACTORY_NAME"; /** Constant for the reserved name attribute. */ - static final String ATTR_NAME = XMLBeanDeclaration.RESERVED_PREFIX + "name"; + static final String ATTR_NAME = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START + + XMLBeanDeclaration.RESERVED_PREFIX + + "name" + + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END; + + /** Constant for the name of the at attribute. */ + static final String ATTR_ATNAME = "at"; /** Constant for the reserved at attribute. */ - static final String ATTR_AT = "at"; + static final String ATTR_AT_RES = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START + + XMLBeanDeclaration.RESERVED_PREFIX + + ATTR_ATNAME + + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END; + + /** Constant for the at attribute without the reserved prefix. */ + static final String ATTR_AT = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START + + ATTR_ATNAME + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END; + + /** Constant for the name of the optional attribute. */ + static final String ATTR_OPTIONALNAME = "optional"; /** Constant for the reserved optional attribute. */ - static final String ATTR_OPTIONAL = "optional"; + static final String ATTR_OPTIONAL_RES = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START + + XMLBeanDeclaration.RESERVED_PREFIX + + ATTR_OPTIONALNAME + + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END; + + /** Constant for the optional attribute without the reserved prefix. */ + static final String ATTR_OPTIONAL = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START + + ATTR_OPTIONALNAME + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END; /** Constant for the file name attribute. */ - static final String ATTR_FILENAME = "fileName"; + static final String ATTR_FILENAME = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START + + "fileName" + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END; /** Constant for the name of the header section. */ static final String SEC_HEADER = "header"; @@ -268,6 +298,9 @@ { PROPERTIES_PROVIDER, XML_PROVIDER, XML_PROVIDER, JNDI_PROVIDER, SYSTEM_PROVIDER, PLIST_PROVIDER, BUILDER_PROVIDER }; + /** Stores the configuration that is currently constructed.*/ + private CombinedConfiguration constructedConfiguration; + /** Stores a map with the registered configuration providers. */ private Map providers; @@ -436,15 +469,21 @@ load(); } - CombinedConfiguration result = createOverrideConfiguration(); + CombinedConfiguration result = createResultConfiguration(); + constructedConfiguration = result; + + List overrides = configurationsAt(KEY_OVERRIDE1); + overrides.addAll(configurationsAt(KEY_OVERRIDE2)); + initCombinedConfiguration(result, overrides, KEY_OVERRIDE_LIST); + List additionals = configurationsAt(KEY_UNION); if (!additionals.isEmpty()) { CombinedConfiguration addConfig = new CombinedConfiguration( new UnionCombiner()); + result.addConfiguration(addConfig, ADDITIONAL_NAME); initCombinedConfiguration(addConfig, additionals, KEY_ADDITIONAL_LIST); - result.addConfiguration(addConfig, ADDITIONAL_NAME); } return result; @@ -452,18 +491,16 @@ /** * 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>getConfiguration()</code>. It 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 + * @return the resulting configuration object * @throws ConfigurationException if an error occurs */ - protected CombinedConfiguration createOverrideConfiguration() + protected CombinedConfiguration createResultConfiguration() throws ConfigurationException { XMLBeanDeclaration decl = new XMLBeanDeclaration(this, KEY_RESULT, true); @@ -476,9 +513,6 @@ result.setNodeCombiner(new OverrideCombiner()); } - List overrides = configurationsAt(KEY_OVERRIDE1); - overrides.addAll(configurationsAt(KEY_OVERRIDE2)); - initCombinedConfiguration(result, overrides, KEY_OVERRIDE_LIST); return result; } @@ -491,11 +525,11 @@ * @param containedConfigs the list with the declaratinos of the contained * configurations * @param keyListNodes a list with the declaration of list nodes + * @param interpolConfig the configuration to be used for interpolation * @throws ConfigurationException if an error occurs */ protected void initCombinedConfiguration(CombinedConfiguration config, - List containedConfigs, String keyListNodes) - throws ConfigurationException + List containedConfigs, String keyListNodes) throws ConfigurationException { List listNodes = getList(keyListNodes); for (Iterator it = listNodes.iterator(); it.hasNext();) @@ -512,8 +546,8 @@ AbstractConfiguration newConf = createConfigurationAt(decl); if (newConf != null) { - config.addConfiguration(newConf, decl - .attributeValueStr(ATTR_NAME), decl.getAt()); + config.addConfiguration(newConf, decl.getConfiguration() + .getString(ATTR_NAME), decl.getAt()); } } } @@ -532,6 +566,26 @@ } /** + * Performs interpolation. This method will not only take this configuration + * instance into account (which is the one that loaded the configuration + * definition file), but also the so far constructed combined configuration. + * So variables can be used that point to properties that are defined in + * configuration sources loaded by this builder. + * + * @param value the value to be interpolated + * @return the interpolated value + */ + protected Object interpolate(Object value) + { + Object result = super.interpolate(value); + if (constructedConfiguration != null) + { + result = constructedConfiguration.interpolate(result); + } + return result; + } + + /** * Creates a configuration object from the specified configuration * declaration. * @@ -654,15 +708,16 @@ */ protected static class ConfigurationDeclaration extends XMLBeanDeclaration { - /** Stores a reference to the associated configuration factory. */ + /** Stores a reference to the associated configuration builder. */ private DefaultConfigurationBuilder configurationBuilder; /** * Creates a new instance of <code>ConfigurationDeclaration</code> and * initializes it. * - * @param buikder the associated configuration builder + * @param builder the associated configuration builder * @param config the configuration this declaration is based onto + * @param interpolConfig the configuration to be used for interpolation */ public ConfigurationDeclaration(DefaultConfigurationBuilder builder, HierarchicalConfiguration config) @@ -688,8 +743,9 @@ */ public String getAt() { - String result = attributeValueStr(RESERVED_PREFIX + ATTR_AT); - return (result == null) ? attributeValueStr(ATTR_AT) : result; + String result = getConfiguration().getString(ATTR_AT_RES); + return (result == null) ? getConfiguration().getString(ATTR_AT) + : result; } /** @@ -700,23 +756,14 @@ */ public boolean isOptional() { - Object value = attributeValue(RESERVED_PREFIX + ATTR_OPTIONAL); + Boolean value = getConfiguration().getBoolean(ATTR_OPTIONAL_RES, + null); if (value == null) { - value = attributeValue(ATTR_OPTIONAL); - } - - try - { - return (value != null) ? PropertyConverter.toBoolean(value) - .booleanValue() : false; - } - catch (ConversionException cex) - { - throw new ConfigurationRuntimeException( - "optional attribute does not have a valid boolean value", - cex); + value = getConfiguration().getBoolean(ATTR_OPTIONAL, + Boolean.FALSE); } + return value.booleanValue(); } /** @@ -743,29 +790,6 @@ } /** - * Returns the value of the specified attribute. This can be useful for - * certain <code>ConfigurationProvider</code> implementations. - * - * @param attrName the attribute's name - * @return the attribute's value (or <b>null</b> if it does not exist) - */ - public Object attributeValue(String attrName) - { - return super.attributeValue(attrName); - } - - /** - * Returns the string value of the specified attribute. - * - * @param attrName the attribute's name - * @return the attribute's value (or <b>null</b> if it does not exist) - */ - public String attributeValueStr(String attrName) - { - return super.attributeValueStr(attrName); - } - - /** * Checks whether the given node is reserved. This method will take * further reserved attributes into account * @@ -780,10 +804,23 @@ } return nd.isAttribute() - && ((ATTR_AT.equals(nd.getName()) && nd.getParentNode() - .getAttributeCount(RESERVED_PREFIX + ATTR_AT) == 0) || (ATTR_OPTIONAL + && ((ATTR_ATNAME.equals(nd.getName()) && nd.getParentNode() + .getAttributeCount(RESERVED_PREFIX + ATTR_ATNAME) == 0) || (ATTR_OPTIONALNAME .equals(nd.getName()) && nd.getParentNode() - .getAttributeCount(RESERVED_PREFIX + ATTR_OPTIONAL) == 0)); + .getAttributeCount(RESERVED_PREFIX + ATTR_OPTIONALNAME) == 0)); + } + + /** + * Performs interpolation. This implementation will delegate + * interpolation to the configuration builder, which takes care that the + * currently constructed configuration is taken into account, too. + * + * @param value the value to be interpolated + * @return the interpolated value + */ + protected Object interpolate(Object value) + { + return getConfigurationBuilder().interpolate(value); } } @@ -971,7 +1008,7 @@ BeanDeclaration data) throws Exception { String fileName = ((ConfigurationDeclaration) data) - .attributeValueStr(ATTR_FILENAME); + .getConfiguration().getString(ATTR_FILENAME); if (fileName != null && fileName.toLowerCase().trim().endsWith(fileExtension)) { Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java?rev=412848&r1=412847&r2=412848&view=diff ============================================================================== --- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java (original) +++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java Thu Jun 8 13:11:29 2006 @@ -407,12 +407,12 @@ /** * <p> - * Returns a hierarchical configuration object that wraps the configuration - * node specified by the given key. This method provides an easy means of - * accessing sub trees of a hierarchical configuration. In the returned - * configuration the sub tree can directly be accessed, it becomes the root - * node of this configuration. Because of this the passed in key must select - * exactly one configuration node; otherwise an + * Returns a hierarchical subnode configuration object that wraps the + * configuration node specified by the given key. This method provides an + * easy means of accessing sub trees of a hierarchical configuration. In the + * returned configuration the sub tree can directly be accessed, it becomes + * the root node of this configuration. Because of this the passed in key + * must select exactly one configuration node; otherwise an * <code>IllegalArgumentException</code> will be thrown. * </p> * <p> @@ -420,18 +420,17 @@ * <code>[EMAIL PROTECTED] #subset(String)}</code> method is that * <code>subset()</code> supports arbitrary subsets of configuration nodes * while <code>configurationAt()</code> only returns a single sub tree. - * Actually, the object returned by this method is an instance of - * <code>SubnodeConfiguration</code>. Please refer to the documentation - * of this class to obtain further information about subnode configurations - * and when they should be used. + * Please refer to the documentation of the + * <code>SubnodeConfiguration</code> class to obtain further information + * about subnode configurations and when they should be used. * </p> - * + * * @param key the key that selects the sub tree * @return a hierarchical configuration that contains this sub tree * @see SubnodeConfiguration * @since 1.3 */ - public HierarchicalConfiguration configurationAt(String key) + public SubnodeConfiguration configurationAt(String key) { List nodes = fetchNodeList(key); if (nodes.size() != 1) @@ -489,7 +488,7 @@ * @return the configuration for the given node * @since 1.3 */ - protected HierarchicalConfiguration createSubnodeConfiguration(ConfigurationNode node) + protected SubnodeConfiguration createSubnodeConfiguration(ConfigurationNode node) { return new SubnodeConfiguration(this, node); } Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java?rev=412848&r1=412847&r2=412848&view=diff ============================================================================== --- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java (original) +++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java Thu Jun 8 13:11:29 2006 @@ -113,7 +113,7 @@ * @param node the sub node, for which the configuration is to be created * @return a hierarchical configuration for this sub node */ - protected HierarchicalConfiguration createSubnodeConfiguration(ConfigurationNode node) + protected SubnodeConfiguration createSubnodeConfiguration(ConfigurationNode node) { return new SubnodeConfiguration(getParent(), node); } Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java?rev=412848&r1=412847&r2=412848&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 Thu Jun 8 13:11:29 2006 @@ -17,11 +17,11 @@ import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.PropertyConverter; +import org.apache.commons.configuration.SubnodeConfiguration; import org.apache.commons.configuration.tree.ConfigurationNode; import org.apache.commons.configuration.tree.DefaultConfigurationNode; @@ -85,6 +85,16 @@ * it can have attributes defining meta data or bean properties and even further * nested elements for complex bean properties. * </p> + * <p> + * A <code>XMLBeanDeclaration</code> object is usually created from a + * <code>HierarchicalConfiguration</code>. From this it will derive a + * <code>SubnodeConfiguration</code>, which is used to access the needed + * properties. This subnode configuration can be obtained using the + * <code>[EMAIL PROTECTED] #getConfiguration()}</code> method. All of its properties can + * be accessed in the usual way. To ensure that the property keys used by this + * class are understood by the configuration, the default expression engine will + * be set. + * </p> * * @since 1.3 * @author Oliver Heger @@ -95,18 +105,21 @@ /** Constant for the prefix of reserved attributes. */ public static final String RESERVED_PREFIX = "config-"; + /** Constant for the prefix for reserved attributes.*/ + private static final String ATTR_PREFIX = "[@" + RESERVED_PREFIX; + /** Constant for the bean class attribute. */ - public static final String ATTR_BEAN_CLASS = RESERVED_PREFIX + "class"; + public static final String ATTR_BEAN_CLASS = ATTR_PREFIX + "class]"; /** Constant for the bean factory attribute. */ - public static final String ATTR_BEAN_FACTORY = RESERVED_PREFIX + "factory"; + public static final String ATTR_BEAN_FACTORY = ATTR_PREFIX + "factory]"; /** Constant for the bean factory parameter attribute. */ - public static final String ATTR_FACTORY_PARAM = RESERVED_PREFIX - + "factoryParam"; + public static final String ATTR_FACTORY_PARAM = ATTR_PREFIX + + "factoryParam]"; /** Stores the associated configuration. */ - private HierarchicalConfiguration configuration; + private SubnodeConfiguration configuration; /** Stores the configuration node that contains the bean declaration. */ private ConfigurationNode node; @@ -153,8 +166,8 @@ try { - node = (key == null) ? config.getRoot() : config.configurationAt( - key).getRoot(); + configuration = config.configurationAt(key); + node = configuration.getRootNode(); } catch (IllegalArgumentException iex) { @@ -163,9 +176,10 @@ { throw iex; } + configuration = config.configurationAt(null); node = new DefaultConfigurationNode(); } - configuration = config; + initSubnodeConfiguration(getConfiguration()); } /** @@ -188,7 +202,7 @@ * @param config the configuration * @param node the node with the bean declaration. */ - public XMLBeanDeclaration(HierarchicalConfiguration config, + public XMLBeanDeclaration(SubnodeConfiguration config, ConfigurationNode node) { if (config == null) @@ -203,6 +217,7 @@ this.node = node; configuration = config; + initSubnodeConfiguration(config); } /** @@ -210,7 +225,7 @@ * * @return the associated configuration */ - public HierarchicalConfiguration getConfiguration() + public SubnodeConfiguration getConfiguration() { return configuration; } @@ -233,7 +248,7 @@ */ public String getBeanFactoryName() { - return attributeValueStr(ATTR_BEAN_FACTORY); + return getConfiguration().getString(ATTR_BEAN_FACTORY); } /** @@ -244,7 +259,7 @@ */ public Object getBeanFactoryParameter() { - return attributeValue(ATTR_FACTORY_PARAM); + return getConfiguration().getProperty(ATTR_FACTORY_PARAM); } /** @@ -255,7 +270,7 @@ */ public String getBeanClassName() { - return attributeValueStr(ATTR_BEAN_CLASS); + return getConfiguration().getString(ATTR_BEAN_CLASS); } /** @@ -272,8 +287,7 @@ ConfigurationNode attr = (ConfigurationNode) it.next(); if (!isReservedNode(attr)) { - props.put(attr.getName(), PropertyConverter.interpolate(attr - .getValue(), getConfiguration())); + props.put(attr.getName(), interpolate(attr .getValue())); } } @@ -296,7 +310,7 @@ if (!isReservedNode(child)) { nested.put(child.getName(), new XMLBeanDeclaration( - getConfiguration(), child)); + getConfiguration().configurationAt(child.getName()), child)); } } @@ -304,18 +318,18 @@ } /** - * Returns the value of the specified attribute node or <b>null</b> if it - * does not exist. If there are multiple attributes with this name, this - * implementation selects the first one. - * - * @param attrName the name of the attribute - * @return the value of this attribute - */ - protected Object attributeValue(String attrName) - { - List attrs = getNode().getAttributes(attrName); - return attrs.isEmpty() ? null : ((ConfigurationNode) attrs.get(0)) - .getValue(); + * Performs interpolation for the specified value. This implementation will + * 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 + */ + protected Object interpolate(Object value) + { + return PropertyConverter.interpolate(value, getConfiguration() + .getParent()); } /** @@ -336,15 +350,14 @@ } /** - * Returns the value of the specified attribute as string. This is a - * convenience method. + * Initializes the internally managed subnode configuration. This method + * will set some default values for some properties. * - * @param attrName the name of the attribute - * @return the attribute's value as string + * @param conf the configuration to initialize */ - protected String attributeValueStr(String attrName) + private void initSubnodeConfiguration(SubnodeConfiguration conf) { - Object value = attributeValue(attrName); - return (value != null) ? value.toString() : null; + conf.setThrowExceptionOnMissing(false); + conf.setExpressionEngine(null); } } 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?rev=412848&r1=412847&r2=412848&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 Thu Jun 8 13:11:29 2006 @@ -20,7 +20,6 @@ import java.util.Set; import org.apache.commons.configuration.beanutils.BeanHelper; -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; @@ -64,6 +63,8 @@ System .setProperty("java.naming.factory.initial", "org.apache.commons.configuration.MockStaticMemoryInitialContextFactory"); + System.setProperty("test_file_xml", "test.xml"); + System.setProperty("test_file_combine", "testcombine1.xml"); factory = new DefaultConfigurationBuilder(); } @@ -81,7 +82,7 @@ nd = new DefaultConfigurationNode("optional"); parent.addAttribute(nd); assertTrue("Attribute optional not recognized", decl.isReservedNode(nd)); - nd = new DefaultConfigurationNode(XMLBeanDeclaration.ATTR_BEAN_CLASS); + nd = new DefaultConfigurationNode("config-class"); parent.addAttribute(nd); assertTrue("Inherited attribute not recognized", decl .isReservedNode(nd)); @@ -502,8 +503,10 @@ CombinedConfiguration cc = (CombinedConfiguration) factory .getConfiguration(); + assertEquals("System property not found", "test.xml", + cc.getString("test_file_xml")); PropertiesConfiguration c1 = (PropertiesConfiguration) cc - .getConfiguration(0); + .getConfiguration(1); assertTrue( "Reloading strategy was not set", c1.getReloadingStrategy() instanceof FileChangedReloadingStrategy); @@ -516,6 +519,8 @@ .getString("element2/subelement/subsubelement")); assertEquals("List index not found", "two", xmlConf .getString("list[0]/item[1]")); + assertEquals("Property in combiner file not found", "yellow", cc + .getString("/gui/selcolor")); assertTrue("Delimiter flag was not set", cc .isDelimiterParsingDisabled()); @@ -534,7 +539,7 @@ assertNotNull("Properties configuration not found", cc .getConfiguration("properties")); assertNotNull("XML configuration not found", cc.getConfiguration("xml")); - assertEquals("Wrong number of contained configs", 3, cc + assertEquals("Wrong number of contained configs", 4, cc .getNumberOfConfigurations()); CombinedConfiguration cc2 = (CombinedConfiguration) cc Modified: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java?rev=412848&r1=412847&r2=412848&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 Thu Jun 8 13:11:29 2006 @@ -77,7 +77,7 @@ { try { - decl = new XMLBeanDeclaration(new HierarchicalConfiguration(), + decl = new XMLBeanDeclaration(new HierarchicalConfiguration().configurationAt(null), (ConfigurationNode) null); fail("Could init declaration with null node!"); } Modified: jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml?rev=412848&r1=412847&r2=412848&view=diff ============================================================================== --- jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml (original) +++ jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml Thu Jun 8 13:11:29 2006 @@ -231,6 +231,29 @@ <code>additional</code> section). </p> <p> + Another useful feature is the built-in support for interpolation (i.e. + variable substitution): You can use variables in your configuration + definition file that are defined in declared configuration sources. For + instance, if the name of a configuration file to be loaded is defined by + the system property <code>CONFIG_FILE</code>, you can do something like + this: + </p> + <source><![CDATA[ +<configuration> + <!-- Load the system properties --> + <system/> + <!-- Now load the config file, using a system property as file name --> + <properties fileName="${CONFIG_FILE}"/> +</configuration> +]]></source> + <p> + Note that you can refer only to properties that have already been loaded. + If you change the order of the <code><system></code> and the + <code><properties></code> elements in the example above, an error + will occur because the <code>${CONFIG_FILE}</code> variable will then be + undefined at the moment it is evaluated. + </p> + <p> <strong>The header section</strong> </p> <p> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]