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