Author: rgoers Date: Mon Jan 26 07:04:53 2009 New Revision: 737640 URL: http://svn.apache.org/viewvc?rev=737640&view=rev Log: CONFIGURATION 361 - use basepath in MultiFileHierarchicalConfiguration. Also added DynamicCombinedConfiguration test to TestDefaultConfigurationBuilder
Added: commons/proper/configuration/trunk/conf/testMultiTenentConfigurationBuilder.xml Modified: commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java commons/proper/configuration/trunk/xdocs/changes.xml commons/proper/configuration/trunk/xdocs/userguide/howto_multitenant.xml Added: commons/proper/configuration/trunk/conf/testMultiTenentConfigurationBuilder.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/conf/testMultiTenentConfigurationBuilder.xml?rev=737640&view=auto ============================================================================== --- commons/proper/configuration/trunk/conf/testMultiTenentConfigurationBuilder.xml (added) +++ commons/proper/configuration/trunk/conf/testMultiTenentConfigurationBuilder.xml Mon Jan 26 07:04:53 2009 @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> +<!-- Test configuration definition file that demonstrates complex initialization --> +<configuration> + <header> + <result delimiterParsingDisabled="true" forceReloadCheck="true" + config-class="org.apache.commons.configuration.DynamicCombinedConfiguration" + keyPattern="$${sys:Id}"> + <expressionEngine + config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/> + </result> + <providers> + <provider config-tag="multifile" + config-class="org.apache.commons.configuration.DefaultConfigurationBuilder$FileConfigurationProvider" + configurationClass="org.apache.commons.configuration.MultiFileHierarchicalConfiguration"/> + </providers> + </header> + <override> + <multifile filePattern="testMultiConfiguration_$$${sys:Id}.xml" + config-name="clientConfig"/> + <xml fileName="testMultiConfiguration_default.xml" + config-name="defaultConfig"/> + </override> +</configuration> \ No newline at end of file Modified: commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java?rev=737640&r1=737639&r2=737640&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java (original) +++ commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java Mon Jan 26 07:04:53 2009 @@ -78,6 +78,9 @@ /** True if the constructor has finished */ private boolean init; + /** Return an empty configuration if loading fails */ + private boolean ignoreException = true; + /** * Default Constructor. */ @@ -108,6 +111,16 @@ } /** + * Set to true if an empty Configuration should be returned when loading fails. If + * false an exception will be thrown. + * @param ignoreException The ignore value. + */ + public void setIgnoreException(boolean ignoreException) + { + this.ignoreException = ignoreException; + } + + /** * Creates the file configuration delegate, i.e. the object that implements * functionality required by the <code>FileConfiguration</code> interface. * This base implementation will return an instance of the @@ -628,11 +641,11 @@ { URL url = getURL(path); configuration.setURL(url); - configuration.load(); configuration.setExpressionEngine(getExpressionEngine()); configuration.setReloadingStrategy(getReloadingStrategy()); configuration.addConfigurationListener(this); configuration.addErrorListener(this); + configuration.load(); synchronized (configurationsMap) { if (!configurationsMap.containsKey(path)) @@ -643,11 +656,17 @@ } catch (ConfigurationException ce) { - throw new ConfigurationRuntimeException(ce); + if (!ignoreException) + { + throw new ConfigurationRuntimeException(ce); + } } catch (FileNotFoundException fnfe) { - throw new ConfigurationRuntimeException(fnfe); + if (!ignoreException) + { + throw new ConfigurationRuntimeException(fnfe); + } } return configuration; @@ -662,7 +681,7 @@ try { // try URL - return new URL(resourceLocation); + return ConfigurationUtils.getURL(getBasePath(), resourceLocation); } catch (MalformedURLException ex) { Modified: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java?rev=737640&r1=737639&r2=737640&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java (original) +++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java Mon Jan 26 07:04:53 2009 @@ -76,6 +76,9 @@ private static final File VALIDATION_FILE = new File( "conf/testValidation.xml"); + private static final File MULTI_TENENT_FILE = new File( + "conf/testMultiTenentConfigurationBuilder.xml"); + /** Constant for the name of an optional configuration.*/ private static final String OPTIONAL_NAME = "optionalConfig"; @@ -834,6 +837,43 @@ assertEquals("Incorrect value retrieved","value1",value); } + public void testMultiTenentConfiguration() throws Exception + { + factory.setFile(MULTI_TENENT_FILE); + System.clearProperty("Id"); + + CombinedConfiguration config = factory.getConfiguration(true); + assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); + + verify("1001", config, 15); + verify("1002", config, 25); + verify("1003", config, 35); + verify("1004", config, 50); + verify("1005", config, 50); + } + + public void testMultiTenentConfiguration2() throws Exception + { + factory.setFile(MULTI_TENENT_FILE); + System.setProperty("Id", "1004"); + + CombinedConfiguration config = factory.getConfiguration(true); + assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration); + + verify("1001", config, 15); + verify("1002", config, 25); + verify("1003", config, 35); + verify("1004", config, 50); + verify("1005", config, 50); + } + + private void verify(String key, CombinedConfiguration config, int rows) + { + System.setProperty("Id", key); + int actual = config.getInt("rowsPerPage"); + assertTrue("expected: " + rows + " actual: " + actual, actual == rows); + } + /** * A specialized combined configuration implementation used for testing Modified: commons/proper/configuration/trunk/xdocs/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/xdocs/changes.xml?rev=737640&r1=737639&r2=737640&view=diff ============================================================================== --- commons/proper/configuration/trunk/xdocs/changes.xml (original) +++ commons/proper/configuration/trunk/xdocs/changes.xml Mon Jan 26 07:04:53 2009 @@ -23,6 +23,12 @@ <body> <release version="1.7" date="in SVN" description=""> + <action dev="rgoers" type="fix" issue="CONFIGURATION-361"> + MultiFileHierarchicalConfiguration was not using basepath to + construct the file url. It also threw an exception if the + file pattern resolved to a non-existant file. This is now + configurable. + </action> <action dev="oheger" type="fix" issue="CONFIGURATION-359"> Fixed broken links to the API documentation in the user's guide. </action> Modified: commons/proper/configuration/trunk/xdocs/userguide/howto_multitenant.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/xdocs/userguide/howto_multitenant.xml?rev=737640&r1=737639&r2=737640&view=diff ============================================================================== --- commons/proper/configuration/trunk/xdocs/userguide/howto_multitenant.xml (original) +++ commons/proper/configuration/trunk/xdocs/userguide/howto_multitenant.xml Mon Jan 26 07:04:53 2009 @@ -77,7 +77,7 @@ <header> <result delimiterParsingDisabled="true" forceReloadCheck="true" config-class="org.apache.commons.configuration.DynamicCombinedConfiguration" - keyPattern="${sys:Id}"> + keyPattern="$${sys:Id}"> <expressionEngine config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/> </result> @@ -88,11 +88,26 @@ </providers> </header> <override> - <multifile filePattern="/opt/configs/${sys:Id}/config.xml" config-name="clientConfig"/> + <multifile filePattern="/opt/configs/$$${sys:Id}/config.xml" config-name="clientConfig"/> <xml fileName="/opt/configs/default/config.xml" config-name="defaultConfig"/> </override> </configuration> ]]></source> + <p> + Note how the variables have multiple '$'. This is how variables are escaped and + is necessary because the variables will be interpolated multiple times. Each + attempt will remove the leading '$'. When there is only a single '$' in front + of the '{' the interpolator will then resolve the variable. The first extra '$' + is necessary because DefaultConfigurationBuilder will interpolate any variables + in the configuration. In the case of the multifile configuration item two + leading '$' characters are necessary before the variable because it will be + interpolated by both DefaultConfigurationBuilder and DynamicCombinedConfiguration + before MultiFileHierarchicalConfiguration gets the chance to evaluate it. + Although in this example one would not expect system properties to change + at runtime, other types of lookups such as the MDCStrLookup provided with + SLF4J require that the variables be evaluated as the configuration is being + accessed instead of when the configuration file is processed to behave as desired. + </p> </subsection> <subsection name="PatternSubtreeConfigurationWrapper"> <p>