Author: oheger Date: Mon Nov 26 20:39:40 2012 New Revision: 1413819 URL: http://svn.apache.org/viewvc?rev=1413819&view=rev Log: [CONFIGURATION-517] Added methods to HierarchicalConfiguration for retrieving sub configurations for all child elements of a given key.
Modified: commons/proper/configuration/trunk/src/changes/changes.xml commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/HierarchicalConfiguration.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/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/changes/changes.xml?rev=1413819&r1=1413818&r2=1413819&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/changes/changes.xml (original) +++ commons/proper/configuration/trunk/src/changes/changes.xml Mon Nov 26 20:39:40 2012 @@ -27,6 +27,10 @@ <body> <release version="2.0" date="in SVN" description="TBD"> + <action dev="oheger" type="add" issue="CONFIGURATION-517"> + Hierarchical configurations now provide methods to obtain sub + configurations for all child elements of a given key. + </action> <action dev="oheger" type="add" issue="CONFIGURATION-514"> Bean declarations now support constructor invocations. </action> 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=1413819&r1=1413818&r2=1413819&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 Mon Nov 26 20:39:40 2012 @@ -224,6 +224,14 @@ public class BaseHierarchicalConfigurati } /** + * {@inheritDoc} This implementation just returns the name of the root node. + */ + public String getRootElementName() + { + return getRootNode().getName(); + } + + /** * Returns the default expression engine. * * @return the default expression engine @@ -629,14 +637,42 @@ public class BaseHierarchicalConfigurati public List<ImmutableHierarchicalConfiguration> immutableConfigurationsAt( String key) { - List<SubnodeConfiguration> subs = configurationsAt(key); - List<ImmutableHierarchicalConfiguration> res = - new ArrayList<ImmutableHierarchicalConfiguration>(subs.size()); - for (SubnodeConfiguration sub : subs) + return toImmutable(configurationsAt(key)); + } + + /** + * {@inheritDoc} This implementation resolves the node(s) selected by the + * given key. If not a single node is selected, an empty list is returned. + * Otherwise, sub configurations for each child of the node are created. + */ + public List<SubnodeConfiguration> childConfigurationsAt(String key) + { + List<ConfigurationNode> nodes = fetchNodeList(key); + if (nodes.size() != 1) { - res.add(ConfigurationUtils.unmodifiableConfiguration(sub)); + return Collections.emptyList(); } - return res; + + ConfigurationNode parent = nodes.get(0); + List<SubnodeConfiguration> subs = + new ArrayList<SubnodeConfiguration>(parent.getChildrenCount()); + for (ConfigurationNode c : parent.getChildren()) + { + subs.add(createSubnodeConfiguration(c)); + } + return subs; + } + + /** + * {@inheritDoc} This implementation first delegates to + * {@code childConfigurationsAt()} to create a list of mutable child + * configurations. Then a list with immutable wrapper configurations is + * created. + */ + public List<ImmutableHierarchicalConfiguration> immutableChildConfigurationsAt( + String key) + { + return toImmutable(childConfigurationsAt(key)); } /** @@ -1073,6 +1109,24 @@ public class BaseHierarchicalConfigurati } /** + * Creates a list with immutable configurations from the given input list. + * + * @param subs a list with mutable configurations + * @return a list with corresponding immutable configurations + */ + private static List<ImmutableHierarchicalConfiguration> toImmutable( + List<? extends HierarchicalConfiguration> subs) + { + List<ImmutableHierarchicalConfiguration> res = + new ArrayList<ImmutableHierarchicalConfiguration>(subs.size()); + for (HierarchicalConfiguration sub : subs) + { + res.add(ConfigurationUtils.unmodifiableConfiguration(sub)); + } + return res; + } + + /** * A specialized visitor that checks if a node is defined. * "Defined" in this terms means that the node or at least one of * its sub nodes is associated with a value. Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/HierarchicalConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/HierarchicalConfiguration.java?rev=1413819&r1=1413818&r2=1413819&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/HierarchicalConfiguration.java (original) +++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/HierarchicalConfiguration.java Mon Nov 26 20:39:40 2012 @@ -173,6 +173,18 @@ public interface HierarchicalConfigurati List<SubnodeConfiguration> configurationsAt(String key); /** + * Returns a list with sub configurations for all child nodes of the node + * selected by the given key. This method works like + * {@link #immutableChildConfigurationsAt(String)}, but returns a list with + * {@code SubnodeConfiguration} objects. + * + * @param key the key for selecting the desired parent node + * @return a collection with {@code SubnodeConfiguration} objects for all + * child nodes of the selected parent node + */ + List<SubnodeConfiguration> childConfigurationsAt(String key); + + /** * Removes all values of the property with the given name and of keys that * start with this name. So if there is a property with the key * "foo" and a property with the key "foo.bar", a call 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=1413819&r1=1413818&r2=1413819&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 Mon Nov 26 20:39:40 2012 @@ -62,6 +62,18 @@ public interface ImmutableHierarchicalCo int getMaxIndex(String key); /** + * Returns the name of the root element of this configuration. This + * information may be of use in some cases, e.g. for sub configurations + * created using the {@code immutableConfigurationsAt()} method. The exact + * meaning of the string returned by this method is specific to a concrete + * implementation. For instance, an XML configuration might return the name + * of the document element. + * + * @return the name of the root element of this configuration + */ + String getRootElementName(); + + /** * <p> * Returns an immutable hierarchical configuration object that wraps the * configuration node specified by the given key. This method provides an @@ -128,4 +140,20 @@ public interface ImmutableHierarchicalCo * configuration represents one of the nodes selected by the passed in key */ List<ImmutableHierarchicalConfiguration> immutableConfigurationsAt(String key); + + /** + * Returns a list of immutable configurations for all direct child elements + * of the node selected by the given key. With this method it is possible to + * inspect the content of a hierarchical structure; all children of a given + * node can be queried without having to know their exact names. If the + * passed in key does not point to a single node, an empty list is returned. + * This is also the result if the node referred to by the key does not have + * child elements. + * + * @param key the key for selecting the desired parent node + * @return a collection with immutable configurations for all child nodes of + * the selected parent node + */ + List<ImmutableHierarchicalConfiguration> immutableChildConfigurationsAt( + 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=1413819&r1=1413818&r2=1413819&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 Mon Nov 26 20:39:40 2012 @@ -1080,6 +1080,64 @@ public class TestHierarchicalConfigurati } /** + * Tests whether immutable configurations for the children of a given node + * can be queried. + */ + @Test + public void testImmutableChildConfigurationsAt() + { + List<ImmutableHierarchicalConfiguration> children = + config.immutableChildConfigurationsAt("tables.table(0)"); + assertEquals("Wrong number of elements", 2, children.size()); + ImmutableHierarchicalConfiguration c1 = children.get(0); + assertEquals("Wrong name (1)", "name", c1.getRootElementName()); + assertEquals("Wrong table name", tables[0], c1.getString(null)); + ImmutableHierarchicalConfiguration c2 = children.get(1); + assertEquals("Wrong name (2)", "fields", c2.getRootElementName()); + assertEquals("Wrong field name", fields[0][0], + c2.getString("field(0).name")); + } + + /** + * Tests whether sub configurations for the children of a given node can be + * queried. + */ + @Test + public void testChildConfigurationsAt() + { + List<SubnodeConfiguration> children = + config.childConfigurationsAt("tables.table(0)"); + assertEquals("Wrong number of elements", 2, children.size()); + SubnodeConfiguration sub = children.get(0); + String newTabName = "otherTabe"; + sub.setProperty(null, newTabName); + assertEquals("Table name not changed", newTabName, + config.getString("tables.table(0).name")); + } + + /** + * Tests the result of childConfigurationsAt() if the key selects multiple + * nodes. + */ + @Test + public void testChildConfigurationsAtNoUniqueKey() + { + assertTrue("Got children", config.childConfigurationsAt("tables.table") + .isEmpty()); + } + + /** + * Tests the result of childConfigurationsAt() if the key does not point to + * an existing node. + */ + @Test + public void testChildConfigurationsAtNotFound() + { + assertTrue("Got children", + config.childConfigurationsAt("not.existing.key").isEmpty()); + } + + /** * Helper method for testing the getKeys(String) method. * * @param prefix the key to pass into getKeys()