BUG 1131: untangling package cyclic dependencies in yang-parser-impl
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / 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.builder.impl;
9
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.List;
13
14 import org.opendaylight.yangtools.yang.common.QName;
15 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
16 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
17 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
18 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
19 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
20 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
21 import org.opendaylight.yangtools.yang.parser.builder.api.ConstraintsBuilder;
22 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
23 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
24 import org.opendaylight.yangtools.yang.parser.builder.api.UnknownSchemaNodeBuilder;
25 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
26 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
27
28 public final class CopyUtils {
29
30     private CopyUtils() {
31     }
32
33     /**
34      * Create copy of DataSchemaNodeBuilder with new parent. If updateQName is
35      * true, qname of node will be corrected based on new parent.
36      *
37      * @param old
38      *            builder to copy
39      * @param newParent
40      *            new parent
41      * @param updateQName
42      *            flag to indicate if qname should be updated based on new
43      *            parent location
44      * @return copy of given builder
45      */
46     public static DataSchemaNodeBuilder copy(final DataSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
47         if (old instanceof AnyXmlBuilder) {
48             return copy((AnyXmlBuilder) old, newParent, updateQName);
49         } else if (old instanceof ChoiceBuilder) {
50             return copy((ChoiceBuilder) old, newParent, updateQName);
51         } else if (old instanceof ContainerSchemaNodeBuilder) {
52             return copy((ContainerSchemaNodeBuilder) old, newParent, updateQName);
53         } else if (old instanceof LeafSchemaNodeBuilder) {
54             return copy((LeafSchemaNodeBuilder) old, newParent, updateQName);
55         } else if (old instanceof LeafListSchemaNodeBuilder) {
56             return copy((LeafListSchemaNodeBuilder) old, newParent, updateQName);
57         } else if (old instanceof ListSchemaNodeBuilder) {
58             return copy((ListSchemaNodeBuilder) old, newParent, updateQName);
59         } else if (old instanceof ChoiceCaseBuilder) {
60             return copy((ChoiceCaseBuilder) old, newParent, updateQName);
61         } else {
62             throw new YangParseException(old.getModuleName(), old.getLine(),
63                     "Failed to copy node: Unknown type of DataSchemaNode: " + old);
64         }
65     }
66
67     private static AnyXmlBuilder copy(final AnyXmlBuilder old, final Builder newParent, final boolean updateQName) {
68         DataBean data = getdata(old, newParent, updateQName);
69         QName newQName = data.qname;
70         SchemaPath newSchemaPath = data.schemaPath;
71
72         AnyXmlBuilder copy = new AnyXmlBuilder(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
73         copyConstraints(copy.getConstraints(), old.getConstraints());
74         copy.setParent(newParent);
75         copy.setDescription(old.getDescription());
76         copy.setReference(old.getReference());
77         copy.setStatus(old.getStatus());
78         copy.setAugmenting(old.isAugmenting());
79         copy.setAddedByUses(old.isAddedByUses());
80         copy.setConfiguration(old.isConfiguration());
81         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
82             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
83         }
84
85         return copy;
86     }
87
88     private static ChoiceBuilder copy(final ChoiceBuilder old, final Builder newParent, final boolean updateQName) {
89         DataBean data = getdata(old, newParent, updateQName);
90         QName newQName = data.qname;
91         SchemaPath newSchemaPath = data.schemaPath;
92
93         ChoiceBuilder copy = new ChoiceBuilder(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
94         copyConstraints(copy.getConstraints(), old.getConstraints());
95         copy.setParent(newParent);
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 (ChoiceCaseBuilder childNode : old.getCases()) {
103             copy.addCase(copy(childNode, copy, updateQName));
104         }
105         for (AugmentationSchemaBuilder augment : old.getAugmentationBuilders()) {
106             copy.addAugmentation(copyAugment(augment, copy));
107         }
108         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
109             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
110         }
111
112         return copy;
113     }
114
115     private static ChoiceCaseBuilder copy(final ChoiceCaseBuilder old, final Builder newParent, final boolean updateQName) {
116         DataBean data = getdata(old, newParent, updateQName);
117         QName newQName = data.qname;
118         SchemaPath newSchemaPath = data.schemaPath;
119
120         ChoiceCaseBuilder copy = new ChoiceCaseBuilder(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
121         copyConstraints(copy.getConstraints(), old.getConstraints());
122         copy.setParent(newParent);
123         copy.setDescription(old.getDescription());
124         copy.setReference(old.getReference());
125         copy.setStatus(old.getStatus());
126         copy.setAugmenting(old.isAugmenting());
127         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
128             copy.addChildNode(copy(childNode, copy, updateQName));
129         }
130         copy.getGroupings().addAll(old.getGroupings());
131         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
132             copy.addGrouping(copy(grouping, copy, updateQName));
133         }
134         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
135             copy.addTypedef(copy(tdb, copy, updateQName));
136         }
137         for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
138             copy.addUsesNode(copyUses(oldUses, copy));
139         }
140         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
141             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
142         }
143
144         return copy;
145     }
146
147     private static ContainerSchemaNodeBuilder copy(final ContainerSchemaNodeBuilder old, final Builder newParent,
148             final boolean updateQName) {
149         DataBean data = getdata(old, newParent, updateQName);
150         QName newQName = data.qname;
151         SchemaPath newSchemaPath = data.schemaPath;
152
153         ContainerSchemaNodeBuilder copy = new ContainerSchemaNodeBuilder(newParent.getModuleName(),
154                 newParent.getLine(), newQName, newSchemaPath);
155         copyConstraints(copy.getConstraints(), old.getConstraints());
156         copy.setParent(newParent);
157         copy.setDescription(old.getDescription());
158         copy.setReference(old.getReference());
159         copy.setStatus(old.getStatus());
160         copy.setPresence(old.isPresence());
161         copy.setAugmenting(old.isAugmenting());
162         copy.setAddedByUses(old.isAddedByUses());
163         copy.setConfiguration(old.isConfiguration());
164         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
165             copy.addChildNode(copy(childNode, copy, updateQName));
166         }
167         copy.getGroupings().addAll(old.getGroupings());
168         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
169             copy.addGrouping(copy(grouping, copy, updateQName));
170         }
171         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
172             copy.addTypedef(copy(tdb, copy, updateQName));
173         }
174         for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
175             copy.addUsesNode(copyUses(oldUses, copy));
176         }
177         for (AugmentationSchemaBuilder augment : old.getAugmentationBuilders()) {
178             copy.addAugmentation(copyAugment(augment, copy));
179         }
180         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
181             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
182         }
183
184         return copy;
185     }
186
187     private static LeafSchemaNodeBuilder copy(final LeafSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
188         DataBean data = getdata(old, newParent, updateQName);
189         QName newQName = data.qname;
190         SchemaPath newSchemaPath = data.schemaPath;
191
192         LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
193                 newQName, newSchemaPath);
194         copyConstraints(copy.getConstraints(), old.getConstraints());
195         copy.setParent(newParent);
196         copy.setDescription(old.getDescription());
197         copy.setReference(old.getReference());
198         copy.setStatus(old.getStatus());
199         copy.setAugmenting(old.isAugmenting());
200         copy.setAddedByUses(old.isAddedByUses());
201         copy.setConfiguration(old.isConfiguration());
202         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
203             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
204         }
205
206         if (old.getType() == null) {
207             copy.setTypedef(copy(old.getTypedef(), copy, updateQName));
208         } else {
209             copy.setType(old.getType());
210         }
211
212         copy.setDefaultStr(old.getDefaultStr());
213         copy.setUnits(old.getUnits());
214
215         return copy;
216     }
217
218     public static LeafListSchemaNodeBuilder copy(final LeafListSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
219         DataBean data = getdata(old, newParent, updateQName);
220         QName newQName = data.qname;
221         SchemaPath newSchemaPath = data.schemaPath;
222
223         LeafListSchemaNodeBuilder copy = new LeafListSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
224                 newQName, newSchemaPath);
225         copyConstraints(copy.getConstraints(), old.getConstraints());
226         copy.setParent(newParent);
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.getUnknownNodes()) {
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.setUserOrdered(old.isUserOrdered());
244
245         return copy;
246     }
247
248     private static ListSchemaNodeBuilder copy(final ListSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
249         DataBean data = getdata(old, newParent, updateQName);
250         QName newQName = data.qname;
251         SchemaPath newSchemaPath = data.schemaPath;
252
253         ListSchemaNodeBuilder copy = new ListSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
254                 newQName, newSchemaPath);
255         copyConstraints(copy.getConstraints(), old.getConstraints());
256         copy.setParent(newParent);
257         copy.setDescription(old.getDescription());
258         copy.setReference(old.getReference());
259         copy.setStatus(old.getStatus());
260         copy.setAugmenting(old.isAugmenting());
261         copy.setAddedByUses(old.isAddedByUses());
262         copy.setConfiguration(old.isConfiguration());
263         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
264             copy.addChildNode(copy(childNode, copy, updateQName));
265         }
266         copy.getGroupings().addAll(old.getGroupings());
267         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
268             copy.addGrouping(copy(grouping, copy, updateQName));
269         }
270         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
271             copy.addTypedef(copy(tdb, copy, updateQName));
272         }
273         for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
274             copy.addUsesNode(copyUses(oldUses, copy));
275         }
276         for (AugmentationSchemaBuilder augment : old.getAugmentationBuilders()) {
277             copy.addAugmentation(copyAugment(augment, copy));
278         }
279         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
280             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
281         }
282
283         copy.setUserOrdered(old.isUserOrdered());
284         copy.setKeys(old.getKeys());
285
286         return copy;
287     }
288
289     public static GroupingBuilder copy(final GroupingBuilder old, final Builder newParent, final boolean updateQName) {
290         DataBean data = getdata(old, newParent, updateQName);
291         QName newQName = data.qname;
292         SchemaPath newSchemaPath = data.schemaPath;
293
294         GroupingBuilderImpl copy = new GroupingBuilderImpl(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
295         copy.setParent(newParent);
296         copy.setDescription(old.getDescription());
297         copy.setReference(old.getReference());
298         copy.setStatus(old.getStatus());
299         copy.setAddedByUses(old.isAddedByUses());
300         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
301             copy.addChildNode(copy(childNode, copy, updateQName));
302         }
303         copy.getGroupings().addAll(old.getGroupings());
304         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
305             copy.addGrouping(copy(grouping, copy, updateQName));
306         }
307         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
308             copy.addTypedef(copy(tdb, copy, updateQName));
309         }
310         for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
311             copy.addUsesNode(copyUses(oldUses, copy));
312         }
313         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
314             copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
315         }
316
317         return copy;
318     }
319
320     public static TypeDefinitionBuilder copy(final TypeDefinitionBuilder old, final Builder newParent, final boolean updateQName) {
321         DataBean data = getdata(old, newParent, updateQName);
322         QName newQName = data.qname;
323         SchemaPath newSchemaPath = data.schemaPath;
324         TypeDefinitionBuilder type;
325
326         if (old instanceof UnionTypeBuilder) {
327             UnionTypeBuilder oldUnion = (UnionTypeBuilder) old;
328             type = new UnionTypeBuilder(newParent.getModuleName(), newParent.getLine());
329             type.setParent(newParent);
330             for (TypeDefinition<?> td : oldUnion.getTypes()) {
331                 type.setType(td);
332             }
333             for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
334                 type.setTypedef(copy(tdb, type, updateQName));
335             }
336         } else if (old instanceof IdentityrefTypeBuilder) {
337             type = new IdentityrefTypeBuilder(newParent.getModuleName(), newParent.getLine(),
338                     ((IdentityrefTypeBuilder) old).getBaseString(), newSchemaPath);
339             type.setParent(newParent);
340         } else {
341             type = new TypeDefinitionBuilderImpl(old.getModuleName(), newParent.getLine(), newQName, old.getPath());
342             type.setParent(newParent);
343
344             if (old.getType() == null) {
345                 type.setTypedef(copy(old.getTypedef(), type, updateQName));
346             } else {
347                 type.setType(old.getType());
348             }
349
350             for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
351                 type.addUnknownNodeBuilder((copy(un, type, updateQName)));
352             }
353
354             type.setRanges(old.getRanges());
355             type.setLengths(old.getLengths());
356             type.setPatterns(old.getPatterns());
357             type.setFractionDigits(old.getFractionDigits());
358             type.setDescription(old.getDescription());
359             type.setReference(old.getReference());
360             type.setStatus(old.getStatus());
361             type.setUnits(old.getUnits());
362             type.setDefaultValue(old.getDefaultValue());
363             type.setAddedByUses(old.isAddedByUses());
364         }
365
366         return type;
367     }
368
369     private static ConstraintsBuilder copyConstraints(final ConstraintsBuilder newConstraints, final ConstraintsBuilder old) {
370         newConstraints.getMustDefinitions().addAll(old.getMustDefinitions());
371         newConstraints.addWhenCondition(old.getWhenCondition());
372         newConstraints.setMandatory(old.isMandatory());
373         newConstraints.setMinElements(old.getMinElements());
374         newConstraints.setMaxElements(old.getMaxElements());
375         return newConstraints;
376     }
377
378     private static UsesNodeBuilder copyUses(final UsesNodeBuilder old, final Builder newParent) {
379         UsesNodeBuilder copy = new UsesNodeBuilderImpl(newParent.getModuleName(), newParent.getLine(),
380                 old.getGroupingPathAsString());
381         copy.setParent(newParent);
382         copy.setGroupingDefinition(old.getGroupingDefinition());
383         copy.setGrouping(old.getGroupingBuilder());
384         copy.setAddedByUses(old.isAddedByUses());
385         copy.getAugmentations().addAll(old.getAugmentations());
386         copy.getRefineNodes().addAll(old.getRefineNodes());
387         copy.getRefines().addAll(old.getRefines());
388         copy.setAugmenting(old.isAugmenting());
389         return copy;
390     }
391
392     private static AugmentationSchemaBuilder copyAugment(final AugmentationSchemaBuilder old, final Builder newParent) {
393         AugmentationSchemaBuilderImpl copy = new AugmentationSchemaBuilderImpl(newParent.getModuleName(),
394                 newParent.getLine(), old.getTargetPathAsString(), old.getOrder());
395         copy.setParent(newParent);
396         copy.setCopyOf(old);
397         copy.setDescription(old.getDescription());
398         copy.setReference(old.getReference());
399         copy.setStatus(old.getStatus());
400         copy.addWhenCondition(old.getWhenCondition());
401         copy.setTargetNodeSchemaPath(old.getTargetNodeSchemaPath());
402         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
403             copy.addChildNode(copy(childNode, copy, false));
404         }
405         for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
406             copy.addUsesNode(copyUses(oldUses, copy));
407         }
408         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
409             copy.addUnknownNodeBuilder((copy(un, copy, false)));
410         }
411
412         return copy;
413     }
414
415     public static UnknownSchemaNodeBuilderImpl copy(final UnknownSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
416         DataBean data = getdata(old, newParent, updateQName);
417         QName newQName = data.qname;
418         SchemaPath newSchemaPath = data.schemaPath;
419
420         UnknownSchemaNodeBuilderImpl c = new UnknownSchemaNodeBuilderImpl(newParent.getModuleName(), newParent.getLine(),
421                 newQName, newSchemaPath);
422
423         c.setNodeType(old.getNodeType());
424         c.setNodeParameter(old.getNodeParameter());
425         c.setParent(newParent);
426         c.setDescription(old.getDescription());
427         c.setReference(old.getReference());
428         c.setStatus(old.getStatus());
429         c.setAddedByUses(old.isAddedByUses());
430         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
431             c.addUnknownNodeBuilder((copy(un, c, updateQName)));
432         }
433         c.setExtensionBuilder(old.getExtensionBuilder());
434         c.setExtensionDefinition(old.getExtensionDefinition());
435
436         return c;
437     }
438
439     private static DataBean getdata(final SchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
440         List<QName> newPath = null;
441         QName newQName = null;
442         if (newParent instanceof ModuleBuilder) {
443             ModuleBuilder parent = (ModuleBuilder) newParent;
444             if (updateQName) {
445                 newQName = new QName(parent.getNamespace(), parent.getRevision(), parent.getPrefix(), old.getQName()
446                         .getLocalName());
447                 newPath = Collections.singletonList(newQName);
448             } else {
449                 newQName = old.getQName();
450                 newPath = Collections.singletonList(newQName);
451             }
452         } else if (newParent instanceof AugmentationSchemaBuilder) {
453             AugmentationSchemaBuilder augment = (AugmentationSchemaBuilder) newParent;
454             ModuleBuilder parent = BuilderUtils.getParentModule(newParent);
455             if (updateQName) {
456                 newQName = new QName(parent.getNamespace(), parent.getRevision(), parent.getPrefix(), old.getQName()
457                         .getLocalName());
458                 newPath = new ArrayList<>(augment.getTargetNodeSchemaPath().getPath());
459                 newPath.add(newQName);
460             } else {
461                 newQName = old.getQName();
462                 newPath = new ArrayList<>(augment.getTargetNodeSchemaPath().getPath());
463                 newPath.add(newQName);
464             }
465
466         } else if (newParent instanceof SchemaNodeBuilder) {
467             SchemaNodeBuilder parent = (SchemaNodeBuilder) newParent;
468             QName parentQName = parent.getQName();
469             if (updateQName) {
470                 newQName = new QName(parentQName.getNamespace(), parentQName.getRevision(), parentQName.getPrefix(),
471                         old.getQName().getLocalName());
472                 newPath = new ArrayList<>(parent.getPath().getPath());
473                 newPath.add(newQName);
474             } else {
475                 newQName = old.getQName();
476                 newPath = new ArrayList<>(parent.getPath().getPath());
477                 newPath.add(newQName);
478             }
479         }
480
481         SchemaPath newSchemaPath = SchemaPath.create(newPath, true);
482         return new DataBean(newQName, newSchemaPath);
483     }
484
485     private static final class DataBean {
486         private final QName qname;
487         private final SchemaPath schemaPath;
488
489         private DataBean(final QName qname, final SchemaPath schemaPath) {
490             this.qname = qname;
491             this.schemaPath = schemaPath;
492         }
493     }
494
495 }