BUG-1472: deprecated CompositeNode and friends
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / NodeFactory.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.data.impl;
9
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;
17 import java.util.Map;
18
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;
28
29 /**
30  * @author michal.rehak
31  *
32  * @deprecated Use {@link Builders} instead.
33  */
34 @Deprecated
35 public abstract class NodeFactory {
36
37     /**
38      * @param qName
39      * @param parent
40      * @param value
41      * @return simple node modification, based on given qname, value and parent
42      */
43     public static <T> SimpleNode<T> createImmutableSimpleNode(final QName qName,
44             final CompositeNode parent, final T value) {
45         return createImmutableSimpleNode(qName, parent, value, null);
46     }
47
48     /**
49      * @param qName
50      * @param parent
51      * @param value
52      * @param modifyAction
53      * @param original originating node, if available
54      * @return simple node modification, based on given qname, value and parent
55      */
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;
62     }
63
64     /**
65      * @param qName
66      * @param parent
67      * @param value
68      * @return composite node modification, based on given qname, value (children), parent and modifyAction
69      */
70     public static CompositeNode createImmutableCompositeNode(final QName qName,
71             final CompositeNode parent, final List<Node<?>> value) {
72         return createImmutableCompositeNode(qName, parent, value, null);
73     }
74
75     /**
76      * @param qName
77      * @param parent
78      * @param valueArg
79      * @param modifyAction
80      * @param original originating node, if available
81      * @return composite node modification, based on given qName, value (children), parent and modifyAction
82      */
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;
86         if (value == null) {
87             value = new ArrayList<>();
88         }
89         MutableCompositeNodeTOImpl compositeNodeTOImpl =
90                 new MutableCompositeNodeTOImpl(qName, parent, value, modifyAction);
91         compositeNodeTOImpl.setOriginal(original);
92         return compositeNodeTOImpl;
93     }
94
95
96     /**
97      * @param qName
98      * @param parent
99      * @param value
100      * @param modifyAction
101      * @return simple node modification, based on given qname, value, parent and modifyAction
102      */
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;
108     }
109
110     /**
111      * @param qName
112      * @param parent
113      * @param value
114      * @param modifyAction
115      * @return composite node modification, based on given qname, value (children), parent and modifyAction
116      */
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);
120     }
121
122     /**
123      * @param node
124      * @return copy of given node, parent and value are the same, but parent
125      * has no reference to this copy
126      */
127     public static <T> SimpleNode<T> copyNode(final SimpleNode<T> node) {
128         return createImmutableSimpleNode(node.getNodeType(), node.getParent(), node.getValue());
129     }
130
131     /**
132      * @param node
133      * @return copy of given node, parent and value are the same, but parent
134      * has no reference to this copy
135      */
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);
140     }
141
142     /**
143      * @param node
144      * @param children
145      * @return copy of given node, parent and children are the same, but parent and children
146      * have no reference to this copy
147      */
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());
151         return twinNode;
152     }
153
154     /**
155      * @param node
156      * @return copy of given node, parent and children are the same, but parent and children
157      * have no reference to this copy
158      */
159     public static CompositeNode copyNode(final CompositeNode node) {
160         return copyNode(node, node.getValue().toArray(new Node<?>[0]));
161     }
162
163     /**
164      * @param node root of original tree
165      * @param originalToCopyArg (optional) empty map, where binding between original and copy
166      * will be stored
167      * @return copy of given node and all subnodes recursively
168      */
169     public static MutableCompositeNode copyDeepAsMutable(final CompositeNode node,
170             final Map<Node<?>, Node<?>> originalToCopyArg) {
171
172         Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;
173         if (originalToCopy == null) {
174             originalToCopy = new HashMap<>();
175         }
176
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);
182
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<?>>());
188
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<?>) {
199                     mutableAscendant =
200                             createMutableSimpleNode(child.getNodeType(), mutableNode,
201                                     child.getValue(),
202                                     ((NodeModification) child).getModificationAction(), null);
203                 } else {
204                     throw new IllegalStateException("Node class deep copy not supported: "
205                             +child.getClass().getName());
206                 }
207
208                 mutableNode.getValue().add(mutableAscendant);
209                 originalToCopy.put(child, mutableAscendant);
210             }
211             mutableNode.init();
212         }
213
214         return mutableRoot;
215     }
216
217     /**
218      * @param node root of original tree
219      * @param originalToCopyArg (optional) empty map, where binding between original and copy
220      * will be stored
221      * @return copy of given node and all subnodes recursively
222      */
223     public static CompositeNode copyDeepAsImmutable(final CompositeNode node,
224             final Map<Node<?>, Node<?>> originalToCopyArg) {
225         final Deque<CompositeNode> jobQueue = new ArrayDeque<>();
226         jobQueue.push(node);
227
228         Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;
229         if (originalToCopy == null) {
230             originalToCopy = new HashMap<>();
231         }
232
233         while (!jobQueue.isEmpty()) {
234             CompositeNode jobNode = jobQueue.peek();
235             if (!originalToCopy.isEmpty()
236                     && originalToCopy.keySet().containsAll(jobNode.getValue())) {
237                 jobQueue.pop();
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);
243             } else {
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);
251                     }
252                 }
253             }
254         }
255
256         return (CompositeNode) originalToCopy.get(node);
257     }
258
259 }