Author: oheger
Date: Wed Nov 7 17:13:14 2012
New Revision: 1406722
URL: http://svn.apache.org/viewvc?rev=1406722&view=rev
Log:
Added support for immutable sub configurations.
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ImmutableHierarchicalConfiguration.java
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestHierarchicalConfiguration.java
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java?rev=1406722&r1=1406721&r2=1406722&view=diff
==============================================================================
---
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java
(original)
+++
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java
Wed Nov 7 17:13:14 2012
@@ -544,6 +544,18 @@ public class BaseHierarchicalConfigurati
}
/**
+ * {@inheritDoc} This implementation creates a {@code SubnodeConfiguration}
+ * by delegating to {@code configurationAt()}. Then an immutable wrapper
+ * is created and returned.
+ */
+ public ImmutableHierarchicalConfiguration immutableConfigurationAt(
+ String key, boolean supportUpdates)
+ {
+ return ConfigurationUtils.unmodifiableConfiguration(configurationAt(
+ key, supportUpdates));
+ }
+
+ /**
* Returns a hierarchical subnode configuration for the node specified by
* the given key. This is a short form for {@code configurationAt(key,
* <b>false</b>)}.
@@ -559,6 +571,18 @@ public class BaseHierarchicalConfigurati
}
/**
+ * {@inheritDoc} This implementation creates a {@code SubnodeConfiguration}
+ * by delegating to {@code configurationAt()}. Then an immutable wrapper
+ * is created and returned.
+ */
+ public ImmutableHierarchicalConfiguration immutableConfigurationAt(
+ String key)
+ {
+ return ConfigurationUtils.unmodifiableConfiguration(configurationAt(
+ key));
+ }
+
+ /**
* Returns a list of sub configurations for all configuration nodes
selected
* by the given key. This method will evaluate the passed in key (using the
* current {@code ExpressionEngine}) and then create a subnode
@@ -597,6 +621,25 @@ public class BaseHierarchicalConfigurati
}
/**
+ * {@inheritDoc} This implementation first delegates to
+ * {@code configurationsAt()} to create a list of
+ * {@code SubnodeConfiguration} objects. Then for each element of this list
+ * an unmodifiable wrapper is created.
+ */
+ public List<ImmutableHierarchicalConfiguration> immutableConfigurationsAt(
+ String key)
+ {
+ List<SubnodeConfiguration> subs = configurationsAt(key);
+ List<ImmutableHierarchicalConfiguration> res =
+ new ArrayList<ImmutableHierarchicalConfiguration>(subs.size());
+ for (SubnodeConfiguration sub : subs)
+ {
+ res.add(ConfigurationUtils.unmodifiableConfiguration(sub));
+ }
+ return res;
+ }
+
+ /**
* Creates a subnode configuration for the specified node. This method is
* called by {@code configurationAt()} and
* {@code configurationsAt()}.
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ImmutableHierarchicalConfiguration.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ImmutableHierarchicalConfiguration.java?rev=1406722&r1=1406721&r2=1406722&view=diff
==============================================================================
---
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ImmutableHierarchicalConfiguration.java
(original)
+++
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ImmutableHierarchicalConfiguration.java
Wed Nov 7 17:13:14 2012
@@ -16,6 +16,8 @@
*/
package org.apache.commons.configuration;
+import java.util.List;
+
import org.apache.commons.configuration.tree.ExpressionEngine;
/**
@@ -58,4 +60,72 @@ public interface ImmutableHierarchicalCo
* @return the maximum defined index for this key
*/
int getMaxIndex(String key);
+
+ /**
+ * <p>
+ * Returns an immutable 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
+ * {@code IllegalArgumentException} will be thrown.
+ * </p>
+ * <p>
+ * The difference between this method and the
+ * {@link #subset(String)} method is that
+ * {@code subset()} supports arbitrary subsets of configuration nodes
+ * while {@code immutableConfigurationAt()} only returns a single sub tree.
+ * Please refer to the documentation of the
+ * {@code SubnodeConfiguration} class to obtain further information
+ * about subnode configurations and when they should be used.
+ * </p>
+ *
+ * @param key the key that selects the sub tree
+ * @param supportUpdates a flag whether the returned subnode configuration
+ * should be able to handle updates of its parent
+ * @return a hierarchical configuration that contains this sub tree
+ */
+ ImmutableHierarchicalConfiguration immutableConfigurationAt(String key,
+ boolean supportUpdates);
+
+ /**
+ * Returns an immutable hierarchical configuration for the node specified
by
+ * the given key. This is a short form for {@code
immutableConfigurationAt(key,
+ * <b>false</b>)}.
+ *
+ * @param key the key that selects the sub tree
+ * @return a hierarchical configuration that contains this sub tree
+ */
+ ImmutableHierarchicalConfiguration immutableConfigurationAt(String key);
+
+ /**
+ * Returns a list of immutable configurations for all configuration nodes
selected
+ * by the given key. This method will evaluate the passed in key (using the
+ * current {@code ExpressionEngine}) and then create an immutable subnode
+ * configuration for each returned node (like
+ * {@link #immutableConfigurationAt(String)}}). This is especially
+ * useful when dealing with list-like structures. As an example consider
the
+ * configuration that contains data about database tables and their fields.
+ * If you need access to all fields of a certain table, you can simply do
+ *
+ * <pre>
+ * List<ImmutableHierarchicalConfiguration> fields =
+ * config.immutableConfigurationsAt("tables.table(0).fields.field");
+ * for(Iterator<ImmutableHierarchicalConfiguration> it = fields.iterator();
+ * it.hasNext();)
+ * {
+ * ImmutableHierarchicalConfiguration sub = it.next();
+ * // now the children and attributes of the field node can be
+ * // directly accessed
+ * String fieldName = sub.getString("name");
+ * String fieldType = sub.getString("type");
+ * ...
+ * </pre>
+ *
+ * @param key the key for selecting the desired nodes
+ * @return a list with immutable hierarchical configuration objects; each
+ * configuration represents one of the nodes selected by the passed in key
+ */
+ List<ImmutableHierarchicalConfiguration> immutableConfigurationsAt(String
key);
}
Modified:
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestHierarchicalConfiguration.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestHierarchicalConfiguration.java?rev=1406722&r1=1406721&r2=1406722&view=diff
==============================================================================
---
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestHierarchicalConfiguration.java
(original)
+++
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestHierarchicalConfiguration.java
Wed Nov 7 17:13:14 2012
@@ -63,25 +63,31 @@ public class TestHierarchicalConfigurati
@Before
public void setUp() throws Exception
{
- /**
- * Initialize the configuration with the following structure:
- *
- * tables
- * table
- * name
- * fields
- * field
- * name
- * field
- * name
- */
config = new BaseHierarchicalConfiguration();
+ fillConfiguration(tables);
+ }
+
+ /**
+ * Initialize the configuration with the following structure:
+ *
+ * tables
+ * table
+ * name
+ * fields
+ * field
+ * name
+ * field
+ * name
+ * @param tabNames the array with the names of the test tables
+ */
+ private void fillConfiguration(String[] tabNames)
+ {
ConfigurationNode nodeTables = createNode("tables", null);
- for(int i = 0; i < tables.length; i++)
+ for(int i = 0; i < tabNames.length; i++)
{
ConfigurationNode nodeTable = createNode("table", null);
nodeTables.addChild(nodeTable);
- ConfigurationNode nodeName = createNode("name", tables[i]);
+ ConfigurationNode nodeName = createNode("name", tabNames[i]);
nodeTable.addChild(nodeName);
ConfigurationNode nodeFields = createNode("fields", null);
nodeTable.addChild(nodeFields);
@@ -95,7 +101,6 @@ public class TestHierarchicalConfigurati
config.getRootNode().addChild(nodeTables);
}
-
@Test
public void testSetRootNode()
{
@@ -567,6 +572,43 @@ public class TestHierarchicalConfigurati
}
/**
+ * Tests whether an immutable configuration for a sub tree can be obtained.
+ */
+ @Test
+ public void testImmutableConfigurationAt()
+ {
+ ImmutableHierarchicalConfiguration subConfig =
+ config.immutableConfigurationAt("tables.table(1)");
+ assertEquals("Wrong table name", tables[1],
subConfig.getString("name"));
+ List<Object> lstFlds = subConfig.getList("fields.field.name");
+ assertEquals("Wrong number of fields", fields[1].length,
lstFlds.size());
+ for (int i = 0; i < fields[1].length; i++)
+ {
+ assertEquals("Wrong field at position " + i, fields[1][i],
+ lstFlds.get(i));
+ }
+ }
+
+ /**
+ * Tests whether the support updates flag is taken into account when
+ * creating an immutable sub configuration.
+ */
+ @Test
+ public void testImmutableConfigurationAtSupportUpdates()
+ {
+ String[] tables2 = new String[tables.length];
+ for(int i = 0; i < tables2.length; i++)
+ {
+ tables2[i] = tables[i] + "_other";
+ }
+ ImmutableHierarchicalConfiguration subConfig =
+ config.immutableConfigurationAt("tables.table(1)", true);
+ config.clear();
+ fillConfiguration(tables2);
+ assertEquals("Name not updated", tables2[1],
subConfig.getString("name"));
+ }
+
+ /**
* Tests the configurationAt() method when the passed in key does not
exist.
*/
@Test(expected = IllegalArgumentException.class)
@@ -622,22 +664,46 @@ public class TestHierarchicalConfigurati
}
/**
- * Tests the configurationsAt() method.
+ * Helper method for checking a list of sub configurations pointing to the
+ * single fields of the table configuration.
+ *
+ * @param lstFlds the list with sub configurations
*/
- @Test
- public void testConfigurationsAt()
+ private void checkSubConfigurations(
+ List<? extends ImmutableConfiguration> lstFlds)
{
- List<SubnodeConfiguration> lstFlds =
config.configurationsAt("tables.table(1).fields.field");
assertEquals("Wrong size of fields", fields[1].length, lstFlds.size());
for (int i = 0; i < fields[1].length; i++)
{
- BaseHierarchicalConfiguration sub = lstFlds.get(i);
- assertEquals("Wrong field at position " + i, fields[1][i], sub
- .getString("name"));
+ ImmutableConfiguration sub = lstFlds.get(i);
+ assertEquals("Wrong field at position " + i, fields[1][i],
+ sub.getString("name"));
}
}
/**
+ * Tests the configurationsAt() method.
+ */
+ @Test
+ public void testConfigurationsAt()
+ {
+ List<SubnodeConfiguration> lstFlds =
+ config.configurationsAt("tables.table(1).fields.field");
+ checkSubConfigurations(lstFlds);
+ }
+
+ /**
+ * Tests whether a list of immutable sub configurations can be queried.
+ */
+ @Test
+ public void testImmutableConfigurationsAt()
+ {
+ List<ImmutableHierarchicalConfiguration> lstFlds =
+
config.immutableConfigurationsAt("tables.table(1).fields.field");
+ checkSubConfigurations(lstFlds);
+ }
+
+ /**
* Tests the configurationsAt() method when the passed in key does not
* select any sub nodes.
*/