import java.util.AbstractMap.SimpleEntry;\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
+import java.util.HashMap;\r
import java.util.List;\r
import java.util.Map;\r
import java.util.Stack;\r
import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
import org.opendaylight.controller.yang.data.api.SimpleNode;\r
\r
/**\r
* @param value\r
* @return simple node modification, based on given qname, value and parent\r
*/\r
- public static <T> SimpleNode<T> createSimpleNode(QName qName,\r
+ public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,\r
CompositeNode parent, T value) {\r
- SimpleNodeTOImpl<T> simpleNodeTOImpl = new SimpleNodeTOImpl<T>(qName, parent, value);\r
- return simpleNodeTOImpl;\r
+ return createImmutableSimpleNode(qName, parent, value, null);\r
}\r
\r
/**\r
* @param qName\r
* @param parent\r
* @param value\r
+ * @param modifyAction \r
+ * @param original originating node, if available\r
* @return simple node modification, based on given qname, value and parent\r
*/\r
public static <T> MutableSimpleNode<T> createMutableSimpleNode(QName qName,\r
- CompositeNode parent, T value) {\r
+ CompositeNode parent, Object value, ModifyAction modifyAction, SimpleNode<T> original) {\r
+ @SuppressWarnings("unchecked")\r
MutableSimpleNodeTOImpl<T> simpleNodeTOImpl = \r
- new MutableSimpleNodeTOImpl<T>(qName, parent, value, null);\r
+ new MutableSimpleNodeTOImpl<T>(qName, parent, (T) value, modifyAction);\r
+ simpleNodeTOImpl.setOriginal(original);\r
return simpleNodeTOImpl;\r
}\r
-\r
+ \r
/**\r
* @param qName\r
* @param parent\r
* @param value\r
* @return composite node modification, based on given qname, value (children), parent and modifyAction\r
*/\r
- public static CompositeNode createCompositeNode(QName qName,\r
+ public static CompositeNode createImmutableCompositeNode(QName qName,\r
CompositeNode parent, List<Node<?>> value) {\r
- CompositeNode compositeNodeTOImpl = new CompositeNodeTOImpl(qName, parent, value);\r
- return compositeNodeTOImpl;\r
+ return createImmutableCompositeNode(qName, parent, value, null);\r
}\r
\r
/**\r
* @param qName\r
* @param parent\r
- * @param value\r
- * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
+ * @param valueArg \r
+ * @param modifyAction \r
+ * @param original originating node, if available\r
+ * @return composite node modification, based on given qName, value (children), parent and modifyAction\r
*/\r
public static MutableCompositeNode createMutableCompositeNode(QName qName,\r
- CompositeNode parent, List<Node<?>> value) {\r
+ CompositeNode parent, List<Node<?>> valueArg, ModifyAction modifyAction, CompositeNode original) {\r
+ List<Node<?>> value = valueArg;\r
+ if (value == null) {\r
+ value = new ArrayList<>();\r
+ }\r
MutableCompositeNodeTOImpl compositeNodeTOImpl = \r
- new MutableCompositeNodeTOImpl(qName, parent, value, null);\r
+ new MutableCompositeNodeTOImpl(qName, parent, value, modifyAction);\r
+ compositeNodeTOImpl.setOriginal(original);\r
return compositeNodeTOImpl;\r
}\r
\r
* @param modifyAction\r
* @return simple node modification, based on given qname, value, parent and modifyAction\r
*/\r
- public static <T> SimpleNodeModificationTOImpl<T> createSimpleNodeModification(QName qName,\r
+ public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,\r
CompositeNode parent, T value, ModifyAction modifyAction) {\r
- SimpleNodeModificationTOImpl<T> simpleNodeModTOImpl = \r
- new SimpleNodeModificationTOImpl<T>(qName, parent, value, modifyAction);\r
+ SimpleNodeTOImpl<T> simpleNodeModTOImpl = \r
+ new SimpleNodeTOImpl<T>(qName, parent, value, modifyAction);\r
return simpleNodeModTOImpl;\r
}\r
\r
* @param modifyAction \r
* @return composite node modification, based on given qname, value (children), parent and modifyAction\r
*/\r
- public static CompositeNodeModificationTOImpl createCompositeNodeModification(QName qName,\r
+ public static CompositeNode createImmutableCompositeNode(QName qName,\r
CompositeNode parent, List<Node<?>> value, ModifyAction modifyAction) {\r
- CompositeNodeModificationTOImpl compositeNodeModTOImpl = \r
- new CompositeNodeModificationTOImpl(qName, parent, value, modifyAction);\r
+ CompositeNodeTOImpl compositeNodeModTOImpl = \r
+ new CompositeNodeTOImpl(qName, parent, value, modifyAction);\r
return compositeNodeModTOImpl;\r
}\r
\r
* has no reference to this copy \r
*/\r
public static <T> SimpleNode<T> copyNode(SimpleNode<T> node) {\r
- SimpleNode<T> twinNode = createSimpleNode(\r
+ SimpleNode<T> twinNode = createImmutableSimpleNode(\r
node.getNodeType(), node.getParent(), node.getValue());\r
return twinNode;\r
}\r
* @return copy of given node, parent and value are the same, but parent \r
* has no reference to this copy \r
*/\r
- public static <T> SimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
- SimpleNode<T> twinNode = createMutableSimpleNode(\r
- node.getNodeType(), node.getParent(), node.getValue());\r
+ public static <T> MutableSimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
+ MutableSimpleNode<T> twinNode = createMutableSimpleNode(\r
+ node.getNodeType(), node.getParent(), node.getValue(), \r
+ node.getModificationAction(), null);\r
return twinNode;\r
}\r
-\r
+ \r
/**\r
* @param node\r
* @param children \r
* have no reference to this copy\r
*/\r
public static CompositeNode copyNode(CompositeNode node, Node<?>... children) {\r
- CompositeNode twinNode = createCompositeNode(\r
- node.getNodeType(), node.getParent(), Arrays.asList(children));\r
+ CompositeNode twinNode = createImmutableCompositeNode(\r
+ node.getNodeType(), node.getParent(), Arrays.asList(children), node.getModificationAction());\r
return twinNode;\r
}\r
\r
\r
/**\r
* @param node root of original tree\r
- * @param originalToMutable (optional) empty map, where binding between original and copy \r
+ * @param originalToCopyArg (optional) empty map, where binding between original and copy \r
* will be stored\r
- * @return copy of given node, parent and children are the same, but parent and children \r
- * have no reference to this copy\r
+ * @return copy of given node and all subnodes recursively\r
*/\r
- public static MutableCompositeNode copyDeepNode(CompositeNode node, \r
- Map<Node<?>, Node<?>> originalToMutable) {\r
- \r
- MutableCompositeNode mutableRoot = \r
- createMutableCompositeNode(node.getNodeType(), null, null);\r
- Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
- jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
- if (originalToMutable != null) {\r
- originalToMutable.put(node, mutableRoot);\r
- }\r
- \r
- while (!jobQueue.isEmpty()) {\r
- SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
- CompositeNode originalNode = job.getKey();\r
- MutableCompositeNode mutableNode = job.getValue();\r
- mutableNode.setValue(new ArrayList<Node<?>>());\r
- \r
- for (Node<?> child : originalNode.getChildren()) {\r
- Node<?> mutableAscendant = null;\r
- if (child instanceof CompositeNode) {\r
- MutableCompositeNode newMutable = \r
- createMutableCompositeNode(child.getNodeType(), mutableNode, null);\r
- jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
- (CompositeNode) child, newMutable));\r
- mutableAscendant = newMutable;\r
- } else if (child instanceof SimpleNode<?>) {\r
- mutableAscendant = \r
- createMutableSimpleNode(child.getNodeType(), mutableNode, child.getValue());\r
- } else {\r
- throw new IllegalStateException("Node class deep copy not supported: "\r
- +child.getClass().getName());\r
- }\r
- \r
- mutableNode.getChildren().add(mutableAscendant);\r
- if (originalToMutable != null) {\r
- originalToMutable.put(child, mutableAscendant);\r
- }\r
- }\r
- mutableNode.init();\r
- }\r
+ public static MutableCompositeNode copyDeepAsMutable(CompositeNode node, \r
+ Map<Node<?>, Node<?>> originalToCopyArg) {\r
+ \r
+ Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;\r
+ if (originalToCopy == null) {\r
+ originalToCopy = new HashMap<>();\r
+ }\r
+\r
+ MutableCompositeNode mutableRoot = createMutableCompositeNode(node.getNodeType(), null, null, \r
+ node.getModificationAction(), null);\r
+ Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
+ jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
+ originalToCopy.put(node, mutableRoot);\r
+\r
+ while (!jobQueue.isEmpty()) {\r
+ SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
+ CompositeNode originalNode = job.getKey();\r
+ MutableCompositeNode mutableNode = job.getValue();\r
+ mutableNode.setValue(new ArrayList<Node<?>>());\r
+\r
+ for (Node<?> child : originalNode.getChildren()) {\r
+ Node<?> mutableAscendant = null;\r
+ if (child instanceof CompositeNode) {\r
+ MutableCompositeNode newMutable = \r
+ createMutableCompositeNode(child.getNodeType(), mutableNode, null, \r
+ ((NodeModification) child).getModificationAction(), null);\r
+ jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
+ (CompositeNode) child, newMutable));\r
+ mutableAscendant = newMutable;\r
+ } else if (child instanceof SimpleNode<?>) {\r
+ mutableAscendant = \r
+ createMutableSimpleNode(child.getNodeType(), mutableNode, \r
+ child.getValue(), \r
+ ((NodeModification) child).getModificationAction(), null);\r
+ } else {\r
+ throw new IllegalStateException("Node class deep copy not supported: "\r
+ +child.getClass().getName());\r
+ }\r
+\r
+ mutableNode.getChildren().add(mutableAscendant);\r
+ originalToCopy.put(child, mutableAscendant);\r
+ }\r
+ mutableNode.init();\r
+ }\r
+\r
+ return mutableRoot;\r
+ }\r
+ \r
+ /**\r
+ * @param node root of original tree\r
+ * @param originalToCopyArg (optional) empty map, where binding between original and copy \r
+ * will be stored\r
+ * @return copy of given node and all subnodes recursively\r
+ */\r
+ public static CompositeNode copyDeepAsImmutable(CompositeNode node, \r
+ Map<Node<?>, Node<?>> originalToCopyArg) {\r
+ Stack<CompositeNode> jobQueue = new Stack<>();\r
+ jobQueue.push(node);\r
+ \r
+ Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;\r
+ if (originalToCopy == null) {\r
+ originalToCopy = new HashMap<>();\r
+ }\r
+ \r
+ while (!jobQueue.isEmpty()) {\r
+ CompositeNode jobNode = jobQueue.peek();\r
+ if (!originalToCopy.isEmpty() \r
+ && originalToCopy.keySet().containsAll(jobNode.getChildren())) {\r
+ jobQueue.pop();\r
+ List<Node<?>> newChildren = NodeUtils.collectMapValues(jobNode.getChildren(), originalToCopy);\r
+ CompositeNode nodeCopy = createImmutableCompositeNode(jobNode.getNodeType(), null, \r
+ newChildren, jobNode.getModificationAction());\r
+ NodeUtils.fixChildrenRelation(nodeCopy);\r
+ originalToCopy.put(jobNode, nodeCopy);\r
+ } else {\r
+ for (Node<?> child : jobNode.getChildren()) {\r
+ if (child instanceof SimpleNode<?>) {\r
+ originalToCopy.put(child, createImmutableSimpleNode(\r
+ child.getNodeType(), null, child.getValue(), \r
+ ((NodeModification) child).getModificationAction()));\r
+ } else if (child instanceof CompositeNode) {\r
+ jobQueue.push((CompositeNode) child);\r
+ }\r
+ }\r
+ }\r
+ }\r
\r
- return mutableRoot;\r
+ return (CompositeNode) originalToCopy.get(node);\r
}\r
\r
}\r