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/01/18 21:49:12 UTC
svn commit: r1233058 - in /commons/proper/configuration/trunk/src:
changes/changes.xml
main/java/org/apache/commons/configuration/CompositeConfiguration.java
test/java/org/apache/commons/configuration/TestCompositeConfiguration.java
Author: oheger
Date: Wed Jan 18 20:49:12 2012
New Revision: 1233058
URL: http://svn.apache.org/viewvc?rev=1233058&view=rev
Log:
[CONFIGURATION-471] Improved handling of in-memory configuration in CompositeConfiguration. Also some Javadocs improvements.
Modified:
commons/proper/configuration/trunk/src/changes/changes.xml
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/CompositeConfiguration.java
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCompositeConfiguration.java
Modified: commons/proper/configuration/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/changes/changes.xml?rev=1233058&r1=1233057&r2=1233058&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/changes/changes.xml (original)
+++ commons/proper/configuration/trunk/src/changes/changes.xml Wed Jan 18 20:49:12 2012
@@ -34,6 +34,10 @@
<action dev="oheger" type="update" issue="CONFIGURATION-475">
Class ConfigurationKey was deprecated in favour of DefaultConfigurationKey.
</action>
+ <action dev="oheger" type="add" issue="CONFIGURATION-471">
+ CompositeConfiguration now provides better support for child
+ configurations that are used as in-memory configuration.
+ </action>
<action dev="oheger" type="update" issue="CONFIGURATION-470">
Classes generated by JavaCC are now created dynamically during the
build process.
Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/CompositeConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/CompositeConfiguration.java?rev=1233058&r1=1233057&r2=1233058&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/CompositeConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/CompositeConfiguration.java Wed Jan 18 20:49:12 2012
@@ -27,11 +27,26 @@ import java.util.ListIterator;
import java.util.Set;
/**
- * This Configuration class allows you to add multiple different types of Configuration
- * to this CompositeConfiguration. If you add Configuration1, and then Configuration2,
- * any properties shared will mean that Configuration1 will be returned.
- * You can add multiple different types or the same type of properties file.
- * If Configuration1 doesn't have the property, then Configuration2 will be checked.
+ * <p>{@code CompositeConfiguration} allows you to add multiple {@code Configuration}
+ * objects to an aggregated configuration. If you add Configuration1, and then Configuration2,
+ * any properties shared will mean that the value defined by Configuration1
+ * will be returned. If Configuration1 doesn't have the property, then
+ * Configuration2 will be checked. You can add multiple different types or the
+ * same type of properties file.</p>
+ * <p>When querying properties the order in which child configurations have been
+ * added is relevant. To deal with property updates, a so-called <em>in-memory
+ * configuration</em> is used. Per default, such a configuration is created
+ * automatically. All property writes target this special configuration. There
+ * are constructors which allow you to provide a specific in-memory configuration.
+ * If used that way, the in-memory configuration is always the last one in the
+ * list of child configurations. This means that for query operations all other
+ * configurations take precedence.</p>
+ * <p>Alternatively it is possible to mark a child configuration as in-memory
+ * configuration when it is added. In this case the treatment of the in-memory
+ * configuration is slightly different: it remains in the list of child
+ * configurations at the position it was added, i.e. its priority for property
+ * queries can be defined by adding the child configurations in the correct
+ * order.</p>
*
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
* @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
@@ -50,6 +65,12 @@ implements Cloneable
private Configuration inMemoryConfiguration;
/**
+ * Stores a flag whether the current in-memory configuration is also a
+ * child configuration.
+ */
+ private boolean inMemoryConfigIsChild;
+
+ /**
* Creates an empty CompositeConfiguration object which can then
* be added some other Configuration files
*/
@@ -59,9 +80,14 @@ implements Cloneable
}
/**
- * Creates a CompositeConfiguration object with a specified in memory
- * configuration. This configuration will store any changes made to
- * the CompositeConfiguration.
+ * Creates a CompositeConfiguration object with a specified <em>in-memory
+ * configuration</em>. This configuration will store any changes made to the
+ * {@code CompositeConfiguration}. Note: Use this constructor if you want to
+ * set a special type of in-memory configuration. If you have a
+ * configuration which should act as both a child configuration and as
+ * in-memory configuration, use
+ * {@link #addConfiguration(Configuration, boolean)} with a value of
+ * <b>true</b> instead.
*
* @param inMemoryConfiguration the in memory configuration to use
*/
@@ -84,11 +110,12 @@ implements Cloneable
}
/**
- * Creates a CompositeConfiguration with a specified in memory
- * configuration, and then adds the given collection of configurations.
+ * Creates a CompositeConfiguration with a specified <em>in-memory
+ * configuration</em>, and then adds the given collection of configurations.
*
* @param inMemoryConfiguration the in memory configuration to use
* @param configurations the collection of configurations to add
+ * @see #CompositeConfiguration(Configuration)
*/
public CompositeConfiguration(Configuration inMemoryConfiguration,
Collection<? extends Configuration> configurations)
@@ -111,17 +138,55 @@ implements Cloneable
*/
public void addConfiguration(Configuration config)
{
+ addConfiguration(config, false);
+ }
+
+ /**
+ * Adds a child configuration and optionally makes it the <em>in-memory
+ * configuration</em>. This means that all future property write operations
+ * are executed on this configuration. Note that the current in-memory
+ * configuration is replaced by the new one. If it was created automatically
+ * or passed to the constructor, it is removed from the list of child
+ * configurations! Otherwise, it stays in the list of child configurations
+ * at its current position, but it passes its role as in-memory
+ * configuration to the new one.
+ *
+ * @param config the configuration to be added
+ * @param asInMemory <b>true</b> if this configuration becomes the new
+ * <em>in-memory</em> configuration, <b>false</b> otherwise
+ * @since 1.8
+ */
+ public void addConfiguration(Configuration config, boolean asInMemory)
+ {
if (!configList.contains(config))
{
- // As the inMemoryConfiguration contains all manually added keys,
- // we must make sure that it is always last. "Normal", non composed
- // configuration add their keys at the end of the configuration and
- // we want to mimic this behavior.
- configList.add(configList.indexOf(inMemoryConfiguration), config);
+ if (asInMemory)
+ {
+ replaceInMemoryConfiguration(config);
+ inMemoryConfigIsChild = true;
+ }
+
+ if (!inMemoryConfigIsChild)
+ {
+ // As the inMemoryConfiguration contains all manually added
+ // keys, we must make sure that it is always last. "Normal", non
+ // composed configurations add their keys at the end of the
+ // configuration and we want to mimic this behavior.
+ configList.add(configList.indexOf(inMemoryConfiguration),
+ config);
+ }
+ else
+ {
+ // However, if the in-memory configuration is a regular child,
+ // only the order in which child configurations are added is
+ // relevant
+ configList.add(config);
+ }
if (config instanceof AbstractConfiguration)
{
- ((AbstractConfiguration) config).setThrowExceptionOnMissing(isThrowExceptionOnMissing());
+ ((AbstractConfiguration) config)
+ .setThrowExceptionOnMissing(isThrowExceptionOnMissing());
}
}
}
@@ -152,7 +217,9 @@ implements Cloneable
}
/**
- * Remove all configuration reinitialize the in memory configuration.
+ * Removes all child configurations and reinitializes the <em>in-memory
+ * configuration</em>. <strong>Attention:</strong> A new in-memory
+ * configuration is created; the old one is lost.
*/
@Override
public void clear()
@@ -164,6 +231,7 @@ implements Cloneable
((BaseConfiguration) inMemoryConfiguration).setListDelimiter(getListDelimiter());
((BaseConfiguration) inMemoryConfiguration).setDelimiterParsingDisabled(isDelimiterParsingDisabled());
configList.add(inMemoryConfiguration);
+ inMemoryConfigIsChild = false;
}
/**
@@ -467,6 +535,21 @@ implements Cloneable
}
/**
+ * Replaces the current in-memory configuration by the given one.
+ *
+ * @param config the new in-memory configuration
+ */
+ private void replaceInMemoryConfiguration(Configuration config)
+ {
+ if (!inMemoryConfigIsChild)
+ {
+ // remove current in-memory configuration
+ configList.remove(inMemoryConfiguration);
+ }
+ inMemoryConfiguration = config;
+ }
+
+ /**
* Adds the value of a property to the given list. This method is used by
* {@code getList()} for gathering property values from the child
* configurations.
Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCompositeConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCompositeConfiguration.java?rev=1233058&r1=1233057&r2=1233058&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCompositeConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCompositeConfiguration.java Wed Jan 18 20:49:12 2012
@@ -876,6 +876,45 @@ public class TestCompositeConfiguration
}
/**
+ * Tests whether a configuration can act as both regular child configuration
+ * and in-memory configuration. This test is related to CONFIGURATION-471.
+ */
+ @Test
+ public void testUseChildConfigAsInMemoryConfig()
+ {
+ conf1.setProperty(TEST_PROPERTY, "conf1");
+ conf2.setProperty(TEST_PROPERTY, "conf2");
+ cc.addConfiguration(conf1, true);
+ cc.addConfiguration(conf2);
+ assertEquals("Wrong number of configurations", 2,
+ cc.getNumberOfConfigurations());
+ assertEquals("Wrong property", "conf1", cc.getString(TEST_PROPERTY));
+ cc.addProperty("newProperty", "newValue");
+ assertEquals("Not added to in-memory config", "newValue",
+ conf1.getString("newProperty"));
+ }
+
+ /**
+ * Tests whether the in-memory configuration can be replaced by a new child
+ * configuration.
+ */
+ @Test
+ public void testReplaceInMemoryConfig()
+ {
+ conf1.setProperty(TEST_PROPERTY, "conf1");
+ conf2.setProperty(TEST_PROPERTY, "conf2");
+ cc.addConfiguration(conf1, true);
+ cc.addProperty("newProperty1", "newValue1");
+ cc.addConfiguration(conf2, true);
+ cc.addProperty("newProperty2", "newValue2");
+ assertEquals("Wrong property", "conf1", cc.getString(TEST_PROPERTY));
+ assertEquals("Not added to in-memory config", "newValue1",
+ conf1.getString("newProperty1"));
+ assertEquals("In-memory config not changed", "newValue2",
+ conf2.getString("newProperty2"));
+ }
+
+ /**
* A test configuration event listener that counts the number of received
* events. Used for testing the event facilities.
*/