You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2011/04/09 21:10:22 UTC

svn commit: r1090651 - in /commons/proper/configuration/trunk/src: changes/changes.xml java/org/apache/commons/configuration/HierarchicalConfiguration.java test/org/apache/commons/configuration/TestCombinedConfiguration.java

Author: oheger
Date: Sat Apr  9 19:10:22 2011
New Revision: 1090651

URL: http://svn.apache.org/viewvc?rev=1090651&view=rev
Log:
[CONFIGURATION-445] Fixed a problem with the handling of ViewNodes in XMLConfiguration.

Modified:
    commons/proper/configuration/trunk/src/changes/changes.xml
    commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
    commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestCombinedConfiguration.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=1090651&r1=1090650&r2=1090651&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/changes/changes.xml (original)
+++ commons/proper/configuration/trunk/src/changes/changes.xml Sat Apr  9 19:10:22 2011
@@ -23,6 +23,11 @@
 
   <body>
     <release version="1.7" date="in SVN" description="">
+      <action dev="oheger" type="fix" issue="CONFIGURATION-445">
+        Transforming a CombinedConfiguration with ViewNodes to an
+        XMLConfiguration could cause problems with attributes. This has been
+        fixed.
+      </action>
       <action dev="oheger" type="update" issue="CONFIGURATION-439">
         Child configuration builders created for a &lt;configuration&gt; element
         in a configuration definition file now inherit the configuration and

Modified: commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java?rev=1090651&r1=1090650&r2=1090651&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java Sat Apr  9 19:10:22 2011
@@ -1170,6 +1170,38 @@ public class HierarchicalConfiguration e
     }
 
     /**
+     * Transforms the specified object into a Node. This method treats view
+     * nodes in a special way. This is necessary because ViewNode does not
+     * extend HierarchicalConfiguration.Node; thus the API for the node visitor
+     * is slightly different. Therefore a view node is transformed into a
+     * special compatibility Node object.
+     *
+     * @param obj the original node object
+     * @return the node to be used
+     */
+    private static Node getNodeFor(Object obj)
+    {
+        Node nd;
+        if (obj instanceof ViewNode)
+        {
+            final ViewNode viewNode = (ViewNode) obj;
+            nd = new Node(viewNode)
+            {
+                public void setReference(Object reference) {
+                    super.setReference(reference);
+                    // also set the reference at the original node
+                    viewNode.setReference(reference);
+                }
+            };
+        }
+        else
+        {
+            nd = (Node) obj;
+        }
+        return nd;
+    }
+
+    /**
      * A data class for storing (hierarchical) property information. A property
      * can have a value and an arbitrary number of child properties. From
      * version 1.3 on this class is only a thin wrapper over the
@@ -1343,27 +1375,13 @@ public class HierarchicalConfiguration e
                     && !visitor.terminate();)
             {
                 Object obj = it.next();
-                if (obj instanceof ViewNode)
-                {
-                    new Node((ViewNode) obj).visit(visitor, key);
-                }
-                else
-                {
-                    ((Node) obj).visit(visitor, key);
-                }
+                getNodeFor(obj).visit(visitor, key);
             }
             for (Iterator it = getAttributes().iterator(); it.hasNext()
                     && !visitor.terminate();)
             {
                 Object obj = it.next();
-                if (obj instanceof ViewNode)
-                {
-                    new Node((ViewNode) obj).visit(visitor, key);
-                }
-                else
-                {
-                    ((Node) obj).visit(visitor, key);
-                }
+                getNodeFor(obj).visit(visitor, key);
             }
 
             visitor.visitAfterChildren(this, key);
@@ -1649,14 +1667,7 @@ public class HierarchicalConfiguration e
                 {
                     sibling1 = nd;
                     Object obj = children.next();
-                    if (obj instanceof ViewNode)
-                    {
-                        nd = new Node((ViewNode) obj);
-                    }
-                    else
-                    {
-                        nd = (Node) obj;
-                    }
+                    nd = getNodeFor(obj);
                 } while (nd.getReference() != null && children.hasNext());
 
                 if (nd.getReference() == null)
@@ -1667,14 +1678,7 @@ public class HierarchicalConfiguration e
                     while (children.hasNext())
                     {
                         Object obj = children.next();
-                        if (obj instanceof ViewNode)
-                        {
-                            nd = new Node((ViewNode) obj);
-                        }
-                        else
-                        {
-                            nd = (Node) obj;
-                        }
+                        nd = getNodeFor(obj);
                         if (nd.getReference() == null)
                         {
                             newNodes.add(nd);

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=1090651&r1=1090650&r2=1090651&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 Sat Apr  9 19:10:22 2011
@@ -20,6 +20,8 @@ import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -36,10 +38,10 @@ import org.apache.commons.configuration.
 import org.apache.commons.configuration.reloading.FileAlwaysReloadingStrategy;
 import org.apache.commons.configuration.reloading.FileRandomReloadingStrategy;
 import org.apache.commons.configuration.tree.DefaultExpressionEngine;
+import org.apache.commons.configuration.tree.MergeCombiner;
 import org.apache.commons.configuration.tree.NodeCombiner;
 import org.apache.commons.configuration.tree.OverrideCombiner;
 import org.apache.commons.configuration.tree.UnionCombiner;
-import org.apache.commons.configuration.tree.MergeCombiner;
 import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
 
 /**
@@ -801,6 +803,38 @@ public class TestCombinedConfiguration e
         assertTrue(totalFailures + " failures Occurred", totalFailures == 0);
     }
 
+    /**
+     * Tests whether a combined configuration can be copied to an XML
+     * configuration. This test is related to CONFIGURATION-445.
+     */
+    public void testCombinedCopyToXML() throws ConfigurationException
+    {
+        XMLConfiguration x1 = new XMLConfiguration();
+        x1.addProperty("key1", "value1");
+        x1.addProperty("key1[@override]", "USER1");
+        x1.addProperty("key2", "value2");
+        x1.addProperty("key2[@override]", "USER2");
+        XMLConfiguration x2 = new XMLConfiguration();
+        x2.addProperty("key2", "value2.2");
+        x2.addProperty("key2[@override]", "USER2");
+        config.setNodeCombiner(new OverrideCombiner());
+        config.addConfiguration(x2);
+        config.addConfiguration(x1);
+        XMLConfiguration x3 = new XMLConfiguration(config);
+        assertEquals("Wrong element value", "value2.2", x3.getString("key2"));
+        assertEquals("Wrong attribute value", "USER2",
+                x3.getString("key2[@override]"));
+        StringWriter w = new StringWriter();
+        x3.save(w);
+        String s = w.toString();
+        x3 = new XMLConfiguration();
+        x3.load(new StringReader(s));
+        assertEquals("Wrong element value after load", "value2.2",
+                x3.getString("key2"));
+        assertEquals("Wrong attribute value after load", "USER2",
+                x3.getString("key2[@override]"));
+    }
+
     private class ReloadThread extends Thread
     {
         CombinedConfiguration combined;