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