commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ohe...@apache.org
Subject svn commit: r1568650 - in /commons/proper/configuration/branches/immutableNodes/src: main/java/org/apache/commons/configuration/tree/ test/java/org/apache/commons/configuration/tree/
Date Sat, 15 Feb 2014 17:59:07 GMT
Author: oheger
Date: Sat Feb 15 17:59:07 2014
New Revision: 1568650

URL: http://svn.apache.org/r1568650
Log:
InMemoryNodeModel now supports adding attribute properties.

ModelTransaction was extended by a special Operation class for adding
attributes.

Modified:
    commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java
    commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java
    commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java

Modified: commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java?rev=1568650&r1=1568649&r2=1568650&view=diff
==============================================================================
--- commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java
(original)
+++ commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java
Sat Feb 15 17:59:07 2014
@@ -198,17 +198,13 @@ public class InMemoryNodeModel implement
         ModelTransaction tx = new ModelTransaction(currentStructure);
         NodeAddData<ImmutableNode> addData =
                 resolver.resolveAddKey(currentStructure.getRoot(), key, this);
-        // TODO handle attributes
-        Collection<ImmutableNode> newNodes =
-                createNodesToAdd(addData.getNewNodeName(), values);
-        if (addData.getPathNodes().isEmpty())
+        if (addData.isAttribute())
         {
-            tx.addAddNodesOperation(addData.getParent(), newNodes);
+            addAttributeProperty(tx, addData, values);
         }
         else
         {
-            ImmutableNode newChild = createNodeToAddWithPath(addData, newNodes);
-            tx.addAddNodeOperation(addData.getParent(), newChild);
+            addNodeProperty(tx, addData, values);
         }
 
         // TODO handle concurrency
@@ -242,6 +238,63 @@ public class InMemoryNodeModel implement
     }
 
     /**
+     * Handles an add property operation if the property to be added is a node.
+     *
+     * @param tx the transaction
+     * @param addData the {@code NodeAddData}
+     * @param values the collection with node values
+     */
+    private static void addNodeProperty(ModelTransaction tx,
+            NodeAddData<ImmutableNode> addData, Iterable<?> values)
+    {
+        Collection<ImmutableNode> newNodes =
+                createNodesToAdd(addData.getNewNodeName(), values);
+        if (addData.getPathNodes().isEmpty())
+        {
+            tx.addAddNodesOperation(addData.getParent(), newNodes);
+        }
+        else
+        {
+            ImmutableNode newChild = createNodeToAddWithPath(addData, newNodes);
+            tx.addAddNodeOperation(addData.getParent(), newChild);
+        }
+    }
+
+    /**
+     * Handles an add property operation if the property to be added is an
+     * attribute.
+     *
+     * @param tx the transaction
+     * @param addData the {@code NodeAddData}
+     * @param values the collection with node values
+     */
+    private static void addAttributeProperty(ModelTransaction tx,
+            NodeAddData<ImmutableNode> addData, Iterable<?> values)
+    {
+        if (addData.getPathNodes().isEmpty())
+        {
+            tx.addAttributeOperation(addData.getParent(),
+                    addData.getNewNodeName(), values.iterator().next());
+        }
+        else
+        {
+            int pathNodeCount = addData.getPathNodes().size();
+            ImmutableNode childWithAttribute =
+                    new ImmutableNode.Builder()
+                            .name(addData.getPathNodes().get(pathNodeCount - 1))
+                            .addAttribute(addData.getNewNodeName(),
+                                    values.iterator().next()).create();
+            ImmutableNode newChild =
+                    (pathNodeCount > 1) ? createNodeOnPath(addData
+                            .getPathNodes().subList(0, pathNodeCount - 1)
+                            .iterator(),
+                            Collections.singleton(childWithAttribute))
+                            : childWithAttribute;
+            tx.addAddNodeOperation(addData.getParent(), newChild);
+        }
+    }
+
+    /**
      * Creates a collection with new nodes with a given name and a value from a
      * given collection.
      *

Modified: commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java?rev=1568650&r1=1568649&r2=1568650&view=diff
==============================================================================
--- commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java
(original)
+++ commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java
Sat Feb 15 17:59:07 2014
@@ -132,6 +132,20 @@ class ModelTransaction
     }
 
     /**
+     * Adds an operation for adding an attribute to a target node.
+     *
+     * @param target the target node
+     * @param name the name of the attribute
+     * @param value the value of the attribute
+     */
+    public void addAttributeOperation(ImmutableNode target, String name,
+            Object value)
+    {
+        fetchOperations(target, LEVEL_UNKNOWN).addOperation(
+                new AddAttributeOperation(name, value));
+    }
+
+    /**
      * Executes this transaction resulting in a new {@code TreeData} object. The
      * object returned by this method serves as the definition of a new node
      * structure for the calling model.
@@ -440,6 +454,37 @@ class ModelTransaction
     }
 
     /**
+     * A specialized operation class for adding an attribute to a target node.
+     */
+    private class AddAttributeOperation extends Operation
+    {
+        /** The attribute name. */
+        private final String attributeName;
+
+        /** The attribute value. */
+        private final Object attributeValue;
+
+        /**
+         * Creates a new instance of {@code AddAttributeOperation}.
+         *
+         * @param name the name of the attribute
+         * @param value the value of the attribute
+         */
+        public AddAttributeOperation(String name, Object value)
+        {
+            attributeName = name;
+            attributeValue = value;
+        }
+
+        @Override
+        protected ImmutableNode apply(ImmutableNode target,
+                Operations operations)
+        {
+            return target.setAttribute(attributeName, attributeValue);
+        }
+    }
+
+    /**
      * A helper class which collects multiple update operations to be executed
      * on a single node.
      */

Modified: commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java?rev=1568650&r1=1568649&r2=1568650&view=diff
==============================================================================
--- commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java
(original)
+++ commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java
Sat Feb 15 17:59:07 2014
@@ -672,4 +672,70 @@ public class TestInMemoryNodeModel
         assertSame("Wrong root node", model.getRootNode(),
                 model.getParent(node));
     }
+
+    /**
+     * Tests whether an attribute can be added if there are some path nodes.
+     */
+    @Test
+    public void testAddPropertyAttributeWithPathNodes()
+    {
+        NodeKeyResolver resolver = EasyMock.createMock(NodeKeyResolver.class);
+        NodeAddData<ImmutableNode> addData =
+                new NodeAddData<ImmutableNode>(nodeForKey(rootAuthorsTree,
+                        "Homer/Ilias"), "number", true, Arrays.asList("scenes",
+                        "scene"));
+        InMemoryNodeModel model = new InMemoryNodeModel(rootAuthorsTree);
+        EasyMock.expect(resolver.resolveAddKey(rootAuthorsTree, KEY, model))
+                .andReturn(addData);
+        EasyMock.replay(resolver);
+
+        model.addProperty(KEY, Collections.singleton(1), resolver);
+        ImmutableNode node = nodeForKey(model, "Homer/Ilias/scenes/scene");
+        assertEquals("Attribute not set", 1, node.getAttributes().get("number"));
+    }
+
+    /**
+     * Tests the special case that an attribute is added with a single path
+     * node.
+     */
+    @Test
+    public void testAddPropertyAttributeWithSinglePathNode()
+    {
+        NodeKeyResolver resolver = EasyMock.createMock(NodeKeyResolver.class);
+        NodeAddData<ImmutableNode> addData =
+                new NodeAddData<ImmutableNode>(nodeForKey(rootAuthorsTree,
+                        AUTHORS[0]), "year", true, Arrays.asList("dateOfBirth"));
+        InMemoryNodeModel model = new InMemoryNodeModel(rootAuthorsTree);
+        EasyMock.expect(resolver.resolveAddKey(rootAuthorsTree, KEY, model))
+                .andReturn(addData);
+        EasyMock.replay(resolver);
+
+        final Integer year = 1564;
+        model.addProperty(KEY, Collections.singleton(year), resolver);
+        ImmutableNode node = nodeForKey(model, "Shakespeare/dateOfBirth");
+        assertEquals("Attribute not set", year, node.getAttributes()
+                .get("year"));
+    }
+
+    /**
+     * Tests whether an attribute property can be added if there are no path
+     * nodes.
+     */
+    @Test
+    public void testAddPropertyAttributeNoPathNodes()
+    {
+        NodeKeyResolver resolver = EasyMock.createMock(NodeKeyResolver.class);
+        NodeAddData<ImmutableNode> addData =
+                new NodeAddData<ImmutableNode>(nodeForKey(rootAuthorsTree,
+                        "Shakespeare/The Tempest"), "year", true, null);
+        InMemoryNodeModel model = new InMemoryNodeModel(rootAuthorsTree);
+        EasyMock.expect(resolver.resolveAddKey(rootAuthorsTree, KEY, model))
+                .andReturn(addData);
+        EasyMock.replay(resolver);
+
+        model.addProperty(KEY, Collections.singleton(1611), resolver);
+        ImmutableNode node = nodeForKey(model, "Shakespeare/The Tempest");
+        assertEquals("Attribute not set", 1611, node.getAttributes()
+                .get("year"));
+    }
 }



Mime
View raw message