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