2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.data.impl;
10 import java.util.AbstractMap.SimpleEntry;
11 import java.util.ArrayDeque;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Deque;
15 import java.util.HashMap;
16 import java.util.List;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
21 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
22 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
23 import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
24 import org.opendaylight.yangtools.yang.data.api.Node;
25 import org.opendaylight.yangtools.yang.data.api.NodeModification;
26 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
27 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
30 * @author michal.rehak
32 * @deprecated Use {@link Builders} instead.
35 public abstract class NodeFactory {
41 * @return simple node modification, based on given qname, value and parent
43 public static <T> SimpleNode<T> createImmutableSimpleNode(final QName qName,
44 final CompositeNode parent, final T value) {
45 return createImmutableSimpleNode(qName, parent, value, null);
53 * @param original originating node, if available
54 * @return simple node modification, based on given qname, value and parent
56 public static <T> MutableSimpleNode<T> createMutableSimpleNode(final QName qName,
57 final CompositeNode parent, final Object value, final ModifyAction modifyAction, final SimpleNode<T> original) {
58 @SuppressWarnings("unchecked")
59 MutableSimpleNodeTOImpl<T> simpleNodeTOImpl = new MutableSimpleNodeTOImpl<>(qName, parent, (T) value, modifyAction);
60 simpleNodeTOImpl.setOriginal(original);
61 return simpleNodeTOImpl;
68 * @return composite node modification, based on given qname, value (children), parent and modifyAction
70 public static CompositeNode createImmutableCompositeNode(final QName qName,
71 final CompositeNode parent, final List<Node<?>> value) {
72 return createImmutableCompositeNode(qName, parent, value, null);
80 * @param original originating node, if available
81 * @return composite node modification, based on given qName, value (children), parent and modifyAction
83 public static MutableCompositeNode createMutableCompositeNode(final QName qName,
84 final CompositeNode parent, final List<Node<?>> valueArg, final ModifyAction modifyAction, final CompositeNode original) {
85 List<Node<?>> value = valueArg;
87 value = new ArrayList<>();
89 MutableCompositeNodeTOImpl compositeNodeTOImpl =
90 new MutableCompositeNodeTOImpl(qName, parent, value, modifyAction);
91 compositeNodeTOImpl.setOriginal(original);
92 return compositeNodeTOImpl;
100 * @param modifyAction
101 * @return simple node modification, based on given qname, value, parent and modifyAction
103 public static <T> SimpleNode<T> createImmutableSimpleNode(final QName qName,
104 final CompositeNode parent, final T value, final ModifyAction modifyAction) {
105 SimpleNodeTOImpl<T> simpleNodeModTOImpl =
106 new SimpleNodeTOImpl<T>(qName, parent, value, modifyAction);
107 return simpleNodeModTOImpl;
114 * @param modifyAction
115 * @return composite node modification, based on given qname, value (children), parent and modifyAction
117 public static CompositeNode createImmutableCompositeNode(final QName qName,
118 final CompositeNode parent, final List<Node<?>> value, final ModifyAction modifyAction) {
119 return new CompositeNodeTOImpl(qName, parent, value, modifyAction);
124 * @return copy of given node, parent and value are the same, but parent
125 * has no reference to this copy
127 public static <T> SimpleNode<T> copyNode(final SimpleNode<T> node) {
128 return createImmutableSimpleNode(node.getNodeType(), node.getParent(), node.getValue());
133 * @return copy of given node, parent and value are the same, but parent
134 * has no reference to this copy
136 public static <T> MutableSimpleNode<T> copyNodeAsMutable(final SimpleNode<T> node) {
137 return createMutableSimpleNode(
138 node.getNodeType(), node.getParent(), node.getValue(),
139 node.getModificationAction(), null);
145 * @return copy of given node, parent and children are the same, but parent and children
146 * have no reference to this copy
148 public static CompositeNode copyNode(final CompositeNode node, final Node<?>... children) {
149 CompositeNode twinNode = createImmutableCompositeNode(
150 node.getNodeType(), node.getParent(), Arrays.asList(children), node.getModificationAction());
156 * @return copy of given node, parent and children are the same, but parent and children
157 * have no reference to this copy
159 public static CompositeNode copyNode(final CompositeNode node) {
160 return copyNode(node, node.getValue().toArray(new Node<?>[0]));
164 * @param node root of original tree
165 * @param originalToCopyArg (optional) empty map, where binding between original and copy
167 * @return copy of given node and all subnodes recursively
169 public static MutableCompositeNode copyDeepAsMutable(final CompositeNode node,
170 final Map<Node<?>, Node<?>> originalToCopyArg) {
172 Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;
173 if (originalToCopy == null) {
174 originalToCopy = new HashMap<>();
177 MutableCompositeNode mutableRoot = createMutableCompositeNode(node.getNodeType(), null, null,
178 node.getModificationAction(), null);
179 final Deque<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new ArrayDeque<>();
180 jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));
181 originalToCopy.put(node, mutableRoot);
183 while (!jobQueue.isEmpty()) {
184 SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();
185 CompositeNode originalNode = job.getKey();
186 MutableCompositeNode mutableNode = job.getValue();
187 mutableNode.setValue(new ArrayList<Node<?>>());
189 for (Node<?> child : originalNode.getValue()) {
190 Node<?> mutableAscendant = null;
191 if (child instanceof CompositeNode) {
192 MutableCompositeNode newMutable =
193 createMutableCompositeNode(child.getNodeType(), mutableNode, null,
194 ((NodeModification) child).getModificationAction(), null);
195 jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(
196 (CompositeNode) child, newMutable));
197 mutableAscendant = newMutable;
198 } else if (child instanceof SimpleNode<?>) {
200 createMutableSimpleNode(child.getNodeType(), mutableNode,
202 ((NodeModification) child).getModificationAction(), null);
204 throw new IllegalStateException("Node class deep copy not supported: "
205 +child.getClass().getName());
208 mutableNode.getValue().add(mutableAscendant);
209 originalToCopy.put(child, mutableAscendant);
218 * @param node root of original tree
219 * @param originalToCopyArg (optional) empty map, where binding between original and copy
221 * @return copy of given node and all subnodes recursively
223 public static CompositeNode copyDeepAsImmutable(final CompositeNode node,
224 final Map<Node<?>, Node<?>> originalToCopyArg) {
225 final Deque<CompositeNode> jobQueue = new ArrayDeque<>();
228 Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;
229 if (originalToCopy == null) {
230 originalToCopy = new HashMap<>();
233 while (!jobQueue.isEmpty()) {
234 CompositeNode jobNode = jobQueue.peek();
235 if (!originalToCopy.isEmpty()
236 && originalToCopy.keySet().containsAll(jobNode.getValue())) {
238 List<Node<?>> newChildren = NodeUtils.collectMapValues(jobNode.getValue(), originalToCopy);
239 CompositeNode nodeCopy = createImmutableCompositeNode(jobNode.getNodeType(), null,
240 newChildren, jobNode.getModificationAction());
241 NodeUtils.fixChildrenRelation(nodeCopy);
242 originalToCopy.put(jobNode, nodeCopy);
244 for (Node<?> child : jobNode.getValue()) {
245 if (child instanceof SimpleNode<?>) {
246 originalToCopy.put(child, createImmutableSimpleNode(
247 child.getNodeType(), null, child.getValue(),
248 ((NodeModification) child).getModificationAction()));
249 } else if (child instanceof CompositeNode) {
250 jobQueue.push((CompositeNode) child);
256 return (CompositeNode) originalToCopy.get(node);