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