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