2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
\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
8 package org.opendaylight.controller.yang.data.impl;
\r
10 import java.util.AbstractMap.SimpleEntry;
\r
11 import java.util.ArrayList;
\r
12 import java.util.Arrays;
\r
13 import java.util.HashMap;
\r
14 import java.util.List;
\r
15 import java.util.Map;
\r
16 import java.util.Stack;
\r
18 import org.opendaylight.controller.yang.common.QName;
\r
19 import org.opendaylight.controller.yang.data.api.CompositeNode;
\r
20 import org.opendaylight.controller.yang.data.api.ModifyAction;
\r
21 import org.opendaylight.controller.yang.data.api.MutableCompositeNode;
\r
22 import org.opendaylight.controller.yang.data.api.MutableSimpleNode;
\r
23 import org.opendaylight.controller.yang.data.api.Node;
\r
24 import org.opendaylight.controller.yang.data.api.NodeModification;
\r
25 import org.opendaylight.controller.yang.data.api.SimpleNode;
\r
28 * @author michal.rehak
\r
31 public abstract class NodeFactory {
\r
37 * @return simple node modification, based on given qname, value and parent
\r
39 public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,
\r
40 CompositeNode parent, T value) {
\r
41 return createImmutableSimpleNode(qName, parent, value, null);
\r
48 * @param modifyAction
\r
49 * @param original originating node, if available
\r
50 * @return simple node modification, based on given qname, value and parent
\r
52 public static <T> MutableSimpleNode<T> createMutableSimpleNode(QName qName,
\r
53 CompositeNode parent, Object value, ModifyAction modifyAction, SimpleNode<T> original) {
\r
54 @SuppressWarnings("unchecked")
\r
55 MutableSimpleNodeTOImpl<T> simpleNodeTOImpl =
\r
56 new MutableSimpleNodeTOImpl<T>(qName, parent, (T) value, modifyAction);
\r
57 simpleNodeTOImpl.setOriginal(original);
\r
58 return simpleNodeTOImpl;
\r
65 * @return composite node modification, based on given qname, value (children), parent and modifyAction
\r
67 public static CompositeNode createImmutableCompositeNode(QName qName,
\r
68 CompositeNode parent, List<Node<?>> value) {
\r
69 return createImmutableCompositeNode(qName, parent, value, null);
\r
76 * @param modifyAction
\r
77 * @param original originating node, if available
\r
78 * @return composite node modification, based on given qName, value (children), parent and modifyAction
\r
80 public static MutableCompositeNode createMutableCompositeNode(QName qName,
\r
81 CompositeNode parent, List<Node<?>> valueArg, ModifyAction modifyAction, CompositeNode original) {
\r
82 List<Node<?>> value = valueArg;
\r
83 if (value == null) {
\r
84 value = new ArrayList<>();
\r
86 MutableCompositeNodeTOImpl compositeNodeTOImpl =
\r
87 new MutableCompositeNodeTOImpl(qName, parent, value, modifyAction);
\r
88 compositeNodeTOImpl.setOriginal(original);
\r
89 return compositeNodeTOImpl;
\r
97 * @param modifyAction
\r
98 * @return simple node modification, based on given qname, value, parent and modifyAction
\r
100 public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,
\r
101 CompositeNode parent, T value, ModifyAction modifyAction) {
\r
102 SimpleNodeTOImpl<T> simpleNodeModTOImpl =
\r
103 new SimpleNodeTOImpl<T>(qName, parent, value, modifyAction);
\r
104 return simpleNodeModTOImpl;
\r
111 * @param modifyAction
\r
112 * @return composite node modification, based on given qname, value (children), parent and modifyAction
\r
114 public static CompositeNode createImmutableCompositeNode(QName qName,
\r
115 CompositeNode parent, List<Node<?>> value, ModifyAction modifyAction) {
\r
116 CompositeNodeTOImpl compositeNodeModTOImpl =
\r
117 new CompositeNodeTOImpl(qName, parent, value, modifyAction);
\r
118 return compositeNodeModTOImpl;
\r
123 * @return copy of given node, parent and value are the same, but parent
\r
124 * has no reference to this copy
\r
126 public static <T> SimpleNode<T> copyNode(SimpleNode<T> node) {
\r
127 SimpleNode<T> twinNode = createImmutableSimpleNode(
\r
128 node.getNodeType(), node.getParent(), node.getValue());
\r
134 * @return copy of given node, parent and value are the same, but parent
\r
135 * has no reference to this copy
\r
137 public static <T> MutableSimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {
\r
138 MutableSimpleNode<T> twinNode = createMutableSimpleNode(
\r
139 node.getNodeType(), node.getParent(), node.getValue(),
\r
140 node.getModificationAction(), null);
\r
147 * @return copy of given node, parent and children are the same, but parent and children
\r
148 * have no reference to this copy
\r
150 public static CompositeNode copyNode(CompositeNode node, Node<?>... children) {
\r
151 CompositeNode twinNode = createImmutableCompositeNode(
\r
152 node.getNodeType(), node.getParent(), Arrays.asList(children), node.getModificationAction());
\r
158 * @return copy of given node, parent and children are the same, but parent and children
\r
159 * have no reference to this copy
\r
161 public static CompositeNode copyNode(CompositeNode node) {
\r
162 return copyNode(node, node.getChildren().toArray(new Node<?>[0]));
\r
166 * @param node root of original tree
\r
167 * @param originalToCopyArg (optional) empty map, where binding between original and copy
\r
169 * @return copy of given node and all subnodes recursively
\r
171 public static MutableCompositeNode copyDeepAsMutable(CompositeNode node,
\r
172 Map<Node<?>, Node<?>> originalToCopyArg) {
\r
174 Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;
\r
175 if (originalToCopy == null) {
\r
176 originalToCopy = new HashMap<>();
\r
179 MutableCompositeNode mutableRoot = createMutableCompositeNode(node.getNodeType(), null, null,
\r
180 node.getModificationAction(), null);
\r
181 Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();
\r
182 jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));
\r
183 originalToCopy.put(node, mutableRoot);
\r
185 while (!jobQueue.isEmpty()) {
\r
186 SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();
\r
187 CompositeNode originalNode = job.getKey();
\r
188 MutableCompositeNode mutableNode = job.getValue();
\r
189 mutableNode.setValue(new ArrayList<Node<?>>());
\r
191 for (Node<?> child : originalNode.getChildren()) {
\r
192 Node<?> mutableAscendant = null;
\r
193 if (child instanceof CompositeNode) {
\r
194 MutableCompositeNode newMutable =
\r
195 createMutableCompositeNode(child.getNodeType(), mutableNode, null,
\r
196 ((NodeModification) child).getModificationAction(), null);
\r
197 jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(
\r
198 (CompositeNode) child, newMutable));
\r
199 mutableAscendant = newMutable;
\r
200 } else if (child instanceof SimpleNode<?>) {
\r
201 mutableAscendant =
\r
202 createMutableSimpleNode(child.getNodeType(), mutableNode,
\r
204 ((NodeModification) child).getModificationAction(), null);
\r
206 throw new IllegalStateException("Node class deep copy not supported: "
\r
207 +child.getClass().getName());
\r
210 mutableNode.getChildren().add(mutableAscendant);
\r
211 originalToCopy.put(child, mutableAscendant);
\r
213 mutableNode.init();
\r
216 return mutableRoot;
\r
220 * @param node root of original tree
\r
221 * @param originalToCopyArg (optional) empty map, where binding between original and copy
\r
223 * @return copy of given node and all subnodes recursively
\r
225 public static CompositeNode copyDeepAsImmutable(CompositeNode node,
\r
226 Map<Node<?>, Node<?>> originalToCopyArg) {
\r
227 Stack<CompositeNode> jobQueue = new Stack<>();
\r
228 jobQueue.push(node);
\r
230 Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;
\r
231 if (originalToCopy == null) {
\r
232 originalToCopy = new HashMap<>();
\r
235 while (!jobQueue.isEmpty()) {
\r
236 CompositeNode jobNode = jobQueue.peek();
\r
237 if (!originalToCopy.isEmpty()
\r
238 && originalToCopy.keySet().containsAll(jobNode.getChildren())) {
\r
240 List<Node<?>> newChildren = NodeUtils.collectMapValues(jobNode.getChildren(), originalToCopy);
\r
241 CompositeNode nodeCopy = createImmutableCompositeNode(jobNode.getNodeType(), null,
\r
242 newChildren, jobNode.getModificationAction());
\r
243 NodeUtils.fixChildrenRelation(nodeCopy);
\r
244 originalToCopy.put(jobNode, nodeCopy);
\r
246 for (Node<?> child : jobNode.getChildren()) {
\r
247 if (child instanceof SimpleNode<?>) {
\r
248 originalToCopy.put(child, createImmutableSimpleNode(
\r
249 child.getNodeType(), null, child.getValue(),
\r
250 ((NodeModification) child).getModificationAction()));
\r
251 } else if (child instanceof CompositeNode) {
\r
252 jobQueue.push((CompositeNode) child);
\r
258 return (CompositeNode) originalToCopy.get(node);
\r