groovy node-tree integration 93/593/5
authorMichal Rehak <mirehak@cisco.com>
Mon, 24 Jun 2013 06:31:00 +0000 (08:31 +0200)
committerMichal Rehak <mirehak@cisco.com>
Thu, 18 Jul 2013 09:26:25 +0000 (11:26 +0200)
logging

fixing groovy tree generating

added params for surefire

lazy node2node map fixing

changed api according to dom usage
added lazy implementation of dom
added unit tests of this dom
changed abstract implementation in yang-data-util according to new api

improved groovy generated tree and testing
removed large testing files
added copyright comments
removed maven-surefire-plugin jConsole argument (plugin fails to start, if property not defined)

Change-Id: I00b9fcbc20ce5d120128940b7b569d7a14628a6e
Signed-off-by: Michal Rehak <mirehak@cisco.com>
40 files changed:
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNode.java
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableCompositeNode.java
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableSimpleNode.java
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/SimpleNode.java
opendaylight/sal/yang-prototype/yang/yang-data-impl/pom.xml [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/AbstractNodeTO.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeModificationTOImpl.java
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeTOImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMap.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableCompositeNodeTOImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableSimpleNodeTOImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeFactory.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeUtils.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeModificationTOImpl.java
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeTOImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/IgnoreWhiteCharsDiffListener.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMapTest.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MemoryConsumption.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MyNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeFactoryTest.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeHelper.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImplTest.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeUtilsTest.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/MyXmlGenerator.groovy [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config01.xml [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.content [deleted file]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.xml [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02g.xml [deleted file]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/controller-network.xsd [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/controller-network.yang [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/generateXml.groovy [deleted file]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/ietf-inet-types@2010-09-24.yang [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/log4j-test.xml [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02-shadow.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02.groovy [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02g-shadow.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/mutableNodesConfig.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/yang/data/util/AbstractNode.java
opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/yang/data/util/Nodes.java

index dfc790e0bddb7f140562ea794ec33e49dfbe2d15..e8ef4067641ac65f37c663a304bcc8dca7027eb5 100644 (file)
@@ -29,7 +29,7 @@ import org.opendaylight.controller.yang.common.QName;
  * \r
  * \r
  */\r
-public interface CompositeNode extends Node<List<Node<?>>> {\r
+public interface CompositeNode extends Node<List<Node<?>>>, NodeModification {\r
 \r
     List<Node<?>> getChildren();\r
 \r
@@ -45,4 +45,8 @@ public interface CompositeNode extends Node<List<Node<?>>> {
 \r
     SimpleNode<?> getFirstSimpleByName(QName leaf);\r
 \r
+    /**\r
+     * @return cast self to mutable, if possible \r
+     */\r
+    MutableCompositeNode asMutable();\r
 }\r
index b1baf309c5de1ead51f67a94cc5779e65e7e0114..4f11adbc174c9b2220c1464b41fbf6a997373cfa 100755 (executable)
@@ -20,4 +20,9 @@ public interface MutableCompositeNode extends MutableNode<List<Node<?>>>, Compos
      * update internal map\r
      */\r
     public void init();\r
+    \r
+    /**\r
+     * @return original node, if available\r
+     */\r
+    CompositeNode getOriginal();\r
 }\r
index 9519fac7922c197e42d774cc130ed42bf5efbad3..ad25f8f380d3eed5ee115d79ce1713bd6b0dc89d 100755 (executable)
@@ -15,6 +15,9 @@ package org.opendaylight.controller.yang.data.api;
  */\r
 public interface MutableSimpleNode<T> extends MutableNode<T>, SimpleNode<T> {\r
     \r
-   // nothing\r
+    /**\r
+     * @return original node, if available\r
+     */\r
+    SimpleNode<T> getOriginal();\r
     \r
 }\r
index 717c7224ee824484f0302ae75546d9bbee6d6aed..3f75da5203c84fe39e0bf07c6fb68e97ee47ef48 100644 (file)
@@ -21,6 +21,10 @@ package org.opendaylight.controller.yang.data.api;
  * \r
  * @param <T>\r
  */\r
-public interface SimpleNode<T> extends Node<T> {\r
+public interface SimpleNode<T> extends Node<T>, NodeModification {\r
 \r
+    /**\r
+     * @return cast self to mutable, if possible \r
+     */\r
+    MutableSimpleNode<T> asMutable();\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 41fd113..7a1b756
     <artifactId>yang-data-impl</artifactId>\r
 \r
     <properties>\r
-        <groovy.version>2.1.5</groovy.version>\r
+        <groovy.version>2.1.6</groovy.version>\r
     </properties>\r
-\r
     <build>\r
         <plugins>\r
             <plugin>\r
                 <groupId>org.apache.maven.plugins</groupId>\r
                 <artifactId>maven-surefire-plugin</artifactId>\r
                 <configuration>\r
-                    <argLine>-Dlog4j.configuration=log4j-test.xml</argLine>\r
+                    <argLine>-Dlog4j.configuration=log4j-test.xml -Xmx1500m</argLine>\r
                     <redirectTestOutputToFile>true</redirectTestOutputToFile>\r
                 </configuration>\r
             </plugin>\r
         <dependency>\r
             <groupId>org.opendaylight.controller</groupId>\r
             <artifactId>yang-model-parser-impl</artifactId>\r
+            <exclusions>\r
+                <exclusion>\r
+                    <groupId>org.slf4j</groupId>\r
+                    <artifactId>slf4j-simple</artifactId>\r
+                </exclusion>\r
+            </exclusions>\r
         </dependency>\r
         <dependency>\r
             <groupId>com.google.guava</groupId>\r
             <artifactId>guava</artifactId>\r
             <version>14.0.1</version>\r
         </dependency>\r
+        \r
         <dependency>\r
             <groupId>junit</groupId>\r
             <artifactId>junit</artifactId>\r
             <version>${groovy.version}</version>\r
             <scope>test</scope>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>xmlunit</groupId>\r
+            <artifactId>xmlunit</artifactId>\r
+            <version>1.4</version>\r
+            <scope>test</scope>\r
+        </dependency>\r
     </dependencies>\r
 </project>\r
old mode 100755 (executable)
new mode 100644 (file)
index cc4dfee..3385700
@@ -9,7 +9,9 @@ package org.opendaylight.controller.yang.data.impl;
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
 \r
 /**\r
  * @author michal.rehak\r
@@ -17,12 +19,13 @@ import org.opendaylight.controller.yang.data.api.Node;
  *            type of node value\r
  * \r
  */\r
-public abstract class AbstractNodeTO<T> implements Node<T> {\r
+public abstract class AbstractNodeTO<T> implements Node<T>, NodeModification {\r
 \r
     private QName qName;\r
     private CompositeNode parent;\r
     private T value;\r
-\r
+    private ModifyAction modifyAction;\r
+    \r
     /**\r
      * @param qname\r
      * @param parent\r
@@ -33,6 +36,19 @@ public abstract class AbstractNodeTO<T> implements Node<T> {
         this.parent = parent;\r
         this.value = value;\r
     }\r
+    \r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     * @param modifyAction \r
+     */\r
+    public AbstractNodeTO(QName qname, CompositeNode parent, T value, ModifyAction modifyAction) {\r
+        this.qName = qname;\r
+        this.parent = parent;\r
+        this.value = value;\r
+        this.modifyAction = modifyAction;\r
+    }\r
 \r
     @Override\r
     public QName getNodeType() {\r
@@ -42,7 +58,7 @@ public abstract class AbstractNodeTO<T> implements Node<T> {
     /**\r
      * @return the qName\r
      */\r
-    protected QName getQName() {\r
+    public QName getQName() {\r
         return qName;\r
     }\r
 \r
@@ -69,4 +85,76 @@ public abstract class AbstractNodeTO<T> implements Node<T> {
     public T getValue() {\r
         return value;\r
     }\r
+\r
+    /**\r
+     * @return modification action\r
+     * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
+     */\r
+    @Override\r
+    public ModifyAction getModificationAction() {\r
+        return modifyAction;\r
+    }\r
+\r
+    /**\r
+     * @param modifyAction\r
+     *            the modifyAction to set\r
+     */\r
+    protected void setModificationAction(ModifyAction modifyAction) {\r
+        this.modifyAction = modifyAction;\r
+    }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        StringBuffer out = new StringBuffer();\r
+        out.append(String.format("Node[%s], qName[%s], modify[%s]", \r
+                getClass().getSimpleName(), getQName().getLocalName(),\r
+                getModificationAction() == null ? "n/a" : getModificationAction()));\r
+        return out.toString();\r
+    }\r
+\r
+    /* */\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((modifyAction == null) ? 0 : modifyAction.hashCode());\r
+//        result = prime * result + ((parent == null) ? 0 : parent.hashCode());\r
+        result = prime * result + ((qName == null) ? 0 : qName.hashCode());\r
+        result = prime * result + ((value == null) ? 0 : value.hashCode());\r
+        return result % 2;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj)\r
+            return true;\r
+        if (obj == null)\r
+            return false;\r
+        if (getClass() != obj.getClass())\r
+            return false;\r
+        @SuppressWarnings("unchecked")\r
+        AbstractNodeTO<T> other = (AbstractNodeTO<T>) obj;\r
+        if (modifyAction != other.modifyAction)\r
+            return false;\r
+        if (parent == null) {\r
+            if (other.parent != null)\r
+                return false;\r
+        } else if (other.parent == null) {\r
+            return false;\r
+        } \r
+        if (qName == null) {\r
+            if (other.qName != null)\r
+                return false;\r
+        } else if (!qName.equals(other.qName))\r
+            return false;\r
+        if (value == null) {\r
+            if (other.value != null)\r
+                return false;\r
+        } else if (!value.equals(other.value))\r
+            return false;\r
+        return true;\r
+    }\r
+    /* */\r
+    \r
 }\r
index 7981df2f204f110bf87f2c484aca83d36dd08bc3..44c8c852f5a49d4361b5d2552f6bf1ce32a8588c 100755 (executable)
@@ -1,5 +1,9 @@
-/**\r
- * \r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
@@ -9,16 +13,12 @@ import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.ModifyAction;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
-import org.opendaylight.controller.yang.data.api.NodeModification;\r
 \r
 /**\r
  * @author michal.rehak\r
  * \r
  */\r
-public class CompositeNodeModificationTOImpl extends CompositeNodeTOImpl\r
-        implements NodeModification {\r
-\r
-    private ModifyAction modifyAction;\r
+public class CompositeNodeModificationTOImpl extends CompositeNodeTOImpl {\r
 \r
     /**\r
      * @param qname\r
@@ -29,24 +29,6 @@ public class CompositeNodeModificationTOImpl extends CompositeNodeTOImpl
     public CompositeNodeModificationTOImpl(QName qname, CompositeNode parent,\r
             List<Node<?>> value, ModifyAction modifyAction) {\r
         super(qname, parent, value);\r
-        this.modifyAction = modifyAction;\r
-    }\r
-\r
-    /**\r
-     * @return modification action\r
-     * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
-     */\r
-    @Override\r
-    public ModifyAction getModificationAction() {\r
-        return modifyAction;\r
+        super.setModificationAction(modifyAction);\r
     }\r
-\r
-    /**\r
-     * @param modifyAction\r
-     *            the modifyAction to set\r
-     */\r
-    protected void setModificationAction(ModifyAction modifyAction) {\r
-        this.modifyAction = modifyAction;\r
-    }\r
-\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index f94163a..605b99c
@@ -13,6 +13,8 @@ import java.util.Map;
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 \r
@@ -36,6 +38,19 @@ public class CompositeNodeTOImpl extends AbstractNodeTO<List<Node<?>>>
         if (value != null) {\r
             nodeMap = NodeUtils.buildNodeMap(getValue());\r
         }\r
+        init();\r
+    }\r
+\r
+    /**\r
+     * @param qname\r
+     * @param parent use null to create top composite node (without parent)\r
+     * @param value\r
+     * @param modifyAction \r
+     */\r
+    public CompositeNodeTOImpl(QName qname, CompositeNode parent,\r
+            List<Node<?>> value, ModifyAction modifyAction) {\r
+        super(qname, parent, value, modifyAction);\r
+        init();\r
     }\r
     \r
 \r
@@ -105,16 +120,34 @@ public class CompositeNodeTOImpl extends AbstractNodeTO<List<Node<?>>>
 \r
     @Override\r
     public List<CompositeNode> getCompositesByName(String children) {\r
-        return getCompositesByName(localQName(children));\r
+        return getCompositesByName(new QName(getNodeType(), children));\r
     }\r
     \r
     @Override\r
     public List<SimpleNode<?>> getSimpleNodesByName(String children) {\r
-        return getSimpleNodesByName(localQName(children));\r
+        return getSimpleNodesByName(new QName(getNodeType(), children));\r
     }\r
 \r
-    private QName localQName(String str) {\r
-        return new QName(getNodeType(), str);\r
+    /**\r
+     * @param value\r
+     */\r
+    protected void init() {\r
+        if (getValue() != null) {\r
+            nodeMap = NodeUtils.buildNodeMap(getValue());\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public MutableCompositeNode asMutable() {\r
+        throw new IllegalAccessError("cast to mutable is not supported - "+getClass().getSimpleName());\r
     }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        return super.toString() + ", children.size = " \r
+                + (getChildren() != null ? getChildren().size() : "n/a");\r
+    }\r
+    \r
+    \r
 \r
 }\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMap.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMap.java
new file mode 100644 (file)
index 0000000..81dd86e
--- /dev/null
@@ -0,0 +1,156 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.Stack;\r
+\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableNode;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class LazyNodeToNodeMap {\r
+    \r
+    private Map<Node<?>, Node<?>> node2node = new HashMap<>();\r
+    private CompositeNode originalRoot;\r
+    private MutableCompositeNode mutableRoot;\r
+    \r
+    /**\r
+     * @param originalNode\r
+     * @return mutable twin\r
+     */\r
+    public Node<?> getMutableEquivalent(Node<?> originalNode) {\r
+        Node<?> mutableNode = node2node.get(originalNode);\r
+        if (mutableNode == null) {\r
+            addPathMembers(originalNode);\r
+            mutableNode = node2node.get(originalNode);\r
+        }\r
+        \r
+        return mutableNode;\r
+    }\r
+    \r
+    /**\r
+     * @param originalNode\r
+     */\r
+    private void addPathMembers(Node<?> originalNode) {\r
+        Stack<Node<?>> jobQueue = new Stack<>(); \r
+        jobQueue.push(originalNode);\r
+        while (!jobQueue.isEmpty()) {\r
+            Node<?> node2add = jobQueue.pop();\r
+            boolean fixChildrenRefOnly = false;\r
+            if (node2node.containsKey(node2add)) {\r
+                if (node2add instanceof SimpleNode<?>) {\r
+                    continue;\r
+                }\r
+                fixChildrenRefOnly = true;\r
+            }\r
+            \r
+            CompositeNode nextParent = node2add.getParent();\r
+            MutableNode<?> mutableEquivalent = null;\r
+            \r
+            if (node2add instanceof SimpleNode<?>) {\r
+                SimpleNode<?> node2addSimple = (SimpleNode<?>) node2add;\r
+                MutableSimpleNode<?> nodeMutant = NodeFactory.createMutableSimpleNode(\r
+                        node2add.getNodeType(), null, node2addSimple.getValue(), \r
+                        node2addSimple.getModificationAction(), node2addSimple);\r
+                mutableEquivalent = nodeMutant;\r
+            } else if (node2add instanceof CompositeNode) {\r
+                MutableCompositeNode nodeMutant = null;\r
+                if (fixChildrenRefOnly) {\r
+                    nodeMutant = (MutableCompositeNode) node2node.get(node2add);\r
+                } else {\r
+                    CompositeNode node2addComposite = (CompositeNode) node2add;\r
+                    nodeMutant = NodeFactory.createMutableCompositeNode(node2add.getNodeType(), \r
+                        null, null, \r
+                        ((NodeModification) node2add).getModificationAction(), node2addComposite);\r
+                }\r
+                \r
+                mutableEquivalent = nodeMutant;\r
+\r
+                // tidy up children\r
+                if (nodeMutant.getChildren() == null) {\r
+                    nodeMutant.setValue(new ArrayList<Node<?>>());\r
+                }\r
+                for (Node<?> originalChildNode : ((CompositeNode) node2add).getChildren()) {\r
+                    MutableNode<?> mutableChild = (MutableNode<?>) node2node.get(originalChildNode);\r
+                    fixChildrenRef(nodeMutant, mutableChild);\r
+                }\r
+                \r
+                if (nodeMutant.getChildren() != null && !nodeMutant.getChildren().isEmpty()) {\r
+                    nodeMutant.init();\r
+                }\r
+\r
+                // store tree root, if occured\r
+                if (nextParent == null) {\r
+                    if (originalRoot == null) {\r
+                        originalRoot = (CompositeNode) node2add;\r
+                        mutableRoot = nodeMutant;\r
+                    } else {\r
+                        if (!originalRoot.equals(node2add)) {\r
+                            throw new IllegalStateException("Different tree root node obtained - " +\r
+                                       "perhaps nodes of different trees are getting mixed up.");\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            \r
+            // feed jobQueue\r
+            node2node.put(node2add, mutableEquivalent);\r
+            if (nextParent != null) {\r
+                jobQueue.push(nextParent);\r
+            } \r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param nodeMutant\r
+     * @param mutableChild\r
+     */\r
+    private static void fixChildrenRef(MutableCompositeNode nodeMutant,\r
+            MutableNode<?> mutableChild) {\r
+        if (mutableChild != null) {\r
+            if (!nodeMutant.getChildren().contains(mutableChild)) {\r
+                nodeMutant.getChildren().add(mutableChild);\r
+            }\r
+            CompositeNode parentOfChild = mutableChild.getParent();\r
+            if (parentOfChild == null) {\r
+                mutableChild.setParent(nodeMutant);\r
+            } else {\r
+                if (!parentOfChild.equals(nodeMutant)) {\r
+                    throw new IllegalStateException("Different parent node obtained - " +\r
+                            "perhaps nodes of different trees are getting mixed up.");\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @return the mutableRoot\r
+     */\r
+    public MutableCompositeNode getMutableRoot() {\r
+        return mutableRoot;\r
+    }\r
+    \r
+    /**\r
+     * @return set of original nodes, registered in map as keys \r
+     */\r
+    public Set<Node<?>> getKeyNodes() {\r
+        return node2node.keySet();\r
+    }\r
+}\r
old mode 100755 (executable)
new mode 100644 (file)
index 997b502..c29ecc4
@@ -20,10 +20,11 @@ import org.opendaylight.controller.yang.data.api.Node;
  * @author michal.rehak\r
  * \r
  */\r
-public class MutableCompositeNodeTOImpl extends CompositeNodeModificationTOImpl\r
+public class MutableCompositeNodeTOImpl extends CompositeNodeTOImpl\r
         implements MutableCompositeNode {\r
 \r
     private Map<QName, List<Node<?>>> nodeMap;\r
+    private CompositeNode original;\r
 \r
     /**\r
      * @param qname\r
@@ -41,7 +42,9 @@ public class MutableCompositeNodeTOImpl extends CompositeNodeModificationTOImpl
      */\r
     @Override\r
     public void init() {\r
-        nodeMap = NodeUtils.buildNodeMap(getChildren());\r
+        if (!getChildren().isEmpty()) {\r
+            nodeMap = NodeUtils.buildNodeMap(getChildren());\r
+        }\r
     }\r
 \r
     @Override\r
@@ -58,4 +61,21 @@ public class MutableCompositeNodeTOImpl extends CompositeNodeModificationTOImpl
     protected Map<QName, List<Node<?>>> getNodeMap() {\r
         return nodeMap;\r
     }\r
+    \r
+    @Override\r
+    public MutableCompositeNode asMutable() {\r
+        return this;\r
+    }\r
+    \r
+    @Override\r
+    public CompositeNode getOriginal() {\r
+        return original;\r
+    }\r
+    \r
+    /**\r
+     * @param original the original to set\r
+     */\r
+    public void setOriginal(CompositeNode original) {\r
+        this.original = original;\r
+    }\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 17cbb8d..a3b73b1
@@ -11,15 +11,18 @@ import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.ModifyAction;\r
 import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 \r
 /**\r
  * @author michal.rehak\r
  * @param <T> type of simple node value\r
  * \r
  */\r
-public class MutableSimpleNodeTOImpl<T> extends SimpleNodeModificationTOImpl<T> \r
+public class MutableSimpleNodeTOImpl<T> extends SimpleNodeTOImpl<T> \r
         implements MutableSimpleNode<T> {\r
 \r
+    private SimpleNode<T> original;\r
+\r
     /**\r
      * @param qname\r
      * @param parent\r
@@ -40,4 +43,21 @@ public class MutableSimpleNodeTOImpl<T> extends SimpleNodeModificationTOImpl<T>
     public void setModifyAction(ModifyAction action) {\r
         super.setModificationAction(action);\r
     }\r
+    \r
+    @Override\r
+    public MutableSimpleNode<T> asMutable() {\r
+        return this;\r
+    }\r
+    \r
+    @Override\r
+    public SimpleNode<T> getOriginal() {\r
+        return original;\r
+    }\r
+    \r
+    /**\r
+     * @param original the original to set\r
+     */\r
+    public void setOriginal(SimpleNode<T> original) {\r
+        this.original = original;\r
+    }\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 8b3b7d4..8e6e774
@@ -10,6 +10,7 @@ package org.opendaylight.controller.yang.data.impl;
 import java.util.AbstractMap.SimpleEntry;\r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
+import java.util.HashMap;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.Stack;\r
@@ -20,6 +21,7 @@ import org.opendaylight.controller.yang.data.api.ModifyAction;
 import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
 import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 \r
 /**\r
@@ -34,47 +36,56 @@ public abstract class NodeFactory {
      * @param value\r
      * @return simple node modification, based on given qname, value and parent\r
      */\r
-    public static <T> SimpleNode<T> createSimpleNode(QName qName,\r
+    public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,\r
             CompositeNode parent, T value) {\r
-        SimpleNodeTOImpl<T> simpleNodeTOImpl = new SimpleNodeTOImpl<T>(qName, parent, value);\r
-        return simpleNodeTOImpl;\r
+        return createImmutableSimpleNode(qName, parent, value, null);\r
     }\r
     \r
     /**\r
      * @param qName\r
      * @param parent\r
      * @param value\r
+     * @param modifyAction \r
+     * @param original originating node, if available\r
      * @return simple node modification, based on given qname, value and parent\r
      */\r
     public static <T> MutableSimpleNode<T> createMutableSimpleNode(QName qName,\r
-            CompositeNode parent, T value) {\r
+            CompositeNode parent, Object value, ModifyAction modifyAction, SimpleNode<T> original) {\r
+        @SuppressWarnings("unchecked")\r
         MutableSimpleNodeTOImpl<T> simpleNodeTOImpl = \r
-                new MutableSimpleNodeTOImpl<T>(qName, parent, value, null);\r
+                new MutableSimpleNodeTOImpl<T>(qName, parent, (T) value, modifyAction);\r
+        simpleNodeTOImpl.setOriginal(original);\r
         return simpleNodeTOImpl;\r
     }\r
-\r
+    \r
     /**\r
      * @param qName\r
      * @param parent\r
      * @param value\r
      * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
      */\r
-    public static CompositeNode createCompositeNode(QName qName,\r
+    public static CompositeNode createImmutableCompositeNode(QName qName,\r
             CompositeNode parent, List<Node<?>> value) {\r
-        CompositeNode compositeNodeTOImpl = new CompositeNodeTOImpl(qName, parent, value);\r
-        return compositeNodeTOImpl;\r
+        return createImmutableCompositeNode(qName, parent, value, null);\r
     }\r
     \r
     /**\r
      * @param qName\r
      * @param parent\r
-     * @param value\r
-     * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
+     * @param valueArg \r
+     * @param modifyAction \r
+     * @param original originating node, if available\r
+     * @return composite node modification, based on given qName, value (children), parent and modifyAction\r
      */\r
     public static MutableCompositeNode createMutableCompositeNode(QName qName,\r
-            CompositeNode parent, List<Node<?>> value) {\r
+            CompositeNode parent, List<Node<?>> valueArg, ModifyAction modifyAction, CompositeNode original) {\r
+        List<Node<?>> value = valueArg;\r
+        if (value == null) {\r
+            value = new ArrayList<>();\r
+        }\r
         MutableCompositeNodeTOImpl compositeNodeTOImpl = \r
-                new MutableCompositeNodeTOImpl(qName, parent, value, null);\r
+                new MutableCompositeNodeTOImpl(qName, parent, value, modifyAction);\r
+        compositeNodeTOImpl.setOriginal(original);\r
         return compositeNodeTOImpl;\r
     }\r
     \r
@@ -86,10 +97,10 @@ public abstract class NodeFactory {
      * @param modifyAction\r
      * @return simple node modification, based on given qname, value, parent and modifyAction\r
      */\r
-    public static <T> SimpleNodeModificationTOImpl<T> createSimpleNodeModification(QName qName,\r
+    public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,\r
             CompositeNode parent, T value, ModifyAction modifyAction) {\r
-        SimpleNodeModificationTOImpl<T> simpleNodeModTOImpl = \r
-                new SimpleNodeModificationTOImpl<T>(qName, parent, value, modifyAction);\r
+        SimpleNodeTOImpl<T> simpleNodeModTOImpl = \r
+                new SimpleNodeTOImpl<T>(qName, parent, value, modifyAction);\r
         return simpleNodeModTOImpl;\r
     }\r
 \r
@@ -100,10 +111,10 @@ public abstract class NodeFactory {
      * @param modifyAction \r
      * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
      */\r
-    public static CompositeNodeModificationTOImpl createCompositeNodeModification(QName qName,\r
+    public static CompositeNode createImmutableCompositeNode(QName qName,\r
             CompositeNode parent, List<Node<?>> value, ModifyAction modifyAction) {\r
-        CompositeNodeModificationTOImpl compositeNodeModTOImpl = \r
-                new CompositeNodeModificationTOImpl(qName, parent, value, modifyAction);\r
+        CompositeNodeTOImpl compositeNodeModTOImpl = \r
+                new CompositeNodeTOImpl(qName, parent, value, modifyAction);\r
         return compositeNodeModTOImpl;\r
     }\r
 \r
@@ -113,7 +124,7 @@ public abstract class NodeFactory {
      * has no reference to this copy \r
      */\r
     public static <T> SimpleNode<T> copyNode(SimpleNode<T> node) {\r
-        SimpleNode<T> twinNode = createSimpleNode(\r
+        SimpleNode<T> twinNode = createImmutableSimpleNode(\r
                     node.getNodeType(), node.getParent(), node.getValue());\r
         return twinNode;\r
     }\r
@@ -123,12 +134,13 @@ public abstract class NodeFactory {
      * @return copy of given node, parent and value are the same, but parent \r
      * has no reference to this copy \r
      */\r
-    public static <T> SimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
-        SimpleNode<T> twinNode = createMutableSimpleNode(\r
-                    node.getNodeType(), node.getParent(), node.getValue());\r
+    public static <T> MutableSimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
+        MutableSimpleNode<T> twinNode = createMutableSimpleNode(\r
+                    node.getNodeType(), node.getParent(), node.getValue(), \r
+                    node.getModificationAction(), null);\r
         return twinNode;\r
     }\r
-\r
+    \r
     /**\r
      * @param node\r
      * @param children \r
@@ -136,8 +148,8 @@ public abstract class NodeFactory {
      * have no reference to this copy\r
      */\r
     public static CompositeNode copyNode(CompositeNode node, Node<?>... children) {\r
-        CompositeNode twinNode = createCompositeNode(\r
-                node.getNodeType(), node.getParent(), Arrays.asList(children));\r
+        CompositeNode twinNode = createImmutableCompositeNode(\r
+                node.getNodeType(), node.getParent(), Arrays.asList(children), node.getModificationAction());\r
         return twinNode;\r
     }\r
     \r
@@ -152,53 +164,98 @@ public abstract class NodeFactory {
     \r
     /**\r
      * @param node root of original tree\r
-     * @param originalToMutable (optional) empty map, where binding between original and copy \r
+     * @param originalToCopyArg (optional) empty map, where binding between original and copy \r
      * will be stored\r
-     * @return copy of given node, parent and children are the same, but parent and children \r
-     * have no reference to this copy\r
+     * @return copy of given node and all subnodes recursively\r
      */\r
-    public static MutableCompositeNode copyDeepNode(CompositeNode node, \r
-            Map<Node<?>, Node<?>> originalToMutable) {\r
-              \r
-       MutableCompositeNode mutableRoot = \r
-               createMutableCompositeNode(node.getNodeType(), null, null);\r
-       Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
-       jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
-       if (originalToMutable != null) {\r
-           originalToMutable.put(node, mutableRoot);\r
-       }\r
-       \r
-       while (!jobQueue.isEmpty()) {\r
-           SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
-           CompositeNode originalNode = job.getKey();\r
-           MutableCompositeNode mutableNode = job.getValue();\r
-           mutableNode.setValue(new ArrayList<Node<?>>());\r
-           \r
-           for (Node<?> child : originalNode.getChildren()) {\r
-               Node<?> mutableAscendant = null;\r
-               if (child instanceof CompositeNode) {\r
-                   MutableCompositeNode newMutable = \r
-                           createMutableCompositeNode(child.getNodeType(), mutableNode, null);\r
-                   jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
-                           (CompositeNode) child, newMutable));\r
-                   mutableAscendant = newMutable;\r
-               } else if (child instanceof SimpleNode<?>) {\r
-                   mutableAscendant = \r
-                           createMutableSimpleNode(child.getNodeType(), mutableNode, child.getValue());\r
-               } else {\r
-                   throw new IllegalStateException("Node class deep copy not supported: "\r
-                           +child.getClass().getName());\r
-               }\r
-               \r
-               mutableNode.getChildren().add(mutableAscendant);\r
-               if (originalToMutable != null) {\r
-                   originalToMutable.put(child, mutableAscendant);\r
-               }\r
-           }\r
-           mutableNode.init();\r
-       }\r
+    public static MutableCompositeNode copyDeepAsMutable(CompositeNode node, \r
+            Map<Node<?>, Node<?>> originalToCopyArg) {\r
+        \r
+        Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;\r
+        if (originalToCopy == null) {\r
+            originalToCopy = new HashMap<>();\r
+        }\r
+\r
+        MutableCompositeNode mutableRoot = createMutableCompositeNode(node.getNodeType(), null, null, \r
+                node.getModificationAction(), null);\r
+        Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
+        jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
+        originalToCopy.put(node, mutableRoot);\r
+\r
+        while (!jobQueue.isEmpty()) {\r
+            SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
+            CompositeNode originalNode = job.getKey();\r
+            MutableCompositeNode mutableNode = job.getValue();\r
+            mutableNode.setValue(new ArrayList<Node<?>>());\r
+\r
+            for (Node<?> child : originalNode.getChildren()) {\r
+                Node<?> mutableAscendant = null;\r
+                if (child instanceof CompositeNode) {\r
+                    MutableCompositeNode newMutable = \r
+                            createMutableCompositeNode(child.getNodeType(), mutableNode, null, \r
+                                    ((NodeModification) child).getModificationAction(), null);\r
+                    jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
+                            (CompositeNode) child, newMutable));\r
+                    mutableAscendant = newMutable;\r
+                } else if (child instanceof SimpleNode<?>) {\r
+                    mutableAscendant = \r
+                            createMutableSimpleNode(child.getNodeType(), mutableNode, \r
+                                    child.getValue(), \r
+                                    ((NodeModification) child).getModificationAction(), null);\r
+                } else {\r
+                    throw new IllegalStateException("Node class deep copy not supported: "\r
+                            +child.getClass().getName());\r
+                }\r
+\r
+                mutableNode.getChildren().add(mutableAscendant);\r
+                originalToCopy.put(child, mutableAscendant);\r
+            }\r
+            mutableNode.init();\r
+        }\r
+\r
+        return mutableRoot;\r
+    }\r
+    \r
+    /**\r
+     * @param node root of original tree\r
+     * @param originalToCopyArg (optional) empty map, where binding between original and copy \r
+     * will be stored\r
+     * @return copy of given node and all subnodes recursively\r
+     */\r
+    public static CompositeNode copyDeepAsImmutable(CompositeNode node, \r
+            Map<Node<?>, Node<?>> originalToCopyArg) {\r
+        Stack<CompositeNode> jobQueue = new Stack<>();\r
+        jobQueue.push(node);\r
+        \r
+        Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;\r
+        if (originalToCopy == null) {\r
+            originalToCopy = new HashMap<>();\r
+        }\r
+        \r
+        while (!jobQueue.isEmpty()) {\r
+            CompositeNode jobNode = jobQueue.peek();\r
+            if (!originalToCopy.isEmpty() \r
+                    && originalToCopy.keySet().containsAll(jobNode.getChildren())) {\r
+                jobQueue.pop();\r
+                List<Node<?>> newChildren = NodeUtils.collectMapValues(jobNode.getChildren(), originalToCopy);\r
+                CompositeNode nodeCopy = createImmutableCompositeNode(jobNode.getNodeType(), null, \r
+                        newChildren, jobNode.getModificationAction());\r
+                NodeUtils.fixChildrenRelation(nodeCopy);\r
+                originalToCopy.put(jobNode, nodeCopy);\r
+            } else {\r
+                for (Node<?> child : jobNode.getChildren()) {\r
+                    if (child instanceof SimpleNode<?>) {\r
+                        originalToCopy.put(child, createImmutableSimpleNode(\r
+                                child.getNodeType(), null, child.getValue(), \r
+                                ((NodeModification) child).getModificationAction()));\r
+                    } else if (child instanceof CompositeNode) {\r
+                        jobQueue.push((CompositeNode) child);\r
+                    }\r
+                }\r
+            }\r
+        }\r
        \r
-       return mutableRoot;\r
+        return (CompositeNode) originalToCopy.get(node);\r
     }\r
     \r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index cd71731..2ab2dd8
@@ -1,14 +1,16 @@
-/**\r
- * \r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
-import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.Set;\r
-import java.util.Stack;\r
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
@@ -30,9 +32,7 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
     private SchemaContext context;\r
     \r
     private Set<MutableNode<?>> changeLog;\r
-    private Map<Node<?>, Node<?>> originalToMutable;\r
-\r
-    private MutableCompositeNode mutableRoot;\r
+    private LazyNodeToNodeMap originalToMutable;\r
 \r
     /**\r
      * @param originalTreeRootNode \r
@@ -40,24 +40,10 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
      */\r
     public NodeModificationBuilderImpl(CompositeNode originalTreeRootNode, SchemaContext context) {\r
         this.context = context;\r
-        originalToMutable = new HashMap<>();\r
-        mutableRoot = NodeFactory.copyDeepNode(originalTreeRootNode, originalToMutable);\r
+        originalToMutable = new LazyNodeToNodeMap();\r
         changeLog = new HashSet<>();\r
     }\r
 \r
-    /**\r
-     * add given node to it's parent's list of children\r
-     * @param newNode\r
-     */\r
-    private static void fixParentRelation(Node<?> newNode) {\r
-        if (newNode.getParent() != null) {\r
-            List<Node<?>> siblings = newNode.getParent().getChildren();\r
-            if (!siblings.contains(newNode)) {\r
-                siblings.add(newNode);\r
-            }\r
-        }\r
-    }\r
-\r
     /**\r
      * @param modNode\r
      * @param action \r
@@ -69,13 +55,13 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
 \r
     @Override\r
     public void addNode(MutableSimpleNode<?> newNode) {\r
-        fixParentRelation(newNode);\r
+        NodeUtils.fixParentRelation(newNode);\r
         addModificationToLog(newNode, ModifyAction.CREATE);\r
     }\r
     \r
     @Override\r
     public void addNode(MutableCompositeNode newNode) {\r
-        fixParentRelation(newNode);\r
+        NodeUtils.fixParentRelation(newNode);\r
         addModificationToLog(newNode, ModifyAction.CREATE);\r
     }\r
     \r
@@ -126,9 +112,8 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
             wanted.addAll(collectSelfAndAllParents(mutant));\r
         }\r
         \r
-        // TODO:: walk wanted and add relevant keys\r
+        // walk wanted and add relevant keys\r
         Map<String, ListSchemaNode>  mapOfLists = NodeUtils.buildMapOfListNodes(context);\r
-        Set<Node<?>> wantedKeys = new HashSet<>();\r
         for (Node<?> outlaw : wanted) {\r
             if (outlaw instanceof CompositeNode) {\r
                 String path = NodeUtils.buildPath(outlaw);\r
@@ -137,54 +122,27 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
                     if (listSchema.getQName().equals(outlaw.getNodeType())) {\r
                         // try to add key subnode to wanted list\r
                         List<QName> supportedKeys = listSchema.getKeyDefinition();\r
-                        for (Node<?> outlawChildren : ((CompositeNode) outlaw).getChildren()) {\r
-                            if (supportedKeys.contains(outlawChildren.getNodeType())) {\r
-                                wantedKeys.add(outlawChildren);\r
+                        CompositeNode outlawOriginal = ((MutableCompositeNode) outlaw).getOriginal();\r
+                        for (Node<?> outlawOriginalChild : outlawOriginal.getChildren()) {\r
+                            if (supportedKeys.contains(outlawOriginalChild.getNodeType())) {\r
+                                originalToMutable.getMutableEquivalent(outlawOriginalChild);\r
                             }\r
                         }\r
                     }\r
                 }\r
             }\r
         }\r
-        wanted.addAll(wantedKeys);\r
-        \r
-        // remove all unwanted nodes from tree\r
-        removeUnrelevantNodes(mutableRoot, wanted);\r
         \r
-        return mutableRoot;\r
-    }\r
-\r
-    /**\r
-     * @param mutableRoot2\r
-     * @param wanted\r
-     */\r
-    private static void removeUnrelevantNodes(MutableCompositeNode mutRoot,\r
-            Set<Node<?>> wanted) {\r
-        Stack<MutableNode<?>> jobQueue = new Stack<>();\r
-        jobQueue.push(mutRoot);\r
-        while (!jobQueue.isEmpty()) {\r
-            MutableNode<?> mutNode = jobQueue.pop();\r
-            if (!wanted.contains(mutNode)) {\r
-                if (mutNode.getParent() != null) {\r
-                    mutNode.getParent().getChildren().remove(mutNode);\r
-                }\r
-            } else {\r
-                if (mutNode instanceof MutableCompositeNode) {\r
-                    for (Node<?> mutChild : ((MutableCompositeNode) mutNode).getChildren()) {\r
-                        jobQueue.push((MutableNode<?>) mutChild);\r
-                    }\r
-                }\r
-            }\r
-        }\r
+        return originalToMutable.getMutableRoot();\r
     }\r
 \r
     /**\r
-     * @param focusedAncestor\r
+     * @param focusedDescendant\r
      * @return set of parents and focusedAncestor itself\r
      */\r
-    private static Set<Node<?>> collectSelfAndAllParents(Node<?> focusedAncestor) {\r
+    private static Set<Node<?>> collectSelfAndAllParents(Node<?> focusedDescendant) {\r
         Set<Node<?>> family = new HashSet<>();\r
-        Node<?> tmpNode = focusedAncestor;\r
+        Node<?> tmpNode = focusedDescendant;\r
         while (tmpNode != null) {\r
             family.add(tmpNode);\r
             tmpNode = tmpNode.getParent();\r
@@ -198,7 +156,7 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
      */\r
     @Override\r
     public Node<?> getMutableEquivalent(Node<?> originalNode) {\r
-        return originalToMutable.get(originalNode);\r
+        return originalToMutable.getMutableEquivalent(originalNode);\r
     }\r
 \r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index b3a7640..513cf06
@@ -36,10 +36,10 @@ import org.opendaylight.controller.yang.model.api.ListSchemaNode;
 import org.opendaylight.controller.yang.model.api.SchemaContext;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
-import org.w3c.dom.Document;\r
 import org.w3c.dom.Element;\r
 \r
 import com.google.common.base.Joiner;\r
+import com.google.common.collect.Lists;\r
 \r
 \r
 /**\r
@@ -48,11 +48,12 @@ import com.google.common.base.Joiner;
  */\r
 public abstract class NodeUtils {\r
     \r
+    private static final Logger LOG = LoggerFactory.getLogger(NodeUtils.class);\r
+    \r
     /**\r
      * \r
      */\r
     private static final String USER_KEY_NODE = "node";\r
-    private static final Logger LOG = LoggerFactory.getLogger(NodeUtils.class);\r
     \r
     /**\r
      * @param node\r
@@ -75,9 +76,9 @@ public abstract class NodeUtils {
      * @return dom tree, containing same node structure, yang nodes are associated \r
      * to dom nodes as user data\r
      */\r
-    public static Document buildShadowDomTree(CompositeNode treeRootNode) {\r
+    public static org.w3c.dom.Document buildShadowDomTree(CompositeNode treeRootNode) {
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\r
-        Document doc = null;\r
+        org.w3c.dom.Document doc = null;\r
         try {\r
             DocumentBuilder bob = dbf.newDocumentBuilder();\r
             doc = bob.newDocument();\r
@@ -86,6 +87,7 @@ public abstract class NodeUtils {
             return null;\r
         }\r
         \r
+        \r
         Stack<SimpleEntry<org.w3c.dom.Node, Node<?>>> jobQueue = new Stack<>();\r
         jobQueue.push(new SimpleEntry<org.w3c.dom.Node, Node<?>>(doc, treeRootNode));\r
         \r
@@ -93,12 +95,14 @@ public abstract class NodeUtils {
             SimpleEntry<org.w3c.dom.Node, Node<?>> job = jobQueue.pop();\r
             org.w3c.dom.Node jointPlace = job.getKey();\r
             Node<?> item = job.getValue();\r
-            Element itemEl = doc.createElement(item.getNodeType().getLocalName());\r
+            QName nodeType = item.getNodeType();\r
+            Element itemEl = doc.createElementNS(nodeType.getNamespace().toString(), \r
+                    item.getNodeType().getLocalName());\r
             itemEl.setUserData(USER_KEY_NODE, item, null);\r
             if (item instanceof SimpleNode<?>) {\r
                 Object value = ((SimpleNode<?>) item).getValue();\r
                 itemEl.setTextContent(String.valueOf(value));\r
-                itemEl.setAttribute("type", value.getClass().getSimpleName());\r
+                //itemEl.setAttribute("type", value.getClass().getSimpleName());\r
             }\r
             if (item instanceof NodeModification) {\r
                 ModifyAction modificationAction = ((NodeModification) item).getModificationAction();\r
@@ -126,7 +130,7 @@ public abstract class NodeUtils {
      * @throws XPathExpressionException\r
      */\r
     @SuppressWarnings("unchecked")\r
-    public static <T> T findNodeByXpath(Document doc, String xpathEx) \r
+    public static <T> T findNodeByXpath(org.w3c.dom.Document doc, String xpathEx) \r
             throws XPathExpressionException {\r
         T userNode = null;\r
         XPathFactory xPathfactory = XPathFactory.newInstance();\r
@@ -190,8 +194,7 @@ public abstract class NodeUtils {
         \r
         return mapOfLists;\r
     }\r
-\r
-\r
+    \r
     /**\r
      * @param path\r
      * @return\r
@@ -203,4 +206,56 @@ public abstract class NodeUtils {
         }\r
         return Joiner.on(".").join(pathSeed);\r
     }\r
+\r
+    /**\r
+     * add given node to it's parent's list of children\r
+     * @param newNode\r
+     */\r
+    public static void fixParentRelation(Node<?> newNode) {\r
+        if (newNode.getParent() != null) {\r
+            List<Node<?>> siblings = newNode.getParent().getChildren();\r
+            if (!siblings.contains(newNode)) {\r
+                siblings.add(newNode);\r
+            }\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * crawl all children of given node and assign it as their parent\r
+     * @param parentNode\r
+     */\r
+    public static void fixChildrenRelation(CompositeNode parentNode) {\r
+        if (parentNode.getChildren() != null) {\r
+            for (Node<?> child : parentNode.getChildren()) {\r
+                if (child instanceof AbstractNodeTO<?>) {\r
+                    ((AbstractNodeTO<?>) child).setParent(parentNode);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * @param keys\r
+     * @param dataMap\r
+     * @return list of values of map, found by given keys \r
+     */\r
+    public static <T, K> List<K> collectMapValues(List<T> keys,\r
+            Map<T, K> dataMap) {\r
+        List<K> valueSubList = new ArrayList<>();\r
+        for (T key : keys) {\r
+            valueSubList.add(dataMap.get(key));\r
+        }\r
+        \r
+        return valueSubList;\r
+    }\r
+    \r
+    /**\r
+     * @param nodes\r
+     * @return list of children in list of appropriate type\r
+     */\r
+    public static List<Node<?>> buildChildrenList(Node<?>...nodes) {\r
+        return Lists.newArrayList(nodes);\r
+    }\r
+\r
 }\r
index 726863737716f891d4d0cec613426c93e01d6955..eaee3730a7979a91a3ba6bcba1409917aee2c188 100755 (executable)
@@ -1,22 +1,22 @@
-/**\r
- * \r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.ModifyAction;\r
-import org.opendaylight.controller.yang.data.api.NodeModification;\r
 \r
 /**\r
  * @author michal.rehak\r
  * @param <T> type of node value\r
  * \r
  */\r
-public class SimpleNodeModificationTOImpl<T> extends SimpleNodeTOImpl<T>\r
-        implements NodeModification {\r
-\r
-    private ModifyAction modifyAction;\r
+public class SimpleNodeModificationTOImpl<T> extends SimpleNodeTOImpl<T> {\r
 \r
     /**\r
      * @param qname\r
@@ -27,23 +27,6 @@ public class SimpleNodeModificationTOImpl<T> extends SimpleNodeTOImpl<T>
     public SimpleNodeModificationTOImpl(QName qname, CompositeNode parent,\r
             T value, ModifyAction modifyAction) {\r
         super(qname, parent, value);\r
-        this.modifyAction = modifyAction;\r
-    }\r
-\r
-    /**\r
-     * @return modification action\r
-     * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
-     */\r
-    @Override\r
-    public ModifyAction getModificationAction() {\r
-        return modifyAction;\r
-    }\r
-\r
-    /**\r
-     * @param modifyAction\r
-     *            the modifyAction to set\r
-     */\r
-    protected void setModificationAction(ModifyAction modifyAction) {\r
-        this.modifyAction = modifyAction;\r
+        setModificationAction(modifyAction);\r
     }\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 5cfc03a..466cea5
@@ -9,6 +9,8 @@ package org.opendaylight.controller.yang.data.impl;
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 \r
 /**\r
@@ -27,5 +29,25 @@ public class SimpleNodeTOImpl<T> extends AbstractNodeTO<T> implements
     public SimpleNodeTOImpl(QName qname, CompositeNode parent, T value) {\r
         super(qname, parent, value);\r
     }\r
+    \r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     * @param modifyAction \r
+     */\r
+    public SimpleNodeTOImpl(QName qname, CompositeNode parent, T value, ModifyAction modifyAction) {\r
+        super(qname, parent, value, modifyAction);\r
+    }\r
 \r
+    \r
+    @Override\r
+    public MutableSimpleNode<T> asMutable() {\r
+        throw new IllegalAccessError("cast to mutable is not supported - "+getClass().getSimpleName());\r
+    }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        return super.toString() + ", value = "+getValue();\r
+    }\r
 }\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/IgnoreWhiteCharsDiffListener.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/IgnoreWhiteCharsDiffListener.java
new file mode 100644 (file)
index 0000000..bf6b292
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.yang.data.impl;
+
+import org.custommonkey.xmlunit.Difference;
+import org.custommonkey.xmlunit.DifferenceConstants;
+import org.custommonkey.xmlunit.DifferenceListener;
+
+/**
+ * Implementatin of {@link DifferenceListener} ignoring white characters around text elements
+ * @author mirehak
+ *
+ */
+public class IgnoreWhiteCharsDiffListener implements DifferenceListener {
+    
+    @Override
+    public void skippedComparison(org.w3c.dom.Node control,
+            org.w3c.dom.Node test) {
+        // do nothing                
+    }
+
+    @Override
+    public int differenceFound(Difference diff) {
+        
+        if (diff.getId() == DifferenceConstants.TEXT_VALUE.getId()) {
+            
+            String control = diff.getControlNodeDetail().getValue();
+            if (control != null) {
+                control = control.trim();
+                if (diff.getTestNodeDetail().getValue() != null
+                    && control.equals(diff.getTestNodeDetail().getValue().trim())) {
+                    return
+                        DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR;
+                }
+            }
+        }
+        return RETURN_ACCEPT_DIFFERENCE;
+    }
+}
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMapTest.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMapTest.java
new file mode 100755 (executable)
index 0000000..c4dc672
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.net.URI;\r
+import java.util.Date;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class LazyNodeToNodeMapTest {\r
+    \r
+    private LazyNodeToNodeMap lazyN2N;\r
+    private CompositeNode tree;\r
+\r
+    /**\r
+     * prepare test values\r
+     * @throws Exception \r
+     */\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        lazyN2N = new LazyNodeToNodeMap();\r
+        \r
+        QName qName = new QName(\r
+                new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
+                new Date(42), "yang-data-impl-mutableTest");\r
+        \r
+        tree = NodeHelper.buildTestConfigTree(qName);\r
+    }\r
+\r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.LazyNodeToNodeMap#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}.\r
+     */\r
+    @Test\r
+    public void testGetMutableEquivalent() {\r
+        MutableCompositeNode mutableTree = (MutableCompositeNode) lazyN2N.getMutableEquivalent(tree);\r
+        \r
+        Assert.assertNull(mutableTree.getParent());\r
+        Assert.assertEquals(tree.getNodeType(), mutableTree.getNodeType());\r
+        Assert.assertEquals(1, lazyN2N.getKeyNodes().size());\r
+        \r
+        Node<?> subNode = tree.getCompositesByName("topologies").iterator().next();\r
+        Node<?> subMutant = lazyN2N.getMutableEquivalent(subNode);\r
+        \r
+        Assert.assertNotNull(subMutant.getParent());\r
+        Assert.assertEquals(subNode.getNodeType(), subMutant.getNodeType());\r
+        Assert.assertEquals(2, lazyN2N.getKeyNodes().size());\r
+        \r
+        Assert.assertEquals(mutableTree, subMutant.getParent());\r
+        Assert.assertEquals(mutableTree.getChildren().size(), 1);\r
+        Assert.assertEquals(mutableTree.getChildren().iterator().next(), subMutant);\r
+    }\r
+\r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.LazyNodeToNodeMap#getMutableRoot()}.\r
+     */\r
+    @Test\r
+    public void testGetMutableRoot() {\r
+        Node<?> subNode = tree.getCompositesByName("topologies").iterator().next();\r
+        Node<?> subMutant = lazyN2N.getMutableEquivalent(subNode);\r
+        \r
+        Assert.assertNotNull(subMutant.getParent());\r
+        Assert.assertEquals(subMutant.getParent(), lazyN2N.getMutableRoot());\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MemoryConsumption.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MemoryConsumption.java
new file mode 100644 (file)
index 0000000..e53307d
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.yang.data.impl;
+
+/**
+ * Provides memory consumption and elapsed time between 2 points 
+ * @author mirehak
+ */
+public class MemoryConsumption {
+    
+    private long memBegin;
+    private long tsBegin;
+
+    /**
+     * record memory and timestamp
+     */
+    public void startObserving() {
+        Runtime runtime = Runtime.getRuntime();
+        // Run the garbage collector
+        runtime.gc();
+        memBegin = getActualMemoryConsumption();
+        tsBegin = System.currentTimeMillis();
+    }
+    
+    
+    /**
+     * @return memory usage and time elapsed message
+     */
+    public String finishObserving() {
+        long memEnd = getActualMemoryConsumption();
+        long tsEnd = System.currentTimeMillis();
+        return String.format("Used memory: %10d B; Elapsed time: %5d ms", (memEnd - memBegin), (tsEnd - tsBegin));
+    }
+    
+    
+    /**
+     * @return actual memory usage
+     */
+    public static long getActualMemoryConsumption() {
+        Runtime runtime = Runtime.getRuntime();
+        // Calculate the used memory
+        long memory = runtime.totalMemory() - runtime.freeMemory();
+        return memory;
+    }
+    
+    
+}
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MyNodeBuilder.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MyNodeBuilder.java
new file mode 100644 (file)
index 0000000..26cee74
--- /dev/null
@@ -0,0 +1,190 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import groovy.util.BuilderSupport;\r
+\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+import java.util.Date;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class MyNodeBuilder extends BuilderSupport {\r
+    \r
+    private static final Logger LOG = LoggerFactory\r
+            .getLogger(MyNodeBuilder.class);\r
+\r
+    private URI qnNamespace;\r
+    private String qnPrefix;\r
+    private Date qnRevision;\r
+    \r
+    private CompositeNode rootNode;\r
+\r
+       /**\r
+        * @param baseQName\r
+        */\r
+       private MyNodeBuilder(QName baseQName) {\r
+               qnNamespace = baseQName.getNamespace();\r
+               qnPrefix = baseQName.getPrefix();\r
+               qnRevision = baseQName.getRevision();\r
+    }\r
+\r
+       /**\r
+        * @return initialized singleton instance\r
+        */\r
+       public static MyNodeBuilder newInstance() {\r
+       QName qName = null;\r
+       try {\r
+                       qName = new QName(\r
+                       new URI("urn:opendaylight:controller:network"), \r
+                       new Date(42), "yang-data-impl-groovyTest_", null);\r
+        } catch (URISyntaxException e) {\r
+               LOG.error(e.getMessage(), e);\r
+        }\r
+        return new MyNodeBuilder(qName);\r
+    }\r
+\r
+    @Override\r
+    protected void setParent(Object parent, Object child) {\r
+       // do nothing\r
+        if (child instanceof AbstractNodeTO<?>) {\r
+            ((AbstractNodeTO<?>) child).setParent((CompositeNode) parent);\r
+        } else {\r
+            LOG.error("PARENTING FAILED: "+parent + " -> " + child);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected Object createNode(Object name) {\r
+        MutableCompositeNode newNode = NodeFactory.createMutableCompositeNode(\r
+                createQName(name), getCurrentNode(), null, null, null);\r
+        NodeUtils.fixParentRelation(newNode);\r
+        return newNode;\r
+    }\r
+\r
+    @Override\r
+    protected Object createNode(Object name, @SuppressWarnings("rawtypes") Map attributes) {\r
+        ModifyAction modifyAction = processAttributes(attributes);\r
+        MutableCompositeNode newNode = NodeFactory.createMutableCompositeNode(\r
+                createQName(name), getCurrentNode(), null, modifyAction, null);\r
+        NodeUtils.fixParentRelation(newNode);\r
+        return newNode;\r
+    }\r
+\r
+\r
+    @Override\r
+    protected Object createNode(Object name, @SuppressWarnings("rawtypes") Map attributes, Object value) {\r
+        ModifyAction modifyAction = processAttributes(attributes);\r
+        SimpleNode<Object> newNode = NodeFactory.createImmutableSimpleNode(\r
+                createQName(name), (CompositeNode) getCurrent(), value, modifyAction);\r
+        NodeUtils.fixParentRelation(newNode);\r
+        return newNode;\r
+    }\r
+    \r
+    /**\r
+     * @param attributes\r
+     * @return \r
+     */\r
+    private ModifyAction processAttributes(@SuppressWarnings("rawtypes") Map attributes) {\r
+        LOG.debug("attributes:" + attributes);\r
+        ModifyAction modAction = null;\r
+        \r
+        @SuppressWarnings("unchecked")\r
+        Map<String, String> attributesSane = attributes;\r
+        for (Entry<String, String> attr : attributesSane.entrySet()) {\r
+            switch (attr.getKey()) {\r
+            case "xmlns":\r
+                try {\r
+                    qnNamespace = new URI(attr.getValue());\r
+                } catch (URISyntaxException e) {\r
+                    LOG.error(e.getMessage(), e);\r
+                }\r
+                break;\r
+            case "modifyAction":\r
+                modAction = ModifyAction.valueOf(attr.getValue());\r
+                break;\r
+                \r
+            default:\r
+                throw new IllegalArgumentException("Attribute not supported: "+attr.getKey());\r
+            }\r
+        }\r
+        return modAction;\r
+    }\r
+\r
+    @Override\r
+    protected Object createNode(Object name, Object value) {\r
+        SimpleNode<Object> newNode = NodeFactory.createImmutableSimpleNode(createQName(name), (CompositeNode) getCurrent(), value);\r
+        NodeUtils.fixParentRelation(newNode);\r
+        return newNode;\r
+    }\r
+\r
+    private QName createQName(Object localName) {\r
+       LOG.debug("qname for: "+localName);\r
+           return new QName(qnNamespace, qnRevision, qnPrefix, (String) localName);\r
+    }\r
+\r
+       protected CompositeNode getCurrentNode() {\r
+           if (getCurrent() != null) {\r
+               if (getCurrent() instanceof CompositeNode) {\r
+                   return (CompositeNode) getCurrent();\r
+                   \r
+               } else {\r
+                   throw new IllegalAccessError("current node is not of type CompositeNode, but: "\r
+                       +getCurrent().getClass().getSimpleName());\r
+               }\r
+           }\r
+           \r
+           return null;\r
+    }\r
+       \r
+       @Override\r
+       protected Object postNodeCompletion(Object parent, Object node) {\r
+           Node<?> nodeRevisited = (Node<?>) node;\r
+           LOG.debug("postNodeCompletion at: \n  "+ nodeRevisited+"\n  "+parent);\r
+           if (nodeRevisited instanceof MutableCompositeNode) {\r
+               MutableCompositeNode mutant = (MutableCompositeNode) nodeRevisited;\r
+               if (mutant.getValue().isEmpty()) {\r
+                   LOG.error("why is it having empty value? -- " + mutant);\r
+               }\r
+               nodeRevisited = NodeFactory.createImmutableCompositeNode(\r
+                       mutant.getNodeType(), mutant.getParent(), mutant.getValue(), mutant.getModificationAction());\r
+               NodeUtils.fixChildrenRelation((CompositeNode) nodeRevisited);\r
+\r
+               if (parent == null) {\r
+                   rootNode = (CompositeNode) nodeRevisited;\r
+               } else {\r
+                   NodeUtils.fixParentRelation(nodeRevisited);\r
+                   nodeRevisited.getParent().getChildren().remove(mutant);\r
+               }\r
+           }\r
+           \r
+           \r
+           return nodeRevisited;\r
+       }\r
+       \r
+       /**\r
+        * @return tree root\r
+        */\r
+       public CompositeNode getRootNode() {\r
+        return rootNode;\r
+    }\r
+}
\ No newline at end of file
old mode 100755 (executable)
new mode 100644 (file)
index 3d97cc8..cafbfa3
@@ -7,8 +7,6 @@
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
-import java.io.ByteArrayOutputStream;\r
-import java.io.PrintStream;\r
 import java.net.URI;\r
 import java.util.ArrayList;\r
 import java.util.Date;\r
@@ -17,6 +15,7 @@ import java.util.List;
 import java.util.Map;\r
 \r
 import org.junit.Assert;\r
+import org.junit.Before;\r
 import org.junit.Test;\r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
@@ -24,6 +23,7 @@ import org.opendaylight.controller.yang.data.api.ModifyAction;
 import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
 import org.opendaylight.controller.yang.data.api.NodeModification;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 import org.w3c.dom.Document;\r
 \r
 /**\r
@@ -31,6 +31,27 @@ import org.w3c.dom.Document;
  * \r
  */\r
 public class NodeFactoryTest {\r
+    \r
+    private QName qName;\r
+    private CompositeNode network;\r
+\r
+    private String ns;\r
+    private Document networkShadow;\r
+\r
+\r
+    /**\r
+     * @throws Exception\r
+     */\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        ns = "urn:ietf:params:xml:ns:netconf:base:1.0";\r
+        qName = new QName(\r
+                new URI(ns), \r
+                new Date(42), null);\r
+        network = NodeHelper.buildTestConfigTree(qName);\r
+        networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        NodeHelper.compareXmlTree(networkShadow, "./config02-shadow.xml", getClass());\r
+    }\r
 \r
     /**\r
      * Test method for methods creating immutable nodes in\r
@@ -39,29 +60,19 @@ public class NodeFactoryTest {
      */\r
     @Test\r
     public void testImmutableNodes() throws Exception {\r
-        QName qName = new QName(\r
-                new URI("urn:opendaylight:controller:network"), \r
-                new Date(42), "yang-data-impl-immutableTest_", null);\r
-        \r
-        CompositeNode network = NodeHelper.buildTestConfigTree(qName);\r
-        \r
-        \r
-        Assert.assertEquals(1, network.getChildren().size());\r
-        Document domTree = NodeUtils.buildShadowDomTree(network);\r
-        NodeHelper.dumpDoc(domTree, System.out);\r
-        \r
-        CompositeNode tpList = NodeUtils.findNodeByXpath(domTree, \r
-                "//node[node-id/text()='nodeId_19']/termination-points");\r
+        Assert.assertEquals(2, network.getChildren().size());\r
+        CompositeNode tpList = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                        "//{0}node[{0}node-id/text()='nodeId_19']/{0}termination-points", ns));\r
         \r
         \r
         Assert.assertEquals(2, tpList.getCompositesByName("termination-point").size());\r
-//        Assert.assertEquals(1, topologies.getCompositesByName("topology").size());\r
-//        Assert.assertEquals(2, destination.getChildren().size());\r
     }\r
 \r
     /**\r
-     * Test method for methods creating immutable nodes in\r
-     * {@link org.opendaylight.controller.yang.data.impl.NodeFactory}.\r
+     * Test method for methods creating immutable and mutable nodes:\r
+     * {@link NodeFactory#createMutableCompositeNode(QName, CompositeNode, List, ModifyAction, CompositeNode)},\r
+     * {@link NodeFactory#createMutableSimpleNode(QName, CompositeNode, Object, ModifyAction, SimpleNode)}\r
      * @throws Exception \r
      */\r
     @Test\r
@@ -79,69 +90,75 @@ public class NodeFactoryTest {
         //   </top>\r
         // </config>\r
         \r
-        QName qName = new QName(\r
-                new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
-                new Date(42), "yang-data-impl-mutableTest");\r
         \r
         List<Node<?>> value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "name"), null, "Ethernet0/0"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "mtu"), null, 1500));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "name"), null, "Ethernet0/0"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "mtu"), null, 1500));\r
         \r
-        CompositeNodeModificationTOImpl ifNode = NodeFactory.createCompositeNodeModification(\r
-                new QName(qName, "interface"), null, value, ModifyAction.DELETE);\r
+        MutableCompositeNode ifNode = NodeFactory.createMutableCompositeNode(\r
+                new QName(qName, "interface"), null, value, ModifyAction.DELETE, null);\r
+        ifNode.init();\r
         NodeHelper.assignParentToChildren(ifNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "name"), null, "Ethernet1/0"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "mtu"), null, 1501));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "name"), null, "Ethernet1/0"));\r
+        value.add(NodeFactory.createMutableSimpleNode(new QName(qName, "mtu"), null, 1501, ModifyAction.REMOVE, null));\r
         \r
-        CompositeNode ifNode2 = NodeFactory.createCompositeNode(new QName(qName, "interface"), null, value);\r
+        CompositeNode ifNode2 = NodeFactory.createImmutableCompositeNode(new QName(qName, "interface"), null, value);\r
         NodeHelper.assignParentToChildren(ifNode2);\r
 \r
         value = new ArrayList<Node<?>>(); \r
         value.add(ifNode);\r
         value.add(ifNode2);\r
         \r
-        CompositeNode topNode = NodeFactory.createCompositeNode(new QName(qName, "top"), null, value);\r
+        CompositeNode topNode = NodeFactory.createImmutableCompositeNode(new QName(qName, "top"), null, value);\r
         NodeHelper.assignParentToChildren(topNode);\r
         value = new ArrayList<Node<?>>(); \r
         value.add(topNode);\r
         \r
-        CompositeNode root = NodeFactory.createCompositeNode(new QName(qName, "config"), null, value);\r
-        \r
+        CompositeNode root = NodeFactory.createImmutableCompositeNode(new QName(qName, "config"), null, value);\r
+        Document shadowConfig = NodeUtils.buildShadowDomTree(root);\r
+        NodeHelper.compareXmlTree(shadowConfig, "./mutableNodesConfig.xml", getClass());\r
         \r
         Assert.assertEquals(1, root.getChildren().size());\r
         Assert.assertEquals(1, ifNode.getSimpleNodesByName("name").size());\r
         Assert.assertEquals(1, ifNode.getSimpleNodesByName("mtu").size());\r
         Assert.assertEquals(2, topNode.getCompositesByName("interface").size());\r
-        NodeModification interfaceMod = (NodeModification) \r
-                topNode.getCompositesByName("interface").get(0);\r
+        NodeModification interfaceMod = topNode.getCompositesByName("interface").get(0);\r
         Assert.assertEquals(ModifyAction.DELETE, interfaceMod.getModificationAction());\r
     }\r
 \r
     /**\r
-     * test modifications builder\r
+     * test of {@link NodeFactory#copyDeepAsMutable(CompositeNode, Map)}\r
      * @throws Exception \r
      */\r
     @Test\r
-    public void testCopyDeepNode() throws Exception {\r
-        QName qName = new QName(\r
-                new URI("urn:opendaylight:controller:network"), \r
-                new Date(42), "yang-data-impl-immutableTest_", null);\r
-        \r
-        CompositeNode network = NodeHelper.buildTestConfigTree(qName);\r
+    public void testCopyDeepAsMutable() throws Exception {\r
         Map<Node<?>, Node<?>> mutableToOrig = new HashMap<>();\r
-        MutableCompositeNode mutableNetwork = NodeFactory.copyDeepNode(network, mutableToOrig );\r
+        CompositeNode mutableNetwork = NodeFactory.copyDeepAsMutable(network, mutableToOrig);\r
 \r
-        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
-        ByteArrayOutputStream expected = new ByteArrayOutputStream();\r
-        NodeHelper.dumpDoc(networkShadow, new PrintStream(expected));\r
-        \r
         Document mutableNetworkShadow = NodeUtils.buildShadowDomTree(mutableNetwork);\r
-        ByteArrayOutputStream actual = new ByteArrayOutputStream();\r
-        NodeHelper.dumpDoc(mutableNetworkShadow, new PrintStream(actual));\r
         \r
-        Assert.assertEquals(new String(expected.toByteArray()), new String(actual.toByteArray()));\r
+        NodeHelper.compareXmlTree(mutableNetworkShadow, "./config02-shadow.xml", getClass());\r
+        \r
+        CompositeNode immutableNetwork = NodeFactory.copyDeepAsImmutable(mutableNetwork, null);\r
+        Assert.assertEquals(network, immutableNetwork);\r
+    }\r
+    \r
+    \r
+    /**\r
+     * test of {@link NodeFactory#copyDeepAsImmutable(CompositeNode, Map)}\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testCopyDeepAsImmutable() throws Exception {\r
+        Map<Node<?>, Node<?>> mutableToOrig = new HashMap<>();\r
+        CompositeNode immutableNetwork = NodeFactory.copyDeepAsImmutable(network, mutableToOrig);\r
+        \r
+        Document mutableNetworkShadow = NodeUtils.buildShadowDomTree(immutableNetwork);\r
+        NodeHelper.compareXmlTree(mutableNetworkShadow, "./config02-shadow.xml", getClass());\r
+        \r
+        Assert.assertEquals(network, immutableNetwork);\r
     }\r
 \r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 3b7c0d0..a7e7d2f
@@ -7,9 +7,20 @@
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
+import groovy.lang.Binding;\r
+import groovy.lang.GroovyShell;\r
+import groovy.lang.Script;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
 import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
 import java.io.PrintStream;\r
+import java.io.Reader;\r
 import java.io.StringWriter;\r
+import java.lang.reflect.Method;\r
+import java.text.MessageFormat;\r
 import java.util.ArrayList;\r
 import java.util.List;\r
 import java.util.Set;\r
@@ -20,6 +31,8 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;\r
 import javax.xml.transform.stream.StreamResult;\r
 \r
+import org.custommonkey.xmlunit.Diff;\r
+import org.junit.Assert;\r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
@@ -27,7 +40,10 @@ import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.SchemaContext;\r
 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;\r
 import org.opendaylight.controller.yang.parser.impl.YangParserImpl;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
 import org.w3c.dom.Document;\r
+import org.xml.sax.SAXException;\r
 \r
 /**\r
  * @author michal.rehak\r
@@ -35,6 +51,8 @@ import org.w3c.dom.Document;
  */\r
 public abstract class NodeHelper {\r
     \r
+    private static final Logger LOG = LoggerFactory.getLogger(NodeHelper.class);\r
+    \r
     /** xml source of example network configuration */\r
     public static final String NETWORK_XML = \r
       "<network xmlns=\"urn:opendaylight:controller:network\">\n" +\r
@@ -127,145 +145,145 @@ public abstract class NodeHelper {
       String xmlString = result.getWriter().toString();\r
       out.println(xmlString);\r
     }\r
-\r
+    \r
     /**\r
      * @param qName\r
      * @return example tree, see {@link #NETWORK_XML}\r
      */\r
     public static CompositeNode buildTestConfigTree(QName qName) {\r
         List<Node<?>> value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "element-id"), null, "ntElementId_09"));\r
-        CompositeNode ntElementNode1 = NodeFactory.createCompositeNode(new QName(qName, "network-element"), null, value);\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "element-id"), null, "ntElementId_09"));\r
+        CompositeNode ntElementNode1 = NodeFactory.createImmutableCompositeNode(new QName(qName, "network-element"), null, value);\r
         assignParentToChildren(ntElementNode1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "element-id"), null, "ntElementId_10"));\r
-        CompositeNode ntElementNode2 = NodeFactory.createCompositeNode(new QName(qName, "network-element"), null, value);\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "element-id"), null, "ntElementId_10"));\r
+        CompositeNode ntElementNode2 = NodeFactory.createImmutableCompositeNode(new QName(qName, "network-element"), null, value);\r
         assignParentToChildren(ntElementNode2);\r
         \r
         value = new ArrayList<Node<?>>();\r
         value.add(ntElementNode1);\r
         value.add(ntElementNode2);\r
-        CompositeNode ntElementsNode = NodeFactory.createCompositeNode(\r
+        CompositeNode ntElementsNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "network-elements"), null, value);\r
         assignParentToChildren(ntElementsNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-node"), null, "nodeId_07"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-tp"), null, "tpId_08"));\r
-        CompositeNode destination = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-node"), null, "nodeId_07"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-tp"), null, "tpId_08"));\r
+        CompositeNode destination = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "destination"), null, value);\r
         assignParentToChildren(destination);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "source-node"), null, "nodeId_05"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "source-tp"), null, "tpId_06"));\r
-        CompositeNode source = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-node"), null, "nodeId_05"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-tp"), null, "tpId_06"));\r
+        CompositeNode source = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "source"), null, value);\r
         assignParentToChildren(source);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "link-id"), null, "linkId_04"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "link-id"), null, "linkId_04"));\r
         value.add(source);\r
         value.add(destination);\r
-        CompositeNode link1 = NodeFactory.createCompositeNode(\r
+        CompositeNode link1 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "link"), null, value);\r
         assignParentToChildren(link1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-node"), null, "nodeId_14"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-tp"), null, "tpId_15"));\r
-        destination = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-node"), null, "nodeId_14"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-tp"), null, "tpId_15"));\r
+        destination = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "destination"), null, value);\r
         assignParentToChildren(destination);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "source-node"), null, "nodeId_12"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "source-tp"), null, "tpId_13"));\r
-        source = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-node"), null, "nodeId_12"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-tp"), null, "tpId_13"));\r
+        source = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "source"), null, value);\r
         assignParentToChildren(source);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "link-id"), null, "linkId_11"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "link-id"), null, "linkId_11"));\r
         value.add(source);\r
         value.add(destination);\r
-        CompositeNode link2 = NodeFactory.createCompositeNode(\r
+        CompositeNode link2 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "link"), null, value);\r
         assignParentToChildren(link2);\r
         \r
         value = new ArrayList<Node<?>>(); \r
         value.add(link1);\r
         value.add(link2);\r
-        CompositeNode links = NodeFactory.createCompositeNode(\r
+        CompositeNode links = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "links"), null, value);\r
         assignParentToChildren(links);\r
         \r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_03"));\r
-        CompositeNode terminationPointNode1 = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_03"));\r
+        CompositeNode terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-point"), null, value);\r
         assignParentToChildren(terminationPointNode1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
         value.add(terminationPointNode1);\r
-        CompositeNode terminationPointsNode = NodeFactory.createCompositeNode(\r
+        CompositeNode terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-points"), null, value);\r
         assignParentToChildren(terminationPointsNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_02"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_02"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_02"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_02"));\r
         value.add(terminationPointsNode);\r
-        CompositeNode node1Node = NodeFactory.createCompositeNode(\r
+        CompositeNode node1Node = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "node"), null, value);\r
         assignParentToChildren(node1Node);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
-        terminationPointNode1 = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
+        terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-point"), null, value);\r
         assignParentToChildren(terminationPointNode1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
         value.add(terminationPointNode1);\r
-        terminationPointsNode = NodeFactory.createCompositeNode(\r
+        terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-points"), null, value);\r
         assignParentToChildren(terminationPointsNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_16"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_17"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_16"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_17"));\r
         value.add(terminationPointsNode);\r
-        CompositeNode node2Node = NodeFactory.createCompositeNode(\r
+        CompositeNode node2Node = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "node"), null, value);\r
         assignParentToChildren(node2Node);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
-        terminationPointNode1 = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
+        terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-point"), null, value);\r
         assignParentToChildren(terminationPointNode1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_19"));\r
-        CompositeNode terminationPointNode2 = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_19"));\r
+        CompositeNode terminationPointNode2 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-point"), null, value);\r
         assignParentToChildren(terminationPointNode2);\r
         \r
         value = new ArrayList<Node<?>>(); \r
         value.add(terminationPointNode1);\r
         value.add(terminationPointNode2);\r
-        terminationPointsNode = NodeFactory.createCompositeNode(\r
+        terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-points"), null, value);\r
         assignParentToChildren(terminationPointsNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_19"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_20"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_19"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_20"));\r
         value.add(terminationPointsNode);\r
-        CompositeNode node3Node = NodeFactory.createCompositeNode(\r
+        CompositeNode node3Node = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "node"), null, value);\r
         assignParentToChildren(node3Node);\r
         \r
@@ -273,27 +291,28 @@ public abstract class NodeHelper {
         value.add(node1Node);\r
         value.add(node2Node);\r
         value.add(node3Node);\r
-        CompositeNode nodesNode = NodeFactory.createCompositeNode(\r
+        CompositeNode nodesNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "nodes"), null, value);\r
         assignParentToChildren(nodesNode);\r
         \r
         value = new ArrayList<Node<?>>();\r
         value.add(links);\r
         value.add(nodesNode);\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "topology-id"), null, "topId_01"));\r
-        CompositeNode topology = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "topology-id"), null, "topId_01"));\r
+        CompositeNode topology = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "topology"), null, value);\r
         assignParentToChildren(topology);\r
         \r
         value = new ArrayList<Node<?>>();\r
         value.add(topology);\r
-        CompositeNode topologies = NodeFactory.createCompositeNode(\r
+        CompositeNode topologies = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "topologies"), null, value);\r
         assignParentToChildren(topologies);\r
         \r
         value = new ArrayList<Node<?>>();\r
         value.add(topologies);\r
-        CompositeNode network = NodeFactory.createCompositeNode(\r
+        value.add(ntElementsNode);\r
+        CompositeNode network = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "network"), null, value);\r
         assignParentToChildren(network);\r
         \r
@@ -323,5 +342,70 @@ public abstract class NodeHelper {
                 .parseYangModelsFromStreams(yangInputStreams);\r
         return yParser.resolveSchemaContext(modules);\r
     }\r
+    \r
+    /**\r
+     * @param scriptName \r
+     * @return tree root\r
+     * @throws Exception\r
+     */\r
+    public static CompositeNode loadConfigByGroovy(String scriptName) throws Exception {\r
+       InputStream configStream = NodeHelper.class.getResourceAsStream(scriptName);\r
+       Binding binding = new Binding();\r
+       GroovyShell gShell = new GroovyShell(binding);\r
+       LOG.debug("groovy: starting script parse..  " + scriptName);\r
+               Script configScript = gShell.parse(new InputStreamReader(configStream));\r
+               LOG.debug("groovy: starting script..  " + scriptName);\r
+               configScript.run();\r
+               LOG.debug("groovy: digging result");\r
+       Object xmlGen = binding.getVariable("xmlGen");\r
+       LOG.debug("xmlGen = " + xmlGen);\r
+       Method getter = xmlGen.getClass().getDeclaredMethod("getBuilder", new Class[0]);\r
+       MyNodeBuilder builder = (MyNodeBuilder) getter.invoke(xmlGen, new Object[0]);\r
+       \r
+       return builder.getRootNode();\r
+    }\r
+    \r
+    /**\r
+     * @param pattern , e.g.: <pre>"//{0}:network/{1}:xx[text() = 'sss']"</pre>\r
+     * @param nsArg , e.g.: <pre>{"uri:ns1", "uri:ns2"}</pre>\r
+     * @return pattern with namespaces: <pre>//uri:ns1:network/uri:ns2:xx[text() = ''sss'']"</pre>\r
+     */\r
+    public static String AddNamespaceToPattern(String pattern, Object... nsArg) {\r
+        Object[] ns = nsArg;\r
+        String patternNs = pattern.replaceAll("'", "''");\r
+        if (ns == null) {\r
+            ns = new Object[]{""};\r
+        } else {\r
+            // add ':' into pattern after placeholders\r
+            patternNs = patternNs.replaceAll("(\\{[0-9]+\\})", "$1:");\r
+        }\r
+        \r
+        return MessageFormat.format(patternNs, ns);\r
+    }\r
+\r
+    /**\r
+     * @param tree\r
+     * @param xmlFile \r
+     * @param clazz \r
+     * @throws Exception\r
+     * @throws SAXException\r
+     * @throws IOException\r
+     */\r
+    public static void compareXmlTree(Document tree, String xmlFile, Class<?> clazz) throws Exception,\r
+            SAXException, IOException {\r
+        ByteArrayOutputStream actualRaw = new ByteArrayOutputStream();\r
+        dumpDoc(tree, new PrintStream(actualRaw));\r
+        Reader actualReader = new InputStreamReader(new ByteArrayInputStream(actualRaw.toByteArray()));\r
+        \r
+        Reader expectedReader = new InputStreamReader(clazz.getResourceAsStream(xmlFile));\r
+        Diff myDiff = new Diff(expectedReader, actualReader);\r
+        myDiff.overrideDifferenceListener(new IgnoreWhiteCharsDiffListener());\r
+        \r
+        boolean similar = myDiff.similar();\r
+        if (! similar) {\r
+            System.out.println(new String(actualRaw.toByteArray()));\r
+        }\r
+        Assert.assertEquals(myDiff.toString(), true, similar);\r
+    }\r
 \r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 2df397a..5f4e482
@@ -18,8 +18,11 @@ import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
 import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
 import org.w3c.dom.Document;\r
 \r
 /**\r
@@ -27,12 +30,28 @@ import org.w3c.dom.Document;
  * \r
  */\r
 public class NodeModificationBuilderImplTest {\r
+    \r
+    private static final Logger LOG = LoggerFactory\r
+            .getLogger(NodeModificationBuilderImplTest.class);\r
 \r
     private SchemaContext schemaCtx;\r
     private QName qName;\r
     private CompositeNode network;\r
     private NodeModificationBuilderImpl nodeModificationBuilder;\r
 \r
+    private String ns;\r
+\r
+    /**\r
+     * @throws Exception\r
+     */\r
+    private void dumpResult() throws Exception {\r
+        CompositeNode diffTree = nodeModificationBuilder.buildDiffTree();\r
+        CompositeNode diffTreeImmutable = NodeFactory.copyDeepAsImmutable(diffTree, null);\r
+        \r
+        Document diffShadow = NodeUtils.buildShadowDomTree(diffTreeImmutable);\r
+        NodeHelper.dumpDoc(diffShadow, System.out);\r
+    }\r
+\r
     /**\r
      * prepare schemaContext\r
      * @throws Exception \r
@@ -41,14 +60,130 @@ public class NodeModificationBuilderImplTest {
     public void setUp() throws Exception {\r
         schemaCtx = NodeHelper.loadSchemaContext();\r
 \r
+        ns = "urn:opendaylight:controller:network";\r
         qName = new QName(\r
-                new URI("urn:opendaylight:controller:network"), \r
+                new URI(ns), \r
                 new Date(1369000800000L), "topos");\r
         network = NodeHelper.buildTestConfigTree(qName);\r
         \r
         nodeModificationBuilder = new NodeModificationBuilderImpl(network, schemaCtx);\r
     }\r
 \r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}\r
+     * .\r
+     */\r
+    @Test\r
+    public void testGetMutableEquivalent() {\r
+        MutableCompositeNode rootMutable = (MutableCompositeNode) \r
+                nodeModificationBuilder.getMutableEquivalent(network);\r
+        \r
+        CompositeNode topologies = network.getCompositesByName("topologies").iterator().next();\r
+        Node<?> mutableEquivalent = nodeModificationBuilder.getMutableEquivalent(topologies);\r
+        CompositeNode topologiesMutable = rootMutable.getCompositesByName("topologies").iterator().next();\r
+        \r
+        Assert.assertSame(topologiesMutable, mutableEquivalent);\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeAddSimple() throws Exception {\r
+        LOG.debug("testBuildDiffTreeAddSimple");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        CompositeNode needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]", ns));\r
+        \r
+        MutableCompositeNode mutableParent = (MutableCompositeNode) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        MutableSimpleNode<String> newMutable = NodeFactory.createMutableSimpleNode(\r
+                new QName(needle.getNodeType(), "anySubNode"), mutableParent, "42", null, null);\r
+        \r
+        nodeModificationBuilder.addNode(newMutable);\r
+        dumpResult();\r
+    }\r
+    \r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeAddComposite() throws Exception {\r
+        LOG.debug("testBuildDiffTreeAddComposite");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        CompositeNode needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]", ns));\r
+        \r
+        MutableCompositeNode mutableParent = (MutableCompositeNode) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        MutableSimpleNode<String> newMutable = NodeFactory.createMutableSimpleNode(\r
+                new QName(needle.getNodeType(), "anySubNode"), null, "42", null, null);\r
+        \r
+        MutableCompositeNode newMutableCom = NodeFactory.createMutableCompositeNode(\r
+                new QName(needle.getNodeType(), "anySubNode"), mutableParent, \r
+                NodeUtils.buildChildrenList(newMutable), null, null);\r
+        NodeUtils.fixChildrenRelation(newMutableCom);\r
+        newMutableCom.init();\r
+        \r
+        nodeModificationBuilder.addNode(newMutableCom);\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeDeleteComposite() throws Exception {\r
+        LOG.debug("testBuildDiffTreeDeleteComposite");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+\r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        nodeModificationBuilder.deleteNode(mutableNeedle.getParent().asMutable());\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeDeleteSimple() throws Exception {\r
+        LOG.debug("testBuildDiffTreeDeleteSimple");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+        \r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        nodeModificationBuilder.deleteNode(mutableNeedle);\r
+        dumpResult();\r
+    }\r
+\r
     /**\r
      * Test method for\r
      * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
@@ -56,37 +191,111 @@ public class NodeModificationBuilderImplTest {
      * @throws Exception \r
      */\r
     @Test\r
-    public void testBuildDiffTree() throws Exception {\r
+    public void testBuildDiffTreeMerge() throws Exception {\r
+        LOG.debug("testBuildDiffTreeMerge");\r
         Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
-        SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, \r
-                "//node[node-id='nodeId_19']//termination-point[2]/tp-id");\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
         \r
         @SuppressWarnings("unchecked")\r
         MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
                 nodeModificationBuilder.getMutableEquivalent(needle);\r
         \r
         mutableNeedle.setValue("tpId_18x");\r
-        nodeModificationBuilder.replaceNode(mutableNeedle);\r
-        CompositeNode diffTree = nodeModificationBuilder.buildDiffTree();\r
+        nodeModificationBuilder.mergeNode(mutableNeedle.getParent().asMutable());\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeRemoveComposite() throws Exception {\r
+        LOG.debug("testBuildDiffTreeRemoveComposite");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
         \r
-        Document diffShadow = NodeUtils.buildShadowDomTree(diffTree);\r
-        NodeHelper.dumpDoc(diffShadow, System.out);\r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        nodeModificationBuilder.removeNode(mutableNeedle.getParent().asMutable());\r
+        dumpResult();\r
     }\r
 \r
     /**\r
      * Test method for\r
-     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
      * .\r
+     * @throws Exception \r
      */\r
     @Test\r
-    public void testGetMutableEquivalent() {\r
-        MutableCompositeNode rootMutable = (MutableCompositeNode) \r
-                nodeModificationBuilder.getMutableEquivalent(network);\r
+    public void testBuildDiffTreeRemoveSimple() throws Exception {\r
+        LOG.debug("testBuildDiffTreeRemoveSimple");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
         \r
-        CompositeNode topologies = network.getCompositesByName("topologies").iterator().next();\r
-        CompositeNode topologiesMutable = rootMutable.getCompositesByName("topologies").iterator().next();\r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        nodeModificationBuilder.removeNode(mutableNeedle);\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeReplaceComposite() throws Exception {\r
+        LOG.debug("testBuildDiffTreeReplaceComposite");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+        \r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        mutableNeedle.setValue("tpId_18x");\r
+        nodeModificationBuilder.replaceNode(mutableNeedle.getParent().asMutable());\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeReplaceSimple() throws Exception {\r
+        LOG.debug("testBuildDiffTreeReplaceSimple");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
         \r
-        Assert.assertSame(topologiesMutable, nodeModificationBuilder.getMutableEquivalent(topologies));\r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        mutableNeedle.setValue("tpId_18x");\r
+        nodeModificationBuilder.replaceNode(mutableNeedle);\r
+        dumpResult();\r
     }\r
 \r
+\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 53ffc2e..16d736a
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.yang.data.impl;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.net.URI;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.yang.common.QName;
-import org.opendaylight.controller.yang.data.api.CompositeNode;
-import org.opendaylight.controller.yang.data.api.Node;
-import org.opendaylight.controller.yang.data.api.SimpleNode;
-import org.opendaylight.controller.yang.model.api.ListSchemaNode;
-import org.opendaylight.controller.yang.model.api.SchemaContext;
-import org.w3c.dom.Document;
-
-/**
- * @author michal.rehak
- *
- */
-public class NodeUtilsTest {
-    
-    private QName qName;
-    private CompositeNode network;
-
-    /**
-     * @throws Exception
-     */
-    @Before
-    public void setUp() throws Exception {
-        qName = new QName(
-                new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), 
-                new Date(42), "yang-data-impl-mutableTest");
-        network = NodeHelper.buildTestConfigTree(qName);
-    }
-
-    /**
-     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildPath(org.opendaylight.controller.yang.data.api.Node)}.
-     * @throws Exception 
-     */
-    @Test
-    public void testBuildPath() throws Exception {
-        SimpleNode<?> needle = network.getCompositesByName("topologies").iterator().next()
-            .getCompositesByName("topology").iterator().next()
-            .getSimpleNodesByName("topology-id").iterator().next();
-        String breadCrumbs = NodeUtils.buildPath(needle);
-        
-        Assert.assertEquals("network.topologies.topology.topology-id", breadCrumbs);
-    }
-
-    /**
-     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildShadowDomTree(org.opendaylight.controller.yang.data.api.CompositeNode)}.
-     * @throws Exception 
-     */
-    @Test
-    public void testBuildShadowDomTree() throws Exception {
-        Document networkShadow = NodeUtils.buildShadowDomTree(network);
-        ByteArrayOutputStream actual = new ByteArrayOutputStream();
-        NodeHelper.dumpDoc(networkShadow, new PrintStream(actual));
-        
-        Assert.assertEquals(2760, new String(actual.toByteArray()).length());
-    }
-
-    /**
-     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#findNodeByXpath(org.w3c.dom.Document, java.lang.String)}.
-     * @throws Exception 
-     */
-    @Test
-    public void testFindNodeByXpath() throws Exception {
-        Document networkShadow = NodeUtils.buildShadowDomTree(network);
-        SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, 
-                "//node[node-id='nodeId_19']//termination-point[2]/tp-id");
-        Assert.assertNotNull(needle);
-        Assert.assertEquals("tpId_18", needle.getValue());
-    }
-
-    /**
-     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildNodeMap(java.util.List)}.
-     */
-    @Test
-    public void testBuildNodeMap() {
-        CompositeNode topology = network.getCompositesByName("topologies").iterator().next()
-            .getCompositesByName("topology").iterator().next();
-        
-        Map<QName, List<Node<?>>> nodeMap = NodeUtils.buildNodeMap(topology.getChildren());
-        Assert.assertEquals(3, nodeMap.size());
-    }
-    
-    /**
-     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildMapOfListNodes(org.opendaylight.controller.yang.model.api.SchemaContext)}.
-     */
-    @Test
-    public void testBuildMapOfListNodes() {
-        SchemaContext schemaCtx = NodeHelper.loadSchemaContext();
-        Map<String, ListSchemaNode> mapOfLists = NodeUtils.buildMapOfListNodes(schemaCtx);
-        Assert.assertEquals(5, mapOfLists.size());
-    }
-
-}
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.io.IOException;\r
+import java.net.URI;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Stack;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.w3c.dom.Document;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class NodeUtilsTest {\r
+    \r
+    private static final Logger LOG = LoggerFactory\r
+            .getLogger(NodeUtilsTest.class);\r
+    \r
+    private QName qName;\r
+    private CompositeNode network;\r
+\r
+    private String ns;\r
+\r
+\r
+    /**\r
+     * @throws Exception\r
+     */\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        ns = "urn:ietf:params:xml:ns:netconf:base:1.0";\r
+        qName = new QName(\r
+                new URI(ns), \r
+                new Date(42), "yang-data-impl-mutableTest");\r
+        network = NodeHelper.buildTestConfigTree(qName);\r
+    }\r
+\r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildPath(org.opendaylight.controller.yang.data.api.Node)}.\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildPath() throws Exception {\r
+        SimpleNode<?> needle = network.getCompositesByName("topologies").iterator().next()\r
+            .getCompositesByName("topology").iterator().next()\r
+            .getSimpleNodesByName("topology-id").iterator().next();\r
+        String breadCrumbs = NodeUtils.buildPath(needle);\r
+        \r
+        Assert.assertEquals("network.topologies.topology.topology-id", breadCrumbs);\r
+    }\r
+\r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildShadowDomTree(org.opendaylight.controller.yang.data.api.CompositeNode)}.\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildShadowDomTree() throws Exception {\r
+        MemoryConsumption mc = new MemoryConsumption();\r
+        mc.startObserving();\r
+        \r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        \r
+        LOG.debug("After dom built: "+mc.finishObserving());\r
+        NodeHelper.compareXmlTree(networkShadow, "./config02-shadow.xml", getClass());\r
+    }\r
+\r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#findNodeByXpath(org.w3c.dom.Document, java.lang.String)}.\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testFindNodeByXpath() throws Exception {\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        MemoryConsumption mc = new MemoryConsumption();\r
+        mc.startObserving();\r
+        \r
+        SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                        "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+        \r
+        LOG.debug("After xpath executed: "+mc.finishObserving());\r
+        \r
+        Assert.assertNotNull(needle);\r
+        Assert.assertEquals("tpId_18", needle.getValue());\r
+    }\r
+    \r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildNodeMap(java.util.List)}.\r
+     */\r
+    @Test\r
+    public void testBuildNodeMap() {\r
+        CompositeNode topology = network.getCompositesByName("topologies").iterator().next()\r
+            .getCompositesByName("topology").iterator().next();\r
+        \r
+        Map<QName, List<Node<?>>> nodeMap = NodeUtils.buildNodeMap(topology.getChildren());\r
+        Assert.assertEquals(3, nodeMap.size());\r
+    }\r
+    \r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildMapOfListNodes(org.opendaylight.controller.yang.model.api.SchemaContext)}.\r
+     */\r
+    @Test\r
+    public void testBuildMapOfListNodes() {\r
+        SchemaContext schemaCtx = NodeHelper.loadSchemaContext();\r
+        Map<String, ListSchemaNode> mapOfLists = NodeUtils.buildMapOfListNodes(schemaCtx);\r
+        Assert.assertEquals(5, mapOfLists.size());\r
+    }\r
+\r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildMapOfListNodes(org.opendaylight.controller.yang.model.api.SchemaContext)}.\r
+     * @throws Exception \r
+     * @throws IOException \r
+     */\r
+    @Test\r
+    public void testLoadConfigByGroovy() throws IOException, Exception {\r
+       CompositeNode treeRoot = NodeHelper.loadConfigByGroovy("./config02.groovy");\r
+       Document shadowTree = NodeUtils.buildShadowDomTree(treeRoot);\r
+       try {\r
+            checkFamilyBinding(treeRoot);\r
+        } catch (Exception e) {\r
+            LOG.error(e.getMessage());\r
+            throw e;\r
+        }\r
+       \r
+       NodeHelper.compareXmlTree(shadowTree, "./config02g-shadow.xml", getClass());\r
+    }\r
+\r
+    private static void checkFamilyBinding(CompositeNode treeRoot) throws Exception {\r
+        Stack<CompositeNode> jobQueue = new Stack<>();\r
+        jobQueue.push(treeRoot);\r
+        \r
+        while (!jobQueue.isEmpty()) {\r
+            CompositeNode job = jobQueue.pop();\r
+            for (Node<?> child : job.getChildren()) {\r
+                if (child instanceof CompositeNode) {\r
+                    jobQueue.push((CompositeNode) child);\r
+                }\r
+                \r
+                if (job != child.getParent()) {\r
+                    throw new Exception("binding mismatch occured: \nPARENT["+job+"]\n CHILD[" + child+"]\n  +->  "+child.getParent());\r
+                }\r
+            }\r
+        }\r
+    }\r
+    \r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/MyXmlGenerator.groovy b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/MyXmlGenerator.groovy
new file mode 100644 (file)
index 0000000..f22da0c
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+import groovy.xml.MarkupBuilder
+import org.opendaylight.controller.yang.data.impl.MyNodeBuilder
+
+/**
+ * wrapper class - applies hardcoded builder on given data closure
+ */
+class MyXmlGenerator {
+
+    def myBuilder
+    
+    MyXmlGenerator() {
+        myBuilder = MyNodeBuilder.newInstance();
+    }
+
+    MyNodeBuilder getBuilder() { 
+      return myBuilder;
+    }
+        
+    void buildTree(data) {
+        data.setDelegate(myBuilder)
+        data()
+    }
+    
+    /**
+     * tests builder execution
+     */
+    static void main(args) {
+        println 'hello'
+        def data = {
+          network(xmlns: 'urn:opendaylight:controller:network') {
+            topologies {
+              topology {
+                'topology-id'('topId_01')
+                
+                nodes {
+                  node {
+                    'node-id'('nodeId_02')
+                    'supporting-ne'('networkId_03')
+                    'termination-points' {
+                      'termination-point' {
+                        'tp-id'('tpId_04')
+                      }
+                    }
+                  }
+                  node {
+                    'node-id'('nodeId_05')
+                    'supporting-ne'('networkId_06')
+                    'termination-points' {
+                      'termination-point' {
+                        'tp-id'('tpId_07')
+                      }
+                    }
+                  }
+                  node {
+                    'node-id'('nodeId_08')
+                    'supporting-ne'('networkId_09')
+                    'termination-points' {
+                      'termination-point' {
+                        'tp-id'('tpId_10')
+                      }
+                      'termination-point' {
+                        'tp-id'('tpId_11')
+                      }
+                    }
+                  }
+                }
+                links {
+                  link {
+                    'link-id'('linkId_12')
+                    source {
+                      'source-node'('nodeId_13')
+                      'source-tp'('tpId_13')
+                    }
+                    destination {
+                      'dest-node'('nodeId_14')
+                      'dest-tp'('tpId_14')
+                    }
+                  }
+                  link {
+                    'link-id'('linkId_15')
+                    source {
+                      'source-node'('nodeId_16')
+                      'source-tp'('tpId_16')
+                    }
+                    destination {
+                      'dest-node'('nodeId_17')
+                      'dest-tp'('tpId_17')
+                    }
+                  }
+                }
+              }
+            }
+            'network-elements' {
+              'network-element' {
+                'element-id'('ntElementId_18')
+              }
+              'network-element' {
+                'element-id'('ntElementId_19')
+              }
+            }
+          }
+
+        }
+
+        def xmlGen = new MyXmlGenerator()
+        xmlGen.buildTree(data)
+        println xmlGen.getBuilder().getRootNode()
+    }
+
+}
+
+
+
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.content b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.content
deleted file mode 100755 (executable)
index e9c05c9..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-xmlDoc.network(xmlns: 'urn:opendaylight:controller:network') {\r
-    topologies {\r
-      topology {\r
-        'topology-id'('topId_'+cnt.get())\r
-        \r
-        types()\r
-        nodes {\r
-          node {\r
-            'node-id'('nodeId_'+cnt.get())\r
-            'supporting-ne'('networkId_'+cnt.get())\r
-            'termination-points' {\r
-              'termination-point' {\r
-                'tp-id'('tpId_'+cnt.get())\r
-              }\r
-            }\r
-          }\r
-          node {\r
-            'node-id'('nodeId_'+cnt.get())\r
-            'supporting-ne'('networkId_'+cnt.get())\r
-            'termination-points' {\r
-              'termination-point' {\r
-                'tp-id'('tpId_'+cnt.get())\r
-              }\r
-            }\r
-          }\r
-          node {\r
-            'node-id'('nodeId_'+cnt.get())\r
-            'supporting-ne'('networkId_'+cnt.get())\r
-            'termination-points' {\r
-              'termination-point' {\r
-                'tp-id'('tpId_'+cnt.get())\r
-              }\r
-              'termination-point' {\r
-                'tp-id'('tpId_'+cnt.get())\r
-              }\r
-            }\r
-          }\r
-        }\r
-        links {\r
-          link {\r
-            'link-id'('linkId_'+cnt.get())\r
-            source {\r
-              'source-node'('nodeId_'+cnt.get())\r
-              'source-tp'('tpId_'+cnt.get(false))\r
-            }\r
-            destination {\r
-              'dest-node'('nodeId_'+cnt.get())\r
-              'dest-tp'('tpId_'+cnt.get(false))\r
-            }\r
-          }\r
-          link {\r
-            'link-id'('linkId_'+cnt.get())\r
-            source {\r
-              'source-node'('nodeId_'+cnt.get())\r
-              'source-tp'('tpId_'+cnt.get(false))\r
-            }\r
-            destination {\r
-              'dest-node'('nodeId_'+cnt.get())\r
-              'dest-tp'('tpId_'+cnt.get(false))\r
-            }\r
-          }\r
-        }\r
-      }\r
-    }\r
-    'network-elements' {\r
-      'network-element' {\r
-        'element-id'('ntElementId_'+cnt.get())\r
-      }\r
-      'network-element' {\r
-        'element-id'('ntElementId_'+cnt.get())\r
-      }\r
-    }\r
-  }
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02g.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02g.xml
deleted file mode 100644 (file)
index d1ac68c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<network xmlns="urn:opendaylight:controller:network">
-  <topologies>
-    <topology>
-      <topology-id>topId_01</topology-id>
-      <types />
-      <nodes>
-        <node>
-          <node-id>nodeId_02</node-id>
-          <supporting-ne>networkId_03</supporting-ne>
-          <termination-points>
-            <termination-point>
-              <tp-id>tpId_04</tp-id>
-            </termination-point>
-          </termination-points>
-        </node>
-        <node>
-          <node-id>nodeId_05</node-id>
-          <supporting-ne>networkId_06</supporting-ne>
-          <termination-points>
-            <termination-point>
-              <tp-id>tpId_07</tp-id>
-            </termination-point>
-          </termination-points>
-        </node>
-        <node>
-          <node-id>nodeId_08</node-id>
-          <supporting-ne>networkId_09</supporting-ne>
-          <termination-points>
-            <termination-point>
-              <tp-id>tpId_10</tp-id>
-            </termination-point>
-            <termination-point>
-              <tp-id>tpId_11</tp-id>
-            </termination-point>
-          </termination-points>
-        </node>
-      </nodes>
-      <links>
-        <link>
-          <link-id>linkId_12</link-id>
-          <source>
-            <source-node>nodeId_13</source-node>
-            <source-tp>tpId_13</source-tp>
-          </source>
-          <destination>
-            <dest-node>nodeId_14</dest-node>
-            <dest-tp>tpId_14</dest-tp>
-          </destination>
-        </link>
-        <link>
-          <link-id>linkId_15</link-id>
-          <source>
-            <source-node>nodeId_16</source-node>
-            <source-tp>tpId_16</source-tp>
-          </source>
-          <destination>
-            <dest-node>nodeId_17</dest-node>
-            <dest-tp>tpId_17</dest-tp>
-          </destination>
-        </link>
-      </links>
-    </topology>
-  </topologies>
-  <network-elements>
-    <network-element>
-      <element-id>ntElementId_18</element-id>
-    </network-element>
-    <network-element>
-      <element-id>ntElementId_19</element-id>
-    </network-element>
-  </network-elements>
-</network>\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/generateXml.groovy b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/generateXml.groovy
deleted file mode 100755 (executable)
index a778137..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-//import groovy.xml.StreamingMarkupBuilder
-import groovy.xml.MarkupBuilder
-import groovy.xml.XmlUtil
-
-class Counter {
-    def counter = 0
-    def get() {
-        return get(true)
-    }
-    def get(isInc) {
-        if (isInc) {
-            counter++
-        }
-        return String.format('%02d', counter)
-    }
-}
-
-
-cnt = new Counter()
-def writer = new StringWriter()
-xmlDoc = new MarkupBuilder(writer)
-xmlDoc.setDoubleQuotes(true)
-xmlDoc.getMkp().xmlDeclaration(version:'1.0', encoding: 'UTF-8')
-
-//def data = {
-//  mkp.xmlDeclaration()
-//  network(xmlns: 'urn:opendaylight:controller:network') {
-dataFile = new File(args[0])
-evaluate(dataFile)
-// xmlDoc.network(xmlns: 'urn:opendaylight:controller:network') {
-    // topologies {
-      // topology {
-        // 'topology-id'('topId_'+cnt.get())
-        // types()
-        // nodes {
-          // node {
-            // 'node-id'('nodeId_'+cnt.get())
-            // 'supporting-ne'('networkId_'+cnt.get())
-            // 'termination-points' {
-              // 'termination-point' {
-                // 'tp-id'('tpId_'+cnt.get())
-              // }
-            // }
-          // }
-          // node {
-            // 'node-id'('nodeId_'+cnt.get())
-            // 'supporting-ne'('networkId_'+cnt.get())
-            // 'termination-points' {
-              // 'termination-point' {
-                // 'tp-id'('tpId_'+cnt.get())
-              // }
-            // }
-          // }
-          // node {
-            // 'node-id'('nodeId_'+cnt.get())
-            // 'supporting-ne'('networkId_'+cnt.get())
-            // 'termination-points' {
-              // 'termination-point' {
-                // 'tp-id'('tpId_'+cnt.get())
-              // }
-              // 'termination-point' {
-                // 'tp-id'('tpId_'+cnt.get())
-              // }
-            // }
-          // }
-        // }
-        // links {
-          // link {
-            // 'link-id'('linkId_'+cnt.get())
-            // source {
-              // 'source-node'('nodeId_'+cnt.get())
-              // 'source-tp'('tpId_'+cnt.get(false))
-            // }
-            // destination {
-              // 'dest-node'('nodeId_'+cnt.get())
-              // 'dest-tp'('tpId_'+cnt.get(false))
-            // }
-          // }
-          // link {
-            // 'link-id'('linkId_'+cnt.get())
-            // source {
-              // 'source-node'('nodeId_'+cnt.get())
-              // 'source-tp'('tpId_'+cnt.get(false))
-            // }
-            // destination {
-              // 'dest-node'('nodeId_'+cnt.get())
-              // 'dest-tp'('tpId_'+cnt.get(false))
-            // }
-          // }
-        // }
-      // }
-    // }
-    // 'network-elements' {
-      // 'network-element' {
-        // 'element-id'('ntElementId_'+cnt.get())
-      // }
-      // 'network-element' {
-        // 'element-id'('ntElementId_'+cnt.get())
-      // }
-    // }
-  // }
-
-//}
-
-
-// def xmlDoc = new StreamingMarkupBuilder()
-// xmlDoc.encoding = 'UTF'
-//println XmlUtil.serialize(xmlDoc.bind(data))
-
-println writer
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/log4j-test.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/log4j-test.xml
new file mode 100755 (executable)
index 0000000..189236a
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">\r
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">\r
+\r
+    <appender name="console" class="org.apache.log4j.ConsoleAppender">\r
+       <layout class="org.apache.log4j.PatternLayout">\r
+          <param name="ConversionPattern" value="%-6p %d{HH:mm:ss.SSS} [%t] %42.42c %x - %m%n"/>\r
+       </layout>\r
+    </appender>        \r
+\r
+    <logger name="org.opendaylight.controller.yang.data.impl" additivity="false">\r
+           <level value="DEBUG" />\r
+           <appender-ref ref="console"/>\r
+       </logger>\r
+    <logger name="org.opendaylight.controller.yang.data.impl.MyNodeBuilder" additivity="false">\r
+        <level value="INFO" />\r
+        <appender-ref ref="console"/>\r
+    </logger>   \r
+       \r
+       <root>\r
+        <priority value="INFO"/>\r
+        <appender-ref ref="console" />\r
+    </root>\r
+</log4j:configuration>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02-shadow.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02-shadow.xml
new file mode 100644 (file)
index 0000000..aaaf22d
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<network xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <topologies>
+        <topology>
+            <topology-id>topId_01</topology-id>
+            <nodes>
+                <node>
+                    <node-id>nodeId_19</node-id>
+                    <supporting-ne>networkId_20</supporting-ne>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_19</tp-id>
+                        </termination-point>
+                        <termination-point>
+                            <tp-id>tpId_18</tp-id>
+                        </termination-point>
+                    </termination-points>
+                </node>
+                <node>
+                    <node-id>nodeId_16</node-id>
+                    <supporting-ne>networkId_17</supporting-ne>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_18</tp-id>
+                        </termination-point>
+                    </termination-points>
+                </node>
+                <node>
+                    <node-id>nodeId_02</node-id>
+                    <supporting-ne>networkId_02</supporting-ne>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_03</tp-id>
+                        </termination-point>
+                    </termination-points>
+                </node>
+            </nodes>
+            <links>
+                <link>
+                    <destination>
+                        <dest-tp>tpId_15</dest-tp>
+                        <dest-node>nodeId_14</dest-node>
+                    </destination>
+                    <source>
+                        <source-tp>tpId_13</source-tp>
+                        <source-node>nodeId_12</source-node>
+                    </source>
+                    <link-id>linkId_11</link-id>
+                </link>
+                <link>
+                    <destination>
+                        <dest-tp>tpId_08</dest-tp>
+                        <dest-node>nodeId_07</dest-node>
+                    </destination>
+                    <source>
+                        <source-tp>tpId_06</source-tp>
+                        <source-node>nodeId_05</source-node>
+                    </source>
+                    <link-id>linkId_04</link-id>
+                </link>
+            </links>
+        </topology>
+    </topologies>
+    <network-elements>
+        <network-element>
+            <element-id>ntElementId_10</element-id>
+        </network-element>
+        <network-element>
+            <element-id>ntElementId_09</element-id>
+        </network-element>
+    </network-elements>
+</network>
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02.groovy b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02.groovy
new file mode 100644 (file)
index 0000000..cfd8ab0
--- /dev/null
@@ -0,0 +1,89 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+def data = {\r
+ network(xmlns: 'urn:opendaylight:controller:network') {\r
+    topologies {\r
+      topology {\r
+        'topology-id'('topId_01')\r
+        \r
+        //types()\r
+        nodes {\r
+          node {\r
+            'node-id'('nodeId_02')\r
+            'supporting-ne'('networkId_03')\r
+            'termination-points' {\r
+              'termination-point' {\r
+                'tp-id'('tpId_04')\r
+              }\r
+            }\r
+          }\r
+          node {\r
+            'node-id'('nodeId_05')\r
+            'supporting-ne'('networkId_06')\r
+            'termination-points' {\r
+              'termination-point' {\r
+                'tp-id'('tpId_07')\r
+              }\r
+            }\r
+          }\r
+          node {\r
+            'node-id'('nodeId_08')\r
+            'supporting-ne'('networkId_09')\r
+            'termination-points' {\r
+              'termination-point' {\r
+                'tp-id'('tpId_10')\r
+              }\r
+              'termination-point' {\r
+                'tp-id'('tpId_11')\r
+              }\r
+            }\r
+          }\r
+        }\r
+        links {\r
+          link {\r
+            'link-id'('linkId_12')\r
+            source {\r
+              'source-node'('nodeId_13')\r
+              'source-tp'('tpId_13')\r
+            }\r
+            destination {\r
+              'dest-node'('nodeId_14')\r
+              'dest-tp'('tpId_14')\r
+            }\r
+          }\r
+          link {\r
+            'link-id'('linkId_15')\r
+            source {\r
+              'source-node'('nodeId_16')\r
+              'source-tp'('tpId_16')\r
+            }\r
+            destination {\r
+              'dest-node'('nodeId_17')\r
+              'dest-tp'('tpId_17')\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+    'network-elements' {\r
+      'network-element' {\r
+        'element-id'('ntElementId_18')\r
+      }\r
+      'network-element' {\r
+        'element-id'('ntElementId_19')\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+System.err.println('data inited')\r
+\r
+import MyXmlGenerator\r
+\r
+xmlGen = new MyXmlGenerator()\r
+xmlGen.buildTree(data)\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02g-shadow.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02g-shadow.xml
new file mode 100644 (file)
index 0000000..9db9342
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<network xmlns="urn:opendaylight:controller:network">
+    <topologies>
+        <topology>
+            <links>
+                <link>
+                    <destination>
+                        <dest-tp>tpId_17</dest-tp>
+                        <dest-node>nodeId_17</dest-node>
+                    </destination>
+                    <source>
+                        <source-tp>tpId_16</source-tp>
+                        <source-node>nodeId_16</source-node>
+                    </source>
+                    <link-id>linkId_15</link-id>
+                </link>
+                <link>
+                    <destination>
+                        <dest-tp>tpId_14</dest-tp>
+                        <dest-node>nodeId_14</dest-node>
+                    </destination>
+                    <source>
+                        <source-tp>tpId_13</source-tp>
+                        <source-node>nodeId_13</source-node>
+                    </source>
+                    <link-id>linkId_12</link-id>
+                </link>
+            </links>
+            <nodes>
+                <node>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_11</tp-id>
+                        </termination-point>
+                        <termination-point>
+                            <tp-id>tpId_10</tp-id>
+                        </termination-point>
+                    </termination-points>
+                    <supporting-ne>networkId_09</supporting-ne>
+                    <node-id>nodeId_08</node-id>
+                </node>
+                <node>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_07</tp-id>
+                        </termination-point>
+                    </termination-points>
+                    <supporting-ne>networkId_06</supporting-ne>
+                    <node-id>nodeId_05</node-id>
+                </node>
+                <node>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_04</tp-id>
+                        </termination-point>
+                    </termination-points>
+                    <supporting-ne>networkId_03</supporting-ne>
+                    <node-id>nodeId_02</node-id>
+                </node>
+            </nodes>
+            <topology-id>topId_01</topology-id>
+        </topology>
+    </topologies>
+    <network-elements>
+        <network-element>
+            <element-id>ntElementId_19</element-id>
+        </network-element>
+        <network-element>
+            <element-id>ntElementId_18</element-id>
+        </network-element>
+    </network-elements>
+</network>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/mutableNodesConfig.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/mutableNodesConfig.xml
new file mode 100644 (file)
index 0000000..851022b
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <top>
+        <interface>
+            <mtu modifyAction="REMOVE">1501</mtu>
+            <name>Ethernet1/0</name>
+        </interface>
+        <interface modifyAction="DELETE">
+            <mtu>1500</mtu>
+            <name>Ethernet0/0</name>
+        </interface>
+    </top>
+</config>
\ No newline at end of file
index 250cd9d2a6e02cd8a0224aabf52fd93e969ea119..e6297f55b2ecef2db772bb2f40d59eae0d82289b 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.yang.data.util;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;
+import org.opendaylight.controller.yang.data.api.ModifyAction;
 import org.opendaylight.controller.yang.data.api.Node;
 
 public abstract class AbstractNode<T> implements Node<T> {
@@ -28,4 +29,14 @@ public abstract class AbstractNode<T> implements Node<T> {
     public CompositeNode getParent() {
         return parent;
     }
+    
+    /* (non-Javadoc)
+     */
+    /**
+     * @see org.opendaylight.controller.yang.data.api.NodeModification#getModificationAction()
+     */
+    public ModifyAction getModificationAction() {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
index 57feff1514526c91dbd2f4a93f5bb2a27e4a9d15..fca835f4585200eb1c5b0f53f0b233f77c3dc4ce 100644 (file)
@@ -14,6 +14,9 @@ import java.util.Map;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;
+import org.opendaylight.controller.yang.data.api.ModifyAction;
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;
 import org.opendaylight.controller.yang.data.api.Node;
 import org.opendaylight.controller.yang.data.api.SimpleNode;
 
@@ -71,6 +74,16 @@ public class Nodes {
 
             return nodeMap;
         }
+
+        /* (non-Javadoc)
+         * @see org.opendaylight.controller.yang.data.api.CompositeNode#asMutable()
+         */
+        @Override
+        public MutableCompositeNode asMutable() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
     }
 
     private static class SimpleNodeTO<T> extends AbstractNode<T> implements
@@ -89,6 +102,15 @@ public class Nodes {
             return value;
         }
 
+        /* (non-Javadoc)
+         * @see org.opendaylight.controller.yang.data.api.SimpleNode#asMutable()
+         */
+        @Override
+        public MutableSimpleNode<T> asMutable() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
     }
 
 }