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