Merge "Added more tests for yang parser. Updated current tests."
[controller.git] / opendaylight / sal / yang-prototype / yang / yang-data-impl / src / main / java / org / opendaylight / controller / yang / data / impl / NodeFactory.java
1 /*\r
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 package org.opendaylight.controller.yang.data.impl;\r
9 \r
10 import java.util.AbstractMap.SimpleEntry;\r
11 import java.util.ArrayList;\r
12 import java.util.Arrays;\r
13 import java.util.List;\r
14 import java.util.Map;\r
15 import java.util.Stack;\r
16 \r
17 import org.opendaylight.controller.yang.common.QName;\r
18 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
19 import org.opendaylight.controller.yang.data.api.ModifyAction;\r
20 import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
21 import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
22 import org.opendaylight.controller.yang.data.api.Node;\r
23 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
24 \r
25 /**\r
26  * @author michal.rehak\r
27  * \r
28  */\r
29 public abstract class NodeFactory {\r
30 \r
31     /**\r
32      * @param qName\r
33      * @param parent\r
34      * @param value\r
35      * @return simple node modification, based on given qname, value and parent\r
36      */\r
37     public static <T> SimpleNode<T> createSimpleNode(QName qName,\r
38             CompositeNode parent, T value) {\r
39         SimpleNodeTOImpl<T> simpleNodeTOImpl = new SimpleNodeTOImpl<T>(qName, parent, value);\r
40         return simpleNodeTOImpl;\r
41     }\r
42     \r
43     /**\r
44      * @param qName\r
45      * @param parent\r
46      * @param value\r
47      * @return simple node modification, based on given qname, value and parent\r
48      */\r
49     public static <T> MutableSimpleNode<T> createMutableSimpleNode(QName qName,\r
50             CompositeNode parent, T value) {\r
51         MutableSimpleNodeTOImpl<T> simpleNodeTOImpl = \r
52                 new MutableSimpleNodeTOImpl<T>(qName, parent, value, null);\r
53         return simpleNodeTOImpl;\r
54     }\r
55 \r
56     /**\r
57      * @param qName\r
58      * @param parent\r
59      * @param value\r
60      * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
61      */\r
62     public static CompositeNode createCompositeNode(QName qName,\r
63             CompositeNode parent, List<Node<?>> value) {\r
64         CompositeNode compositeNodeTOImpl = new CompositeNodeTOImpl(qName, parent, value);\r
65         return compositeNodeTOImpl;\r
66     }\r
67     \r
68     /**\r
69      * @param qName\r
70      * @param parent\r
71      * @param value\r
72      * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
73      */\r
74     public static MutableCompositeNode createMutableCompositeNode(QName qName,\r
75             CompositeNode parent, List<Node<?>> value) {\r
76         MutableCompositeNodeTOImpl compositeNodeTOImpl = \r
77                 new MutableCompositeNodeTOImpl(qName, parent, value, null);\r
78         return compositeNodeTOImpl;\r
79     }\r
80     \r
81     \r
82     /**\r
83      * @param qName\r
84      * @param parent\r
85      * @param value\r
86      * @param modifyAction\r
87      * @return simple node modification, based on given qname, value, parent and modifyAction\r
88      */\r
89     public static <T> SimpleNodeModificationTOImpl<T> createSimpleNodeModification(QName qName,\r
90             CompositeNode parent, T value, ModifyAction modifyAction) {\r
91         SimpleNodeModificationTOImpl<T> simpleNodeModTOImpl = \r
92                 new SimpleNodeModificationTOImpl<T>(qName, parent, value, modifyAction);\r
93         return simpleNodeModTOImpl;\r
94     }\r
95 \r
96     /**\r
97      * @param qName\r
98      * @param parent\r
99      * @param value\r
100      * @param modifyAction \r
101      * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
102      */\r
103     public static CompositeNodeModificationTOImpl createCompositeNodeModification(QName qName,\r
104             CompositeNode parent, List<Node<?>> value, ModifyAction modifyAction) {\r
105         CompositeNodeModificationTOImpl compositeNodeModTOImpl = \r
106                 new CompositeNodeModificationTOImpl(qName, parent, value, modifyAction);\r
107         return compositeNodeModTOImpl;\r
108     }\r
109 \r
110     /**\r
111      * @param node\r
112      * @return copy of given node, parent and value are the same, but parent \r
113      * has no reference to this copy \r
114      */\r
115     public static <T> SimpleNode<T> copyNode(SimpleNode<T> node) {\r
116         SimpleNode<T> twinNode = createSimpleNode(\r
117                     node.getNodeType(), node.getParent(), node.getValue());\r
118         return twinNode;\r
119     }\r
120     \r
121     /**\r
122      * @param node\r
123      * @return copy of given node, parent and value are the same, but parent \r
124      * has no reference to this copy \r
125      */\r
126     public static <T> SimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
127         SimpleNode<T> twinNode = createMutableSimpleNode(\r
128                     node.getNodeType(), node.getParent(), node.getValue());\r
129         return twinNode;\r
130     }\r
131 \r
132     /**\r
133      * @param node\r
134      * @param children \r
135      * @return copy of given node, parent and children are the same, but parent and children \r
136      * have no reference to this copy\r
137      */\r
138     public static CompositeNode copyNode(CompositeNode node, Node<?>... children) {\r
139         CompositeNode twinNode = createCompositeNode(\r
140                 node.getNodeType(), node.getParent(), Arrays.asList(children));\r
141         return twinNode;\r
142     }\r
143     \r
144     /**\r
145      * @param node\r
146      * @return copy of given node, parent and children are the same, but parent and children \r
147      * have no reference to this copy\r
148      */\r
149     public static CompositeNode copyNode(CompositeNode node) {\r
150        return copyNode(node, node.getChildren().toArray(new Node<?>[0]));\r
151     }\r
152     \r
153     /**\r
154      * @param node root of original tree\r
155      * @param originalToMutable (optional) empty map, where binding between original and copy \r
156      * will be stored\r
157      * @return copy of given node, parent and children are the same, but parent and children \r
158      * have no reference to this copy\r
159      */\r
160     public static MutableCompositeNode copyDeepNode(CompositeNode node, \r
161             Map<Node<?>, Node<?>> originalToMutable) {\r
162               \r
163        MutableCompositeNode mutableRoot = \r
164                createMutableCompositeNode(node.getNodeType(), null, null);\r
165        Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
166        jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
167        if (originalToMutable != null) {\r
168            originalToMutable.put(node, mutableRoot);\r
169        }\r
170        \r
171        while (!jobQueue.isEmpty()) {\r
172            SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
173            CompositeNode originalNode = job.getKey();\r
174            MutableCompositeNode mutableNode = job.getValue();\r
175            mutableNode.setValue(new ArrayList<Node<?>>());\r
176            \r
177            for (Node<?> child : originalNode.getChildren()) {\r
178                Node<?> mutableAscendant = null;\r
179                if (child instanceof CompositeNode) {\r
180                    MutableCompositeNode newMutable = \r
181                            createMutableCompositeNode(child.getNodeType(), mutableNode, null);\r
182                    jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
183                            (CompositeNode) child, newMutable));\r
184                    mutableAscendant = newMutable;\r
185                } else if (child instanceof SimpleNode<?>) {\r
186                    mutableAscendant = \r
187                            createMutableSimpleNode(child.getNodeType(), mutableNode, child.getValue());\r
188                } else {\r
189                    throw new IllegalStateException("Node class deep copy not supported: "\r
190                            +child.getClass().getName());\r
191                }\r
192                \r
193                mutableNode.getChildren().add(mutableAscendant);\r
194                if (originalToMutable != null) {\r
195                    originalToMutable.put(child, mutableAscendant);\r
196                }\r
197            }\r
198            mutableNode.init();\r
199        }\r
200        \r
201        return mutableRoot;\r
202     }\r
203     \r
204 }\r