Author: oheger
Date: Sat Jun 1 19:55:19 2013
New Revision: 1488572
URL: http://svn.apache.org/r1488572
Log:
Fixed a problem with BaseHierarchicalConfiguration.clone() related to
SubnodeConfiguration management.
It must be ensured that the cloned configuration creates its own data
structures for managing SubnodeConfigurations.
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestBaseHierarchicalConfigurationSynchronization.java
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.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=1488572&r1=1488571&r2=1488572&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
Sat Jun 1 19:55:19 2013
@@ -882,9 +882,7 @@ public class BaseHierarchicalConfigurati
if (changeListener == null)
{
- changeListener = createChangeListener();
- subConfigs = new WeakHashMap<SubnodeConfiguration, Object>();
- addConfigurationListener(changeListener);
+ setUpSubConfigManagementData();
}
sub.addConfigurationListener(changeListener);
sub.initSubConfigManagementData(subConfigs, changeListener);
@@ -915,6 +913,17 @@ public class BaseHierarchicalConfigurati
}
/**
+ * Initializes internal data structures for managing associated
+ * {@code SubnodeConfiguration} objects.
+ */
+ private void setUpSubConfigManagementData()
+ {
+ changeListener = createChangeListener();
+ subConfigs = new WeakHashMap<SubnodeConfiguration, Object>();
+ addConfigurationListener(changeListener);
+ }
+
+ /**
* Creates a listener which reacts on all changes on this configuration or
* one of its {@code SubnodeConfiguration} instances. If such a change is
* detected, some updates have to be performed.
@@ -1219,6 +1228,7 @@ public class BaseHierarchicalConfigurati
getRootNode().visit(v);
copy.setRootNode(v.getClone());
copy.cloneInterpolator(this);
+ copy.setUpSubConfigManagementData();
copy.setSynchronizer(ConfigurationUtils.cloneSynchronizer(getSynchronizer()));
return copy;
Modified:
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestBaseHierarchicalConfigurationSynchronization.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestBaseHierarchicalConfigurationSynchronization.java?rev=1488572&r1=1488571&r2=1488572&view=diff
==============================================================================
---
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestBaseHierarchicalConfigurationSynchronization.java
(original)
+++
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestBaseHierarchicalConfigurationSynchronization.java
Sat Jun 1 19:55:19 2013
@@ -24,11 +24,14 @@ import static org.junit.Assert.assertNul
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import org.apache.commons.configuration.SynchronizerTestImpl.Methods;
import org.apache.commons.configuration.io.FileHandler;
+import org.apache.commons.configuration.tree.ConfigurationNode;
import org.apache.commons.configuration.tree.DefaultConfigurationNode;
import org.junit.Before;
import org.junit.Test;
@@ -238,6 +241,57 @@ public class TestBaseHierarchicalConfigu
}
/**
+ * Tests whether a clone() operation also copies the data used to manage
+ * SubnodeConfiguration objects.
+ */
+ @Test
+ public void testCloneCopySubnodeData()
+ {
+ final Collection<SubnodeConfiguration> validatedConfigs =
+ new LinkedList<SubnodeConfiguration>();
+
+ // A special configuration class which creates SubConfigurations that
+ // record validation operations
+ BaseHierarchicalConfiguration conf2 =
+ new BaseHierarchicalConfiguration(config)
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected SubnodeConfiguration createSubnodeConfiguration(
+ ConfigurationNode node, String subnodeKey)
+ {
+ return new SubnodeConfiguration(this, node, subnodeKey)
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ void validateRootNode()
+ {
+ super.validateRootNode();
+ validatedConfigs.add(this);
+ }
+ };
+ }
+ };
+
+ SubnodeConfiguration sub =
+ conf2.configurationAt("element2.subelement", true);
+ HierarchicalConfiguration copy =
+ (HierarchicalConfiguration) conf2.clone();
+ SubnodeConfiguration sub2 =
+ copy.configurationAt("element2.subelement", true);
+ // This must not cause a validate operation on sub1, but on sub2
+ copy.clearTree("element2");
+ assertNull("Sub2 not detached", sub2.getSubnodeKey());
+ assertNotNull("Sub 1 was detached", sub.getSubnodeKey());
+ assertEquals("Wrong number of validated configs", 1,
+ validatedConfigs.size());
+ assertSame("Wrong validated config", sub2, validatedConfigs.iterator()
+ .next());
+ }
+
+ /**
* Tests whether a SubnodeConfiguration's clearAndDetachFromParent() method
* is correctly synchronized.
*/
Modified:
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.java?rev=1488572&r1=1488571&r2=1488572&view=diff
==============================================================================
---
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.java
(original)
+++
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.java
Sat Jun 1 19:55:19 2013
@@ -29,6 +29,7 @@ import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
@@ -391,8 +392,8 @@ public class TestCombinedConfiguration
.getNodeCombiner());
assertEquals("Wrong number of names", config.getConfigurationNames()
.size(), cc2.getConfigurationNames().size());
- assertTrue("Event listeners were cloned", cc2
- .getConfigurationListeners().isEmpty());
+ assertTrue("Found duplicate event listeners", Collections.disjoint(cc2
+ .getConfigurationListeners(),
config.getConfigurationListeners()));
StrictConfigurationComparator comp = new
StrictConfigurationComparator();
for (int i = 0; i < config.getNumberOfConfigurations(); i++)
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=1488572&r1=1488571&r2=1488572&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
Sat Jun 1 19:55:19 2013
@@ -726,17 +726,18 @@ public class TestHierarchicalConfigurati
@Test
public void testCloneWithEventListeners()
{
- config.addConfigurationListener(new ConfigurationListener()
+ ConfigurationListener l = new ConfigurationListener()
{
public void configurationChanged(ConfigurationEvent event)
{
// just a dummy
}
- });
+ };
+ config.addConfigurationListener(l);
BaseHierarchicalConfiguration copy = (BaseHierarchicalConfiguration)
config
.clone();
- assertTrue("Event listener registered at clone", copy
- .getConfigurationListeners().isEmpty());
+ assertFalse("Event listener registered at clone", copy
+ .getConfigurationListeners().contains(l));
}
/**