You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2012/12/29 21:16:40 UTC
svn commit: r1426821 - in /commons/proper/configuration/trunk/src:
main/java/org/apache/commons/configuration/builder/combined/
test/java/org/apache/commons/configuration/builder/combined/ test/resources/
Author: oheger
Date: Sat Dec 29 20:16:40 2012
New Revision: 1426821
URL: http://svn.apache.org/viewvc?rev=1426821&view=rev
Log:
CombinedConfigurationBuilder now creates child builders at a later stage. This makes it possible to enable enhanced interpolation in the definition configuration.
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilder.java
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java
commons/proper/configuration/trunk/src/test/resources/testInterpolation.properties
commons/proper/configuration/trunk/src/test/resources/testInterpolationBuilder.xml
Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilder.java?rev=1426821&r1=1426820&r2=1426821&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilder.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilder.java Sat Dec 29 20:16:40 2012
@@ -567,20 +567,33 @@ public class CombinedConfigurationBuilde
}
/**
+ * <p>
* Returns the configuration builder with the given name. With this method a
* builder of a child configuration which was given a name in the
* configuration definition file can be accessed directly.
+ * </p>
+ * <p>
+ * <strong>Important note:</strong> This method only returns a meaningful
+ * result after the result configuration has been created by calling
+ * {@code getConfiguration()}. If called before, always an exception is
+ * thrown.
+ * </p>
*
* @param name the name of the builder in question
* @return the child configuration builder with this name
- * @throws ConfigurationException if an error occurs setting up the
- * definition configuration or no builder with this name exists
+ * @throws ConfigurationException if information about named builders is not
+ * yet available or no builder with this name exists
*/
public synchronized ConfigurationBuilder<? extends Configuration> getNamedBuilder(
String name) throws ConfigurationException
{
+ if (sourceData == null)
+ {
+ throw new ConfigurationException("Information about child builders"
+ + " has not been setup yet! Call getConfiguration() first.");
+ }
ConfigurationBuilder<? extends Configuration> builder =
- getSourceData().getNamedBuilder(name);
+ sourceData.getNamedBuilder(name);
if (builder == null)
{
throw new ConfigurationException("Builder cannot be resolved: "
@@ -590,21 +603,33 @@ public class CombinedConfigurationBuilde
}
/**
+ * <p>
* Returns a set with the names of all child configuration builders. A tag
* defining a configuration source in the configuration definition file can
* have the {@code config-name} attribute. If this attribute is present, the
* corresponding builder is assigned this name and can be directly accessed
* through the {@link #getNamedBuilder(String)} method. This method returns
* a collection with all available builder names.
+ * </p>
+ * <p>
+ * <strong>Important note:</strong> This method only returns a meaningful
+ * result after the result configuration has been created by calling
+ * {@code getConfiguration()}. If called before, always an empty set is
+ * returned.
+ * </p>
*
- * @return a collection with the names of all builders
- * @throws ConfigurationException if an error occurs setting up the
- * definition configuration
+ * @return a set with the names of all builders
*/
public synchronized Set<String> builderNames()
- throws ConfigurationException
{
- return Collections.unmodifiableSet(getSourceData().builderNames());
+ if (sourceData == null)
+ {
+ return Collections.emptySet();
+ }
+ else
+ {
+ return Collections.unmodifiableSet(sourceData.builderNames());
+ }
}
/**
@@ -749,13 +774,13 @@ public class CombinedConfigurationBuilde
setUpParentInterpolator(currentConfiguration, config);
ConfigurationSourceData data = getSourceData();
- createAndAddConfigurations(result, data.getOverrideBuilders(), data);
- if (!data.getUnionBuilders().isEmpty())
+ data.createAndAddConfigurations(result, data.getOverrideSources());
+ if (!data.getUnionSources().isEmpty())
{
CombinedConfiguration addConfig = createAdditionalsConfiguration(result);
result.addConfiguration(addConfig, ADDITIONAL_NAME);
initNodeCombinerListNodes(addConfig, config, KEY_ADDITIONAL_LIST);
- createAndAddConfigurations(addConfig, data.getUnionBuilders(), data);
+ data.createAndAddConfigurations(addConfig, data.getUnionSources());
}
currentConfiguration = null;
}
@@ -1281,40 +1306,6 @@ public class CombinedConfigurationBuilde
}
/**
- * Queries the current {@code Configuration} objects from the given builders
- * and adds them to the specified combined configuration.
- *
- * @param cc the resulting combined configuration
- * @param builders the collection with configuration builders
- * @param srcData the data object for configuration sources
- * @throws ConfigurationException if an error occurs
- */
- private static void createAndAddConfigurations(CombinedConfiguration cc,
- Collection<ConfigurationBuilder<? extends Configuration>> builders,
- ConfigurationSourceData srcData) throws ConfigurationException
- {
- for (ConfigurationBuilder<? extends Configuration> builder : builders)
- {
- ConfigurationDeclaration decl = srcData.getDeclaration(builder);
- assert decl != null : "Cannot resolve builder!";
- try
- {
- cc.addConfiguration(
- (AbstractConfiguration) builder.getConfiguration(),
- decl.getName(), decl.getAt());
- }
- catch (ConfigurationException cex)
- {
- // ignore exceptions for optional configurations
- if (!decl.isOptional())
- {
- throw cex;
- }
- }
- }
- }
-
- /**
* Creates the map with the default configuration builder providers.
*
* @return the map with default providers
@@ -1342,23 +1333,14 @@ public class CombinedConfigurationBuilde
private class ConfigurationSourceData
{
/** A list with all builders for override configurations. */
- private final Collection<ConfigurationBuilder<? extends Configuration>> overrideBuilders;
+ private final Collection<SubnodeConfiguration> overrideBuilders;
/** A list with all builders for union configurations. */
- private final Collection<ConfigurationBuilder<? extends Configuration>> unionBuilders;
-
- /** A list with all sub builders (override plus union). */
- private final Collection<ConfigurationBuilder<? extends Configuration>> allBuilders;
+ private final Collection<SubnodeConfiguration> unionBuilders;
/** A map for direct access to a builder by its name. */
private final Map<String, ConfigurationBuilder<? extends Configuration>> namedBuilders;
- /**
- * A map for retrieving the bean declarations associated with
- * configuration builders.
- */
- private final Map<ConfigurationBuilder<? extends Configuration>, ConfigurationDeclaration> declarations;
-
/** A listener for reacting on changes of sub builders. */
private BuilderListener changeListener;
@@ -1368,15 +1350,11 @@ public class CombinedConfigurationBuilde
public ConfigurationSourceData()
{
overrideBuilders =
- new LinkedList<ConfigurationBuilder<? extends Configuration>>();
+ new LinkedList<SubnodeConfiguration>();
unionBuilders =
- new LinkedList<ConfigurationBuilder<? extends Configuration>>();
- allBuilders =
- new LinkedList<ConfigurationBuilder<? extends Configuration>>();
+ new LinkedList<SubnodeConfiguration>();
namedBuilders =
new HashMap<String, ConfigurationBuilder<? extends Configuration>>();
- declarations =
- new HashMap<ConfigurationBuilder<? extends Configuration>, ConfigurationDeclaration>();
}
/**
@@ -1388,16 +1366,35 @@ public class CombinedConfigurationBuilde
public void initFromDefinitionConfiguration(
HierarchicalConfiguration config) throws ConfigurationException
{
- createBuilders(overrideBuilders,
- fetchTopLevelOverrideConfigs(config));
- createBuilders(overrideBuilders,
- config.childConfigurationsAt(KEY_OVERRIDE));
- createBuilders(unionBuilders,
- config.childConfigurationsAt(KEY_UNION));
-
- allBuilders.addAll(overrideBuilders);
- allBuilders.addAll(unionBuilders);
- registerChangeListener();
+ overrideBuilders.addAll(fetchTopLevelOverrideConfigs(config));
+ overrideBuilders.addAll(config.childConfigurationsAt(KEY_OVERRIDE));
+ unionBuilders.addAll(config.childConfigurationsAt(KEY_UNION));
+ }
+
+ /**
+ * Processes the declaration of configuration builder providers, creates
+ * the corresponding builder, obtains configurations, and adds them to
+ * the specified result configuration.
+ *
+ * @param ccResult the result configuration
+ * @param srcDecl the collection with the declarations of configuration
+ * sources to process
+ * @throws ConfigurationException if an error occurs
+ */
+ public void createAndAddConfigurations(CombinedConfiguration ccResult,
+ Collection<SubnodeConfiguration> srcDecl)
+ throws ConfigurationException
+ {
+ createBuilderChangeListener();
+ for (HierarchicalConfiguration src : srcDecl)
+ {
+ ConfigurationDeclaration decl =
+ new ConfigurationDeclaration(
+ CombinedConfigurationBuilder.this, src);
+ ConfigurationBuilder<? extends Configuration> builder =
+ createConfigurationBuilder(src, decl);
+ addChildConfiguration(ccResult, decl, builder);
+ }
}
/**
@@ -1406,30 +1403,31 @@ public class CombinedConfigurationBuilde
*/
public void cleanUp()
{
- for (ConfigurationBuilder<?> b : allBuilders)
+ for (ConfigurationBuilder<?> b : namedBuilders.values())
{
b.removeBuilderListener(changeListener);
}
+ namedBuilders.clear();
}
/**
- * Returns a collection with all configuration builders defined in the
- * override section.
+ * Returns a collection with all configuration source declarations
+ * defined in the override section.
*
* @return the override configuration builders
*/
- public Collection<ConfigurationBuilder<? extends Configuration>> getOverrideBuilders()
+ public Collection<SubnodeConfiguration> getOverrideSources()
{
return overrideBuilders;
}
/**
- * Returns a collection with all configuration builders defined in the
- * union section.
+ * Returns a collection with all configuration source declarations
+ * defined in the union section.
*
* @return the union configuration builders
*/
- public Collection<ConfigurationBuilder<? extends Configuration>> getUnionBuilders()
+ public Collection<SubnodeConfiguration> getUnionSources()
{
return unionBuilders;
}
@@ -1459,25 +1457,72 @@ public class CombinedConfigurationBuilde
}
/**
- * Returns the {@code ConfigurationDeclaration} associated with the
- * specified builder. If the builder is unknown, result is <b>null</b>.
+ * Creates a configuration builder based on a source declaration in the
+ * definition configuration.
*
- * @param builder the builder in question
- * @return the {@code ConfigurationDeclaration} for this builder or
- * <b>null</b>
+ * @param src the sub configuration for the current configuration source
+ * @param decl the current {@code ConfigurationDeclaration}
+ * @return the newly created bulder
+ * @throws ConfigurationException if an error occurs
*/
- public ConfigurationDeclaration getDeclaration(
- ConfigurationBuilder<?> builder)
+ private ConfigurationBuilder<? extends Configuration> createConfigurationBuilder(
+ HierarchicalConfiguration src, ConfigurationDeclaration decl)
+ throws ConfigurationException
{
- return declarations.get(builder);
+ ConfigurationBuilderProvider provider =
+ providerForTag(src.getRootElementName());
+ if (provider == null)
+ {
+ throw new ConfigurationException(
+ "Unsupported configuration source: "
+ + src.getRootElementName());
+ }
+
+ ConfigurationBuilder<? extends Configuration> builder =
+ provider.getConfigurationBuilder(decl);
+ if (decl.getName() != null)
+ {
+ namedBuilders.put(decl.getName(), builder);
+ }
+ builder.addBuilderListener(changeListener);
+ return builder;
+ }
+
+ /**
+ * Creates a new configuration using the specified builder and adds it
+ * to the resulting combined configuration.
+ *
+ * @param ccResult the resulting combined configuration
+ * @param decl the current {@code ConfigurationDeclaration}
+ * @param builder the configuration builder
+ * @throws ConfigurationException if an error occurs
+ */
+ private void addChildConfiguration(CombinedConfiguration ccResult,
+ ConfigurationDeclaration decl,
+ ConfigurationBuilder<? extends Configuration> builder)
+ throws ConfigurationException
+ {
+ try
+ {
+ ccResult.addConfiguration(
+ (AbstractConfiguration) builder.getConfiguration(),
+ decl.getName(), decl.getAt());
+ }
+ catch (ConfigurationException cex)
+ {
+ // ignore exceptions for optional configurations
+ if (!decl.isOptional())
+ {
+ throw cex;
+ }
+ }
}
/**
- * Registers a change listener at all sub builders. Whenever one of the
- * sub builders is reset, the combined configuration managed by this
- * builder has to be reset, too.
+ * Creates a listener for builder change events. This listener is
+ * registered at all builders for child configurations.
*/
- private void registerChangeListener()
+ private void createBuilderChangeListener()
{
changeListener = new BuilderListener()
{
@@ -1487,11 +1532,6 @@ public class CombinedConfigurationBuilde
resetResult();
}
};
-
- for (ConfigurationBuilder<?> b : allBuilders)
- {
- b.addBuilderListener(changeListener);
- }
}
/**
@@ -1525,43 +1565,5 @@ public class CombinedConfigurationBuilde
}
return configs;
}
-
- /**
- * Creates configuration builder objects from the given configurations
- * for configuration sources.
- *
- * @param builders the collection with builders to be filled
- * @param sources the definitions for the single configuration sources
- * @throws ConfigurationException if an error occurs
- */
- private void createBuilders(
- Collection<ConfigurationBuilder<? extends Configuration>> builders,
- Collection<? extends HierarchicalConfiguration> sources)
- throws ConfigurationException
- {
- for (HierarchicalConfiguration src : sources)
- {
- ConfigurationBuilderProvider provider =
- providerForTag(src.getRootElementName());
- if (provider == null)
- {
- throw new ConfigurationException(
- "Unsupported configuration source: "
- + src.getRootElementName());
- }
-
- ConfigurationDeclaration decl =
- new ConfigurationDeclaration(
- CombinedConfigurationBuilder.this, src);
- ConfigurationBuilder<? extends Configuration> builder =
- provider.getConfigurationBuilder(decl);
- builders.add(builder);
- declarations.put(builder, decl);
- if (decl.getName() != null)
- {
- namedBuilders.put(decl.getName(), builder);
- }
- }
- }
}
}
Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java?rev=1426821&r1=1426820&r2=1426821&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java Sat Dec 29 20:16:40 2012
@@ -299,6 +299,19 @@ public class TestCombinedConfigurationBu
}
/**
+ * Tests the behavior of builderNames() before the result configuration has
+ * been created.
+ */
+ @Test
+ public void testBuilderNamesBeforeConfigurationAccess()
+ {
+ assertTrue("Got builders (1)", factory.builderNames().isEmpty());
+ factory.configure(new FileBasedBuilderParametersImpl()
+ .setFile(TEST_FILE));
+ assertTrue("Got builders (2)", factory.builderNames().isEmpty());
+ }
+
+ /**
* Tests whether the names of sub builders can be queried.
*/
@Test
@@ -306,6 +319,7 @@ public class TestCombinedConfigurationBu
{
factory.configure(new FileBasedBuilderParametersImpl()
.setFile(TEST_FILE));
+ factory.getConfiguration();
Set<String> names = factory.builderNames();
List<String> expected = Arrays.asList("props", "xml");
assertEquals("Wrong number of named builders", expected.size(),
@@ -321,8 +335,9 @@ public class TestCombinedConfigurationBu
{
factory.configure(new FileBasedBuilderParametersImpl()
.setFile(TEST_FILE));
+ factory.getConfiguration();
Set<String> names = factory.builderNames();
- names.clear();
+ names.add(BUILDER_NAME);
}
/**
@@ -333,6 +348,7 @@ public class TestCombinedConfigurationBu
{
factory.configure(new FileBasedBuilderParametersImpl()
.setFile(TEST_FILE));
+ factory.getConfiguration();
ConfigurationBuilder<? extends Configuration> propBuilder =
factory.getNamedBuilder("props");
assertTrue("Wrong builder class",
@@ -350,6 +366,20 @@ public class TestCombinedConfigurationBu
{
factory.configure(new FileBasedBuilderParametersImpl()
.setFile(TEST_FILE));
+ factory.getConfiguration();
+ factory.getNamedBuilder("nonExistingBuilder");
+ }
+
+ /**
+ * Tries to query a named builder before the result configuration has been
+ * created.
+ */
+ @Test(expected = ConfigurationException.class)
+ public void testGetNamedBuilderBeforeConfigurationAccess()
+ throws ConfigurationException
+ {
+ factory.configure(new FileBasedBuilderParametersImpl()
+ .setFile(TEST_FILE));
factory.getNamedBuilder("nonExistingBuilder");
}
@@ -406,6 +436,7 @@ public class TestCombinedConfigurationBu
Map<String, Object> attrs = new HashMap<String, Object>();
attrs.put("config-reload", Boolean.TRUE);
prepareSubBuilderTest(attrs);
+ factory.getConfiguration();
assertTrue(
"Not a reloading builder",
factory.getNamedBuilder(BUILDER_NAME) instanceof ReloadingFileBasedConfigurationBuilder);
@@ -438,6 +469,7 @@ public class TestCombinedConfigurationBu
{
Map<String, Object> attrs = new HashMap<String, Object>();
prepareSubBuilderTest(attrs);
+ factory.getConfiguration();
BasicConfigurationBuilder<?> subBuilder =
(BasicConfigurationBuilder<?>) factory
.getNamedBuilder(BUILDER_NAME);
Modified: commons/proper/configuration/trunk/src/test/resources/testInterpolation.properties
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/resources/testInterpolation.properties?rev=1426821&r1=1426820&r2=1426821&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/resources/testInterpolation.properties (original)
+++ commons/proper/configuration/trunk/src/test/resources/testInterpolation.properties Sat Dec 29 20:16:40 2012
@@ -17,6 +17,7 @@
# configuration sources created by a DefaultConfigurationBuilder.
# This properties configuration defines a property which is referenced by
# another configuration source.
-# $Id:$
+# $Id$
myvar=abc
+testXmlFile=testInterpolation.xml
Modified: commons/proper/configuration/trunk/src/test/resources/testInterpolationBuilder.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/resources/testInterpolationBuilder.xml?rev=1426821&r1=1426820&r2=1426821&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/resources/testInterpolationBuilder.xml (original)
+++ commons/proper/configuration/trunk/src/test/resources/testInterpolationBuilder.xml Sat Dec 29 20:16:40 2012
@@ -20,12 +20,12 @@
configuration sources created by a DefaultConfigurationBuilder.
This configuration definition file for a DefaultConfigurationBuilder
references multiple sources which contain variable references.
- $Id:$
+ $Id$
-->
<configuration>
<system/>
<properties fileName="testInterpolation.properties"/>
- <xml fileName="testInterpolation.xml" config-name="test">
+ <xml fileName="${testXmlFile}" config-name="test">
<expressionEngine config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
</xml>
</configuration>