Fixed yang grouping resolution.
[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.parser.builder.api.AugmentationSchemaBuilder;
20 import org.opendaylight.controller.yang.parser.builder.api.Builder;
21 import org.opendaylight.controller.yang.parser.builder.api.ChildNodeBuilder;
22 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
23 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
24 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
25 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
26 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
27 import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder;
28 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder;
29 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceCaseBuilder;
30 import org.opendaylight.controller.yang.parser.builder.impl.ConstraintsBuilder;
31 import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
32 import org.opendaylight.controller.yang.parser.builder.impl.GroupingBuilderImpl;
33 import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
34 import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder;
35 import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder;
36 import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder;
37 import org.opendaylight.controller.yang.parser.builder.impl.TypedefBuilder;
38 import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
39 import org.opendaylight.controller.yang.parser.builder.impl.UsesNodeBuilderImpl;
40
41 public final class ParserUtils {
42
43     private ParserUtils() {
44     }
45
46     /**
47      * Get module import referenced by given prefix.
48      *
49      * @param builder
50      *            module to search
51      * @param prefix
52      *            prefix associated with import
53      * @return ModuleImport based on given prefix
54      */
55     public static ModuleImport getModuleImport(final ModuleBuilder builder,
56             final String prefix) {
57         ModuleImport moduleImport = null;
58         for (ModuleImport mi : builder.getModuleImports()) {
59             if (mi.getPrefix().equals(prefix)) {
60                 moduleImport = mi;
61                 break;
62             }
63         }
64         return moduleImport;
65     }
66
67     /**
68      * Parse uses path.
69      *
70      * @param usesPath
71      *            as String
72      * @return SchemaPath from given String
73      */
74     public static SchemaPath parseUsesPath(final String usesPath) {
75         final boolean absolute = usesPath.startsWith("/");
76         final String[] splittedPath = usesPath.split("/");
77         final List<QName> path = new ArrayList<QName>();
78         QName name;
79         for (String pathElement : splittedPath) {
80             if (pathElement.length() > 0) {
81                 final String[] splittedElement = pathElement.split(":");
82                 if (splittedElement.length == 1) {
83                     name = new QName(null, null, null, splittedElement[0]);
84                 } else {
85                     name = new QName(null, null, splittedElement[0],
86                             splittedElement[1]);
87                 }
88                 path.add(name);
89             }
90         }
91         return new SchemaPath(path, absolute);
92     }
93
94     /**
95      * Add all augment's child nodes to given target.
96      *
97      * @param augment
98      * @param target
99      */
100     public static void fillAugmentTarget(
101             final AugmentationSchemaBuilder augment,
102             final ChildNodeBuilder target) {
103         for (DataSchemaNodeBuilder builder : augment.getChildNodes()) {
104             builder.setAugmenting(true);
105             correctPath(augment, target.getPath());
106             target.addChildNode(builder);
107         }
108     }
109
110     private static void correctPath(final ChildNodeBuilder node,
111             final SchemaPath parentSchemaPath) {
112         for (DataSchemaNodeBuilder builder : node.getChildNodes()) {
113
114             // add correct path
115             SchemaPath targetNodeSchemaPath = parentSchemaPath;
116             List<QName> targetNodePath = new ArrayList<QName>(
117                     targetNodeSchemaPath.getPath());
118             targetNodePath.add(builder.getQName());
119             builder.setPath(new SchemaPath(targetNodePath, true));
120
121             if (builder instanceof ChildNodeBuilder) {
122                 ChildNodeBuilder cnb = (ChildNodeBuilder) builder;
123                 correctPath(cnb, builder.getPath());
124             }
125         }
126     }
127
128     public static void refineLeaf(LeafSchemaNodeBuilder leaf,
129             RefineHolder refine, int line) {
130         String defaultStr = refine.getDefaultStr();
131         Boolean mandatory = refine.isMandatory();
132         MustDefinition must = refine.getMust();
133         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
134
135         if (defaultStr != null && !("".equals(defaultStr))) {
136             leaf.setDefaultStr(defaultStr);
137         }
138         if (mandatory != null) {
139             leaf.getConstraints().setMandatory(mandatory);
140         }
141         if (must != null) {
142             leaf.getConstraints().addMustDefinition(must);
143         }
144         if (unknownNodes != null) {
145             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
146                 leaf.addUnknownSchemaNode(unknown);
147             }
148         }
149     }
150
151     public static void refineContainer(ContainerSchemaNodeBuilder container,
152             RefineHolder refine, int line) {
153         Boolean presence = refine.isPresence();
154         MustDefinition must = refine.getMust();
155         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
156
157         if (presence != null) {
158             container.setPresence(presence);
159         }
160         if (must != null) {
161             container.getConstraints().addMustDefinition(must);
162         }
163         if (unknownNodes != null) {
164             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
165                 container.addUnknownSchemaNode(unknown);
166             }
167         }
168     }
169
170     public static void refineList(ListSchemaNodeBuilder list,
171             RefineHolder refine, int line) {
172         MustDefinition must = refine.getMust();
173         Integer min = refine.getMinElements();
174         Integer max = refine.getMaxElements();
175         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
176
177         if (must != null) {
178             list.getConstraints().addMustDefinition(must);
179         }
180         if (min != null) {
181             list.getConstraints().setMinElements(min);
182         }
183         if (max != null) {
184             list.getConstraints().setMaxElements(max);
185         }
186         if (unknownNodes != null) {
187             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
188                 list.addUnknownSchemaNode(unknown);
189             }
190         }
191     }
192
193     public static void refineLeafList(LeafListSchemaNodeBuilder leafList,
194             RefineHolder refine, int line) {
195         MustDefinition must = refine.getMust();
196         Integer min = refine.getMinElements();
197         Integer max = refine.getMaxElements();
198         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
199
200         if (must != null) {
201             leafList.getConstraints().addMustDefinition(must);
202         }
203         if (min != null) {
204             leafList.getConstraints().setMinElements(min);
205         }
206         if (max != null) {
207             leafList.getConstraints().setMaxElements(max);
208         }
209         if (unknownNodes != null) {
210             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
211                 leafList.addUnknownSchemaNode(unknown);
212             }
213         }
214     }
215
216     public static void refineChoice(ChoiceBuilder choice, RefineHolder refine,
217             int line) {
218         String defaultStr = refine.getDefaultStr();
219         Boolean mandatory = refine.isMandatory();
220         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
221
222         if (defaultStr != null) {
223             choice.setDefaultCase(defaultStr);
224         }
225         if (mandatory != null) {
226             choice.getConstraints().setMandatory(mandatory);
227         }
228         if (unknownNodes != null) {
229             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
230                 choice.addUnknownSchemaNode(unknown);
231             }
232         }
233     }
234
235     public static void refineAnyxml(AnyXmlBuilder anyXml, RefineHolder refine,
236             int line) {
237         Boolean mandatory = refine.isMandatory();
238         MustDefinition must = refine.getMust();
239         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
240
241         if (mandatory != null) {
242             anyXml.getConstraints().setMandatory(mandatory);
243         }
244         if (must != null) {
245             anyXml.getConstraints().addMustDefinition(must);
246         }
247         if (unknownNodes != null) {
248             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
249                 anyXml.addUnknownSchemaNode(unknown);
250             }
251         }
252     }
253
254     /**
255      * Perform refine operation of following parameters:
256      * <ul>
257      * <li>description</li>
258      * <li>reference</li>
259      * <li>config</li>
260      * </ul>
261      *
262      * These parameters may be refined for any node.
263      *
264      * @param node
265      *            node to refine
266      * @param refine
267      *            refine holder containing values to refine
268      * @param line
269      *            current line in yang model
270      */
271     public static void refineDefault(Builder node, RefineHolder refine, int line) {
272         Class<? extends Builder> cls = node.getClass();
273
274         String description = refine.getDescription();
275         if (description != null) {
276             try {
277                 Method method = cls.getDeclaredMethod("setDescription",
278                         String.class);
279                 method.invoke(node, description);
280             } catch (Exception e) {
281                 throw new YangParseException(line,
282                         "Cannot refine description in " + cls.getName(), e);
283             }
284         }
285
286         String reference = refine.getReference();
287         if (reference != null) {
288             try {
289                 Method method = cls.getDeclaredMethod("setReference",
290                         String.class);
291                 method.invoke(node, reference);
292             } catch (Exception e) {
293                 throw new YangParseException(line,
294                         "Cannot refine reference in " + cls.getName(), e);
295             }
296         }
297
298         Boolean config = refine.isConfig();
299         if (config != null) {
300             try {
301                 Method method = cls.getDeclaredMethod("setConfiguration",
302                         Boolean.TYPE);
303                 method.invoke(node, config);
304             } catch (Exception e) {
305                 throw new YangParseException(line, "Cannot refine config in "
306                         + cls.getName(), e);
307             }
308         }
309     }
310
311     public static LeafSchemaNodeBuilder copyLeafBuilder(
312             final LeafSchemaNodeBuilder old) {
313         final LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder(
314                 old.getQName(), old.getLine());
315         final TypeDefinition<?> type = old.getType();
316
317         if (type == null) {
318             copy.setType(old.getTypedef());
319         } else {
320             copy.setType(type);
321         }
322         copy.setPath(old.getPath());
323         copyConstraints(old, copy);
324         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
325             copy.addUnknownSchemaNode(unknown);
326         }
327         copy.setDescription(old.getDescription());
328         copy.setReference(old.getReference());
329         copy.setStatus(old.getStatus());
330         copy.setAugmenting(old.isAugmenting());
331         copy.setConfiguration(old.isConfiguration());
332         copy.setDefaultStr(old.getDefaultStr());
333         copy.setUnits(old.getUnits());
334         return copy;
335     }
336
337     public static ContainerSchemaNodeBuilder copyContainerBuilder(
338             final ContainerSchemaNodeBuilder old) {
339         final ContainerSchemaNodeBuilder copy = new ContainerSchemaNodeBuilder(
340                 old.getQName(), old.getLine());
341         copy.setPath(old.getPath());
342         copyConstraints(old, copy);
343         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
344             copy.addUnknownSchemaNode(unknown);
345         }
346         for (DataSchemaNodeBuilder child : old.getChildNodes()) {
347             copy.addChildNode(child);
348         }
349         for (GroupingBuilder grouping : old.getGroupings()) {
350             copy.addGrouping(grouping);
351         }
352         for (TypeDefinitionBuilder typedef : old.getTypedefs()) {
353             copy.addTypedef(typedef);
354         }
355         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
356             copy.addAugmentation(augment);
357         }
358         for (UsesNodeBuilder use : old.getUsesNodes()) {
359             copy.addUsesNode(use);
360         }
361         copy.setDescription(old.getDescription());
362         copy.setReference(old.getReference());
363         copy.setStatus(old.getStatus());
364         copy.setAugmenting(old.isAugmenting());
365         copy.setConfiguration(old.isConfiguration());
366         copy.setPresence(old.isPresence());
367         return copy;
368     }
369
370     public static ListSchemaNodeBuilder copyListBuilder(
371             final ListSchemaNodeBuilder old) {
372         final ListSchemaNodeBuilder copy = new ListSchemaNodeBuilder(
373                 old.getQName(), old.getLine());
374         copy.setPath(old.getPath());
375         copyConstraints(old, copy);
376         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
377             copy.addUnknownSchemaNode(unknown);
378         }
379         for (DataSchemaNodeBuilder child : old.getChildNodes()) {
380             copy.addChildNode(child);
381         }
382         for (GroupingBuilder grouping : old.getGroupings()) {
383             copy.addGrouping(grouping);
384         }
385         for (TypeDefinitionBuilder typedef : old.getTypedefs()) {
386             copy.addTypedef(typedef);
387         }
388         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
389             copy.addAugmentation(augment);
390         }
391         for (UsesNodeBuilder use : old.getUsesNodes()) {
392             copy.addUsesNode(use);
393         }
394         copy.setDescription(old.getDescription());
395         copy.setReference(old.getReference());
396         copy.setStatus(old.getStatus());
397         copy.setAugmenting(old.isAugmenting());
398         copy.setConfiguration(old.isConfiguration());
399         copy.setUserOrdered(old.isUserOrdered());
400         return copy;
401     }
402
403     public static LeafListSchemaNodeBuilder copyLeafListBuilder(
404             final LeafListSchemaNodeBuilder old) {
405         final LeafListSchemaNodeBuilder copy = new LeafListSchemaNodeBuilder(
406                 old.getQName(), old.getLine());
407         copy.setPath(old.getPath());
408         copyConstraints(old, copy);
409         final TypeDefinition<?> type = old.getType();
410         if (type == null) {
411             copy.setType(old.getTypedef());
412         } else {
413             copy.setType(type);
414         }
415         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
416             copy.addUnknownSchemaNode(unknown);
417         }
418         copy.setDescription(old.getDescription());
419         copy.setReference(old.getReference());
420         copy.setStatus(old.getStatus());
421         copy.setAugmenting(old.isAugmenting());
422         copy.setConfiguration(old.isConfiguration());
423         copy.setUserOrdered(old.isUserOrdered());
424         return copy;
425     }
426
427     public static ChoiceBuilder copyChoiceBuilder(final ChoiceBuilder old) {
428         final ChoiceBuilder copy = new ChoiceBuilder(old.getQName(),
429                 old.getLine());
430         copy.setPath(old.getPath());
431         copyConstraints(old, copy);
432         for (ChoiceCaseBuilder caseBuilder : old.getCases()) {
433             copy.addChildNode(caseBuilder);
434         }
435         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
436             copy.addUnknownSchemaNode(unknown);
437         }
438         for (TypeDefinitionBuilder typedef : old.getTypedefs()) {
439             copy.addTypedef(typedef);
440         }
441         for (UsesNodeBuilder use : old.getUsesNodes()) {
442             copy.addUsesNode(use);
443         }
444         copy.setDefaultCase(old.getDefaultCase());
445         copy.setDescription(old.getDescription());
446         copy.setReference(old.getReference());
447         copy.setStatus(old.getStatus());
448         copy.setAugmenting(old.isAugmenting());
449         copy.setConfiguration(old.isConfiguration());
450         return copy;
451     }
452
453     public static AnyXmlBuilder copyAnyXmlBuilder(final AnyXmlBuilder old) {
454         final AnyXmlBuilder copy = new AnyXmlBuilder(old.getQName(),
455                 old.getLine());
456         copy.setPath(old.getPath());
457         copyConstraints(old, copy);
458         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
459             copy.addUnknownSchemaNode(unknown);
460         }
461         copy.setDescription(old.getDescription());
462         copy.setReference(old.getReference());
463         copy.setStatus(old.getStatus());
464         copy.setConfiguration(old.isConfiguration());
465         return copy;
466     }
467
468     public static GroupingBuilder copyGroupingBuilder(final GroupingBuilder old) {
469         final GroupingBuilder copy = new GroupingBuilderImpl(old.getQName(),
470                 old.getLine());
471         copy.setPath(old.getPath());
472         for (DataSchemaNodeBuilder child : old.getChildNodes()) {
473             copy.addChildNode(child);
474         }
475         for (GroupingBuilder grouping : old.getGroupings()) {
476             copy.addGrouping(grouping);
477         }
478         for (TypeDefinitionBuilder typedef : old.getTypedefs()) {
479             copy.addTypedef(typedef);
480         }
481         for (UsesNodeBuilder use : old.getUses()) {
482             copy.addUsesNode(use);
483         }
484         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
485             copy.addUnknownSchemaNode(unknown);
486         }
487         copy.setDescription(old.getDescription());
488         copy.setReference(old.getReference());
489         copy.setStatus(old.getStatus());
490         return copy;
491     }
492
493     public static TypedefBuilder copyTypedefBuilder(TypedefBuilder old) {
494         final TypedefBuilder copy = new TypedefBuilder(old.getQName(),
495                 old.getLine());
496         copy.setPath(old.getPath());
497         copy.setDefaultValue(old.getDefaultValue());
498         copy.setUnits(old.getUnits());
499         copy.setDescription(old.getDescription());
500         copy.setReference(old.getReference());
501         copy.setStatus(old.getStatus());
502
503         copy.setRanges(old.getRanges());
504         copy.setLengths(old.getLengths());
505         copy.setPatterns(old.getPatterns());
506         copy.setFractionDigits(old.getFractionDigits());
507
508         TypeDefinition<?> type = old.getType();
509         if(type == null) {
510             copy.setType(old.getTypedef());
511         } else {
512             copy.setType(old.getType());
513         }
514         copy.setUnits(old.getUnits());
515         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
516             copy.addUnknownSchemaNode(unknown);
517         }
518         return copy;
519     }
520
521     public static UsesNodeBuilder copyUsesNodeBuilder(UsesNodeBuilder old) {
522         final UsesNodeBuilder copy = new UsesNodeBuilderImpl(
523                 old.getGroupingPathString(), old.getLine());
524         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
525             copy.addAugment(augment);
526         }
527         copy.setAugmenting(old.isAugmenting());
528         for (SchemaNodeBuilder refineNode : old.getRefineNodes()) {
529             copy.addRefineNode(refineNode);
530         }
531         return copy;
532     }
533
534     private static void copyConstraints(final DataSchemaNodeBuilder oldBuilder,
535             final DataSchemaNodeBuilder newBuilder) {
536         final ConstraintsBuilder oldConstraints = oldBuilder.getConstraints();
537         final ConstraintsBuilder newConstraints = newBuilder.getConstraints();
538         newConstraints.addWhenCondition(oldConstraints.getWhenCondition());
539         for (MustDefinition must : oldConstraints.getMustDefinitions()) {
540             newConstraints.addMustDefinition(must);
541         }
542         newConstraints.setMandatory(oldConstraints.isMandatory());
543         newConstraints.setMinElements(oldConstraints.getMinElements());
544         newConstraints.setMaxElements(oldConstraints.getMaxElements());
545     }
546
547 }