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