first implementation of yang-data-api 30/530/2
authorMichal Rehak <mirehak@cisco.com>
Thu, 27 Jun 2013 14:01:29 +0000 (16:01 +0200)
committerMichal Rehak <mirehak@cisco.com>
Mon, 8 Jul 2013 09:35:32 +0000 (11:35 +0200)
created maven project
added basic implementations of api
added unit tests
changed api according to implementation

Change-Id: I888371d5a7afc46c843f882bee9bfcaa19d5ccbc
Signed-off-by: Michal Rehak <mirehak@cisco.com>
32 files changed:
opendaylight/sal/yang-prototype/yang/pom.xml
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNodeModification.java [deleted file]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableCompositeNode.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableNode.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableSimpleNode.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/Node.java
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/NodeModification.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/NodeModificationBuilder.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/pom.xml [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/AbstractNodeTO.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeModificationTOImpl.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeTOImpl.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableCompositeNodeTOImpl.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableSimpleNodeTOImpl.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeFactory.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImpl.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeUtils.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeModificationTOImpl.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeTOImpl.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeFactoryTest.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeHelper.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImplTest.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeUtilsTest.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config01.xml [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.content [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.xml [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02g.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/controller-network.xsd [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/controller-network.yang [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/generateXml.groovy [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/ietf-inet-types@2010-09-24.xsd [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/ietf-inet-types@2010-09-24.yang [new file with mode: 0755]

index 33c1604..3076a6f 100644 (file)
@@ -19,6 +19,7 @@
                <module>yang-common</module>
                <module>yang-data-api</module>
                <module>yang-data-util</module>
+               <module>yang-data-impl</module>
                <module>yang-model-api</module>
                <module>yang-model-util</module>
                <module>yang-binding</module>
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNodeModification.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNodeModification.java
deleted file mode 100644 (file)
index 1772ddf..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*\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.api;\r
-\r
-import org.opendaylight.controller.yang.common.QName;\r
-\r
-/**\r
- * For the use cases of changing the state data, the node modifications are\r
- * modeled as part of additional metadata in data tree. The modification types\r
- * are based on Netconf edit-config RPCs. In order to modify the configuration\r
- * or state data tree the user must create a tree representing the modification\r
- * of the data and apply that modification to the target tree.\r
- * \r
- * \r
- * @see <a href="http://tools.ietf.org/html/rfc6241">Network Configuration\r
- *      Protocol (NETCONF)</a>\r
- * \r
- */\r
-public interface CompositeNodeModification extends CompositeNode {\r
-\r
-    ModifyAction getModificationAction();\r
-\r
-    // Container Modification\r
-\r
-    /**\r
-     * The data identified by the node containing this modification is merged\r
-     * with the data at the corresponding level in the data tree\r
-     * \r
-     * @param node\r
-     *            in data tree\r
-     */\r
-    void mergeChild(CompositeNode node);\r
-\r
-    /**\r
-     * The data identified by the node containing this modification replaces any\r
-     * related data in the target data tree If no such data exists in the target\r
-     * data tree, the child node is created.\r
-     * \r
-     * @param node\r
-     *            composite node\r
-     */\r
-    void replaceChild(CompositeNode node);\r
-\r
-    /**\r
-     * Adds new composite node into data tree\r
-     * \r
-     * @param node\r
-     *            composite node\r
-     */\r
-    void addChild(CompositeNode node);\r
-\r
-    /**\r
-     * The data identified by the node containing this modification is deleted\r
-     * from the target data tree if and only if the data currently exists in the\r
-     * target data tree. If the data does not exist, an error is returned with\r
-     * an error value of "data-missing".\r
-     * \r
-     * @param node\r
-     */\r
-    void deleteChild(CompositeNode node);\r
-\r
-    /**\r
-     * The data identified by the node containing this attribute is deleted from\r
-     * the target data tree if the data currently exists in the target data\r
-     * tree. If the data does not exist, the modification is silently ignored.\r
-     * \r
-     * @param node\r
-     *            composite node\r
-     */\r
-    void removeChild(CompositeNode node);\r
-\r
-    // Leaf Modifications\r
-\r
-    /**\r
-     * The data identified by the node containing this modification replaces any\r
-     * related data in the target data tree If no such data exists in the target\r
-     * data tree, it is created.\r
-     * \r
-     * @param leaf\r
-     */\r
-    void replaceSimpleNode(SimpleNode<?> leaf);\r
-\r
-    /**\r
-     * The data identified by the node containing this modification is deleted\r
-     * from the target data tree if and only if the data currently exists in the\r
-     * target data tree. If the data does not exist, an error is returned with\r
-     * an error value of "data-missing".\r
-     * \r
-     * @param leaf\r
-     */\r
-    void deleteSimpleNode(SimpleNode<?> leaf);\r
-\r
-    /**\r
-     * The data identified by the node containing this attribute is deleted from\r
-     * the target data tree if the data currently exists in the target data\r
-     * tree. If the data does not exist, the modification is silently ignored.\r
-     * \r
-     * @param leaf\r
-     */\r
-    void removeSimpleNode(SimpleNode<?> leaf);\r
-\r
-    void removeLeaf(SimpleNode<?> leaf);\r
-\r
-    void removeLeaf(QName leaf);\r
-}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableCompositeNode.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableCompositeNode.java
new file mode 100755 (executable)
index 0000000..b1baf30
--- /dev/null
@@ -0,0 +1,23 @@
+/*\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.api;\r
+\r
+import java.util.List;\r
+\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public interface MutableCompositeNode extends MutableNode<List<Node<?>>>, CompositeNode {\r
+    \r
+    /**\r
+     * update internal map\r
+     */\r
+    public void init();\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableNode.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableNode.java
new file mode 100755 (executable)
index 0000000..3eddbe5
--- /dev/null
@@ -0,0 +1,34 @@
+/*\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.api;\r
+\r
+\r
+/**\r
+ * Base representation of node in the data tree, defines basic parameters of\r
+ * node such as a QName.\r
+ * \r
+ * \r
+ * @param <T>\r
+ */\r
+public interface MutableNode<T> extends Node<T> {\r
+\r
+    /**\r
+     * @param parent value to set\r
+     */\r
+    void setParent(CompositeNode parent);\r
+    \r
+    /**\r
+     * @param value value to set (children list or leaf value)\r
+     */\r
+    void setValue(T value);\r
+    \r
+    /**\r
+     * @param action value to set\r
+     */\r
+    void setModifyAction(ModifyAction action);\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableSimpleNode.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableSimpleNode.java
new file mode 100755 (executable)
index 0000000..9519fac
--- /dev/null
@@ -0,0 +1,20 @@
+/*\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.api;\r
+\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * @param <T> node value type\r
+ *\r
+ */\r
+public interface MutableSimpleNode<T> extends MutableNode<T>, SimpleNode<T> {\r
+    \r
+   // nothing\r
+    \r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/NodeModification.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/NodeModification.java
new file mode 100755 (executable)
index 0000000..c6b64f3
--- /dev/null
@@ -0,0 +1,21 @@
+/*\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.api;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public interface NodeModification {\r
+\r
+    /**\r
+     * @return modify action\r
+     */\r
+    ModifyAction getModificationAction();\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/NodeModificationBuilder.java b/opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/NodeModificationBuilder.java
new file mode 100755 (executable)
index 0000000..4e4af9b
--- /dev/null
@@ -0,0 +1,39 @@
+/*\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.api;\r
+\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public interface NodeModificationBuilder {\r
+\r
+    public abstract Node<?> getMutableEquivalent(Node<?> originalNode);\r
+\r
+    public abstract CompositeNode buildDiffTree();\r
+\r
+    public abstract void mergeNode(MutableCompositeNode alteredNode);\r
+\r
+    public abstract void removeNode(MutableCompositeNode deadNode);\r
+\r
+    public abstract void removeNode(MutableSimpleNode<?> deadNode);\r
+\r
+    public abstract void deleteNode(MutableSimpleNode<?> deadNode);\r
+\r
+    public abstract void deleteNode(MutableCompositeNode deadNode);\r
+\r
+    public abstract void replaceNode(MutableCompositeNode replacementNode);\r
+\r
+    public abstract void replaceNode(MutableSimpleNode<?> replacementNode);\r
+\r
+    public abstract void addNode(MutableCompositeNode newNode);\r
+\r
+    public abstract void addNode(MutableSimpleNode<?> newNode);\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/pom.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/pom.xml
new file mode 100755 (executable)
index 0000000..5843de1
--- /dev/null
@@ -0,0 +1,72 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"\r
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <parent>\r
+        <groupId>org.opendaylight.controller</groupId>\r
+        <artifactId>yang</artifactId>\r
+        <version>0.5.3-SNAPSHOT</version>\r
+    </parent>\r
+    <artifactId>yang-data-impl</artifactId>\r
+\r
+    <properties>\r
+        <groovy.version>2.1.5</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
+                    <redirectTestOutputToFile>true</redirectTestOutputToFile>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>yang-common</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>yang-data-api</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>yang-model-parser-impl</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.google.guava</groupId>\r
+            <artifactId>guava</artifactId>\r
+            <version>14.0.1</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>junit</groupId>\r
+            <artifactId>junit</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.slf4j</groupId>\r
+            <artifactId>slf4j-log4j12</artifactId>\r
+            <version>${slf4j.version}</version>\r
+            <scope>test</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.codehaus.groovy</groupId>\r
+            <artifactId>groovy</artifactId>\r
+            <version>${groovy.version}</version>\r
+            <scope>test</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.codehaus.groovy</groupId>\r
+            <artifactId>groovy-xml</artifactId>\r
+            <version>${groovy.version}</version>\r
+            <scope>test</scope>\r
+        </dependency>\r
+    </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/AbstractNodeTO.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/AbstractNodeTO.java
new file mode 100755 (executable)
index 0000000..cc4dfee
--- /dev/null
@@ -0,0 +1,72 @@
+/*\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.Node;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * @param <T>\r
+ *            type of node value\r
+ * \r
+ */\r
+public abstract class AbstractNodeTO<T> implements Node<T> {\r
+\r
+    private QName qName;\r
+    private CompositeNode parent;\r
+    private T value;\r
+\r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     */\r
+    public AbstractNodeTO(QName qname, CompositeNode parent, T value) {\r
+        this.qName = qname;\r
+        this.parent = parent;\r
+        this.value = value;\r
+    }\r
+\r
+    @Override\r
+    public QName getNodeType() {\r
+        return qName;\r
+    }\r
+\r
+    /**\r
+     * @return the qName\r
+     */\r
+    protected QName getQName() {\r
+        return qName;\r
+    }\r
+\r
+    @Override\r
+    public CompositeNode getParent() {\r
+        return parent;\r
+    }\r
+    \r
+    /**\r
+     * @param parent the parent to set\r
+     */\r
+    public void setParent(CompositeNode parent) {\r
+        this.parent = parent;\r
+    }\r
+    \r
+    /**\r
+     * @param value the value to set\r
+     */\r
+    protected void setValue(T value) {\r
+        this.value = value;\r
+    }\r
+\r
+    @Override\r
+    public T getValue() {\r
+        return value;\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeModificationTOImpl.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeModificationTOImpl.java
new file mode 100755 (executable)
index 0000000..7981df2
--- /dev/null
@@ -0,0 +1,52 @@
+/**\r
+ * \r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.List;\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.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
+\r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     * @param modifyAction\r
+     */\r
+    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
+    }\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
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeTOImpl.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeTOImpl.java
new file mode 100755 (executable)
index 0000000..f94163a
--- /dev/null
@@ -0,0 +1,120 @@
+/*\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.List;\r
+import java.util.Map;\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.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public class CompositeNodeTOImpl extends AbstractNodeTO<List<Node<?>>>\r
+        implements CompositeNode {\r
+\r
+    private Map<QName, List<Node<?>>> nodeMap;\r
+\r
+    /**\r
+     * @param qname\r
+     * @param parent use null to create top composite node (without parent)\r
+     * @param value\r
+     */\r
+    public CompositeNodeTOImpl(QName qname, CompositeNode parent,\r
+            List<Node<?>> value) {\r
+        super(qname, parent, value);\r
+        if (value != null) {\r
+            nodeMap = NodeUtils.buildNodeMap(getValue());\r
+        }\r
+    }\r
+    \r
+\r
+    /**\r
+     * @return the nodeMap\r
+     */\r
+    protected Map<QName, List<Node<?>>> getNodeMap() {\r
+        return nodeMap;\r
+    }\r
+    \r
+    @Override\r
+    public List<Node<?>> getChildren() {\r
+        return getValue();\r
+    }\r
+\r
+    @Override\r
+    public SimpleNode<?> getFirstSimpleByName(QName leafQName) {\r
+        List<SimpleNode<?>> list = getSimpleNodesByName(leafQName);\r
+        if (list.isEmpty())\r
+            return null;\r
+        return list.get(0);\r
+    }\r
+\r
+    @Override\r
+    public List<CompositeNode> getCompositesByName(QName children) {\r
+        List<Node<?>> toFilter = getNodeMap().get(children);\r
+        List<CompositeNode> list = new ArrayList<CompositeNode>();\r
+        for (Node<?> node : toFilter) {\r
+            if (node instanceof CompositeNode)\r
+                list.add((CompositeNode) node);\r
+        }\r
+        return list;\r
+    }\r
+\r
+    @Override\r
+    public List<SimpleNode<?>> getSimpleNodesByName(QName children) {\r
+        List<Node<?>> toFilter = getNodeMap().get(children);\r
+        List<SimpleNode<?>> list = new ArrayList<SimpleNode<?>>();\r
+\r
+        for (Node<?> node : toFilter) {\r
+            if (node instanceof SimpleNode<?>)\r
+                list.add((SimpleNode<?>) node);\r
+        }\r
+        return list;\r
+    }\r
+\r
+    @Override\r
+    public CompositeNode getFirstCompositeByName(QName container) {\r
+        List<CompositeNode> list = getCompositesByName(container);\r
+        if (list.isEmpty()) {\r
+            return null;\r
+        }\r
+        return list.get(0);\r
+    }\r
+\r
+    /**\r
+     * @param leaf\r
+     * @return TODO:: do we need this method?\r
+     */\r
+    public SimpleNode<?> getFirstLeafByName(QName leaf) {\r
+        List<SimpleNode<?>> list = getSimpleNodesByName(leaf);\r
+        if (list.isEmpty()) {\r
+            return null;\r
+        }\r
+        return list.get(0);\r
+    }\r
+\r
+    @Override\r
+    public List<CompositeNode> getCompositesByName(String children) {\r
+        return getCompositesByName(localQName(children));\r
+    }\r
+    \r
+    @Override\r
+    public List<SimpleNode<?>> getSimpleNodesByName(String children) {\r
+        return getSimpleNodesByName(localQName(children));\r
+    }\r
+\r
+    private QName localQName(String str) {\r
+        return new QName(getNodeType(), str);\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableCompositeNodeTOImpl.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableCompositeNodeTOImpl.java
new file mode 100755 (executable)
index 0000000..997b502
--- /dev/null
@@ -0,0 +1,61 @@
+/*\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.List;\r
+import java.util.Map;\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
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public class MutableCompositeNodeTOImpl extends CompositeNodeModificationTOImpl\r
+        implements MutableCompositeNode {\r
+\r
+    private Map<QName, List<Node<?>>> nodeMap;\r
+\r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     * @param modifyAction\r
+     */\r
+    public MutableCompositeNodeTOImpl(QName qname, CompositeNode parent,\r
+            List<Node<?>> value, ModifyAction modifyAction) {\r
+        super(qname, parent, value, modifyAction);\r
+    }\r
+    \r
+    /**\r
+     * update nodeMap\r
+     */\r
+    @Override\r
+    public void init() {\r
+        nodeMap = NodeUtils.buildNodeMap(getChildren());\r
+    }\r
+\r
+    @Override\r
+    public void setValue(List<Node<?>> value) {\r
+        super.setValue(value);\r
+    }\r
+    \r
+    @Override\r
+    public void setModifyAction(ModifyAction action) {\r
+        super.setModificationAction(action);\r
+    }\r
+    \r
+    @Override\r
+    protected Map<QName, List<Node<?>>> getNodeMap() {\r
+        return nodeMap;\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableSimpleNodeTOImpl.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableSimpleNodeTOImpl.java
new file mode 100755 (executable)
index 0000000..17cbb8d
--- /dev/null
@@ -0,0 +1,43 @@
+/*\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.MutableSimpleNode;\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
+        implements MutableSimpleNode<T> {\r
+\r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     * @param modifyAction\r
+     */\r
+    public MutableSimpleNodeTOImpl(QName qname, CompositeNode parent, T value,\r
+            ModifyAction modifyAction) {\r
+        super(qname, parent, value, modifyAction);\r
+    }\r
+\r
+    @Override\r
+    public void setValue(T value) {\r
+        super.setValue(value);\r
+    }\r
+    \r
+    @Override\r
+    public void setModifyAction(ModifyAction action) {\r
+        super.setModificationAction(action);\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeFactory.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeFactory.java
new file mode 100755 (executable)
index 0000000..8b3b7d4
--- /dev/null
@@ -0,0 +1,204 @@
+/*\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.AbstractMap.SimpleEntry;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Stack;\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.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public abstract class NodeFactory {\r
+\r
+    /**\r
+     * @param qName\r
+     * @param parent\r
+     * @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
+            CompositeNode parent, T value) {\r
+        SimpleNodeTOImpl<T> simpleNodeTOImpl = new SimpleNodeTOImpl<T>(qName, parent, value);\r
+        return simpleNodeTOImpl;\r
+    }\r
+    \r
+    /**\r
+     * @param qName\r
+     * @param parent\r
+     * @param value\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
+        MutableSimpleNodeTOImpl<T> simpleNodeTOImpl = \r
+                new MutableSimpleNodeTOImpl<T>(qName, parent, value, null);\r
+        return simpleNodeTOImpl;\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
+            CompositeNode parent, List<Node<?>> value) {\r
+        CompositeNode compositeNodeTOImpl = new CompositeNodeTOImpl(qName, parent, value);\r
+        return compositeNodeTOImpl;\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 MutableCompositeNode createMutableCompositeNode(QName qName,\r
+            CompositeNode parent, List<Node<?>> value) {\r
+        MutableCompositeNodeTOImpl compositeNodeTOImpl = \r
+                new MutableCompositeNodeTOImpl(qName, parent, value, null);\r
+        return compositeNodeTOImpl;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * @param qName\r
+     * @param parent\r
+     * @param value\r
+     * @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
+            CompositeNode parent, T value, ModifyAction modifyAction) {\r
+        SimpleNodeModificationTOImpl<T> simpleNodeModTOImpl = \r
+                new SimpleNodeModificationTOImpl<T>(qName, parent, value, modifyAction);\r
+        return simpleNodeModTOImpl;\r
+    }\r
+\r
+    /**\r
+     * @param qName\r
+     * @param parent\r
+     * @param value\r
+     * @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
+            CompositeNode parent, List<Node<?>> value, ModifyAction modifyAction) {\r
+        CompositeNodeModificationTOImpl compositeNodeModTOImpl = \r
+                new CompositeNodeModificationTOImpl(qName, parent, value, modifyAction);\r
+        return compositeNodeModTOImpl;\r
+    }\r
+\r
+    /**\r
+     * @param node\r
+     * @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> copyNode(SimpleNode<T> node) {\r
+        SimpleNode<T> twinNode = createSimpleNode(\r
+                    node.getNodeType(), node.getParent(), node.getValue());\r
+        return twinNode;\r
+    }\r
+    \r
+    /**\r
+     * @param node\r
+     * @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
+        return twinNode;\r
+    }\r
+\r
+    /**\r
+     * @param node\r
+     * @param children \r
+     * @return copy of given node, parent and children are the same, but parent and children \r
+     * 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
+        return twinNode;\r
+    }\r
+    \r
+    /**\r
+     * @param node\r
+     * @return copy of given node, parent and children are the same, but parent and children \r
+     * have no reference to this copy\r
+     */\r
+    public static CompositeNode copyNode(CompositeNode node) {\r
+       return copyNode(node, node.getChildren().toArray(new Node<?>[0]));\r
+    }\r
+    \r
+    /**\r
+     * @param node root of original tree\r
+     * @param originalToMutable (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
+     */\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
+       \r
+       return mutableRoot;\r
+    }\r
+    \r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImpl.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImpl.java
new file mode 100755 (executable)
index 0000000..cd71731
--- /dev/null
@@ -0,0 +1,204 @@
+/**\r
+ * \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
+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.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.NodeModificationBuilder;\r
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class NodeModificationBuilderImpl implements NodeModificationBuilder {\r
+    \r
+    private SchemaContext context;\r
+    \r
+    private Set<MutableNode<?>> changeLog;\r
+    private Map<Node<?>, Node<?>> originalToMutable;\r
+\r
+    private MutableCompositeNode mutableRoot;\r
+\r
+    /**\r
+     * @param originalTreeRootNode \r
+     * @param context\r
+     */\r
+    public NodeModificationBuilderImpl(CompositeNode originalTreeRootNode, SchemaContext context) {\r
+        this.context = context;\r
+        originalToMutable = new HashMap<>();\r
+        mutableRoot = NodeFactory.copyDeepNode(originalTreeRootNode, originalToMutable);\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
+     */\r
+    private void addModificationToLog(MutableNode<?> modNode, ModifyAction action) {\r
+        modNode.setModifyAction(action);\r
+        changeLog.add(modNode);\r
+    }\r
+\r
+    @Override\r
+    public void addNode(MutableSimpleNode<?> newNode) {\r
+        fixParentRelation(newNode);\r
+        addModificationToLog(newNode, ModifyAction.CREATE);\r
+    }\r
+    \r
+    @Override\r
+    public void addNode(MutableCompositeNode newNode) {\r
+        fixParentRelation(newNode);\r
+        addModificationToLog(newNode, ModifyAction.CREATE);\r
+    }\r
+    \r
+    @Override\r
+    public void replaceNode(MutableSimpleNode<?> replacementNode) {\r
+        addModificationToLog(replacementNode, ModifyAction.REPLACE);\r
+    }\r
+    \r
+    @Override\r
+    public void replaceNode(MutableCompositeNode replacementNode) {\r
+        addModificationToLog(replacementNode, ModifyAction.REPLACE);\r
+    }\r
+\r
+    @Override\r
+    public void deleteNode(MutableCompositeNode deadNode) {\r
+        addModificationToLog(deadNode, ModifyAction.DELETE);\r
+    }\r
+    \r
+    @Override\r
+    public void deleteNode(MutableSimpleNode<?> deadNode) {\r
+        addModificationToLog(deadNode, ModifyAction.DELETE);\r
+    }\r
+\r
+    @Override\r
+    public void removeNode(MutableSimpleNode<?> deadNode) {\r
+        addModificationToLog(deadNode, ModifyAction.REMOVE);\r
+    }\r
+    \r
+    @Override\r
+    public void removeNode(MutableCompositeNode deadNode) {\r
+        addModificationToLog(deadNode, ModifyAction.REMOVE);\r
+    }\r
+    \r
+    @Override\r
+    public void mergeNode(MutableCompositeNode alteredNode) {\r
+        addModificationToLog(alteredNode, ModifyAction.MERGE);\r
+    }\r
+\r
+    /**\r
+     * @return minimalistic tree containing diffs only\r
+     */\r
+    @Override\r
+    public CompositeNode buildDiffTree() {\r
+        Set<Node<?>> wanted = new HashSet<>();\r
+        \r
+        // walk changeLog, collect all required nodes\r
+        for (MutableNode<?> mutant : changeLog) {\r
+            wanted.addAll(collectSelfAndAllParents(mutant));\r
+        }\r
+        \r
+        // TODO:: 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
+                if (mapOfLists.containsKey(path)) {\r
+                    ListSchemaNode listSchema = mapOfLists.get(path);\r
+                    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
+                            }\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
+    }\r
+\r
+    /**\r
+     * @param focusedAncestor\r
+     * @return set of parents and focusedAncestor itself\r
+     */\r
+    private static Set<Node<?>> collectSelfAndAllParents(Node<?> focusedAncestor) {\r
+        Set<Node<?>> family = new HashSet<>();\r
+        Node<?> tmpNode = focusedAncestor;\r
+        while (tmpNode != null) {\r
+            family.add(tmpNode);\r
+            tmpNode = tmpNode.getParent();\r
+        }\r
+        return family;\r
+    }\r
+\r
+    /**\r
+     * @param originalNode\r
+     * @return mutable version of given node\r
+     */\r
+    @Override\r
+    public Node<?> getMutableEquivalent(Node<?> originalNode) {\r
+        return originalToMutable.get(originalNode);\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeUtils.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeUtils.java
new file mode 100755 (executable)
index 0000000..b3a7640
--- /dev/null
@@ -0,0 +1,206 @@
+/*\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.AbstractMap.SimpleEntry;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Stack;\r
+import java.util.Vector;\r
+\r
+import javax.xml.parsers.DocumentBuilder;\r
+import javax.xml.parsers.DocumentBuilderFactory;\r
+import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.xpath.XPath;\r
+import javax.xml.xpath.XPathConstants;\r
+import javax.xml.xpath.XPathExpression;\r
+import javax.xml.xpath.XPathExpressionException;\r
+import javax.xml.xpath.XPathFactory;\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.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+import org.opendaylight.controller.yang.model.api.DataNodeContainer;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\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
+import org.w3c.dom.Element;\r
+\r
+import com.google.common.base.Joiner;\r
+\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public abstract class NodeUtils {\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
+     * @return node path up till root node\r
+     */\r
+    public static String buildPath(Node<?> node) {\r
+        Vector<String> breadCrumbs = new Vector<>();\r
+        Node<?> tmpNode = node;\r
+        while (tmpNode != null) {\r
+            breadCrumbs.insertElementAt(tmpNode.getNodeType().getLocalName(), 0);\r
+            tmpNode = tmpNode.getParent();\r
+        }\r
+        \r
+        return Joiner.on(".").join(breadCrumbs);\r
+    }\r
+\r
+    \r
+    /**\r
+     * @param treeRootNode\r
+     * @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
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\r
+        Document doc = null;\r
+        try {\r
+            DocumentBuilder bob = dbf.newDocumentBuilder();\r
+            doc = bob.newDocument();\r
+        } catch (ParserConfigurationException e) {\r
+            LOG.error("documentBuilder problem", e);\r
+            return null;\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
+        while (!jobQueue.isEmpty()) {\r
+            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
+            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
+            }\r
+            if (item instanceof NodeModification) {\r
+                ModifyAction modificationAction = ((NodeModification) item).getModificationAction();\r
+                if (modificationAction != null) {\r
+                    itemEl.setAttribute("modifyAction", modificationAction.toString());\r
+                }\r
+            }\r
+            \r
+            jointPlace.appendChild(itemEl);\r
+            \r
+            if (item instanceof CompositeNode) {\r
+                for (Node<?> child : ((CompositeNode) item).getChildren()) {\r
+                    jobQueue.push(new SimpleEntry<org.w3c.dom.Node, Node<?>>(itemEl, child));\r
+                }\r
+            }\r
+        }\r
+        \r
+        return doc;\r
+    }\r
+    \r
+    /**\r
+     * @param doc\r
+     * @param xpathEx\r
+     * @return user data value on found node\r
+     * @throws XPathExpressionException\r
+     */\r
+    @SuppressWarnings("unchecked")\r
+    public static <T> T findNodeByXpath(Document doc, String xpathEx) \r
+            throws XPathExpressionException {\r
+        T userNode = null;\r
+        XPathFactory xPathfactory = XPathFactory.newInstance();\r
+        XPath xpath = xPathfactory.newXPath();\r
+        XPathExpression expr = xpath.compile(xpathEx);\r
+        \r
+        org.w3c.dom.Node result = (org.w3c.dom.Node) expr.evaluate(doc, XPathConstants.NODE);\r
+        if (result != null) {\r
+            userNode = (T) result.getUserData(USER_KEY_NODE);\r
+        } \r
+        \r
+        return userNode;\r
+    }\r
+\r
+\r
+    /**\r
+     * build NodeMap, where key = qName; value = node\r
+     * \r
+     * @param value\r
+     * @return map of children, where key = qName and value is list of children groupped by qName  \r
+     */\r
+    public static Map<QName, List<Node<?>>> buildNodeMap(List<Node<?>> value) {\r
+        Map<QName, List<Node<?>>> nodeMapTmp = new HashMap<>();\r
+        if (value == null || value.isEmpty()) {\r
+            throw new IllegalStateException(\r
+                    "nodeList should not be null or empty");\r
+        }\r
+        for (Node<?> node : value) {\r
+            List<Node<?>> qList = nodeMapTmp.get(node.getNodeType());\r
+            if (qList == null) {\r
+                qList = new ArrayList<>();\r
+                nodeMapTmp.put(node.getNodeType(), qList);\r
+            }\r
+            qList.add(node);\r
+        }\r
+        return nodeMapTmp;\r
+    }\r
+\r
+\r
+    /**\r
+     * @param context\r
+     * @return map of lists, where key = path; value = {@link DataSchemaNode}\r
+     */\r
+    public static Map<String, ListSchemaNode> buildMapOfListNodes(\r
+            SchemaContext context) {\r
+        Map<String, ListSchemaNode> mapOfLists = new HashMap<>();\r
+        \r
+        Stack<DataSchemaNode> jobQueue = new Stack<>();\r
+        jobQueue.addAll(context.getDataDefinitions());\r
+        \r
+        while (!jobQueue.isEmpty()) {\r
+            DataSchemaNode dataSchema = jobQueue.pop();\r
+            if (dataSchema instanceof ListSchemaNode) {\r
+                mapOfLists.put(schemaPathToPath(dataSchema.getPath().getPath()), (ListSchemaNode) dataSchema);\r
+            }\r
+            \r
+            if (dataSchema instanceof DataNodeContainer) {\r
+                jobQueue.addAll(((DataNodeContainer) dataSchema).getChildNodes());\r
+            }\r
+        }\r
+        \r
+        return mapOfLists;\r
+    }\r
+\r
+\r
+    /**\r
+     * @param path\r
+     * @return\r
+     */\r
+    private static String schemaPathToPath(List<QName> qNamesPath) {\r
+        List<String> pathSeed = new ArrayList<>();\r
+        for (QName qNameItem : qNamesPath) {\r
+            pathSeed.add(qNameItem.getLocalName());\r
+        }\r
+        return Joiner.on(".").join(pathSeed);\r
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeModificationTOImpl.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeModificationTOImpl.java
new file mode 100755 (executable)
index 0000000..7268637
--- /dev/null
@@ -0,0 +1,49 @@
+/**\r
+ * \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
+\r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     * @param modifyAction \r
+     */\r
+    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
+    }\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeTOImpl.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeTOImpl.java
new file mode 100755 (executable)
index 0000000..5cfc03a
--- /dev/null
@@ -0,0 +1,31 @@
+/*\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.SimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * @param <T> type of simple node value\r
+ * \r
+ */\r
+public class SimpleNodeTOImpl<T> extends AbstractNodeTO<T> implements\r
+        SimpleNode<T> {\r
+\r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     */\r
+    public SimpleNodeTOImpl(QName qname, CompositeNode parent, T value) {\r
+        super(qname, parent, value);\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeFactoryTest.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeFactoryTest.java
new file mode 100755 (executable)
index 0000000..3d97cc8
--- /dev/null
@@ -0,0 +1,147 @@
+/*\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.ByteArrayOutputStream;\r
+import java.io.PrintStream;\r
+import java.net.URI;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.junit.Assert;\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.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.NodeModification;\r
+import org.w3c.dom.Document;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public class NodeFactoryTest {\r
+\r
+    /**\r
+     * Test method for methods creating immutable nodes in\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeFactory}.\r
+     * @throws Exception \r
+     */\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
+        \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
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testMutableNodes() throws Exception {\r
+        // <config>\r
+        //   <top xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\r
+        //     <interface xc:operation="delete">\r
+        //       <name>Ethernet0/0</name>\r
+        //       <mtu>1500</mtu>\r
+        //     </interface>\r
+        //     <interface>\r
+        //       <name>Ethernet0/1</name>\r
+        //       <mtu>1501</mtu>\r
+        //     </interface>\r
+        //   </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
+        \r
+        CompositeNodeModificationTOImpl ifNode = NodeFactory.createCompositeNodeModification(\r
+                new QName(qName, "interface"), null, value, ModifyAction.DELETE);\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
+        \r
+        CompositeNode ifNode2 = NodeFactory.createCompositeNode(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
+        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
+        \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
+        Assert.assertEquals(ModifyAction.DELETE, interfaceMod.getModificationAction());\r
+    }\r
+\r
+    /**\r
+     * test modifications builder\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
+        Map<Node<?>, Node<?>> mutableToOrig = new HashMap<>();\r
+        MutableCompositeNode mutableNetwork = NodeFactory.copyDeepNode(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
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeHelper.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeHelper.java
new file mode 100755 (executable)
index 0000000..3b7c0d0
--- /dev/null
@@ -0,0 +1,327 @@
+/*\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.InputStream;\r
+import java.io.PrintStream;\r
+import java.io.StringWriter;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import javax.xml.transform.OutputKeys;\r
+import javax.xml.transform.Transformer;\r
+import javax.xml.transform.TransformerFactory;\r
+import javax.xml.transform.dom.DOMSource;\r
+import javax.xml.transform.stream.StreamResult;\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.Node;\r
+import org.opendaylight.controller.yang.model.api.Module;\r
+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.w3c.dom.Document;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public abstract class NodeHelper {\r
+    \r
+    /** xml source of example network configuration */\r
+    public static final String NETWORK_XML = \r
+      "<network xmlns=\"urn:opendaylight:controller:network\">\n" +\r
+      //"<network>\n" +\r
+      "    <topologies>\n" +\r
+      "        <topology>\n" +\r
+      "            <topology-id>topId_01</topology-id>\n" +\r
+      "            <nodes>\n" +\r
+      "                <node>\n" +\r
+      "                    <node-id>nodeId_02</node-id>\n" +\r
+      "                    <supporting-ne>networkId_02</supporting-ne>\n" +\r
+      "                    <termination-points>\n" +\r
+      "                        <termination-point>\n" +\r
+      "                            <tp-id>tpId_03</tp-id>\n" +\r
+      "                        </termination-point>\n" +\r
+      "                    </termination-points>\n" +\r
+      "                </node>\n" +\r
+      "                <node>\n" +\r
+      "                    <node-id>nodeId_16</node-id>\n" +\r
+      "                    <supporting-ne>networkId_17</supporting-ne>\n" +\r
+      "                    <termination-points>\n" +\r
+      "                        <termination-point>\n" +\r
+      "                            <tp-id>tpId_18</tp-id>\n" +\r
+      "                        </termination-point>\n" +\r
+      "                    </termination-points>\n" +\r
+      "                </node>\n" +\r
+      "                <node>\n" +\r
+      "                    <node-id>nodeId_19</node-id>\n" +\r
+      "                    <supporting-ne>networkId_20</supporting-ne>\n" +\r
+      "                    <termination-points>\n" +\r
+      "                        <termination-point>\n" +\r
+      "                            <tp-id>tpId_18</tp-id>\n" +\r
+      "                        </termination-point>\n" +\r
+      "                        <termination-point>\n" +\r
+      "                            <tp-id>tpId_19</tp-id>\n" +\r
+      "                        </termination-point>\n" +\r
+      "                    </termination-points>\n" +\r
+      "                </node>\n" +\r
+      "            </nodes>\n" +\r
+      "            <links>\n" +\r
+      "                <link>\n" +\r
+      "                    <link-id>linkId_04</link-id>\n" +\r
+      "                    <source>\n" +\r
+      "                        <source-node>nodeId_05</source-node>\n" +\r
+      "                        <source-tp>tpId_06</source-tp>\n" +\r
+      "                    </source>\n" +\r
+      "                    <destination>\n" +\r
+      "                        <dest-node>nodeId_07</dest-node>\n" +\r
+      "                        <dest-tp>tpId_08</dest-tp>\n" +\r
+      "                    </destination>\n" +\r
+      "                </link>\n" +\r
+      "                <link>\n" +\r
+      "                    <link-id>linkId_11</link-id>\n" +\r
+      "                    <source>\n" +\r
+      "                        <source-node>nodeId_12</source-node>\n" +\r
+      "                        <source-tp>tpId_13</source-tp>\n" +\r
+      "                    </source>\n" +\r
+      "                    <destination>\n" +\r
+      "                        <dest-node>nodeId_14</dest-node>\n" +\r
+      "                        <dest-tp>tpId_15</dest-tp>\n" +\r
+      "                    </destination>\n" +\r
+      "                </link>\n" +\r
+      "            </links>\n" +\r
+      "        </topology>\n" +\r
+      "    </topologies>\n" +\r
+      "    <network-elements>\n" +\r
+      "        <network-element>\n" +\r
+      "            <element-id>ntElementId_09</element-id>\n" +\r
+      "        </network-element>\n" +\r
+      "        <network-element>\n" +\r
+      "            <element-id>ntElementId_10</element-id>\n" +\r
+      "        </network-element>\n" +\r
+      "    </network-elements>\n" +\r
+      "</network>";\r
+\r
+    /**\r
+     * @param domTree\r
+     * @param out\r
+     * @throws Exception \r
+     */\r
+    public static void dumpDoc(Document domTree, PrintStream out) throws Exception {\r
+      TransformerFactory transformerFact = TransformerFactory.newInstance();\r
+      transformerFact.setAttribute("indent-number", 4);\r
+      Transformer transformer = transformerFact.newTransformer();\r
+      transformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
+      //initialize StreamResult with File object to save to file\r
+      StreamResult result = new StreamResult(new StringWriter());\r
+      DOMSource source = new DOMSource(domTree);\r
+      transformer.transform(source, result);\r
+      String xmlString = result.getWriter().toString();\r
+      out.println(xmlString);\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
+        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
+        assignParentToChildren(ntElementNode2);\r
+        \r
+        value = new ArrayList<Node<?>>();\r
+        value.add(ntElementNode1);\r
+        value.add(ntElementNode2);\r
+        CompositeNode ntElementsNode = NodeFactory.createCompositeNode(\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
+                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
+                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(source);\r
+        value.add(destination);\r
+        CompositeNode link1 = NodeFactory.createCompositeNode(\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
+                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
+                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(source);\r
+        value.add(destination);\r
+        CompositeNode link2 = NodeFactory.createCompositeNode(\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
+                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
+                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
+                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(terminationPointsNode);\r
+        CompositeNode node1Node = NodeFactory.createCompositeNode(\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
+                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
+                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(terminationPointsNode);\r
+        CompositeNode node2Node = NodeFactory.createCompositeNode(\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
+                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
+                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
+                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(terminationPointsNode);\r
+        CompositeNode node3Node = NodeFactory.createCompositeNode(\r
+                new QName(qName, "node"), null, value);\r
+        assignParentToChildren(node3Node);\r
+        \r
+        value = new ArrayList<Node<?>>(); \r
+        value.add(node1Node);\r
+        value.add(node2Node);\r
+        value.add(node3Node);\r
+        CompositeNode nodesNode = NodeFactory.createCompositeNode(\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
+                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
+                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
+                new QName(qName, "network"), null, value);\r
+        assignParentToChildren(network);\r
+        \r
+        return network;\r
+    }\r
+\r
+    /**\r
+     * @param parentNode\r
+     */\r
+    public static void assignParentToChildren(CompositeNode parentNode) {\r
+        for (Node<?> child : parentNode.getChildren()) {\r
+            ((AbstractNodeTO<?>) child).setParent(parentNode);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @return schema context of controller-network.yang\r
+     */\r
+    public static SchemaContext loadSchemaContext() {\r
+        YangModelParser yParser = new YangParserImpl();\r
+        List<InputStream> yangInputStreams = new ArrayList<>();\r
+        yangInputStreams.add(NodeHelper.class.getResourceAsStream(\r
+                "/controller-network.yang"));\r
+        yangInputStreams.add(NodeHelper.class.getResourceAsStream(\r
+                "/ietf-inet-types@2010-09-24.yang"));\r
+        Set<Module> modules = yParser\r
+                .parseYangModelsFromStreams(yangInputStreams);\r
+        return yParser.resolveSchemaContext(modules);\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImplTest.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImplTest.java
new file mode 100755 (executable)
index 0000000..2df397a
--- /dev/null
@@ -0,0 +1,92 @@
+/*\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 junit.framework.Assert;\r
+\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.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.w3c.dom.Document;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ * \r
+ */\r
+public class NodeModificationBuilderImplTest {\r
+\r
+    private SchemaContext schemaCtx;\r
+    private QName qName;\r
+    private CompositeNode network;\r
+    private NodeModificationBuilderImpl nodeModificationBuilder;\r
+\r
+    /**\r
+     * prepare schemaContext\r
+     * @throws Exception \r
+     */\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        schemaCtx = NodeHelper.loadSchemaContext();\r
+\r
+        qName = new QName(\r
+                new URI("urn:opendaylight:controller:network"), \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#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTree() throws Exception {\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
+        \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
+        \r
+        Document diffShadow = NodeUtils.buildShadowDomTree(diffTree);\r
+        NodeHelper.dumpDoc(diffShadow, System.out);\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
+        CompositeNode topologiesMutable = rootMutable.getCompositesByName("topologies").iterator().next();\r
+        \r
+        Assert.assertSame(topologiesMutable, nodeModificationBuilder.getMutableEquivalent(topologies));\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeUtilsTest.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeUtilsTest.java
new file mode 100755 (executable)
index 0000000..487c10c
--- /dev/null
@@ -0,0 +1,110 @@
+/*\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.ByteArrayOutputStream;\r
+import java.io.PrintStream;\r
+import java.net.URI;\r
+import java.util.Date;\r
+import java.util.List;\r
+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
+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.w3c.dom.Document;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class NodeUtilsTest {\r
+    \r
+    private QName qName;\r
+    private CompositeNode network;\r
+\r
+    /**\r
+     * @throws Exception\r
+     */\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        qName = new QName(\r
+                new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \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
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        ByteArrayOutputStream actual = new ByteArrayOutputStream();\r
+        NodeHelper.dumpDoc(networkShadow, new PrintStream(actual));\r
+        \r
+        Assert.assertEquals(2760, new String(actual.toByteArray()).length());\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
+        SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                "//node[node-id='nodeId_19']//termination-point[2]/tp-id");\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
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config01.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config01.xml
new file mode 100755 (executable)
index 0000000..8ffac5b
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>\r
+<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\r
+    <edit-config>\r
+        <target>\r
+            <running />\r
+        </target>\r
+        <config>\r
+            <top xmlns="http://example.com/schema/1.2/config">\r
+                <interface>\r
+                    <name>Ethernet0/0</name>\r
+                    <mtu>1500</mtu>\r
+                </interface>\r
+            </top>\r
+        </config>\r
+    </edit-config>\r
+</rpc>\r
+     
\ No newline at end of file
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
new file mode 100755 (executable)
index 0000000..e9c05c9
--- /dev/null
@@ -0,0 +1,73 @@
+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/config02.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.xml
new file mode 100755 (executable)
index 0000000..99b862b
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<network xmlns="urn:opendaylight:controller:network">\r
+    <topologies>\r
+        <topology>\r
+            <topology-id>topId_01</topology-id>\r
+            <types></types>\r
+            <nodes>\r
+                <node>\r
+                    <node-id>nodeId_02</node-id>\r
+                    <supporting-ne>networkId_02</supporting-ne>\r
+                    <termination-points>\r
+                        <termination-point>\r
+                            <tp-id>tpId_03</tp-id>\r
+                        </termination-point>\r
+                    </termination-points>\r
+                </node>\r
+                <node>\r
+                    <node-id>nodeId_16</node-id>\r
+                    <supporting-ne>networkId_17</supporting-ne>\r
+                    <termination-points>\r
+                        <termination-point>\r
+                            <tp-id>tpId_18</tp-id>\r
+                        </termination-point>\r
+                    </termination-points>\r
+                </node>\r
+                <node>\r
+                    <node-id>nodeId_19</node-id>\r
+                    <supporting-ne>networkId_20</supporting-ne>\r
+                    <termination-points>\r
+                        <termination-point>\r
+                            <tp-id>tpId_18</tp-id>\r
+                        </termination-point>\r
+                        <termination-point>\r
+                            <tp-id>tpId_19</tp-id>\r
+                        </termination-point>\r
+                    </termination-points>\r
+                </node>\r
+            </nodes>\r
+            <links>\r
+                <link>\r
+                    <link-id>linkId_04</link-id>\r
+                    <source>\r
+                        <source-node>nodeId_05</source-node>\r
+                        <source-tp>tpId_06</source-tp>\r
+                    </source>\r
+                    <destination>\r
+                        <dest-node>nodeId_07</dest-node>\r
+                        <dest-tp>tpId_08</dest-tp>\r
+                    </destination>\r
+                </link>\r
+                <link>\r
+                    <link-id>linkId_11</link-id>\r
+                    <source>\r
+                        <source-node>nodeId_12</source-node>\r
+                        <source-tp>tpId_13</source-tp>\r
+                    </source>\r
+                    <destination>\r
+                        <dest-node>nodeId_14</dest-node>\r
+                        <dest-tp>tpId_15</dest-tp>\r
+                    </destination>\r
+                </link>\r
+            </links>\r
+        </topology>\r
+    </topologies>\r
+    <network-elements>\r
+        <network-element>\r
+            <element-id>ntElementId_09</element-id>\r
+        </network-element>\r
+        <network-element>\r
+            <element-id>ntElementId_10</element-id>\r
+        </network-element>\r
+    </network-elements>\r
+</network>\r
+\r
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
new file mode 100644 (file)
index 0000000..d1ac68c
--- /dev/null
@@ -0,0 +1,73 @@
+<?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/controller-network.xsd b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/controller-network.xsd
new file mode 100755 (executable)
index 0000000..6cadb69
--- /dev/null
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:yin="urn:ietf:params:xml:schema:yang:yin:1"
+           targetNamespace="urn:opendaylight:controller:network"
+           xmlns="urn:opendaylight:controller:network"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           version="2013-05-20"
+           xml:lang="en"
+           xmlns:topos="urn:opendaylight:controller:network"
+           xmlns:inet="urn:ietf:params:xml:ns:yang:ietf-inet-types">
+
+  <xs:import namespace="urn:ietf:params:xml:ns:yang:ietf-inet-types"
+             schemaLocation="ietf-inet-types@2010-09-24.xsd"/>
+
+  <xs:annotation>
+    <xs:documentation>
+      This schema was generated from the YANG module controller-network
+      by pyang version 1.2.
+
+      The schema describes an instance document consisting
+      of the entire configuration data store, operational
+      data, rpc operations, and notifications.
+      This schema can thus NOT be used as-is to
+      validate NETCONF PDUs.
+    </xs:documentation>
+  </xs:annotation>
+
+
+  <!-- YANG typedefs -->
+  <xs:simpleType name="topology-id">
+    <xs:restriction base="xs:string">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="node-id">
+    <xs:restriction base="xs:string">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="link-id">
+    <xs:restriction base="xs:string">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="tp-id">
+    <xs:annotation>
+      <xs:documentation>
+        identifier for termination points on a port
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:string">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="tp-ref">
+    <xs:restriction base="tp-id">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="topology-ref">
+    <xs:annotation>
+      <xs:documentation>
+        This type is used for leafs that reference topology identifier instance.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="topology-id">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="node-ref">
+    <xs:annotation>
+      <xs:documentation>
+        This type is used for leafs that reference a node instance.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="node-id">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="link-ref">
+    <xs:annotation>
+      <xs:documentation>
+        This type is used for leafs that reference a link instance.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="link-id">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="network-element-ref">
+    <xs:restriction base="element-id">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="element-id">
+    <xs:restriction base="xs:string">
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:element name="network">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="topologies" minOccurs="0">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="topology" minOccurs="0" maxOccurs="unbounded">
+                <xs:annotation>
+                  <xs:documentation>
+
+                    This is the model of abstract topology which contains only Network
+                    Nodes and Network Links. Each topology MUST be identified by
+                    unique topology-id for reason that the store could contain many
+                    topologies.
+
+                  </xs:documentation>
+                </xs:annotation>
+                <xs:complexType>
+                  <xs:sequence>
+                    <xs:element name="topology-id"  type="topology-id">
+                      <xs:annotation>
+                        <xs:documentation>
+
+                          It is presumed that datastore will contain many topologies. To
+                          distinguish between topologies it is vital to have UNIQUE
+                          topology identifier.
+
+                        </xs:documentation>
+                      </xs:annotation>
+                    </xs:element>
+                    <xs:element name="types" minOccurs="0">
+                      <xs:annotation>
+                        <xs:documentation>
+
+                          The container for definition of topology types.
+                          The augmenting modules should add empty optional leaf 
+                          to this container to signalize topology type.
+
+                        </xs:documentation>
+                      </xs:annotation>
+                      <xs:complexType>
+                        <xs:sequence>
+                          <xs:any minOccurs="0" maxOccurs="unbounded"
+                                  namespace="##other" processContents="lax"/>
+                        </xs:sequence>
+                      </xs:complexType>
+                    </xs:element>
+                    <xs:element name="nodes" minOccurs="0">
+                      <xs:complexType>
+                        <xs:sequence>
+                          <xs:element name="node" minOccurs="0" maxOccurs="unbounded">
+                            <xs:annotation>
+                              <xs:documentation>
+                                The list of network nodes defined for topology.
+                              </xs:documentation>
+                            </xs:annotation>
+                            <xs:complexType>
+                              <xs:sequence>
+                                <xs:element name="node-id"  type="node-id">
+                                  <xs:annotation>
+                                    <xs:documentation>
+                                      The Topology identifier of network-node.
+                                    </xs:documentation>
+                                  </xs:annotation>
+                                </xs:element>
+                                <xs:element name="supporting-ne" minOccurs="0"  type="network-element-ref">
+                                </xs:element>
+                                <xs:element name="termination-points" minOccurs="0">
+                                  <xs:complexType>
+                                    <xs:sequence>
+                                      <xs:element name="termination-point" minOccurs="0" maxOccurs="unbounded">
+                                        <xs:complexType>
+                                          <xs:sequence>
+                                            <xs:element name="tp-id"  type="tp-id">
+                                            </xs:element>
+                                            <xs:any minOccurs="0" maxOccurs="unbounded"
+                                                    namespace="##other" processContents="lax"/>
+                                          </xs:sequence>
+                                        </xs:complexType>
+                                      </xs:element>
+                                      <xs:any minOccurs="0" maxOccurs="unbounded"
+                                              namespace="##other" processContents="lax"/>
+                                    </xs:sequence>
+                                  </xs:complexType>
+                                  <xs:key name="key_termination-points_node_nodes_topology_topologies_network_termination-point">
+                                    <xs:selector xpath="topos:termination-point"/>
+                                    <xs:field xpath="topos:tp-id"/>
+                                  </xs:key>
+                                </xs:element>
+                                <xs:any minOccurs="0" maxOccurs="unbounded"
+                                        namespace="##other" processContents="lax"/>
+                              </xs:sequence>
+                            </xs:complexType>
+                          </xs:element>
+                          <xs:any minOccurs="0" maxOccurs="unbounded"
+                                  namespace="##other" processContents="lax"/>
+                        </xs:sequence>
+                      </xs:complexType>
+                      <xs:key name="key_nodes_topology_topologies_network_node">
+                        <xs:selector xpath="topos:node"/>
+                        <xs:field xpath="topos:node-id"/>
+                      </xs:key>
+                    </xs:element>
+                    <xs:element name="links" minOccurs="0">
+                      <xs:complexType>
+                        <xs:sequence>
+                          <xs:element name="link" minOccurs="0" maxOccurs="unbounded">
+                            <xs:annotation>
+                              <xs:documentation>
+
+                                The Network Link which is defined by Local (Source) and
+                                Remote (Destination) Network Nodes. Every link MUST be
+                                defined either by identifier and his local and remote
+                                Network Nodes (in real applications it is common that many
+                                links are originated from one node and end up in same
+                                remote node). To ensure that we would always know to
+                                distinguish between links, every link SHOULD have
+                                identifier.
+
+                              </xs:documentation>
+                            </xs:annotation>
+                            <xs:complexType>
+                              <xs:sequence>
+                                <xs:element name="link-id"  type="link-id">
+                                </xs:element>
+                                <xs:element name="source" minOccurs="0">
+                                  <xs:complexType>
+                                    <xs:sequence>
+                                      <xs:element name="source-node" minOccurs="0"  type="node-ref">
+                                        <xs:annotation>
+                                          <xs:documentation>
+                                            Source node identifier.
+                                          </xs:documentation>
+                                        </xs:annotation>
+                                      </xs:element>
+                                      <xs:element name="source-tp" minOccurs="0"  type="tp-ref">
+                                      </xs:element>
+                                      <xs:any minOccurs="0" maxOccurs="unbounded"
+                                              namespace="##other" processContents="lax"/>
+                                    </xs:sequence>
+                                  </xs:complexType>
+                                </xs:element>
+                                <xs:element name="destination" minOccurs="0">
+                                  <xs:complexType>
+                                    <xs:sequence>
+                                      <xs:element name="dest-node" minOccurs="0"  type="node-ref">
+                                        <xs:annotation>
+                                          <xs:documentation>
+                                            Destination node identifier.
+                                          </xs:documentation>
+                                        </xs:annotation>
+                                      </xs:element>
+                                      <xs:element name="dest-tp" minOccurs="0"  type="tp-ref">
+                                      </xs:element>
+                                      <xs:any minOccurs="0" maxOccurs="unbounded"
+                                              namespace="##other" processContents="lax"/>
+                                    </xs:sequence>
+                                  </xs:complexType>
+                                </xs:element>
+                                <xs:any minOccurs="0" maxOccurs="unbounded"
+                                        namespace="##other" processContents="lax"/>
+                              </xs:sequence>
+                            </xs:complexType>
+                          </xs:element>
+                          <xs:any minOccurs="0" maxOccurs="unbounded"
+                                  namespace="##other" processContents="lax"/>
+                        </xs:sequence>
+                      </xs:complexType>
+                      <xs:key name="key_links_topology_topologies_network_link">
+                        <xs:selector xpath="topos:link"/>
+                        <xs:field xpath="topos:link-id"/>
+                      </xs:key>
+                    </xs:element>
+                    <xs:any minOccurs="0" maxOccurs="unbounded"
+                            namespace="##other" processContents="lax"/>
+                  </xs:sequence>
+                </xs:complexType>
+              </xs:element>
+              <xs:any minOccurs="0" maxOccurs="unbounded"
+                      namespace="##other" processContents="lax"/>
+            </xs:sequence>
+          </xs:complexType>
+          <xs:key name="key_topologies_network_topology">
+            <xs:selector xpath="topos:topology"/>
+            <xs:field xpath="topos:topology-id"/>
+          </xs:key>
+        </xs:element>
+        <xs:element name="network-elements" minOccurs="0">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="network-element" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                  <xs:sequence>
+                    <xs:element name="element-id"  type="element-id">
+                    </xs:element>
+                    <xs:any minOccurs="0" maxOccurs="unbounded"
+                            namespace="##other" processContents="lax"/>
+                  </xs:sequence>
+                </xs:complexType>
+              </xs:element>
+              <xs:any minOccurs="0" maxOccurs="unbounded"
+                      namespace="##other" processContents="lax"/>
+            </xs:sequence>
+          </xs:complexType>
+          <xs:key name="key_network-elements_network_network-element">
+            <xs:selector xpath="topos:network-element"/>
+            <xs:field xpath="topos:element-id"/>
+          </xs:key>
+        </xs:element>
+        <xs:any minOccurs="0" maxOccurs="unbounded"
+                namespace="##other" processContents="lax"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+</xs:schema>
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/controller-network.yang b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/controller-network.yang
new file mode 100755 (executable)
index 0000000..022ece9
--- /dev/null
@@ -0,0 +1,172 @@
+module controller-network {
+    yang-version 1;
+    namespace "urn:opendaylight:controller:network";
+    prefix "topos";
+    
+    import ietf-inet-types { prefix "inet"; }
+    
+    revision 2013-05-20 {
+       description "Initial demo";
+    }
+    
+
+    
+    
+    typedef topology-id {
+        type string;
+    }
+
+    typedef node-id {
+        type string;
+    }
+
+    typedef link-id {
+        type string;
+    }
+
+    typedef tp-id {
+        type string;
+        description "identifier for termination points on a port";
+    }
+
+    typedef tp-ref {
+        type leafref {
+            path "/network/topologies/topology/nodes/node/termination-points/termination-point/tp-id";
+        }
+    }
+    typedef topology-ref {
+        type leafref {
+            path "/network/topologies/topology/topology-id";
+        }
+        description "This type is used for leafs that reference topology identifier instance.";
+        // currently not used
+    }
+
+    typedef node-ref {
+        type leafref {
+            path "/network/topologies/topology/nodes/node/node-id";
+        }
+        description "This type is used for leafs that reference a node instance.";
+    }
+
+    typedef link-ref {
+        type leafref {
+            path "/network/topologies/topology/links/link/link-id";
+        }
+        description "This type is used for leafs that reference a link instance.";
+        // currently not used
+    }
+    
+    typedef network-element-ref {
+        type leafref {
+            path "/network/network-elements/network-element/element-id";
+        }
+    }
+
+
+    typedef element-id {
+        type string;
+    }
+    
+    container network {
+        container topologies {
+            list topology {
+                description "
+                    This is the model of abstract topology which contains only Network
+                    Nodes and Network Links. Each topology MUST be identified by
+                    unique topology-id for reason that the store could contain many
+                    topologies.
+                ";
+                key "topology-id";
+                leaf topology-id {
+                    type topology-id; 
+                    description "
+                        It is presumed that datastore will contain many topologies. To
+                        distinguish between topologies it is vital to have UNIQUE
+                        topology identifier.
+                    ";
+                }
+
+                container types {
+                    description "
+                        The container for definition of topology types.
+                        The augmenting modules should add empty optional leaf 
+                        to this container to signalize topology type.
+                    ";
+                }
+
+                container nodes {
+                    list node {
+                        description "The list of network nodes defined for topology.";
+
+                        key "node-id";
+                        leaf node-id {
+                            type node-id;
+                            description "The Topology identifier of network-node.";
+                        }
+
+                        leaf supporting-ne {
+                            type network-element-ref;
+                        }
+                        
+                        container termination-points {
+                            list termination-point {
+                                key "tp-id";
+                                leaf tp-id {
+                                    type tp-id;
+                                }
+                            }
+                        }
+                    }
+                }
+        
+                container links {
+                    list link {
+                        description "
+                            The Network Link which is defined by Local (Source) and
+                            Remote (Destination) Network Nodes. Every link MUST be
+                            defined either by identifier and his local and remote
+                            Network Nodes (in real applications it is common that many
+                            links are originated from one node and end up in same
+                            remote node). To ensure that we would always know to
+                            distinguish between links, every link SHOULD have
+                            identifier.
+                        ";
+                        key "link-id";
+        
+                        leaf link-id {
+                            type link-id;
+                        }
+                        container source { 
+                            leaf source-node {
+                                type node-ref;
+                                description "Source node identifier.";
+                            }
+                            leaf source-tp {
+                                type tp-ref;
+                            }
+                        }
+                        container destination { 
+                            leaf dest-node {
+                                type node-ref;
+                                description "Destination node identifier.";
+                            }
+                            leaf dest-tp {
+                                type tp-ref;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        container network-elements {
+            config true;
+            list network-element {
+                key "element-id";
+                leaf element-id {
+                    type element-id;
+                }
+            }
+        }
+    }
+}
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
new file mode 100755 (executable)
index 0000000..a778137
--- /dev/null
@@ -0,0 +1,110 @@
+//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/ietf-inet-types@2010-09-24.xsd b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/ietf-inet-types@2010-09-24.xsd
new file mode 100644 (file)
index 0000000..3da8ec7
--- /dev/null
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:yin="urn:ietf:params:xml:schema:yang:yin:1"
+           targetNamespace="urn:ietf:params:xml:ns:yang:ietf-inet-types"
+           xmlns="urn:ietf:params:xml:ns:yang:ietf-inet-types"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           version="2010-09-24"
+           xml:lang="en"
+          xmlns:inet="urn:ietf:params:xml:ns:yang:ietf-inet-types">
+
+  <xs:annotation>
+    <xs:documentation>
+      This schema was generated from the YANG module ietf-inet-types
+      by pyang version 1.2.
+
+      The schema describes an instance document consisting
+      of the entire configuration data store, operational
+      data, rpc operations, and notifications.
+      This schema can thus NOT be used as-is to
+      validate NETCONF PDUs.
+    </xs:documentation>
+  </xs:annotation>
+
+  <xs:annotation>
+    <xs:documentation>
+      This module contains a collection of generally useful derived
+      YANG data types for Internet addresses and related things.
+
+      Copyright (c) 2010 IETF Trust and the persons identified as
+      authors of the code.  All rights reserved.
+
+      Redistribution and use in source and binary forms, with or without
+      modification, is permitted pursuant to, and subject to the license
+      terms contained in, the Simplified BSD License set forth in Section
+      4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+      (http://trustee.ietf.org/license-info).
+
+      This version of this YANG module is part of RFC 6021; see
+      the RFC itself for full legal notices.
+    </xs:documentation>
+  </xs:annotation>
+
+  <!-- YANG typedefs -->
+  <xs:simpleType name="ip-version">
+    <xs:annotation>
+      <xs:documentation>
+        This value represents the version of the IP protocol.
+
+        In the value set and its semantics, this type is equivalent
+        to the InetVersion textual convention of the SMIv2.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="unknown"/>
+      <xs:enumeration value="ipv4"/>
+      <xs:enumeration value="ipv6"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="dscp">
+    <xs:annotation>
+      <xs:documentation>
+        The dscp type represents a Differentiated Services Code-Point
+        that may be used for marking packets in a traffic stream.
+
+        In the value set and its semantics, this type is equivalent
+        to the Dscp textual convention of the SMIv2.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:unsignedByte">
+      <xs:minInclusive value="0"/>
+      <xs:maxInclusive value="63"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="ipv6-flow-label">
+    <xs:annotation>
+      <xs:documentation>
+        The flow-label type represents flow identifier or Flow Label
+        in an IPv6 packet header that may be used to discriminate
+        traffic flows.
+
+        In the value set and its semantics, this type is equivalent
+        to the IPv6FlowLabel textual convention of the SMIv2.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:unsignedInt">
+      <xs:minInclusive value="0"/>
+      <xs:maxInclusive value="1048575"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="port-number">
+    <xs:annotation>
+      <xs:documentation>
+        The port-number type represents a 16-bit port number of an
+        Internet transport layer protocol such as UDP, TCP, DCCP, or
+        SCTP.  Port numbers are assigned by IANA.  A current list of
+        all assignments is available from &lt;http://www.iana.org/&gt;.
+
+        Note that the port number value zero is reserved by IANA.  In
+        situations where the value zero does not make sense, it can
+        be excluded by subtyping the port-number type.
+
+        In the value set and its semantics, this type is equivalent
+        to the InetPortNumber textual convention of the SMIv2.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:unsignedShort">
+      <xs:minInclusive value="0"/>
+      <xs:maxInclusive value="65535"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="as-number">
+    <xs:annotation>
+      <xs:documentation>
+        The as-number type represents autonomous system numbers
+        which identify an Autonomous System (AS).  An AS is a set
+        of routers under a single technical administration, using
+        an interior gateway protocol and common metrics to route
+        packets within the AS, and using an exterior gateway
+        protocol to route packets to other ASs'.  IANA maintains
+        the AS number space and has delegated large parts to the
+        regional registries.
+
+        Autonomous system numbers were originally limited to 16
+        bits.  BGP extensions have enlarged the autonomous system
+        number space to 32 bits.  This type therefore uses an uint32
+        base type without a range restriction in order to support
+        a larger autonomous system number space.
+
+        In the value set and its semantics, this type is equivalent
+        to the InetAutonomousSystemNumber textual convention of
+        the SMIv2.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:unsignedInt">
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="ip-address">
+    <xs:annotation>
+      <xs:documentation>
+        The ip-address type represents an IP address and is IP
+        version neutral.  The format of the textual representations
+        implies the IP version.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:union>
+      <xs:simpleType>
+        <xs:restriction base="ipv4-address">
+        </xs:restriction>
+      </xs:simpleType>
+      <xs:simpleType>
+        <xs:restriction base="ipv6-address">
+        </xs:restriction>
+      </xs:simpleType>
+    </xs:union>
+  </xs:simpleType>
+  <xs:simpleType name="ipv4-address">
+    <xs:annotation>
+      <xs:documentation>
+        The ipv4-address type represents an IPv4 address in
+        dotted-quad notation.  The IPv4 address may include a zone
+        index, separated by a % sign.
+
+        The zone index is used to disambiguate identical address
+        values.  For link-local addresses, the zone index will
+        typically be the interface index number or the name of an
+        interface.  If the zone index is not present, the default
+        zone of the device will be used.
+
+        The canonical format for the zone index is the numerical
+        format
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:string">
+    <xs:pattern value="(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\p{N}\p{L}]+)?"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="ipv6-address">
+    <xs:annotation>
+      <xs:documentation>
+        The ipv6-address type represents an IPv6 address in full,
+        mixed, shortened, and shortened-mixed notation.  The IPv6
+        address may include a zone index, separated by a % sign.
+
+        The zone index is used to disambiguate identical address
+        values.  For link-local addresses, the zone index will
+        typically be the interface index number or the name of an
+        interface.  If the zone index is not present, the default
+        zone of the device will be used.
+
+        The canonical format of IPv6 addresses uses the compressed
+        format described in RFC 4291, Section 2.2, item 2 with the
+        following additional rules: the :: substitution must be
+        applied to the longest sequence of all-zero 16-bit chunks
+        in an IPv6 address.  If there is a tie, the first sequence
+        of all-zero 16-bit chunks is replaced by ::.  Single
+        all-zero 16-bit chunks are not compressed.  The canonical
+        format uses lowercase characters and leading zeros are
+        not allowed.  The canonical format for the zone index is
+        the numerical format as described in RFC 4007, Section
+        11.2.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:string">
+    <xs:pattern value="(((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\p{N}\p{L}]+)?)|((([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?)"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="ip-prefix">
+    <xs:annotation>
+      <xs:documentation>
+        The ip-prefix type represents an IP prefix and is IP
+        version neutral.  The format of the textual representations
+        implies the IP version.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:union>
+      <xs:simpleType>
+        <xs:restriction base="ipv4-prefix">
+        </xs:restriction>
+      </xs:simpleType>
+      <xs:simpleType>
+        <xs:restriction base="ipv6-prefix">
+        </xs:restriction>
+      </xs:simpleType>
+    </xs:union>
+  </xs:simpleType>
+  <xs:simpleType name="ipv4-prefix">
+    <xs:annotation>
+      <xs:documentation>
+        The ipv4-prefix type represents an IPv4 address prefix.
+        The prefix length is given by the number following the
+        slash character and must be less than or equal to 32.
+
+        A prefix length value of n corresponds to an IP address
+        mask that has n contiguous 1-bits from the most
+        significant bit (MSB) and all other bits set to 0.
+
+        The canonical format of an IPv4 prefix has all bits of
+        the IPv4 address set to zero that are not part of the
+        IPv4 prefix.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:string">
+    <xs:pattern value="(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="ipv6-prefix">
+    <xs:annotation>
+      <xs:documentation>
+        The ipv6-prefix type represents an IPv6 address prefix.
+        The prefix length is given by the number following the
+        slash character and must be less than or equal 128.
+
+        A prefix length value of n corresponds to an IP address
+        mask that has n contiguous 1-bits from the most
+        significant bit (MSB) and all other bits set to 0.
+
+        The IPv6 address should have all bits that do not belong
+        to the prefix set to zero.
+
+        The canonical format of an IPv6 prefix has all bits of
+        the IPv6 address set to zero that are not part of the
+        IPv6 prefix.  Furthermore, IPv6 address is represented
+        in the compressed format described in RFC 4291, Section
+        2.2, item 2 with the following additional rules: the ::
+        substitution must be applied to the longest sequence of
+        all-zero 16-bit chunks in an IPv6 address.  If there is
+        a tie, the first sequence of all-zero 16-bit chunks is
+        replaced by ::.  Single all-zero 16-bit chunks are not
+        compressed.  The canonical format uses lowercase
+        characters and leading zeros are not allowed.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:string">
+    <xs:pattern value="(((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8]))))|((([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(/.+))"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="domain-name">
+    <xs:annotation>
+      <xs:documentation>
+        The domain-name type represents a DNS domain name.  The
+        name SHOULD be fully qualified whenever possible.
+
+        Internet domain names are only loosely specified.  Section
+        3.5 of RFC 1034 recommends a syntax (modified in Section
+        2.1 of RFC 1123).  The pattern above is intended to allow
+        for current practice in domain name use, and some possible
+        future expansion.  It is designed to hold various types of
+        domain names, including names used for A or AAAA records
+        (host names) and other records, such as SRV records.  Note
+        that Internet host names have a stricter syntax (described
+        in RFC 952) than the DNS recommendations in RFCs 1034 and
+        1123, and that systems that want to store host names in
+        schema nodes using the domain-name type are recommended to
+        adhere to this stricter standard to ensure interoperability.
+
+        The encoding of DNS names in the DNS protocol is limited
+        to 255 characters.  Since the encoding consists of labels
+        prefixed by a length bytes and there is a trailing NULL
+        byte, only 253 characters can appear in the textual dotted
+        notation.
+
+        The description clause of schema nodes using the domain-name
+        type MUST describe when and how these names are resolved to
+        IP addresses.  Note that the resolution of a domain-name value
+        may require to query multiple DNS records (e.g., A for IPv4
+        and AAAA for IPv6).  The order of the resolution process and
+        which DNS record takes precedence can either be defined
+        explicitely or it may depend on the configuration of the
+        resolver.
+
+        Domain-name values use the US-ASCII encoding.  Their canonical
+        format uses lowercase US-ASCII characters.  Internationalized
+        domain names MUST be encoded in punycode as described in RFC
+        3492
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="t0">
+      <xs:minLength value="1"/>
+      <xs:maxLength value="253"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="host">
+    <xs:annotation>
+      <xs:documentation>
+        The host type represents either an IP address or a DNS
+        domain name.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:union>
+      <xs:simpleType>
+        <xs:restriction base="ip-address">
+        </xs:restriction>
+      </xs:simpleType>
+      <xs:simpleType>
+        <xs:restriction base="domain-name">
+        </xs:restriction>
+      </xs:simpleType>
+    </xs:union>
+  </xs:simpleType>
+  <xs:simpleType name="uri">
+    <xs:annotation>
+      <xs:documentation>
+        The uri type represents a Uniform Resource Identifier
+        (URI) as defined by STD 66.
+
+        Objects using the uri type MUST be in US-ASCII encoding,
+        and MUST be normalized as described by RFC 3986 Sections
+        6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+        percent-encoding is removed, and all case-insensitive
+        characters are set to lowercase except for hexadecimal
+        digits, which are normalized to uppercase as described in
+        Section 6.2.2.1.
+
+        The purpose of this normalization is to help provide
+        unique URIs.  Note that this normalization is not
+        sufficient to provide uniqueness.  Two URIs that are
+        textually distinct after this normalization may still be
+        equivalent.
+
+        Objects using the uri type may restrict the schemes that
+        they permit.  For example, 'data:' and 'urn:' schemes
+        might not be appropriate.
+
+        A zero-length URI is not a valid URI.  This can be used to
+        express 'URI absent' where required.
+
+        In the value set and its semantics, this type is equivalent
+        to the Uri SMIv2 textual convention defined in RFC 5017.
+      </xs:documentation>
+    </xs:annotation>
+
+    <xs:restriction base="xs:string">
+    </xs:restriction>
+  </xs:simpleType>
+
+
+  <!-- locally generated simpleType helpers -->
+
+  <xs:simpleType name="t0">
+    <xs:restriction base="xs:string">
+    <xs:pattern value="((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)|\."/>
+    </xs:restriction>
+  </xs:simpleType>
+
+</xs:schema>
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/ietf-inet-types@2010-09-24.yang b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/ietf-inet-types@2010-09-24.yang
new file mode 100755 (executable)
index 0000000..de20feb
--- /dev/null
@@ -0,0 +1,418 @@
+ module ietf-inet-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+   prefix "inet";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types for Internet addresses and related things.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of protocol field related types ***/
+
+   typedef ip-version {
+     type enumeration {
+       enum unknown {
+         value "0";
+         description
+          "An unknown or unspecified version of the Internet protocol.";
+       }
+       enum ipv4 {
+         value "1";
+         description
+          "The IPv4 protocol as defined in RFC 791.";
+       }
+       enum ipv6 {
+         value "2";
+         description
+          "The IPv6 protocol as defined in RFC 2460.";
+       }
+     }
+     description
+      "This value represents the version of the IP protocol.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetVersion textual convention of the SMIv2.";
+     reference
+      "RFC  791: Internet Protocol
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   typedef dscp {
+     type uint8 {
+       range "0..63";
+     }
+     description
+      "The dscp type represents a Differentiated Services Code-Point
+       that may be used for marking packets in a traffic stream.
+
+       In the value set and its semantics, this type is equivalent
+       to the Dscp textual convention of the SMIv2.";
+     reference
+      "RFC 3289: Management Information Base for the Differentiated
+                 Services Architecture
+       RFC 2474: Definition of the Differentiated Services Field
+                 (DS Field) in the IPv4 and IPv6 Headers
+       RFC 2780: IANA Allocation Guidelines For Values In
+                 the Internet Protocol and Related Headers";
+   }
+
+   typedef ipv6-flow-label {
+     type uint32 {
+       range "0..1048575";
+     }
+     description
+      "The flow-label type represents flow identifier or Flow Label
+       in an IPv6 packet header that may be used to discriminate
+       traffic flows.
+
+       In the value set and its semantics, this type is equivalent
+       to the IPv6FlowLabel textual convention of the SMIv2.";
+     reference
+      "RFC 3595: Textual Conventions for IPv6 Flow Label
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+   }
+
+   typedef port-number {
+     type uint16 {
+       range "0..65535";
+     }
+     description
+      "The port-number type represents a 16-bit port number of an
+       Internet transport layer protocol such as UDP, TCP, DCCP, or
+       SCTP.  Port numbers are assigned by IANA.  A current list of
+       all assignments is available from <http://www.iana.org/>.
+
+       Note that the port number value zero is reserved by IANA.  In
+       situations where the value zero does not make sense, it can
+       be excluded by subtyping the port-number type.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetPortNumber textual convention of the SMIv2.";
+     reference
+      "RFC  768: User Datagram Protocol
+       RFC  793: Transmission Control Protocol
+       RFC 4960: Stream Control Transmission Protocol
+       RFC 4340: Datagram Congestion Control Protocol (DCCP)
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of autonomous system related types ***/
+
+   typedef as-number {
+     type uint32;
+     description
+      "The as-number type represents autonomous system numbers
+       which identify an Autonomous System (AS).  An AS is a set
+       of routers under a single technical administration, using
+       an interior gateway protocol and common metrics to route
+       packets within the AS, and using an exterior gateway
+       protocol to route packets to other ASs'.  IANA maintains
+       the AS number space and has delegated large parts to the
+       regional registries.
+
+       Autonomous system numbers were originally limited to 16
+       bits.  BGP extensions have enlarged the autonomous system
+       number space to 32 bits.  This type therefore uses an uint32
+       base type without a range restriction in order to support
+       a larger autonomous system number space.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetAutonomousSystemNumber textual convention of
+       the SMIv2.";
+     reference
+      "RFC 1930: Guidelines for creation, selection, and registration
+                 of an Autonomous System (AS)
+       RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+       RFC 4893: BGP Support for Four-octet AS Number Space
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of IP address and hostname related types ***/
+
+   typedef ip-address {
+     type union {
+       type inet:ipv4-address;
+       type inet:ipv6-address;
+     }
+     description
+      "The ip-address type represents an IP address and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-address {
+     type string {
+       pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '(%[\p{N}\p{L}]+)?';
+     }
+     description
+       "The ipv4-address type represents an IPv4 address in
+        dotted-quad notation.  The IPv4 address may include a zone
+        index, separated by a % sign.
+
+        The zone index is used to disambiguate identical address
+        values.  For link-local addresses, the zone index will
+        typically be the interface index number or the name of an
+        interface.  If the zone index is not present, the default
+        zone of the device will be used.
+
+        The canonical format for the zone index is the numerical
+        format";
+   }
+
+   typedef ipv6-address {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(%[\p{N}\p{L}]+)?';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(%.+)?';
+     }
+     description
+      "The ipv6-address type represents an IPv6 address in full,
+       mixed, shortened, and shortened-mixed notation.  The IPv6
+       address may include a zone index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format of IPv6 addresses uses the compressed
+       format described in RFC 4291, Section 2.2, item 2 with the
+       following additional rules: the :: substitution must be
+       applied to the longest sequence of all-zero 16-bit chunks
+       in an IPv6 address.  If there is a tie, the first sequence
+       of all-zero 16-bit chunks is replaced by ::.  Single
+       all-zero 16-bit chunks are not compressed.  The canonical
+       format uses lowercase characters and leading zeros are
+       not allowed.  The canonical format for the zone index is
+       the numerical format as described in RFC 4007, Section
+       11.2.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture
+       RFC 4007: IPv6 Scoped Address Architecture
+       RFC 5952: A Recommendation for IPv6 Address Text Representation";
+   }
+
+   typedef ip-prefix {
+     type union {
+       type inet:ipv4-prefix;
+       type inet:ipv6-prefix;
+     }
+     description
+      "The ip-prefix type represents an IP prefix and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-prefix {
+     type string {
+       pattern
+          '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+        +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+        + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+     }
+     description
+      "The ipv4-prefix type represents an IPv4 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal to 32.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The canonical format of an IPv4 prefix has all bits of
+       the IPv4 address set to zero that are not part of the
+       IPv4 prefix.";
+   }
+
+   typedef ipv6-prefix {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(/.+)';
+     }
+     description
+      "The ipv6-prefix type represents an IPv6 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal 128.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The IPv6 address should have all bits that do not belong
+       to the prefix set to zero.
+
+       The canonical format of an IPv6 prefix has all bits of
+       the IPv6 address set to zero that are not part of the
+       IPv6 prefix.  Furthermore, IPv6 address is represented
+       in the compressed format described in RFC 4291, Section
+       2.2, item 2 with the following additional rules: the ::
+       substitution must be applied to the longest sequence of
+       all-zero 16-bit chunks in an IPv6 address.  If there is
+       a tie, the first sequence of all-zero 16-bit chunks is
+       replaced by ::.  Single all-zero 16-bit chunks are not
+       compressed.  The canonical format uses lowercase
+       characters and leading zeros are not allowed.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture";
+   }
+
+   /*** collection of domain name and URI types ***/
+
+   typedef domain-name {
+     type string {
+       pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+            +  '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+            +  '|\.';
+       length "1..253";
+     }
+     description
+      "The domain-name type represents a DNS domain name.  The
+       name SHOULD be fully qualified whenever possible.
+
+       Internet domain names are only loosely specified.  Section
+       3.5 of RFC 1034 recommends a syntax (modified in Section
+       2.1 of RFC 1123).  The pattern above is intended to allow
+       for current practice in domain name use, and some possible
+       future expansion.  It is designed to hold various types of
+       domain names, including names used for A or AAAA records
+       (host names) and other records, such as SRV records.  Note
+       that Internet host names have a stricter syntax (described
+       in RFC 952) than the DNS recommendations in RFCs 1034 and
+       1123, and that systems that want to store host names in
+       schema nodes using the domain-name type are recommended to
+       adhere to this stricter standard to ensure interoperability.
+
+       The encoding of DNS names in the DNS protocol is limited
+       to 255 characters.  Since the encoding consists of labels
+       prefixed by a length bytes and there is a trailing NULL
+       byte, only 253 characters can appear in the textual dotted
+       notation.
+
+       The description clause of schema nodes using the domain-name
+       type MUST describe when and how these names are resolved to
+       IP addresses.  Note that the resolution of a domain-name value
+       may require to query multiple DNS records (e.g., A for IPv4
+       and AAAA for IPv6).  The order of the resolution process and
+       which DNS record takes precedence can either be defined
+       explicitely or it may depend on the configuration of the
+       resolver.
+
+       Domain-name values use the US-ASCII encoding.  Their canonical
+       format uses lowercase US-ASCII characters.  Internationalized
+       domain names MUST be encoded in punycode as described in RFC
+       3492";
+     reference
+      "RFC  952: DoD Internet Host Table Specification
+       RFC 1034: Domain Names - Concepts and Facilities
+       RFC 1123: Requirements for Internet Hosts -- Application
+                 and Support
+       RFC 2782: A DNS RR for specifying the location of services
+                 (DNS SRV)
+       RFC 3492: Punycode: A Bootstring encoding of Unicode for
+                 Internationalized Domain Names in Applications
+                 (IDNA)
+       RFC 5891: Internationalizing Domain Names in Applications
+                 (IDNA): Protocol";
+   }
+
+   typedef host {
+     type union {
+       type inet:ip-address;
+       type inet:domain-name;
+     }
+     description
+      "The host type represents either an IP address or a DNS
+       domain name.";
+   }
+
+   typedef uri {
+     type string;
+     description
+      "The uri type represents a Uniform Resource Identifier
+       (URI) as defined by STD 66.
+
+       Objects using the uri type MUST be in US-ASCII encoding,
+       and MUST be normalized as described by RFC 3986 Sections
+       6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+       percent-encoding is removed, and all case-insensitive
+       characters are set to lowercase except for hexadecimal
+       digits, which are normalized to uppercase as described in
+       Section 6.2.2.1.
+
+       The purpose of this normalization is to help provide
+       unique URIs.  Note that this normalization is not
+       sufficient to provide uniqueness.  Two URIs that are
+       textually distinct after this normalization may still be
+       equivalent.
+
+       Objects using the uri type may restrict the schemes that
+       they permit.  For example, 'data:' and 'urn:' schemes
+       might not be appropriate.
+
+       A zero-length URI is not a valid URI.  This can be used to
+       express 'URI absent' where required.
+
+       In the value set and its semantics, this type is equivalent
+       to the Uri SMIv2 textual convention defined in RFC 5017.";
+     reference
+      "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+       RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                 Group: Uniform Resource Identifiers (URIs), URLs,
+                 and Uniform Resource Names (URNs): Clarifications
+                 and Recommendations
+       RFC 5017: MIB Textual Conventions for Uniform Resource
+                 Identifiers (URIs)";
+   }
+
+ }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.