Author: oheger
Date: Sat May 26 11:49:26 2007
New Revision: 541925
URL: http://svn.apache.org/viewvc?view=rev&rev=541925
Log:
CONFIGURATION-215: Added a getSource() method to CombinedConfiguration
Modified:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
Modified:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java?view=diff&rev=541925&r1=541924&r2=541925
==============================================================================
---
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java
(original)
+++
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java
Sat May 26 11:49:26 2007
@@ -512,6 +512,59 @@
}
/**
+ * Returns the configuration source, in which the specified key is defined.
+ * This method will determine the configuration node that is identified by
+ * the given key. The following constellations are possible:
+ * <ul>
+ * <li>If no node object is found for this key, <b>null</b> is
returned.</li>
+ * <li>If the key maps to multiple nodes belonging to different
+ * configuration sources, a <code>IllegalArgumentException</code> is
+ * thrown (in this case no unique source can be determined).</li>
+ * <li>If exactly one node is found for the key, the (child) configuration
+ * object, to which the node belongs is determined and returned.</li>
+ * <li>For keys that have been added directly to this combined
+ * configuration and that do not belong to the namespaces defined by
+ * existing child configurations this configuration will be returned.</li>
+ * </ul>
+ *
+ * @param key the key of a configuration property
+ * @return the configuration, to which this property belongs or <b>null</b>
+ * if the key cannot be resolved
+ * @throws IllegalArgumentException if the key maps to multiple properties
+ * and the source cannot be determined, or if the key is <b>null</b>
+ * @since 1.5
+ */
+ public Configuration getSource(String key)
+ {
+ if (key == null)
+ {
+ throw new IllegalArgumentException("Key must not be null!");
+ }
+
+ List nodes = fetchNodeList(key);
+ if (nodes.isEmpty())
+ {
+ return null;
+ }
+
+ Iterator it = nodes.iterator();
+ Configuration source = findSourceConfiguration((ConfigurationNode) it
+ .next());
+ while (it.hasNext())
+ {
+ Configuration src = findSourceConfiguration((ConfigurationNode) it
+ .next());
+ if (src != source)
+ {
+ throw new IllegalArgumentException("The key " + key
+ + " is defined by multiple sources!");
+ }
+ }
+
+ return source;
+ }
+
+ /**
* Creates the root node of this combined configuration.
*
* @return the combined root node
@@ -538,6 +591,37 @@
}
/**
+ * Determines the configuration that owns the specified node.
+ *
+ * @param node the node
+ * @return the owning configuration
+ */
+ private Configuration findSourceConfiguration(ConfigurationNode node)
+ {
+ ConfigurationNode root = null;
+ ConfigurationNode current = node;
+
+ // find the root node in this hierarchy
+ while (current != null)
+ {
+ root = current;
+ current = current.getParentNode();
+ }
+
+ // Check with the root nodes of the child configurations
+ for (Iterator it = configurations.iterator(); it.hasNext();)
+ {
+ ConfigData cd = (ConfigData) it.next();
+ if (root == cd.getRootNode())
+ {
+ return cd.getConfiguration();
+ }
+ }
+
+ return this;
+ }
+
+ /**
* An internal helper class for storing information about contained
* configurations.
*/
@@ -555,6 +639,9 @@
/** Stores the at string.*/
private String at;
+ /** Stores the root node for this child configuration.*/
+ private ConfigurationNode rootNode;
+
/**
* Creates a new instance of <code>ConfigData</code> and initializes
* it.
@@ -602,6 +689,17 @@
}
/**
+ * Returns the root node for this child configuration.
+ *
+ * @return the root node of this child configuration
+ * @since 1.5
+ */
+ public ConfigurationNode getRootNode()
+ {
+ return rootNode;
+ }
+
+ /**
* Returns the transformed root node of the stored configuration. The
* term "transformed" means that an eventually defined at
path
* has been applied.
@@ -630,6 +728,7 @@
.convertToHierarchical(getConfiguration());
atParent.appendChildren(hc.getRootNode());
atParent.appendAttributes(hc.getRootNode());
+ rootNode = hc.getRootNode();
return result;
}
Modified:
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java?view=diff&rev=541925&r1=541924&r2=541925
==============================================================================
---
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
(original)
+++
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
Sat May 26 11:49:26 2007
@@ -45,6 +45,12 @@
/** Constant for a test key. */
static final String TEST_KEY = "test.value";
+ /** Constant for the name of the first child configuration.*/
+ static final String CHILD1 = TEST_NAME + "1";
+
+ /** Constant for the name of the second child configuration.*/
+ static final String CHILD2 = TEST_NAME + "2";
+
/** The configuration to be tested. */
CombinedConfiguration config;
@@ -441,6 +447,115 @@
assertTrue("XML file cannot be removed", testXmlFile.delete());
assertTrue("Props file cannot be removed", testPropsFile.delete());
+ }
+
+ /**
+ * Prepares a test of the getSource() method.
+ */
+ private void setUpSourceTest()
+ {
+ HierarchicalConfiguration c1 = new HierarchicalConfiguration();
+ PropertiesConfiguration c2 = new PropertiesConfiguration();
+ c1.addProperty(TEST_KEY, TEST_NAME);
+ c2.addProperty("another.key", "test");
+ config.addConfiguration(c1, CHILD1);
+ config.addConfiguration(c2, CHILD2);
+ }
+
+ /**
+ * Tests the gestSource() method when the source property is defined in a
+ * hierarchical configuration.
+ */
+ public void testGetSourceHierarchical()
+ {
+ setUpSourceTest();
+ assertEquals("Wrong source configuration", config
+ .getConfiguration(CHILD1), config.getSource(TEST_KEY));
+ }
+
+ /**
+ * Tests whether the source configuration can be detected for non
+ * hierarchical configurations.
+ */
+ public void testGetSourceNonHierarchical()
+ {
+ setUpSourceTest();
+ assertEquals("Wrong source configuration", config
+ .getConfiguration(CHILD2), config.getSource("another.key"));
+ }
+
+ /**
+ * Tests the getSource() method when the passed in key is not contained.
+ * Result should be null in this case.
+ */
+ public void testGetSourceUnknown()
+ {
+ setUpSourceTest();
+ assertNull("Wrong result for unknown key", config
+ .getSource("an.unknown.key"));
+ }
+
+ /**
+ * Tests the getSource() method when a null key is passed in. This should
+ * cause an exception.
+ */
+ public void testGetSourceNull()
+ {
+ try
+ {
+ config.getSource(null);
+ fail("Could resolve source for null key!");
+ }
+ catch (IllegalArgumentException iex)
+ {
+ // ok
+ }
+ }
+
+ /**
+ * Tests the getSource() method when the passed in key belongs to the
+ * combined configuration itself.
+ */
+ public void testGetSourceCombined()
+ {
+ setUpSourceTest();
+ final String key = "yet.another.key";
+ config.addProperty(key, Boolean.TRUE);
+ assertEquals("Wrong source for key", config, config.getSource(key));
+ }
+
+ /**
+ * Tests the getSource() method when the passed in key refers to multiple
+ * values, which are all defined in the same source configuration.
+ */
+ public void testGetSourceMulti()
+ {
+ setUpSourceTest();
+ final String key = "list.key";
+ config.getConfiguration(CHILD1).addProperty(key, "1,2,3");
+ assertEquals("Wrong source for multi-value property", config
+ .getConfiguration(CHILD1), config.getSource(key));
+ }
+
+ /**
+ * Tests the getSource() method when the passed in key refers to multiple
+ * values defined by different sources. This should cause an exception.
+ */
+ public void testGetSourceMultiSources()
+ {
+ setUpSourceTest();
+ final String key = "list.key";
+ config.getConfiguration(CHILD1).addProperty(key, "1,2,3");
+ config.getConfiguration(CHILD2).addProperty(key, "a,b,c");
+ try
+ {
+ config.getSource(key);
+ fail("Multiple sources not detected!");
+ }
+ catch (IllegalArgumentException iex)
+ {
+ //ok
+ }
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]