Refactored SchemaPath for yang java types. Fixed SchemaPath for augmented nodes types.
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / yang / parser / util / ParserUtils.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.controller.yang.parser.util;
9
10 import java.lang.reflect.Method;
11 import java.math.BigDecimal;
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import org.opendaylight.controller.yang.common.QName;
16 import org.opendaylight.controller.yang.model.api.ModuleImport;
17 import org.opendaylight.controller.yang.model.api.MustDefinition;
18 import org.opendaylight.controller.yang.model.api.SchemaPath;
19 import org.opendaylight.controller.yang.model.api.TypeDefinition;
20 import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition;
21 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition;
22 import org.opendaylight.controller.yang.model.api.type.BooleanTypeDefinition;
23 import org.opendaylight.controller.yang.model.api.type.DecimalTypeDefinition;
24 import org.opendaylight.controller.yang.model.api.type.EmptyTypeDefinition;
25 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
26 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
27 import org.opendaylight.controller.yang.model.api.type.IdentityrefTypeDefinition;
28 import org.opendaylight.controller.yang.model.api.type.InstanceIdentifierTypeDefinition;
29 import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition;
30 import org.opendaylight.controller.yang.model.api.type.LeafrefTypeDefinition;
31 import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
32 import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
33 import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
34 import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition;
35 import org.opendaylight.controller.yang.model.api.type.UnionTypeDefinition;
36 import org.opendaylight.controller.yang.model.api.type.UnsignedIntegerTypeDefinition;
37 import org.opendaylight.controller.yang.model.util.BinaryType;
38 import org.opendaylight.controller.yang.model.util.BitsType;
39 import org.opendaylight.controller.yang.model.util.BooleanType;
40 import org.opendaylight.controller.yang.model.util.Decimal64;
41 import org.opendaylight.controller.yang.model.util.EmptyType;
42 import org.opendaylight.controller.yang.model.util.EnumerationType;
43 import org.opendaylight.controller.yang.model.util.IdentityrefType;
44 import org.opendaylight.controller.yang.model.util.InstanceIdentifier;
45 import org.opendaylight.controller.yang.model.util.Int16;
46 import org.opendaylight.controller.yang.model.util.Int32;
47 import org.opendaylight.controller.yang.model.util.Int64;
48 import org.opendaylight.controller.yang.model.util.Int8;
49 import org.opendaylight.controller.yang.model.util.Leafref;
50 import org.opendaylight.controller.yang.model.util.StringType;
51 import org.opendaylight.controller.yang.model.util.UnionType;
52 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
53 import org.opendaylight.controller.yang.parser.builder.api.Builder;
54 import org.opendaylight.controller.yang.parser.builder.api.ChildNodeBuilder;
55 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
56 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
57 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
58 import org.opendaylight.controller.yang.parser.builder.api.TypeAwareBuilder;
59 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
60 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
61 import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder;
62 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder;
63 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceCaseBuilder;
64 import org.opendaylight.controller.yang.parser.builder.impl.ConstraintsBuilder;
65 import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
66 import org.opendaylight.controller.yang.parser.builder.impl.GroupingBuilderImpl;
67 import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
68 import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder;
69 import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder;
70 import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder;
71 import org.opendaylight.controller.yang.parser.builder.impl.TypedefBuilder;
72 import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
73 import org.opendaylight.controller.yang.parser.builder.impl.UsesNodeBuilderImpl;
74
75 public final class ParserUtils {
76
77     private ParserUtils() {
78     }
79
80     /**
81      * Get module import referenced by given prefix.
82      *
83      * @param builder
84      *            module to search
85      * @param prefix
86      *            prefix associated with import
87      * @return ModuleImport based on given prefix
88      */
89     public static ModuleImport getModuleImport(final ModuleBuilder builder,
90             final String prefix) {
91         ModuleImport moduleImport = null;
92         for (ModuleImport mi : builder.getModuleImports()) {
93             if (mi.getPrefix().equals(prefix)) {
94                 moduleImport = mi;
95                 break;
96             }
97         }
98         return moduleImport;
99     }
100
101     /**
102      * Parse uses path.
103      *
104      * @param usesPath
105      *            as String
106      * @return SchemaPath from given String
107      */
108     public static SchemaPath parseUsesPath(final String usesPath) {
109         final boolean absolute = usesPath.startsWith("/");
110         final String[] splittedPath = usesPath.split("/");
111         final List<QName> path = new ArrayList<QName>();
112         QName name;
113         for (String pathElement : splittedPath) {
114             if (pathElement.length() > 0) {
115                 final String[] splittedElement = pathElement.split(":");
116                 if (splittedElement.length == 1) {
117                     name = new QName(null, null, null, splittedElement[0]);
118                 } else {
119                     name = new QName(null, null, splittedElement[0],
120                             splittedElement[1]);
121                 }
122                 path.add(name);
123             }
124         }
125         return new SchemaPath(path, absolute);
126     }
127
128     /**
129      * Add all augment's child nodes to given target.
130      *
131      * @param augment
132      * @param target
133      */
134     public static void fillAugmentTarget(
135             final AugmentationSchemaBuilder augment,
136             final ChildNodeBuilder target) {
137         for (DataSchemaNodeBuilder builder : augment.getChildNodes()) {
138             builder.setAugmenting(true);
139             correctAugmentChildPath(augment, target.getPath());
140             target.addChildNode(builder);
141         }
142     }
143
144     private static void correctAugmentChildPath(final ChildNodeBuilder node,
145             final SchemaPath parentSchemaPath) {
146         for (DataSchemaNodeBuilder builder : node.getChildNodes()) {
147
148             // add correct path
149             List<QName> targetNodePath = new ArrayList<QName>(
150                     parentSchemaPath.getPath());
151             targetNodePath.add(builder.getQName());
152             builder.setPath(new SchemaPath(targetNodePath, true));
153
154             if (builder instanceof ChildNodeBuilder) {
155                 ChildNodeBuilder cnb = (ChildNodeBuilder) builder;
156                 correctAugmentChildPath(cnb, builder.getPath());
157             }
158
159             // if child can contains type, correct path for this type too
160             if(builder instanceof TypeAwareBuilder) {
161                 TypeAwareBuilder nodeBuilder = (TypeAwareBuilder)builder;
162                 QName nodeBuilderQName = nodeBuilder.getQName();
163                 TypeDefinition<?> nodeBuilderType = nodeBuilder.getType();
164                 if(nodeBuilderType != null) {
165                     TypeDefinition<?> newType = createCorrectTypeDefinition(parentSchemaPath, nodeBuilderQName, nodeBuilderType);
166                     nodeBuilder.setType(newType);
167                 } else {
168                     TypeDefinitionBuilder nodeBuilderTypedef = nodeBuilder.getTypedef();
169                     SchemaPath newSchemaPath = createNewSchemaPath(nodeBuilderTypedef.getPath(), nodeBuilderQName, nodeBuilderTypedef.getQName());
170                     nodeBuilderTypedef.setPath(newSchemaPath);
171                 }
172             }
173         }
174     }
175
176     private static TypeDefinition<?> createCorrectTypeDefinition(SchemaPath parentSchemaPath, QName nodeQName, TypeDefinition<?> nodeType) {
177         TypeDefinition<?> result = null;
178         SchemaPath newSchemaPath = null;
179         if(nodeType != null) {
180             if(nodeType instanceof BinaryTypeDefinition) {
181                 BinaryTypeDefinition binType = (BinaryTypeDefinition)nodeType;
182                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, binType.getQName());
183                 List<Byte> bytes = (List<Byte>)binType.getDefaultValue();
184                 result = new BinaryType(newSchemaPath, bytes, binType.getLengthConstraints(), binType.getUnits());
185             } else if(nodeType instanceof BitsTypeDefinition) {
186                 BitsTypeDefinition bitsType = (BitsTypeDefinition)nodeType;
187                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, nodeType.getQName());
188                 result = new BitsType(newSchemaPath, bitsType.getBits(), bitsType.getUnits());
189             } else if(nodeType instanceof BooleanTypeDefinition) {
190                 BooleanTypeDefinition booleanType = (BooleanTypeDefinition)nodeType;
191                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, booleanType.getQName());
192                 result = new BooleanType(newSchemaPath, (Boolean)booleanType.getDefaultValue(), booleanType.getUnits());
193             } else if(nodeType instanceof DecimalTypeDefinition) {
194                 DecimalTypeDefinition decimalType = (DecimalTypeDefinition)nodeType;
195                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, decimalType.getQName());
196                 BigDecimal defaultValue = (BigDecimal)decimalType.getDefaultValue();
197                 result = new Decimal64(newSchemaPath, decimalType.getUnits(), defaultValue, decimalType.getRangeStatements(), decimalType.getFractionDigits());
198             } else if(nodeType instanceof EmptyTypeDefinition) {
199                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, nodeType.getQName());
200                 result = new EmptyType(newSchemaPath);
201             } else if(nodeType instanceof EnumTypeDefinition) {
202                 EnumTypeDefinition enumType = (EnumTypeDefinition)nodeType;
203                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, enumType.getQName());
204                 result = new EnumerationType(newSchemaPath, (EnumPair)enumType.getDefaultValue(), enumType.getValues(), enumType.getUnits());
205             } else if(nodeType instanceof IdentityrefTypeDefinition) {
206                 IdentityrefTypeDefinition idrefType = (IdentityrefTypeDefinition)nodeType;
207                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, idrefType.getQName());
208                 result = new IdentityrefType(idrefType.getIdentity(), newSchemaPath);
209             } else if(nodeType instanceof InstanceIdentifierTypeDefinition) {
210                 InstanceIdentifierTypeDefinition instIdType = (InstanceIdentifierTypeDefinition)nodeType;
211                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, instIdType.getQName());
212                 return new InstanceIdentifier(newSchemaPath, instIdType.getPathStatement(), instIdType.requireInstance());
213             } else if(nodeType instanceof StringTypeDefinition) {
214                 result = copyStringType(parentSchemaPath, nodeQName, (StringTypeDefinition)nodeType);
215             } else if(nodeType instanceof IntegerTypeDefinition) {
216                 result = copyIntType(parentSchemaPath, nodeQName, (IntegerTypeDefinition)nodeType);
217             } else if(nodeType instanceof UnsignedIntegerTypeDefinition) {
218                 result = copyUIntType(parentSchemaPath, nodeQName, (UnsignedIntegerTypeDefinition)nodeType);
219             } else if(nodeType instanceof LeafrefTypeDefinition) {
220                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, nodeType.getQName());
221                 result = new Leafref(newSchemaPath, ((LeafrefTypeDefinition)nodeType).getPathStatement());
222             } else if(nodeType instanceof UnionTypeDefinition) {
223                 UnionTypeDefinition unionType = (UnionTypeDefinition)nodeType;
224                 newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, unionType.getQName());
225                 return new UnionType(newSchemaPath, unionType.getTypes());
226             }
227         }
228         return result;
229     }
230
231     private static TypeDefinition<?> copyStringType(SchemaPath schemaPath, QName nodeQName, StringTypeDefinition nodeType) {
232         List<QName> path = schemaPath.getPath();
233         List<QName> newPath = new ArrayList<QName>(path);
234         newPath.add(nodeQName);
235         newPath.add(nodeType.getQName());
236         SchemaPath newSchemaPath = new SchemaPath(newPath, schemaPath.isAbsolute());
237
238         String newDefault = nodeType.getDefaultValue().toString();
239         String newUnits = nodeType.getUnits();
240         List<LengthConstraint> lengths = nodeType.getLengthStatements();
241         List<PatternConstraint> patterns = nodeType.getPatterns();
242
243         return new StringType(newSchemaPath, newDefault, lengths, patterns, newUnits);
244     }
245
246     private static TypeDefinition<?> copyIntType(SchemaPath schemaPath, QName nodeQName, IntegerTypeDefinition type) {
247         QName typeQName = type.getQName();
248         SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName);
249
250         String localName = typeQName.getLocalName();
251         List<RangeConstraint> ranges = type.getRangeStatements();
252         String units = type.getUnits();
253
254         if("int8".equals(localName)) {
255             Byte defaultValue = (Byte)type.getDefaultValue();
256             return new Int8(newSchemaPath, ranges, units, defaultValue);
257         } else if("int16".equals(localName)) {
258             Short defaultValue = (Short)type.getDefaultValue();
259             return new Int16(newSchemaPath, ranges, units, defaultValue);
260         } else if("int32".equals(localName)) {
261             Integer defaultValue = (Integer)type.getDefaultValue();
262             return new Int32(newSchemaPath, ranges, units, defaultValue);
263         } else if("int64".equals(localName)) {
264             Long defaultValue = (Long)type.getDefaultValue();
265             return new Int64(newSchemaPath, ranges, units, defaultValue);
266         } else {
267             return null;
268         }
269     }
270
271     private static TypeDefinition<?> copyUIntType(SchemaPath schemaPath, QName nodeQName, UnsignedIntegerTypeDefinition type) {
272         QName typeQName = type.getQName();
273         SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName);
274
275         String localName = typeQName.getLocalName();
276         List<RangeConstraint> ranges = type.getRangeStatements();
277         String units = type.getUnits();
278
279         if("uint8".equals(localName)) {
280             Byte defaultValue = (Byte)type.getDefaultValue();
281             return new Int8(newSchemaPath, ranges, units, defaultValue);
282         } else if("uint16".equals(localName)) {
283             Short defaultValue = (Short)type.getDefaultValue();
284             return new Int16(newSchemaPath, ranges, units, defaultValue);
285         } else if("uint32".equals(localName)) {
286             Integer defaultValue = (Integer)type.getDefaultValue();
287             return new Int32(newSchemaPath, ranges, units, defaultValue);
288         } else if("uint64".equals(localName)) {
289             Long defaultValue = (Long)type.getDefaultValue();
290             return new Int64(newSchemaPath, ranges, units, defaultValue);
291         } else {
292             return null;
293         }
294     }
295
296     private static SchemaPath createNewSchemaPath(SchemaPath schemaPath, QName currentQName, QName qname) {
297         List<QName> newPath = new ArrayList<QName>(schemaPath.getPath());
298         newPath.add(currentQName);
299         newPath.add(qname);
300         return new SchemaPath(newPath, schemaPath.isAbsolute());
301     }
302
303     public static void refineLeaf(LeafSchemaNodeBuilder leaf,
304             RefineHolder refine, int line) {
305         String defaultStr = refine.getDefaultStr();
306         Boolean mandatory = refine.isMandatory();
307         MustDefinition must = refine.getMust();
308         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
309
310         if (defaultStr != null && !("".equals(defaultStr))) {
311             leaf.setDefaultStr(defaultStr);
312         }
313         if (mandatory != null) {
314             leaf.getConstraints().setMandatory(mandatory);
315         }
316         if (must != null) {
317             leaf.getConstraints().addMustDefinition(must);
318         }
319         if (unknownNodes != null) {
320             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
321                 leaf.addUnknownSchemaNode(unknown);
322             }
323         }
324     }
325
326     public static void refineContainer(ContainerSchemaNodeBuilder container,
327             RefineHolder refine, int line) {
328         Boolean presence = refine.isPresence();
329         MustDefinition must = refine.getMust();
330         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
331
332         if (presence != null) {
333             container.setPresence(presence);
334         }
335         if (must != null) {
336             container.getConstraints().addMustDefinition(must);
337         }
338         if (unknownNodes != null) {
339             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
340                 container.addUnknownSchemaNode(unknown);
341             }
342         }
343     }
344
345     public static void refineList(ListSchemaNodeBuilder list,
346             RefineHolder refine, int line) {
347         MustDefinition must = refine.getMust();
348         Integer min = refine.getMinElements();
349         Integer max = refine.getMaxElements();
350         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
351
352         if (must != null) {
353             list.getConstraints().addMustDefinition(must);
354         }
355         if (min != null) {
356             list.getConstraints().setMinElements(min);
357         }
358         if (max != null) {
359             list.getConstraints().setMaxElements(max);
360         }
361         if (unknownNodes != null) {
362             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
363                 list.addUnknownSchemaNode(unknown);
364             }
365         }
366     }
367
368     public static void refineLeafList(LeafListSchemaNodeBuilder leafList,
369             RefineHolder refine, int line) {
370         MustDefinition must = refine.getMust();
371         Integer min = refine.getMinElements();
372         Integer max = refine.getMaxElements();
373         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
374
375         if (must != null) {
376             leafList.getConstraints().addMustDefinition(must);
377         }
378         if (min != null) {
379             leafList.getConstraints().setMinElements(min);
380         }
381         if (max != null) {
382             leafList.getConstraints().setMaxElements(max);
383         }
384         if (unknownNodes != null) {
385             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
386                 leafList.addUnknownSchemaNode(unknown);
387             }
388         }
389     }
390
391     public static void refineChoice(ChoiceBuilder choice, RefineHolder refine,
392             int line) {
393         String defaultStr = refine.getDefaultStr();
394         Boolean mandatory = refine.isMandatory();
395         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
396
397         if (defaultStr != null) {
398             choice.setDefaultCase(defaultStr);
399         }
400         if (mandatory != null) {
401             choice.getConstraints().setMandatory(mandatory);
402         }
403         if (unknownNodes != null) {
404             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
405                 choice.addUnknownSchemaNode(unknown);
406             }
407         }
408     }
409
410     public static void refineAnyxml(AnyXmlBuilder anyXml, RefineHolder refine,
411             int line) {
412         Boolean mandatory = refine.isMandatory();
413         MustDefinition must = refine.getMust();
414         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
415
416         if (mandatory != null) {
417             anyXml.getConstraints().setMandatory(mandatory);
418         }
419         if (must != null) {
420             anyXml.getConstraints().addMustDefinition(must);
421         }
422         if (unknownNodes != null) {
423             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
424                 anyXml.addUnknownSchemaNode(unknown);
425             }
426         }
427     }
428
429     /**
430      * Perform refine operation of following parameters:
431      * <ul>
432      * <li>description</li>
433      * <li>reference</li>
434      * <li>config</li>
435      * </ul>
436      *
437      * These parameters may be refined for any node.
438      *
439      * @param node
440      *            node to refine
441      * @param refine
442      *            refine holder containing values to refine
443      * @param line
444      *            current line in yang model
445      */
446     public static void refineDefault(Builder node, RefineHolder refine, int line) {
447         Class<? extends Builder> cls = node.getClass();
448
449         String description = refine.getDescription();
450         if (description != null) {
451             try {
452                 Method method = cls.getDeclaredMethod("setDescription",
453                         String.class);
454                 method.invoke(node, description);
455             } catch (Exception e) {
456                 throw new YangParseException(line,
457                         "Cannot refine description in " + cls.getName(), e);
458             }
459         }
460
461         String reference = refine.getReference();
462         if (reference != null) {
463             try {
464                 Method method = cls.getDeclaredMethod("setReference",
465                         String.class);
466                 method.invoke(node, reference);
467             } catch (Exception e) {
468                 throw new YangParseException(line,
469                         "Cannot refine reference in " + cls.getName(), e);
470             }
471         }
472
473         Boolean config = refine.isConfig();
474         if (config != null) {
475             try {
476                 Method method = cls.getDeclaredMethod("setConfiguration",
477                         Boolean.TYPE);
478                 method.invoke(node, config);
479             } catch (Exception e) {
480                 throw new YangParseException(line, "Cannot refine config in "
481                         + cls.getName(), e);
482             }
483         }
484     }
485
486     public static LeafSchemaNodeBuilder copyLeafBuilder(
487             final LeafSchemaNodeBuilder old) {
488         final LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder(
489                 old.getQName(), old.getLine());
490         final TypeDefinition<?> type = old.getType();
491
492         if (type == null) {
493             copy.setType(old.getTypedef());
494         } else {
495             copy.setType(type);
496         }
497         copy.setPath(old.getPath());
498         copyConstraints(old, copy);
499         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
500             copy.addUnknownSchemaNode(unknown);
501         }
502         copy.setDescription(old.getDescription());
503         copy.setReference(old.getReference());
504         copy.setStatus(old.getStatus());
505         copy.setAugmenting(old.isAugmenting());
506         copy.setConfiguration(old.isConfiguration());
507         copy.setDefaultStr(old.getDefaultStr());
508         copy.setUnits(old.getUnits());
509         return copy;
510     }
511
512     public static ContainerSchemaNodeBuilder copyContainerBuilder(
513             final ContainerSchemaNodeBuilder old) {
514         final ContainerSchemaNodeBuilder copy = new ContainerSchemaNodeBuilder(
515                 old.getQName(), old.getLine());
516         copy.setPath(old.getPath());
517         copyConstraints(old, copy);
518         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
519             copy.addUnknownSchemaNode(unknown);
520         }
521         for (DataSchemaNodeBuilder child : old.getChildNodes()) {
522             copy.addChildNode(child);
523         }
524         for (GroupingBuilder grouping : old.getGroupings()) {
525             copy.addGrouping(grouping);
526         }
527         for (TypeDefinitionBuilder typedef : old.getTypedefs()) {
528             copy.addTypedef(typedef);
529         }
530         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
531             copy.addAugmentation(augment);
532         }
533         for (UsesNodeBuilder use : old.getUsesNodes()) {
534             copy.addUsesNode(use);
535         }
536         copy.setDescription(old.getDescription());
537         copy.setReference(old.getReference());
538         copy.setStatus(old.getStatus());
539         copy.setAugmenting(old.isAugmenting());
540         copy.setConfiguration(old.isConfiguration());
541         copy.setPresence(old.isPresence());
542         return copy;
543     }
544
545     public static ListSchemaNodeBuilder copyListBuilder(
546             final ListSchemaNodeBuilder old) {
547         final ListSchemaNodeBuilder copy = new ListSchemaNodeBuilder(
548                 old.getQName(), old.getLine());
549         copy.setPath(old.getPath());
550         copyConstraints(old, copy);
551         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
552             copy.addUnknownSchemaNode(unknown);
553         }
554         for (DataSchemaNodeBuilder child : old.getChildNodes()) {
555             copy.addChildNode(child);
556         }
557         for (GroupingBuilder grouping : old.getGroupings()) {
558             copy.addGrouping(grouping);
559         }
560         for (TypeDefinitionBuilder typedef : old.getTypedefs()) {
561             copy.addTypedef(typedef);
562         }
563         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
564             copy.addAugmentation(augment);
565         }
566         for (UsesNodeBuilder use : old.getUsesNodes()) {
567             copy.addUsesNode(use);
568         }
569         copy.setDescription(old.getDescription());
570         copy.setReference(old.getReference());
571         copy.setStatus(old.getStatus());
572         copy.setAugmenting(old.isAugmenting());
573         copy.setConfiguration(old.isConfiguration());
574         copy.setUserOrdered(old.isUserOrdered());
575         return copy;
576     }
577
578     public static LeafListSchemaNodeBuilder copyLeafListBuilder(
579             final LeafListSchemaNodeBuilder old) {
580         final LeafListSchemaNodeBuilder copy = new LeafListSchemaNodeBuilder(
581                 old.getQName(), old.getLine());
582         copy.setPath(old.getPath());
583         copyConstraints(old, copy);
584         final TypeDefinition<?> type = old.getType();
585         if (type == null) {
586             copy.setType(old.getTypedef());
587         } else {
588             copy.setType(type);
589         }
590         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
591             copy.addUnknownSchemaNode(unknown);
592         }
593         copy.setDescription(old.getDescription());
594         copy.setReference(old.getReference());
595         copy.setStatus(old.getStatus());
596         copy.setAugmenting(old.isAugmenting());
597         copy.setConfiguration(old.isConfiguration());
598         copy.setUserOrdered(old.isUserOrdered());
599         return copy;
600     }
601
602     public static ChoiceBuilder copyChoiceBuilder(final ChoiceBuilder old) {
603         final ChoiceBuilder copy = new ChoiceBuilder(old.getQName(),
604                 old.getLine());
605         copy.setPath(old.getPath());
606         copyConstraints(old, copy);
607         for (ChoiceCaseBuilder caseBuilder : old.getCases()) {
608             copy.addChildNode(caseBuilder);
609         }
610         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
611             copy.addUnknownSchemaNode(unknown);
612         }
613         for (TypeDefinitionBuilder typedef : old.getTypedefs()) {
614             copy.addTypedef(typedef);
615         }
616         for (UsesNodeBuilder use : old.getUsesNodes()) {
617             copy.addUsesNode(use);
618         }
619         copy.setDefaultCase(old.getDefaultCase());
620         copy.setDescription(old.getDescription());
621         copy.setReference(old.getReference());
622         copy.setStatus(old.getStatus());
623         copy.setAugmenting(old.isAugmenting());
624         copy.setConfiguration(old.isConfiguration());
625         return copy;
626     }
627
628     public static AnyXmlBuilder copyAnyXmlBuilder(final AnyXmlBuilder old) {
629         final AnyXmlBuilder copy = new AnyXmlBuilder(old.getQName(),
630                 old.getLine());
631         copy.setPath(old.getPath());
632         copyConstraints(old, copy);
633         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
634             copy.addUnknownSchemaNode(unknown);
635         }
636         copy.setDescription(old.getDescription());
637         copy.setReference(old.getReference());
638         copy.setStatus(old.getStatus());
639         copy.setConfiguration(old.isConfiguration());
640         return copy;
641     }
642
643     public static GroupingBuilder copyGroupingBuilder(final GroupingBuilder old) {
644         final GroupingBuilder copy = new GroupingBuilderImpl(old.getQName(),
645                 old.getLine());
646         copy.setPath(old.getPath());
647         for (DataSchemaNodeBuilder child : old.getChildNodes()) {
648             copy.addChildNode(child);
649         }
650         for (GroupingBuilder grouping : old.getGroupings()) {
651             copy.addGrouping(grouping);
652         }
653         for (TypeDefinitionBuilder typedef : old.getTypedefs()) {
654             copy.addTypedef(typedef);
655         }
656         for (UsesNodeBuilder use : old.getUses()) {
657             copy.addUsesNode(use);
658         }
659         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
660             copy.addUnknownSchemaNode(unknown);
661         }
662         copy.setDescription(old.getDescription());
663         copy.setReference(old.getReference());
664         copy.setStatus(old.getStatus());
665         return copy;
666     }
667
668     public static TypedefBuilder copyTypedefBuilder(TypedefBuilder old) {
669         final TypedefBuilder copy = new TypedefBuilder(old.getQName(),
670                 old.getLine());
671         copy.setPath(old.getPath());
672         copy.setDefaultValue(old.getDefaultValue());
673         copy.setUnits(old.getUnits());
674         copy.setDescription(old.getDescription());
675         copy.setReference(old.getReference());
676         copy.setStatus(old.getStatus());
677
678         copy.setRanges(old.getRanges());
679         copy.setLengths(old.getLengths());
680         copy.setPatterns(old.getPatterns());
681         copy.setFractionDigits(old.getFractionDigits());
682
683         TypeDefinition<?> type = old.getType();
684         if(type == null) {
685             copy.setType(old.getTypedef());
686         } else {
687             copy.setType(old.getType());
688         }
689         copy.setUnits(old.getUnits());
690         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
691             copy.addUnknownSchemaNode(unknown);
692         }
693         return copy;
694     }
695
696     public static UsesNodeBuilder copyUsesNodeBuilder(UsesNodeBuilder old) {
697         final UsesNodeBuilder copy = new UsesNodeBuilderImpl(
698                 old.getGroupingPathString(), old.getLine());
699         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
700             copy.addAugment(augment);
701         }
702         copy.setAugmenting(old.isAugmenting());
703         for (SchemaNodeBuilder refineNode : old.getRefineNodes()) {
704             copy.addRefineNode(refineNode);
705         }
706         return copy;
707     }
708
709     private static void copyConstraints(final DataSchemaNodeBuilder oldBuilder,
710             final DataSchemaNodeBuilder newBuilder) {
711         final ConstraintsBuilder oldConstraints = oldBuilder.getConstraints();
712         final ConstraintsBuilder newConstraints = newBuilder.getConstraints();
713         newConstraints.addWhenCondition(oldConstraints.getWhenCondition());
714         for (MustDefinition must : oldConstraints.getMustDefinitions()) {
715             newConstraints.addMustDefinition(must);
716         }
717         newConstraints.setMandatory(oldConstraints.isMandatory());
718         newConstraints.setMinElements(oldConstraints.getMinElements());
719         newConstraints.setMaxElements(oldConstraints.getMaxElements());
720     }
721
722 }