You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by oh...@apache.org on 2006/07/08 21:46:20 UTC

svn commit: r420182 - in /jakarta/commons/proper/configuration/trunk: src/java/org/apache/commons/configuration/ src/test/org/apache/commons/configuration/ xdocs/

Author: oheger
Date: Sat Jul  8 12:46:20 2006
New Revision: 420182

URL: http://svn.apache.org/viewvc?rev=420182&view=rev
Log:
Added clone() methods to CombinedConfiguration and MapConfiguration. CombinedConfiguration was also given a clear() method.

Modified:
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CombinedConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CompositeConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestMapConfiguration.java
    jakarta/commons/proper/configuration/trunk/xdocs/changes.xml

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?rev=420182&r1=420181&r2=420182&view=diff
==============================================================================
--- 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 Jul  8 12:46:20 2006
@@ -27,6 +27,7 @@
 import org.apache.commons.configuration.event.ConfigurationListener;
 import org.apache.commons.configuration.tree.ConfigurationNode;
 import org.apache.commons.configuration.tree.DefaultConfigurationKey;
+import org.apache.commons.configuration.tree.DefaultConfigurationNode;
 import org.apache.commons.configuration.tree.DefaultExpressionEngine;
 import org.apache.commons.configuration.tree.NodeCombiner;
 import org.apache.commons.configuration.tree.UnionCombiner;
@@ -94,7 +95,7 @@
  * @version $Id$
  */
 public class CombinedConfiguration extends HierarchicalConfiguration implements
-        ConfigurationListener
+        ConfigurationListener, Cloneable
 {
     /**
      * Constant for the invalidate event that is fired when the internal node
@@ -130,8 +131,7 @@
     public CombinedConfiguration(NodeCombiner comb)
     {
         setNodeCombiner((comb != null) ? comb : DEFAULT_COMBINER);
-        configurations = new ArrayList();
-        namedConfigurations = new HashMap();
+        clear();
     }
 
     /**
@@ -398,6 +398,43 @@
     }
 
     /**
+     * Clears this configuration. All contained configurations will be removed.
+     */
+    public void clear()
+    {
+        fireEvent(EVENT_CLEAR, null, null, true);
+        configurations = new ArrayList();
+        namedConfigurations = new HashMap();
+        fireEvent(EVENT_CLEAR, null, null, false);
+        invalidate();
+    }
+
+    /**
+     * Returns a copy of this object. This implementation performs a deep clone,
+     * i.e. all contained configurations will be cloned, too. For this to work,
+     * all contained configurations must be cloneable. Registered event
+     * listeners won't be cloned. The clone will use the same node combiner than
+     * the original.
+     *
+     * @return the copied object
+     */
+    public Object clone()
+    {
+        CombinedConfiguration copy = (CombinedConfiguration) super.clone();
+        copy.clear();
+        for (Iterator it = configurations.iterator(); it.hasNext();)
+        {
+            ConfigData cd = (ConfigData) it.next();
+            copy.addConfiguration((AbstractConfiguration) ConfigurationUtils
+                    .cloneConfiguration(cd.getConfiguration()), cd.getName(),
+                    cd.getAt());
+        }
+
+        copy.setRootNode(new DefaultConfigurationNode());
+        return copy;
+    }
+
+    /**
      * Creates the root node of this combined configuration.
      *
      * @return the combined root node
@@ -435,9 +472,12 @@
         /** Stores the name under which the configuration is stored. */
         private String name;
 
-        /** Stores the at information. */
+        /** Stores the at information as path of nodes. */
         private Collection atPath;
 
+        /** Stores the at string.*/
+        private String at;
+
         /**
          * Creates a new instance of <code>ConfigData</code> and initializes
          * it.
@@ -451,6 +491,7 @@
             configuration = config;
             name = n;
             atPath = parseAt(at);
+            this.at = at;
         }
 
         /**
@@ -471,6 +512,16 @@
         public String getName()
         {
             return name;
+        }
+
+        /**
+         * Returns the at position of this configuration.
+         *
+         * @return the at position
+         */
+        public String getAt()
+        {
+            return at;
         }
 
         /**

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CompositeConfiguration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CompositeConfiguration.java?rev=420182&r1=420181&r2=420182&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CompositeConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/CompositeConfiguration.java Sat Jul  8 12:46:20 2006
@@ -371,6 +371,7 @@
      * won't get cloned.
      *
      * @return the copy
+     * @since 1.3
      */
     public Object clone()
     {

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java?rev=420182&r1=420181&r2=420182&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java Sat Jul  8 12:46:20 2006
@@ -1231,7 +1231,6 @@
     /**
      * A specialized visitor that is able to create a deep copy of a node
      * hierarchy.
-     *
      */
     static class CloneVisitor extends ConfigurationNodeVisitorAdapter
     {
@@ -1239,7 +1238,7 @@
         private Stack copyStack;
 
         /** Stores the result of the clone process. */
-        private Node result;
+        private ConfigurationNode result;
 
         /**
          * Creates a new instance of <code>CloneVisitor</code>.
@@ -1256,7 +1255,7 @@
          */
         public void visitAfterChildren(ConfigurationNode node)
         {
-            Node copy = (Node) copyStack.pop();
+            ConfigurationNode copy = (ConfigurationNode) copyStack.pop();
             if (copyStack.isEmpty())
             {
                 result = copy;
@@ -1277,11 +1276,11 @@
             {
                 if (node.isAttribute())
                 {
-                    ((Node) copyStack.peek()).addAttribute(copy);
+                    ((ConfigurationNode) copyStack.peek()).addAttribute(copy);
                 }
                 else
                 {
-                    ((Node) copyStack.peek()).addChild(copy);
+                    ((ConfigurationNode) copyStack.peek()).addChild(copy);
                 }
             }
 
@@ -1294,7 +1293,7 @@
          *
          * @return the cloned root node
          */
-        public Node getClone()
+        public ConfigurationNode getClone()
         {
             return result;
         }

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java?rev=420182&r1=420181&r2=420182&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java Sat Jul  8 12:46:20 2006
@@ -28,7 +28,7 @@
  * @version $Revision$, $Date$
  * @since 1.1
  */
-public class MapConfiguration extends AbstractConfiguration
+public class MapConfiguration extends AbstractConfiguration implements Cloneable
 {
     /** The Map decorated by this configuration. */
     protected Map map;
@@ -111,5 +111,28 @@
     public Iterator getKeys()
     {
         return map.keySet().iterator();
+    }
+
+    /**
+     * Returns a copy of this object. The returned configuration will contain
+     * the same properties as the original. Event listeners are not cloned.
+     *
+     * @return the copy
+     * @since 1.3
+     */
+    public Object clone()
+    {
+        try
+        {
+            MapConfiguration copy = (MapConfiguration) super.clone();
+            copy.clearConfigurationListeners();
+            copy.map = (Map) ConfigurationUtils.clone(map);
+            return copy;
+        }
+        catch (CloneNotSupportedException cex)
+        {
+            // cannot happen
+            throw new ConfigurationRuntimeException(cex);
+        }
     }
 }

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?rev=420182&r1=420181&r2=420182&view=diff
==============================================================================
--- 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 Jul  8 12:46:20 2006
@@ -338,6 +338,72 @@
     }
 
     /**
+     * Tests cloning a combined configuration.
+     */
+    public void testClone()
+    {
+        config.addConfiguration(setUpTestConfiguration());
+        config.addConfiguration(setUpTestConfiguration(), TEST_NAME, "conf2");
+        config.addConfiguration(new PropertiesConfiguration(), "props");
+
+        CombinedConfiguration cc2 = (CombinedConfiguration) config.clone();
+        assertEquals("Wrong number of contained configurations", config
+                .getNumberOfConfigurations(), cc2.getNumberOfConfigurations());
+        assertSame("Wrong node combiner", config.getNodeCombiner(), cc2
+                .getNodeCombiner());
+        assertEquals("Wrong number of names", config.getConfigurationNames()
+                .size(), cc2.getConfigurationNames().size());
+        assertTrue("Event listeners were cloned", cc2
+                .getConfigurationListeners().isEmpty());
+
+        StrictConfigurationComparator comp = new StrictConfigurationComparator();
+        for (int i = 0; i < config.getNumberOfConfigurations(); i++)
+        {
+            assertNotSame("Configuration at " + i + " was not cloned", config
+                    .getConfiguration(i), cc2.getConfiguration(i));
+            assertEquals("Wrong config class at " + i, config.getConfiguration(
+                    i).getClass(), cc2.getConfiguration(i).getClass());
+            assertTrue("Configs not equal at " + i, comp.compare(config
+                    .getConfiguration(i), cc2.getConfiguration(i)));
+        }
+
+        assertTrue("Combined configs not equal", comp.compare(config, cc2));
+    }
+
+    /**
+     * Tests if the cloned configuration is decoupled from the original.
+     */
+    public void testCloneModify()
+    {
+        config.addConfiguration(setUpTestConfiguration(), TEST_NAME);
+        CombinedConfiguration cc2 = (CombinedConfiguration) config.clone();
+        assertTrue("Name is missing", cc2.getConfigurationNames().contains(
+                TEST_NAME));
+        cc2.removeConfiguration(TEST_NAME);
+        assertFalse("Names in original changed", config.getConfigurationNames()
+                .isEmpty());
+    }
+
+    /**
+     * Tests clearing a combined configuration. This should remove all contained
+     * configurations.
+     */
+    public void testClear()
+    {
+        config.addConfiguration(setUpTestConfiguration(), TEST_NAME, "test");
+        config.addConfiguration(setUpTestConfiguration());
+
+        config.clear();
+        assertEquals("Still configs contained", 0, config
+                .getNumberOfConfigurations());
+        assertTrue("Still names contained", config.getConfigurationNames()
+                .isEmpty());
+        assertTrue("Config is not empty", config.isEmpty());
+
+        listener.checkEvent(3, 2);
+    }
+
+    /**
      * Helper method for creating a test configuration to be added to the
      * combined configuration.
      *

Modified: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestMapConfiguration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestMapConfiguration.java?rev=420182&r1=420181&r2=420182&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestMapConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestMapConfiguration.java Sat Jul  8 12:46:20 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 The Apache Software Foundation.
+ * Copyright 2004-2006 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License")
  * you may not use this file except in compliance with the License.
@@ -19,6 +19,9 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.commons.configuration.event.ConfigurationEvent;
+import org.apache.commons.configuration.event.ConfigurationListener;
+
 /**
  * Tests for MapConfiguration.
  *
@@ -48,5 +51,37 @@
 
         MapConfiguration conf = new MapConfiguration(map);
         assertEquals(map, conf.getMap());
+    }
+
+    public void testClone()
+    {
+        MapConfiguration config = (MapConfiguration) getConfiguration();
+        MapConfiguration copy = (MapConfiguration) config.clone();
+        StrictConfigurationComparator comp = new StrictConfigurationComparator();
+        assertTrue("Configurations are not equal", comp.compare(config, copy));
+    }
+
+    /**
+     * Tests if the cloned configuration decoupled from the original.
+     */
+    public void testCloneModify()
+    {
+        MapConfiguration config = (MapConfiguration) getConfiguration();
+        config.addConfigurationListener(new ConfigurationListener()
+        {
+            public void configurationChanged(ConfigurationEvent event)
+            {
+                // Just a dummy
+            }
+        });
+        MapConfiguration copy = (MapConfiguration) config.clone();
+        assertTrue("Event listeners were copied", copy
+                .getConfigurationListeners().isEmpty());
+
+        config.addProperty("cloneTest", Boolean.TRUE);
+        assertFalse("Map not decoupled", copy.containsKey("cloneTest"));
+        copy.clearProperty("key1");
+        assertEquals("Map not decoupled (2)", "value1", config
+                .getString("key1"));
     }
 }

Modified: jakarta/commons/proper/configuration/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/xdocs/changes.xml?rev=420182&r1=420181&r2=420182&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/xdocs/changes.xml (original)
+++ jakarta/commons/proper/configuration/trunk/xdocs/changes.xml Sat Jul  8 12:46:20 2006
@@ -23,6 +23,13 @@
   <body>
 
     <release version="1.3-SNAPSHOT" date="in SVN">
+      <action dev="oheger" type="add" issue="CONFIGURATION-145">
+        clone() methods have been added to BaseConfiguration, AbstractFileConfiguration,
+        MapConfiguration, CompositeConfiguration, and CombinedConfiguration.
+        So the most important Configuration implementations now support
+        cloning. To ConfigurationUtils an utility method cloneConfiguration()
+        was added that allows to conveniently clone a configuration.
+      </action>
       <action dev="oheger" type="update" issue="CONFIGURATION-216">
         If a configuration file was to be loaded from classpath, the
         constructor of AbstractFileConfiguration dropped the file's path. The



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org