Author: oheger Date: Sat May 6 08:05:54 2006 New Revision: 400319 URL: http://svn.apache.org/viewcvs?rev=400319&view=rev Log: Added support for new configuration-tag to DefaultConfigurationBuilder for including other configuration definition files; added support for the optional-attribute for other configuration types than file-based configurations
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/howto_configurationbuilder.xml 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=400319&r1=400318&r2=400319&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 Sat May 6 08:05:54 2006 @@ -256,14 +256,17 @@ XMLPropertyListConfiguration.class, PropertyListConfiguration.class, EXT_XML); + /** Constant for the provider for configuration definition files.*/ + private static final ConfigurationProvider BUILDER_PROVIDER = new ConfigurationBuilderProvider(); + /** An array with the names of the default tags. */ private static final String[] DEFAULT_TAGS = - { "properties", "xml", "hierarchicalXml", "jndi", "system", "plist" }; + { "properties", "xml", "hierarchicalXml", "jndi", "system", "plist", "configuration" }; /** An array with the providers for the default tags. */ private static final ConfigurationProvider[] DEFAULT_PROVIDERS = { PROPERTIES_PROVIDER, XML_PROVIDER, XML_PROVIDER, JNDI_PROVIDER, - SYSTEM_PROVIDER, PLIST_PROVIDER }; + SYSTEM_PROVIDER, PLIST_PROVIDER, BUILDER_PROVIDER }; /** Stores a map with the registered configuration providers. */ private Map providers; @@ -506,8 +509,12 @@ .next(); ConfigurationDeclaration decl = new ConfigurationDeclaration(this, conf); - config.addConfiguration(createConfigurationAt(decl), decl - .attributeValueStr(ATTR_NAME), decl.getAt()); + AbstractConfiguration newConf = createConfigurationAt(decl); + if (newConf != null) + { + config.addConfiguration(newConf, decl + .attributeValueStr(ATTR_NAME), decl.getAt()); + } } } @@ -681,7 +688,8 @@ */ public String getAt() { - return attributeValueStr(ATTR_AT); + String result = attributeValueStr(RESERVED_PREFIX + ATTR_AT); + return (result == null) ? attributeValueStr(ATTR_AT) : result; } /** @@ -692,7 +700,12 @@ */ public boolean isOptional() { - Object value = attributeValue(ATTR_OPTIONAL); + Object value = attributeValue(RESERVED_PREFIX + ATTR_OPTIONAL); + if (value == null) + { + value = attributeValue(ATTR_OPTIONAL); + } + try { return (value != null) ? PropertyConverter.toBoolean(value) @@ -786,7 +799,9 @@ * Creates an instance of a bean class. This implementation expects that * the passed in bean declaration is a declaration for a configuration. * It will determine the responsible configuration provider and delegate - * the call to this instance. + * the call to this instance. If creation of the configuration fails + * and the <code>optional</code> attribute is set, the exception will + * be ignored and <b>null</b> will be returned. * * @param beanClass the bean class (will be ignored) * @param data the declaration @@ -808,7 +823,22 @@ + tagName); } - return provider.getConfiguration(decl); + try + { + return provider.getConfiguration(decl); + } + catch (Exception ex) + { + // If this is an optional configuration, ignore the exception + if (!decl.isOptional()) + { + throw ex; + } + else + { + return null; + } + } } /** @@ -864,17 +894,7 @@ { FileConfiguration config = (FileConfiguration) super .getConfiguration(decl); - try - { - config.load(); - } - catch (ConfigurationException cex) - { - if (!decl.isOptional()) - { - throw cex; - } - } + config.load(); return (AbstractConfiguration) config; } @@ -961,6 +981,37 @@ { return super.createBeanInstance(defaultClass, data); } + } + } + + /** + * A specialized configuration provider class that allows to include other + * configuration definition files. + */ + static class ConfigurationBuilderProvider extends ConfigurationProvider + { + /** + * Creates a new instance of <code>ConfigurationBuilderProvider</code>. + */ + public ConfigurationBuilderProvider() + { + super(DefaultConfigurationBuilder.class); + } + + /** + * Creates the configuration. First creates a configuration builder + * object. Then returns the configuration created by this builder. + * + * @param decl the configuration declaration + * @return the configuration + * @exception Exception if an error occurs + */ + public AbstractConfiguration getConfiguration( + ConfigurationDeclaration decl) throws Exception + { + DefaultConfigurationBuilder builder = (DefaultConfigurationBuilder) super + .getConfiguration(decl); + return builder.getConfiguration(true); } } 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=400319&r1=400318&r2=400319&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 Sat May 6 08:05:54 2006 @@ -72,7 +72,6 @@ */ public void testConfigurationDeclarationIsReserved() { - factory = new DefaultConfigurationBuilder(); DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( factory, factory); DefaultConfigurationNode parent = new DefaultConfigurationNode(); @@ -121,7 +120,6 @@ */ private void checkOldReservedAttribute(String name) { - factory = new DefaultConfigurationBuilder(); DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration( factory, factory); DefaultConfigurationNode parent = new DefaultConfigurationNode(); @@ -144,16 +142,24 @@ */ public void testConfigurationDeclarationGetAttributes() { - factory = new DefaultConfigurationBuilder(); 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 @at", "test1"); + factory.addProperty("/xml @config-at", "test1"); assertEquals("Wrong value of at attribute", "test1", decl.getAt()); - factory.addProperty("/xml @optional", "true"); + factory.addProperty("/xml @at", "test2"); + assertEquals("Wrong value of config-at attribute", "test1", decl.getAt()); + factory.clearProperty("/xml/@config-at"); + assertEquals("Old at attribute not detected", "test2", decl.getAt()); + factory.addProperty("/xml @config-optional", "true"); assertTrue("Wrong value of optional attribute", decl.isOptional()); + factory.addProperty("/xml @optional", "false"); + assertTrue("Wrong value of config-optional attribute", decl.isOptional()); + factory.clearProperty("/xml/@config-optional"); + factory.setProperty("/xml/@optional", Boolean.TRUE); + assertTrue("Old optional attribute not detected", decl.isOptional()); factory.setProperty("/xml/@optional", "invalid value"); try { @@ -328,6 +334,16 @@ .getFileName()); // check some properties + checkProperties(compositeConfiguration); + } + + /** + * Checks if the passed in configuration contains the expected properties. + * + * @param compositeConfiguration the configuration to check + */ + private void checkProperties(Configuration compositeConfiguration) + { assertTrue("Make sure we have loaded our key", compositeConfiguration .getBoolean("test.boolean")); assertEquals("I'm complex!", compositeConfiguration @@ -410,6 +426,25 @@ } /** + * Tries to load a configuration file with an optional, non file-based + * configuration. The optional attribute should work for other configuration + * classes, too. + */ + public void testLoadOptionalNonFileBased() throws ConfigurationException + { + factory.addProperty("/ override/[EMAIL PROTECTED]", + "nonExisting.xml"); + factory.addProperty("/override/configuration[1] @config-optional", + Boolean.TRUE); + factory.addProperty("/override/configuration[1] @config-name", + "optionalConfig"); + CombinedConfiguration config = factory.getConfiguration(false); + assertTrue("Configuration not empty", config.isEmpty()); + assertEquals("Wrong number of configurations", 0, config + .getNumberOfConfigurations()); + } + + /** * Tests loading a definition file with multiple different sources. */ public void testLoadDifferentSources() throws ConfigurationException @@ -543,5 +578,20 @@ listNodes = cca.getNodeCombiner().getListNodes(); assertTrue("Found list nodes for additional combiner", listNodes .isEmpty()); + } + + /** + * Tests whether a configuration builder can itself be declared in a + * configuration definition file. + */ + public void testConfigurationBuilderProvider() + throws ConfigurationException + { + factory.addProperty("/ override/[EMAIL PROTECTED]", TEST_FILE + .getAbsolutePath()); + CombinedConfiguration cc = factory.getConfiguration(false); + assertEquals("Wrong number of configurations", 1, cc + .getNumberOfConfigurations()); + checkProperties(cc); } } Modified: jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml?rev=400319&r1=400318&r2=400319&view=diff ============================================================================== --- jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml (original) +++ jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml Sat May 6 08:05:54 2006 @@ -132,6 +132,23 @@ are also allowed for <code>ConfigurationFactory</code>. A list of all supported tags can be found <a href="howto_configurationfactory.html#Configuration definition file reference">here</a>. + In addition to the default tags provided by <code>ConfigurationFactory</code> + <code>DefaultConfigurationBuilder</code> knows the following tags: + </p> + <p> + <dl> + <dt>configuration</dt> + <dd>The <code>configuration</code> tag allows to include other + configuration definition files. This makes it possible to nest these + definition files up to an arbitrary depth. In fact, this tag will + create another <code>DefaultConfigurationBuilder</code> object, + initialize it, and obtain the <code>CombinedConfiguation</code> from it. + This combined configuration will then be added to the resulting + combined configuration. Like for other file-based configurations the + <code>fileName</code> attribute can be used to specify the configuration + definition file to be loaded. This file must be an XML document that + conforms to the format described here.</dd> + </dl> </p> <p> In the declaration of a configuration source it is possible to set @@ -193,7 +210,13 @@ <tr> <td valign="top"><code>config-optional</code></td> <td>Declares a configuration as optional. This means that errors that - occur when creating the configuration are silently ignored.</td> + occur when creating the configuration are silently ignored. Note that in + case of an error no configuration is added to the resulting combined + configuration. This fact can be used to find out whether an optional + configuration could be successfully created or not: If you specify a name + for the optional configuration (using the <code>config-name</code> + attribute), you can later check the combined configuration whether it + contains a configuration with this name.</td> </tr> </table> </p> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]