4b5d8dc5662cd15dedf5ee043eaa31ea5b586bef
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / util / CopyUtils.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.parser.util;
9
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.List;
13 import java.util.Set;
14
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
17 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
18 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
19 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
20 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
22 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
26 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
27 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
28 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
29 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
30 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
31 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
32 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
33 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
34 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
35 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
36 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
37 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
38 import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder;
39 import org.opendaylight.yangtools.yang.parser.builder.impl.AugmentationSchemaBuilderImpl;
40 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
41 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
42 import org.opendaylight.yangtools.yang.parser.builder.impl.ConstraintsBuilder;
43 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
44 import org.opendaylight.yangtools.yang.parser.builder.impl.GroupingBuilderImpl;
45 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder;
46 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
47 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
48 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder;
49 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
50 import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
51 import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
52 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
53 import org.opendaylight.yangtools.yang.parser.builder.impl.UsesNodeBuilderImpl;
54
55 public class CopyUtils {
56
57     /**
58      * Create copy of DataSchemaNodeBuilder with new parent. If updateQName is
59      * true, qname of node will be corrected based on new parent.
60      *
61      * @param old
62      * @param newParent
63      * @param updateQName
64      * @return
65      */
66     public static DataSchemaNodeBuilder copy(DataSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
67         if (old instanceof AnyXmlBuilder) {
68             return copy((AnyXmlBuilder) old, newParent, updateQName);
69         } else if (old instanceof ChoiceBuilder) {
70             return copy((ChoiceBuilder) old, newParent, updateQName);
71         } else if (old instanceof ContainerSchemaNodeBuilder) {
72             return copy((ContainerSchemaNodeBuilder) old, newParent, updateQName);
73         } else if (old instanceof LeafSchemaNodeBuilder) {
74             return copy((LeafSchemaNodeBuilder) old, newParent, updateQName);
75         } else if (old instanceof LeafListSchemaNodeBuilder) {
76             return copy((LeafListSchemaNodeBuilder) old, newParent, updateQName);
77         } else if (old instanceof ListSchemaNodeBuilder) {
78             return copy((ListSchemaNodeBuilder) old, newParent, updateQName);
79         } else if (old instanceof ChoiceCaseBuilder) {
80             return copy((ChoiceCaseBuilder) old, newParent, updateQName);
81         } else {
82             throw new YangParseException(old.getModuleName(), old.getLine(),
83                     "Failed to copy node: Unknown type of DataSchemaNode: " + old);
84         }
85     }
86
87     private static AnyXmlBuilder copy(AnyXmlBuilder old, Builder newParent, boolean updateQName) {
88         DataBean data = getdata(old, newParent, updateQName);
89         QName newQName = data.qname;
90         SchemaPath newSchemaPath = data.schemaPath;
91
92         AnyXmlBuilder copy = new AnyXmlBuilder(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
93         copyConstraints(copy.getConstraints(), old.getConstraints());
94         copy.setParent(newParent);
95         copy.setPath(newSchemaPath);
96         copy.setDescription(old.getDescription());
97         copy.setReference(old.getReference());
98         copy.setStatus(old.getStatus());
99         copy.setAugmenting(old.isAugmenting());
100         copy.setAddedByUses(old.isAddedByUses());
101         copy.setConfiguration(old.isConfiguration());
102         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
103             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
104         }
105
106         return copy;
107     }
108
109     private static ChoiceBuilder copy(ChoiceBuilder old, Builder newParent, boolean updateQName) {
110         DataBean data = getdata(old, newParent, updateQName);
111         QName newQName = data.qname;
112         SchemaPath newSchemaPath = data.schemaPath;
113
114         ChoiceBuilder copy = new ChoiceBuilder(newParent.getModuleName(), newParent.getLine(), newQName);
115         copyConstraints(copy.getConstraints(), old.getConstraints());
116         copy.setParent(newParent);
117         copy.setPath(newSchemaPath);
118         copy.setDescription(old.getDescription());
119         copy.setReference(old.getReference());
120         copy.setStatus(old.getStatus());
121         copy.setAugmenting(old.isAugmenting());
122         copy.setAddedByUses(old.isAddedByUses());
123         copy.setConfiguration(old.isConfiguration());
124         for (ChoiceCaseBuilder childNode : old.getCases()) {
125             copy.addCase(copy(childNode, copy, updateQName));
126         }
127         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
128             copy.addAugmentation(copyAugment(augment, copy));
129         }
130         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
131             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
132         }
133
134         return copy;
135     }
136
137     private static ChoiceCaseBuilder copy(ChoiceCaseBuilder old, Builder newParent, boolean updateQName) {
138         DataBean data = getdata(old, newParent, updateQName);
139         QName newQName = data.qname;
140         SchemaPath newSchemaPath = data.schemaPath;
141
142         ChoiceCaseBuilder copy = new ChoiceCaseBuilder(newParent.getModuleName(), newParent.getLine(), newQName);
143         copyConstraints(copy.getConstraints(), old.getConstraints());
144         copy.setParent(newParent);
145         copy.setPath(newSchemaPath);
146         copy.setDescription(old.getDescription());
147         copy.setReference(old.getReference());
148         copy.setStatus(old.getStatus());
149         copy.setAugmenting(old.isAugmenting());
150         copy.getChildNodes().addAll(old.getChildNodes());
151         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
152             copy.addChildNode(copy(childNode, copy, updateQName));
153         }
154         copy.getGroupings().addAll(old.getGroupings());
155         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
156             copy.addGrouping(copy(grouping, copy, updateQName));
157         }
158         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
159             copy.addTypedef(copy(tdb, copy, updateQName));
160         }
161         for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
162             copy.addUsesNode(copyUses(oldUses, copy));
163         }
164         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
165             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
166         }
167
168         return copy;
169     }
170
171     private static ContainerSchemaNodeBuilder copy(ContainerSchemaNodeBuilder old, Builder newParent,
172             boolean updateQName) {
173         DataBean data = getdata(old, newParent, updateQName);
174         QName newQName = data.qname;
175         SchemaPath newSchemaPath = data.schemaPath;
176
177         ContainerSchemaNodeBuilder copy = new ContainerSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
178                 newQName, newSchemaPath);
179         copyConstraints(copy.getConstraints(), old.getConstraints());
180         copy.setParent(newParent);
181         copy.setPath(newSchemaPath);
182         copy.setDescription(old.getDescription());
183         copy.setReference(old.getReference());
184         copy.setStatus(old.getStatus());
185         copy.setPresence(old.isPresence());
186         copy.setAugmenting(old.isAugmenting());
187         copy.setAddedByUses(old.isAddedByUses());
188         copy.setConfiguration(old.isConfiguration());
189         copy.setChildNodes(old.getChildNodes());
190         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
191             copy.addChildNode(copy(childNode, copy, updateQName));
192         }
193         copy.getGroupings().addAll(old.getGroupings());
194         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
195             copy.addGrouping(copy(grouping, copy, updateQName));
196         }
197         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
198             copy.addTypedef(copy(tdb, copy, updateQName));
199         }
200         for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
201             copy.addUsesNode(copyUses(oldUses, copy));
202         }
203         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
204             copy.addAugmentation(copyAugment(augment, copy));
205         }
206         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
207             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
208         }
209
210         return copy;
211     }
212
213     private static LeafSchemaNodeBuilder copy(LeafSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
214         DataBean data = getdata(old, newParent, updateQName);
215         QName newQName = data.qname;
216         SchemaPath newSchemaPath = data.schemaPath;
217
218         LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(), newQName,
219                 newSchemaPath);
220         copyConstraints(copy.getConstraints(), old.getConstraints());
221         copy.setParent(newParent);
222         copy.setPath(newSchemaPath);
223         copy.setDescription(old.getDescription());
224         copy.setReference(old.getReference());
225         copy.setStatus(old.getStatus());
226         copy.setAugmenting(old.isAugmenting());
227         copy.setAddedByUses(old.isAddedByUses());
228         copy.setConfiguration(old.isConfiguration());
229         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
230             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
231         }
232
233         if (old.getType() == null) {
234             copy.setTypedef(copy(old.getTypedef(), copy, updateQName));
235         } else {
236             copy.setType(ParserUtils.createCorrectTypeDefinition(copy.getPath(), old.getType()));
237         }
238
239         copy.setDefaultStr(old.getDefaultStr());
240         copy.setUnits(old.getUnits());
241
242         return copy;
243     }
244
245     public static LeafListSchemaNodeBuilder copy(LeafListSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
246         DataBean data = getdata(old, newParent, updateQName);
247         QName newQName = data.qname;
248         SchemaPath newSchemaPath = data.schemaPath;
249
250         LeafListSchemaNodeBuilder copy = new LeafListSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
251                 newQName, newSchemaPath);
252         copyConstraints(copy.getConstraints(), old.getConstraints());
253         copy.setParent(newParent);
254         copy.setPath(newSchemaPath);
255         copy.setDescription(old.getDescription());
256         copy.setReference(old.getReference());
257         copy.setStatus(old.getStatus());
258         copy.setAugmenting(old.isAugmenting());
259         copy.setAddedByUses(old.isAddedByUses());
260         copy.setConfiguration(old.isConfiguration());
261         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
262             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
263         }
264
265         if (old.getType() == null) {
266             copy.setTypedef(copy(old.getTypedef(), copy, updateQName));
267         } else {
268             copy.setType(ParserUtils.createCorrectTypeDefinition(copy.getPath(), old.getType()));
269         }
270
271         copy.setUserOrdered(old.isUserOrdered());
272
273         return copy;
274     }
275
276     private static ListSchemaNodeBuilder copy(ListSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
277         DataBean data = getdata(old, newParent, updateQName);
278         QName newQName = data.qname;
279         SchemaPath newSchemaPath = data.schemaPath;
280
281         ListSchemaNodeBuilder copy = new ListSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(), newQName,
282                 newSchemaPath);
283         copyConstraints(copy.getConstraints(), old.getConstraints());
284         copy.setParent(newParent);
285         copy.setPath(newSchemaPath);
286         copy.setDescription(old.getDescription());
287         copy.setReference(old.getReference());
288         copy.setStatus(old.getStatus());
289         copy.setAugmenting(old.isAugmenting());
290         copy.setAddedByUses(old.isAddedByUses());
291         copy.setConfiguration(old.isConfiguration());
292         copy.setChildNodes(old.getChildNodes());
293         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
294             copy.addChildNode(copy(childNode, copy, updateQName));
295         }
296         copy.getGroupings().addAll(old.getGroupings());
297         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
298             copy.addGrouping(copy(grouping, copy, updateQName));
299         }
300         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
301             copy.addTypedef(copy(tdb, copy, updateQName));
302         }
303         for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
304             copy.addUsesNode(copyUses(oldUses, copy));
305         }
306         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
307             copy.addAugmentation(copyAugment(augment, copy));
308         }
309         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
310             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
311         }
312
313         copy.setUserOrdered(old.isUserOrdered());
314         copy.setKeyDefinition(old.getKeyDefinition());
315
316         return copy;
317     }
318
319     public static GroupingBuilder copy(GroupingBuilder old, Builder newParent, boolean updateQName) {
320         DataBean data = getdata(old, newParent, updateQName);
321         QName newQName = data.qname;
322         SchemaPath newSchemaPath = data.schemaPath;
323
324         GroupingBuilderImpl copy = new GroupingBuilderImpl(newParent.getModuleName(), newParent.getLine(), newQName);
325         copy.setParent(newParent);
326         copy.setPath(newSchemaPath);
327         copy.setDescription(old.getDescription());
328         copy.setReference(old.getReference());
329         copy.setStatus(old.getStatus());
330         copy.setAddedByUses(old.isAddedByUses());
331         copy.setChildNodes(old.getChildNodes());
332         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
333             copy.addChildNode(copy(childNode, copy, updateQName));
334         }
335         copy.getGroupings().addAll(old.getGroupings());
336         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
337             copy.addGrouping(copy(grouping, copy, updateQName));
338         }
339         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
340             copy.addTypedef(copy(tdb, copy, updateQName));
341         }
342         for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
343             copy.addUsesNode(copyUses(oldUses, copy));
344         }
345         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
346             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
347         }
348
349         return copy;
350     }
351
352     public static GroupingBuilder copyGroupingWithoutDeep(GroupingBuilder old, Builder newParent, boolean updateQName) {
353         DataBean data = getdata(old, newParent, updateQName);
354         QName newQName = data.qname;
355         SchemaPath newSchemaPath = data.schemaPath;
356
357         GroupingBuilderImpl copy = new GroupingBuilderImpl(newParent.getModuleName(), newParent.getLine(), newQName);
358         copy.setParent(newParent);
359         copy.setPath(newSchemaPath);
360         copy.setDescription(old.getDescription());
361         copy.setReference(old.getReference());
362         copy.setStatus(old.getStatus());
363         copy.setAddedByUses(old.isAddedByUses());
364         copy.setChildNodes(old.getChildNodes());
365         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
366             copy.addChildNode(copy(childNode, copy, updateQName));
367         }
368         copy.getGroupings().addAll(old.getGroupings());
369         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
370             copy.addGrouping(copy(grouping, copy, updateQName));
371         }
372         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
373             copy.addTypedef(copy(tdb, copy, updateQName));
374         }
375         for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
376             copy.addUsesNode(copyUses(oldUses, copy));
377
378         }
379         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
380             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
381         }
382
383         return copy;
384     }
385
386     public static TypeDefinitionBuilder copy(TypeDefinitionBuilder old, Builder newParent, boolean updateQName) {
387         DataBean data = getdata(old, newParent, updateQName);
388         QName newQName = data.qname;
389         SchemaPath newSchemaPath = data.schemaPath;
390         TypeDefinitionBuilder type = null;
391
392         if (old instanceof UnionTypeBuilder) {
393             UnionTypeBuilder oldUnion = (UnionTypeBuilder)old;
394             type = new UnionTypeBuilder(newParent.getModuleName(), newParent.getLine());
395             type.setParent(newParent);
396             type.setPath(newSchemaPath);
397             for(TypeDefinition<?> td : oldUnion.getTypes()) {
398                 type.setType(ParserUtils.createCorrectTypeDefinition(type.getPath(), td));
399             }
400             for(TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
401                 type.setTypedef(copy(tdb, type, updateQName));
402             }
403         } else if (old instanceof IdentityrefTypeBuilder) {
404             type = new IdentityrefTypeBuilder(newParent.getModuleName(), newParent.getLine(),
405                     ((IdentityrefTypeBuilder) old).getBaseString(), newSchemaPath);
406             type.setParent(newParent);
407             type.setPath(newSchemaPath);
408         } else {
409             type = new TypeDefinitionBuilderImpl(old.getModuleName(), newParent.getLine(), newQName);
410             type.setParent(newParent);
411             type.setPath(newSchemaPath);
412
413             if (old.getType() == null) {
414                 type.setTypedef(copy(old.getTypedef(), type, updateQName));
415             } else {
416                 type.setType(ParserUtils.createCorrectTypeDefinition(type.getPath(), old.getType()));
417             }
418
419             for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
420                 type.addUnknownNodeBuilder((copy(un, type, updateQName)));
421             }
422
423             type.setRanges(old.getRanges());
424             type.setLengths(old.getLengths());
425             type.setPatterns(old.getPatterns());
426             type.setFractionDigits(old.getFractionDigits());
427             type.setDescription(old.getDescription());
428             type.setReference(old.getReference());
429             type.setStatus(old.getStatus());
430             type.setUnits(old.getUnits());
431             type.setDefaultValue(old.getDefaultValue());
432             type.setAddedByUses(old.isAddedByUses());
433         }
434
435         return type;
436     }
437
438     private static ConstraintsBuilder copyConstraints(ConstraintsBuilder newConstraints, ConstraintsBuilder old) {
439         newConstraints.getMustDefinitions().addAll(old.getMustDefinitions());
440         newConstraints.addWhenCondition(old.getWhenCondition());
441         newConstraints.setMandatory(old.isMandatory());
442         newConstraints.setMinElements(old.getMinElements());
443         newConstraints.setMaxElements(old.getMaxElements());
444         return newConstraints;
445     }
446
447     static UsesNodeBuilder copyUses(UsesNodeBuilder old, Builder newParent) {
448         UsesNodeBuilder copy = new UsesNodeBuilderImpl(newParent.getModuleName(), newParent.getLine(),
449                 old.getGroupingName());
450         copy.setParent(newParent);
451         copy.setGroupingPath(old.getGroupingPath());
452         // TODO grouping vs grouping path?
453         copy.setGrouping(old.getGroupingBuilder());
454         copy.setAugmenting(old.isAugmenting());
455         copy.setAddedByUses(old.isAddedByUses());
456         copy.getAugmentations().addAll(old.getAugmentations());
457         copy.getRefineNodes().addAll(old.getRefineNodes());
458         copy.getRefines().addAll(old.getRefines());
459
460         copy.setTargetChildren(old.getTargetChildren());
461         copy.setTargetTypedefs(old.getTargetTypedefs());
462         copy.setTargetGroupings(old.getTargetGroupings());
463         copy.setTargetUnknownNodes(old.getTargetUnknownNodes());
464
465         // add new uses to collection of uses in module
466         ModuleBuilder module = ParserUtils.getParentModule(newParent);
467         module.addUsesNode(copy);
468
469         return copy;
470     }
471
472     private static AugmentationSchemaBuilder copyAugment(AugmentationSchemaBuilder old, Builder newParent) {
473         AugmentationSchemaBuilderImpl copy = new AugmentationSchemaBuilderImpl(newParent.getModuleName(),
474                 newParent.getLine(), old.getTargetPathAsString());
475         copy.setParent(newParent);
476
477         copy.setDescription(old.getDescription());
478         copy.setReference(old.getReference());
479         copy.setStatus(old.getStatus());
480         copy.addWhenCondition(old.getWhenCondition());
481         copy.setChildNodes(old.getChildNodes());
482         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
483             copy.addChildNode(copy(childNode, copy, false));
484         }
485         for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
486             copy.addUsesNode(copyUses(oldUses, copy));
487         }
488         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
489             copy.addUnknownNodeBuilder((copy(un, copy, false)));
490         }
491
492         return copy;
493     }
494
495     static UnknownSchemaNodeBuilder copy(UnknownSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
496         DataBean data = getdata(old, newParent, updateQName);
497         QName newQName = data.qname;
498         SchemaPath newSchemaPath = data.schemaPath;
499
500         UnknownSchemaNodeBuilder c = new UnknownSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
501                 newQName);
502
503         c.setParent(newParent);
504         c.setPath(newSchemaPath);
505         c.setDescription(old.getDescription());
506         c.setReference(old.getReference());
507         c.setStatus(old.getStatus());
508         c.setAddedByUses(old.isAddedByUses());
509         for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
510             c.addUnknownNodeBuilder((copy(un, c, updateQName)));
511         }
512
513         return c;
514     }
515
516     private static DataBean getdata(SchemaNodeBuilder old, Builder newParent, boolean updateQName) {
517         List<QName> newPath = null;
518         QName newQName = null;
519         if (newParent instanceof ModuleBuilder) {
520             ModuleBuilder parent = (ModuleBuilder) newParent;
521             if (updateQName) {
522                 newQName = new QName(parent.getNamespace(), parent.getRevision(), parent.getPrefix(), old.getQName()
523                         .getLocalName());
524                 newPath = Collections.singletonList(newQName);
525             } else {
526                 newQName = old.getQName();
527                 newPath = Collections.singletonList(newQName);
528             }
529         } else if (newParent instanceof AugmentationSchemaBuilder) {
530             ModuleBuilder parent = ParserUtils.getParentModule(newParent);
531             if (updateQName) {
532                 newQName = new QName(parent.getNamespace(), parent.getRevision(), parent.getPrefix(), old.getQName()
533                         .getLocalName());
534                 newPath = Collections.singletonList(newQName);
535             } else {
536                 newQName = old.getQName();
537                 newPath = Collections.singletonList(newQName);
538             }
539
540         } else if (newParent instanceof SchemaNodeBuilder) {
541             SchemaNodeBuilder parent = (SchemaNodeBuilder) newParent;
542             QName parentQName = parent.getQName();
543             if (updateQName) {
544                 newQName = new QName(parentQName.getNamespace(), parentQName.getRevision(), parentQName.getPrefix(),
545                         old.getQName().getLocalName());
546                 newPath = new ArrayList<>(parent.getPath().getPath());
547                 newPath.add(newQName);
548             } else {
549                 if(old == null) {
550                     System.out.println();
551                 }
552                 newQName = old.getQName();
553                 newPath = new ArrayList<>(parent.getPath().getPath());
554                 newPath.add(newQName);
555             }
556         }
557
558         SchemaPath newSchemaPath = new SchemaPath(newPath, true);
559         return new DataBean(newQName, newSchemaPath);
560     }
561
562     private static class DataBean {
563         private QName qname;
564         private SchemaPath schemaPath;
565
566         private DataBean(QName qname, SchemaPath schemaPath) {
567             this.qname = qname;
568             this.schemaPath = schemaPath;
569         }
570     }
571
572
573     /**
574      * Create AnyXmlBuilder from given AnyXmlSchemaNode.
575      *
576      * @param anyxml
577      * @param qname
578      * @param moduleName
579      *            current module name
580      * @param line
581      *            current line in module
582      * @return anyxml builder based on given anyxml node
583      */
584     public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, QName qname, String moduleName, int line) {
585         final AnyXmlBuilder builder = new AnyXmlBuilder(moduleName, line, qname, anyxml.getPath());
586         convertDataSchemaNode(anyxml, builder);
587         builder.setConfiguration(anyxml.isConfiguration());
588         builder.setUnknownNodes(anyxml.getUnknownSchemaNodes());
589         return builder;
590     }
591
592     /**
593      * Create GroupingBuilder from given GroupingDefinition.
594      *
595      * @param grouping
596      * @param qname
597      * @param moduleName
598      *            current module name
599      * @param line
600      *            current line in module
601      * @return grouping builder based on given grouping node
602      */
603     public static GroupingBuilder createGrouping(GroupingDefinition grouping, QName qname, String moduleName, int line) {
604         final GroupingBuilderImpl builder = new GroupingBuilderImpl(moduleName, line, qname);
605         builder.setPath(grouping.getPath());
606         builder.setChildNodes(grouping.getChildNodes());
607         builder.setGroupings(grouping.getGroupings());
608         builder.setTypedefs(grouping.getTypeDefinitions());
609         builder.setUsesnodes(grouping.getUses());
610         builder.setUnknownNodes(grouping.getUnknownSchemaNodes());
611         builder.setDescription(grouping.getDescription());
612         builder.setReference(grouping.getReference());
613         builder.setStatus(grouping.getStatus());
614         return builder;
615     }
616
617     /**
618      * Create TypeDefinitionBuilder from given ExtendedType.
619      *
620      * @param typedef
621      * @param qname
622      * @param moduleName
623      *            current module name
624      * @param line
625      *            current line in module
626      * @return typedef builder based on given typedef node
627      */
628     public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, QName qname, String moduleName, int line) {
629         final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(moduleName, line, qname);
630         builder.setPath(typedef.getPath());
631         builder.setDefaultValue(typedef.getDefaultValue());
632         builder.setUnits(typedef.getUnits());
633         builder.setDescription(typedef.getDescription());
634         builder.setReference(typedef.getReference());
635         builder.setStatus(typedef.getStatus());
636         builder.setRanges(typedef.getRanges());
637         builder.setLengths(typedef.getLengths());
638         builder.setPatterns(typedef.getPatterns());
639         builder.setFractionDigits(typedef.getFractionDigits());
640         final TypeDefinition<?> type = typedef.getBaseType();
641         builder.setType(type);
642         builder.setUnits(typedef.getUnits());
643         builder.setUnknownNodes(typedef.getUnknownSchemaNodes());
644         return builder;
645     }
646
647     /**
648      * Create UnknownSchemaNodeBuilder from given UnknownSchemaNode.
649      *
650      * @param unknownNode
651      * @param qname
652      * @param moduleName
653      *            current module name
654      * @param line
655      *            current line in module
656      * @return unknown node builder based on given unknown node
657      */
658     public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, QName qname,
659             String moduleName, int line) {
660         final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(moduleName, line, qname);
661         builder.setPath(unknownNode.getPath());
662         builder.setUnknownNodes(unknownNode.getUnknownSchemaNodes());
663         builder.setDescription(unknownNode.getDescription());
664         builder.setReference(unknownNode.getReference());
665         builder.setStatus(unknownNode.getStatus());
666         builder.setAddedByUses(unknownNode.isAddedByUses());
667         builder.setNodeType(unknownNode.getNodeType());
668         builder.setNodeParameter(unknownNode.getNodeParameter());
669         return builder;
670     }
671
672
673     /**
674      * Create LeafSchemaNodeBuilder from given LeafSchemaNode.
675      *
676      * @param leaf
677      *            leaf from which to create builder
678      * @param qname
679      * @param moduleName
680      *            current module name
681      * @param line
682      *            line in module
683      * @return leaf builder based on given leaf node
684      */
685     public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, QName qname, String moduleName, int line) {
686         final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(moduleName, line, qname, leaf.getPath());
687         convertDataSchemaNode(leaf, builder);
688         builder.setConfiguration(leaf.isConfiguration());
689         final TypeDefinition<?> type = leaf.getType();
690         builder.setType(type);
691         builder.setPath(leaf.getPath());
692         builder.setUnknownNodes(leaf.getUnknownSchemaNodes());
693         builder.setDefaultStr(leaf.getDefault());
694         builder.setUnits(leaf.getUnits());
695         return builder;
696     }
697
698     /**
699      * Create ContainerSchemaNodeBuilder from given ContainerSchemaNode.
700      *
701      * @param container
702      * @param qname
703      * @param moduleName
704      *            current module name
705      * @param line
706      *            current line in module
707      * @return container builder based on given container node
708      */
709     public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, QName qname,
710             String moduleName, int line) {
711         final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(moduleName, line, qname,
712                 container.getPath());
713         convertDataSchemaNode(container, builder);
714         builder.setConfiguration(container.isConfiguration());
715         builder.setUnknownNodes(container.getUnknownSchemaNodes());
716         builder.setChildNodes(container.getChildNodes());
717         builder.setGroupings(container.getGroupings());
718         builder.setTypedefs(container.getTypeDefinitions());
719         builder.setAugmentations(container.getAvailableAugmentations());
720         builder.setUsesnodes(container.getUses());
721         builder.setPresence(container.isPresenceContainer());
722         return builder;
723     }
724
725     /**
726      * Create ListSchemaNodeBuilder from given ListSchemaNode.
727      *
728      * @param list
729      * @param qname
730      * @param moduleName
731      *            current module name
732      * @param line
733      *            current line in module
734      * @return list builder based on given list node
735      */
736     public static ListSchemaNodeBuilder createList(ListSchemaNode list, QName qname, String moduleName, int line) {
737         ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(moduleName, line, qname, list.getPath());
738         convertDataSchemaNode(list, builder);
739         builder.setConfiguration(list.isConfiguration());
740         builder.setUnknownNodes(list.getUnknownSchemaNodes());
741         builder.setTypedefs(list.getTypeDefinitions());
742         builder.setChildNodes(list.getChildNodes());
743         builder.setGroupings(list.getGroupings());
744         builder.setAugmentations(list.getAvailableAugmentations());
745         builder.setUsesnodes(list.getUses());
746         builder.setUserOrdered(builder.isUserOrdered());
747         return builder;
748     }
749
750     /**
751      * Create LeafListSchemaNodeBuilder from given LeafListSchemaNode.
752      *
753      * @param leafList
754      * @param qname
755      * @param moduleName
756      *            current module name
757      * @param line
758      *            current line in module
759      * @return leaf-list builder based on given leaf-list node
760      */
761     public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, QName qname, String moduleName,
762             int line) {
763         final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(moduleName, line, qname,
764                 leafList.getPath());
765         convertDataSchemaNode(leafList, builder);
766         builder.setConfiguration(leafList.isConfiguration());
767         builder.setType(leafList.getType());
768         builder.setUnknownNodes(leafList.getUnknownSchemaNodes());
769         builder.setUserOrdered(leafList.isUserOrdered());
770         return builder;
771     }
772
773     /**
774      * Create ChoiceBuilder from given ChoiceNode.
775      *
776      * @param choice
777      * @param qname
778      * @param moduleName
779      *            current module name
780      * @param line
781      *            current line in module
782      * @return choice builder based on given choice node
783      */
784     public static ChoiceBuilder createChoice(ChoiceNode choice, QName qname, String moduleName, int line) {
785         final ChoiceBuilder builder = new ChoiceBuilder(moduleName, line, qname);
786         convertDataSchemaNode(choice, builder);
787         builder.setConfiguration(choice.isConfiguration());
788         builder.setCases(choice.getCases());
789         builder.setUnknownNodes(choice.getUnknownSchemaNodes());
790         builder.setDefaultCase(choice.getDefaultCase());
791         return builder;
792     }
793
794
795     /**
796      * Set DataSchemaNode arguments to builder object
797      *
798      * @param node
799      *            node from which arguments should be read
800      * @param builder
801      *            builder to which arguments should be set
802      */
803     private static void convertDataSchemaNode(DataSchemaNode node, DataSchemaNodeBuilder builder) {
804         builder.setPath(node.getPath());
805         builder.setDescription(node.getDescription());
806         builder.setReference(node.getReference());
807         builder.setStatus(node.getStatus());
808         builder.setAugmenting(node.isAugmenting());
809         copyConstraintsFromDefinition(node.getConstraints(), builder.getConstraints());
810     }
811
812     /**
813      * Copy constraints from constraints definition to constraints builder.
814      *
815      * @param nodeConstraints
816      *            definition from which constraints will be copied
817      * @param constraints
818      *            builder to which constraints will be added
819      */
820     private static void copyConstraintsFromDefinition(final ConstraintDefinition nodeConstraints,
821             final ConstraintsBuilder constraints) {
822         final RevisionAwareXPath when = nodeConstraints.getWhenCondition();
823         final Set<MustDefinition> must = nodeConstraints.getMustConstraints();
824
825         if (when != null) {
826             constraints.addWhenCondition(when.toString());
827         }
828         if (must != null) {
829             for (MustDefinition md : must) {
830                 constraints.addMustDefinition(md);
831             }
832         }
833         constraints.setMandatory(nodeConstraints.isMandatory());
834         constraints.setMinElements(nodeConstraints.getMinElements());
835         constraints.setMaxElements(nodeConstraints.getMaxElements());
836     }
837
838 }