Author: oheger
Date: Sun Mar  8 19:03:22 2009
New Revision: 751500

URL: http://svn.apache.org/viewvc?rev=751500&view=rev
Log:
CONFIGURATION-368: Generate change events for SubnodeConfigurations when 
changes of the parent configuration are detected. Also access the root nodes of 
the child configurations only once when constructing the combined node 
structure of the CombinedConfiguration to avoid multiple reloads.

Modified:
    
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java
    
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java
    
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
    
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestSubnodeConfiguration.java
    commons/proper/configuration/trunk/xdocs/changes.xml

Modified: 
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java?rev=751500&r1=751499&r2=751500&view=diff
==============================================================================
--- 
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java
 (original)
+++ 
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java
 Sun Mar  8 19:03:22 2009
@@ -875,12 +875,11 @@
             }
 
             // Copy data of the root node to the new path
-            HierarchicalConfiguration hc = ConfigurationUtils
+            rootNode = ConfigurationUtils
                     .convertToHierarchical(getConfiguration(),
-                            getConversionExpressionEngine());
-            atParent.appendChildren(hc.getRootNode());
-            atParent.appendAttributes(hc.getRootNode());
-            rootNode = hc.getRootNode();
+                            getConversionExpressionEngine()).getRootNode();
+            atParent.appendChildren(rootNode);
+            atParent.appendAttributes(rootNode);
 
             return result;
         }

Modified: 
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java?rev=751500&r1=751499&r2=751500&view=diff
==============================================================================
--- 
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java
 (original)
+++ 
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java
 Sun Mar  8 19:03:22 2009
@@ -217,7 +217,9 @@
                     {
                         // the root node was changed due to a change of the
                         // parent
+                        fireEvent(EVENT_SUBNODE_CHANGED, null, null, true);
                         setRootNode(currentRoot);
+                        fireEvent(EVENT_SUBNODE_CHANGED, null, null, false);
                     }
                     return currentRoot;
                 }

Modified: 
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java?rev=751500&r1=751499&r2=751500&view=diff
==============================================================================
--- 
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
 (original)
+++ 
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
 Sun Mar  8 19:03:22 2009
@@ -21,7 +21,12 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.text.MessageFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
 
 import junit.framework.Assert;
 import junit.framework.TestCase;
@@ -31,6 +36,7 @@
 import org.apache.commons.configuration.reloading.FileAlwaysReloadingStrategy;
 import org.apache.commons.configuration.tree.DefaultExpressionEngine;
 import org.apache.commons.configuration.tree.NodeCombiner;
+import org.apache.commons.configuration.tree.OverrideCombiner;
 import org.apache.commons.configuration.tree.UnionCombiner;
 
 /**
@@ -718,7 +724,6 @@
         assertTrue("Incorrect configuration", c == pc);
     }
 
-
     public void testGetConfigurationNameList() throws Exception
     {
         config.addConfiguration(setUpTestConfiguration());
@@ -734,6 +739,32 @@
     }
 
     /**
+     * Tests whether changes on a sub node configuration that is part of a
+     * combined configuration are detected. This test is related to
+     * CONFIGURATION-368.
+     */
+    public void testReloadWithSubNodeConfig() throws Exception
+    {
+        final String reloadContent = 
"<config><default><xmlReload1>{0}</xmlReload1></default></config>";
+        config.setForceReloadCheck(true);
+        config.setNodeCombiner(new OverrideCombiner());
+        File testXmlFile1 = writeReloadFile(RELOAD_XML_NAME, reloadContent, 0);
+        final String prefix1 = "default";
+        XMLConfiguration c1 = new XMLConfiguration(testXmlFile1);
+        SubnodeConfiguration sub1 = c1.configurationAt(prefix1, true);
+        assertEquals("Inital test for sub config 1 failed", 0, sub1
+                .getInt("xmlReload1"));
+        config.addConfiguration(sub1);
+        assertEquals(
+                "Could not get value for sub config 1 from combined config", 0,
+                config.getInt("xmlReload1"));
+        c1.setReloadingStrategy(new FileAlwaysReloadingStrategy());
+        writeReloadFile(RELOAD_XML_NAME, reloadContent, 1);
+        assertEquals("Reload of sub config 1 not detected", 1, config
+                .getInt("xmlReload1"));
+    }
+
+    /**
      * Helper method for writing a file. The file is also added to a list and
      * will be deleted in teadDown() automatically.
      *

Modified: 
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestSubnodeConfiguration.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestSubnodeConfiguration.java?rev=751500&r1=751499&r2=751500&view=diff
==============================================================================
--- 
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestSubnodeConfiguration.java
 (original)
+++ 
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestSubnodeConfiguration.java
 Sun Mar  8 19:03:22 2009
@@ -17,7 +17,9 @@
 package org.apache.commons.configuration;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Set;
@@ -25,6 +27,8 @@
 import junit.framework.TestCase;
 
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.configuration.event.ConfigurationEvent;
+import org.apache.commons.configuration.event.ConfigurationListener;
 import org.apache.commons.configuration.reloading.FileAlwaysReloadingStrategy;
 import org.apache.commons.configuration.tree.ConfigurationNode;
 import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
@@ -355,6 +359,31 @@
     }
 
     /**
+     * Tests whether events are fired if a change of the parent is detected.
+     */
+    public void testParentReloadEvents() throws ConfigurationException
+    {
+        setUpReloadTest(true);
+        ConfigurationListenerTestImpl l = new ConfigurationListenerTestImpl();
+        config.addConfigurationListener(l);
+        config.getString("name");
+        assertEquals("Wrong number of events", 2, l.events.size());
+        boolean before = true;
+        for (Iterator it = l.events.iterator(); it.hasNext();)
+        {
+            ConfigurationEvent e = (ConfigurationEvent) it.next();
+            assertEquals("Wrong configuration", config, e.getSource());
+            assertEquals("Wrong event type",
+                    HierarchicalConfiguration.EVENT_SUBNODE_CHANGED, e
+                            .getType());
+            assertNull("Got a property name", e.getPropertyName());
+            assertNull("Got a property value", e.getPropertyValue());
+            assertEquals("Wrong before flag", before, e.isBeforeUpdate());
+            before = !before;
+        }
+    }
+
+    /**
      * Tests a reload operation for the parent configuration when the subnode
      * configuration is aware of reloads, and the parent configuration is
      * accessed first. The new value should be returned.
@@ -505,4 +534,19 @@
     {
         config = new SubnodeConfiguration(parent, getSubnodeRoot(parent));
     }
+
+    /**
+     * A specialized configuration listener for testing whether the expected
+     * events are fired.
+     */
+    private static class ConfigurationListenerTestImpl implements 
ConfigurationListener
+    {
+        /** Stores the events received.*/
+        final List events = new ArrayList();
+
+        public void configurationChanged(ConfigurationEvent event)
+        {
+            events.add(event);
+        }
+    }
 }

Modified: commons/proper/configuration/trunk/xdocs/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/xdocs/changes.xml?rev=751500&r1=751499&r2=751500&view=diff
==============================================================================
--- commons/proper/configuration/trunk/xdocs/changes.xml (original)
+++ commons/proper/configuration/trunk/xdocs/changes.xml Sun Mar  8 19:03:22 
2009
@@ -23,6 +23,12 @@
 
   <body>
     <release version="1.7" date="in SVN" description="">
+      <action dev="oheger" type="fix" issue="CONFIGURATION-368">
+        SubnodeConfiguration now fires an event of type EVENT_SUBNODE_CHANGED
+        if a structural change of the parent configuration was detected. If the
+        SubnodeConfiguration is contained in a CombinedConfiguration, the
+        CombinedConfiguration receives this event and can update itself.
+      </action>
       <action dev="rgoers" type="fix" issue="CONFIGURATION-361">
         MultiFileHierarchicalConfiguration was not using basepath to
         construct the file url. It also threw an exception if the


Reply via email to