Added 'code-generator' and 'model' projects from controller project.
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / util / RefineUtils.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.yangtools.yang.parser.util;
9
10 import java.lang.reflect.Method;
11 import java.util.List;
12
13 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
14 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
15 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
16 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
17 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
18 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
19 import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder;
20 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
21 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
22 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
23 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
24 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder;
25 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
26
27 /**
28  * Utility class with helper methods to perform operations tied to refine
29  * process.
30  */
31 public class RefineUtils {
32
33     private RefineUtils() {
34     }
35
36     public static void refineLeaf(LeafSchemaNodeBuilder leaf, RefineHolder refine) {
37         String defaultStr = refine.getDefaultStr();
38         Boolean mandatory = refine.isMandatory();
39         MustDefinition must = refine.getMust();
40         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodeBuilders();
41
42         if (defaultStr != null && !("".equals(defaultStr))) {
43             leaf.setDefaultStr(defaultStr);
44         }
45         if (mandatory != null) {
46             leaf.getConstraints().setMandatory(mandatory);
47         }
48         if (must != null) {
49             leaf.getConstraints().addMustDefinition(must);
50         }
51         if (unknownNodes != null) {
52             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
53                 leaf.addUnknownNodeBuilder(unknown);
54             }
55         }
56     }
57
58     public static void refineContainer(ContainerSchemaNodeBuilder container, RefineHolder refine, int line) {
59         Boolean presence = refine.isPresence();
60         MustDefinition must = refine.getMust();
61         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodeBuilders();
62
63         if (presence != null) {
64             container.setPresence(presence);
65         }
66         if (must != null) {
67             container.getConstraints().addMustDefinition(must);
68         }
69         if (unknownNodes != null) {
70             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
71                 container.addUnknownNodeBuilder(unknown);
72             }
73         }
74     }
75
76     public static void refineList(ListSchemaNodeBuilder list, RefineHolder refine, int line) {
77         MustDefinition must = refine.getMust();
78         Integer min = refine.getMinElements();
79         Integer max = refine.getMaxElements();
80         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodeBuilders();
81
82         if (must != null) {
83             list.getConstraints().addMustDefinition(must);
84         }
85         if (min != null) {
86             list.getConstraints().setMinElements(min);
87         }
88         if (max != null) {
89             list.getConstraints().setMaxElements(max);
90         }
91         if (unknownNodes != null) {
92             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
93                 list.addUnknownNodeBuilder(unknown);
94             }
95         }
96     }
97
98     public static void refineLeafList(LeafListSchemaNodeBuilder leafList, RefineHolder refine, int line) {
99         MustDefinition must = refine.getMust();
100         Integer min = refine.getMinElements();
101         Integer max = refine.getMaxElements();
102         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodeBuilders();
103
104         if (must != null) {
105             leafList.getConstraints().addMustDefinition(must);
106         }
107         if (min != null) {
108             leafList.getConstraints().setMinElements(min);
109         }
110         if (max != null) {
111             leafList.getConstraints().setMaxElements(max);
112         }
113         if (unknownNodes != null) {
114             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
115                 leafList.addUnknownNodeBuilder(unknown);
116             }
117         }
118     }
119
120     public static void refineChoice(ChoiceBuilder choice, RefineHolder refine, int line) {
121         String defaultStr = refine.getDefaultStr();
122         Boolean mandatory = refine.isMandatory();
123         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodeBuilders();
124
125         if (defaultStr != null) {
126             choice.setDefaultCase(defaultStr);
127         }
128         if (mandatory != null) {
129             choice.getConstraints().setMandatory(mandatory);
130         }
131         if (unknownNodes != null) {
132             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
133                 choice.addUnknownNodeBuilder(unknown);
134             }
135         }
136     }
137
138     public static void refineAnyxml(AnyXmlBuilder anyXml, RefineHolder refine, int line) {
139         Boolean mandatory = refine.isMandatory();
140         MustDefinition must = refine.getMust();
141         List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodeBuilders();
142
143         if (mandatory != null) {
144             anyXml.getConstraints().setMandatory(mandatory);
145         }
146         if (must != null) {
147             anyXml.getConstraints().addMustDefinition(must);
148         }
149         if (unknownNodes != null) {
150             for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
151                 anyXml.addUnknownNodeBuilder(unknown);
152             }
153         }
154     }
155
156     /**
157      * Check if refine can be performed on given node.
158      *
159      * @param node
160      *            node to refine
161      * @param refine
162      *            refine object containing information about refine process
163      */
164     public static void checkRefine(SchemaNodeBuilder node, RefineHolder refine) {
165         String moduleName = refine.getModuleName();
166         int line = refine.getLine();
167         String name = node.getQName().getLocalName();
168
169         String defaultStr = refine.getDefaultStr();
170         Boolean mandatory = refine.isMandatory();
171         Boolean presence = refine.isPresence();
172         MustDefinition must = refine.getMust();
173         Integer min = refine.getMinElements();
174         Integer max = refine.getMaxElements();
175
176         if (node instanceof AnyXmlBuilder) {
177             checkRefineDefault(node, defaultStr, moduleName, line);
178             checkRefinePresence(node, presence, moduleName, line);
179             checkRefineMinMax(name, min, max, moduleName, line);
180         } else if (node instanceof ChoiceBuilder) {
181             checkRefinePresence(node, presence, moduleName, line);
182             checkRefineMust(node, must, moduleName, line);
183             checkRefineMinMax(name, min, max, moduleName, line);
184         } else if (node instanceof ContainerSchemaNodeBuilder) {
185             checkRefineDefault(node, defaultStr, moduleName, line);
186             checkRefineMandatory(node, mandatory, moduleName, line);
187             checkRefineMust(node, must, moduleName, line);
188             checkRefineMinMax(name, min, max, moduleName, line);
189         } else if (node instanceof LeafSchemaNodeBuilder) {
190             checkRefinePresence(node, presence, moduleName, line);
191             checkRefineMinMax(name, min, max, moduleName, line);
192         } else if (node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder) {
193             checkRefineDefault(node, defaultStr, moduleName, line);
194             checkRefinePresence(node, presence, moduleName, line);
195             checkRefineMandatory(node, mandatory, moduleName, line);
196         } else if (node instanceof GroupingBuilder || node instanceof TypeDefinitionBuilder
197                 || node instanceof UsesNodeBuilder) {
198             checkRefineDefault(node, defaultStr, moduleName, line);
199             checkRefinePresence(node, presence, moduleName, line);
200             checkRefineMandatory(node, mandatory, moduleName, line);
201             checkRefineMust(node, must, moduleName, line);
202             checkRefineMinMax(name, min, max, moduleName, line);
203         }
204     }
205
206     private static void checkRefineDefault(SchemaNodeBuilder node, String defaultStr, String moduleName, int line) {
207         if (defaultStr != null) {
208             throw new YangParseException(moduleName, line, "Can not refine 'default' for '"
209                     + node.getQName().getLocalName() + "'.");
210         }
211     }
212
213     private static void checkRefineMandatory(SchemaNodeBuilder node, Boolean mandatory, String moduleName, int line) {
214         if (mandatory != null) {
215             throw new YangParseException(moduleName, line, "Can not refine 'mandatory' for '"
216                     + node.getQName().getLocalName() + "'.");
217         }
218     }
219
220     private static void checkRefinePresence(SchemaNodeBuilder node, Boolean presence, String moduleName, int line) {
221         if (presence != null) {
222             throw new YangParseException(moduleName, line, "Can not refine 'presence' for '"
223                     + node.getQName().getLocalName() + "'.");
224         }
225     }
226
227     private static void checkRefineMust(SchemaNodeBuilder node, MustDefinition must, String moduleName, int line) {
228         if (must != null) {
229             throw new YangParseException(moduleName, line, "Can not refine 'must' for '"
230                     + node.getQName().getLocalName() + "'.");
231         }
232     }
233
234     private static void checkRefineMinMax(String refineTargetName, Integer min, Integer max, String moduleName, int line) {
235         if (min != null || max != null) {
236             throw new YangParseException(moduleName, line, "Can not refine 'min-elements' or 'max-elements' for '"
237                     + refineTargetName + "'.");
238         }
239     }
240
241     /**
242      * Perform refine operation of following parameters:
243      * <ul>
244      * <li>description</li>
245      * <li>reference</li>
246      * <li>config</li>
247      * </ul>
248      *
249      * These parameters may be refined for any node.
250      *
251      * @param node
252      *            node to refine
253      * @param refine
254      *            refine object containing information about refine process
255      */
256     public static void refineDefault(final Builder node, final RefineHolder refine) {
257         final String moduleName = refine.getModuleName();
258         final int line = refine.getLine();
259         Class<? extends Builder> cls = node.getClass();
260
261         String description = refine.getDescription();
262         if (description != null) {
263             try {
264                 Method method = cls.getDeclaredMethod("setDescription", String.class);
265                 method.invoke(node, description);
266             } catch (Exception e) {
267                 throw new YangParseException(moduleName, line, "Cannot refine description in " + cls.getName(), e);
268             }
269         }
270
271         String reference = refine.getReference();
272         if (reference != null) {
273             try {
274                 Method method = cls.getDeclaredMethod("setReference", String.class);
275                 method.invoke(node, reference);
276             } catch (Exception e) {
277                 throw new YangParseException(moduleName, line, "Cannot refine reference in " + cls.getName(), e);
278             }
279         }
280
281         Boolean config = refine.isConfiguration();
282         if (config != null) {
283             try {
284                 Method method = cls.getDeclaredMethod("setConfiguration", Boolean.class);
285                 method.invoke(node, config);
286             } catch (Exception e) {
287                 throw new YangParseException(moduleName, line, "Cannot refine config in " + cls.getName(), e);
288             }
289         }
290     }
291
292     /**
293      * Perform refine operation on given node.
294      *
295      * @param nodeToRefine
296      *            builder of node to refine
297      * @param refine
298      *            refine object containing information about refine process
299      */
300     public static void performRefine(SchemaNodeBuilder nodeToRefine, RefineHolder refine) {
301         final int line = refine.getLine();
302         checkRefine(nodeToRefine, refine);
303         refineDefault(nodeToRefine, refine);
304         if (nodeToRefine instanceof LeafSchemaNodeBuilder) {
305             refineLeaf((LeafSchemaNodeBuilder) nodeToRefine, refine);
306         } else if (nodeToRefine instanceof ContainerSchemaNodeBuilder) {
307             refineContainer((ContainerSchemaNodeBuilder) nodeToRefine, refine, line);
308         } else if (nodeToRefine instanceof ListSchemaNodeBuilder) {
309             refineList((ListSchemaNodeBuilder) nodeToRefine, refine, line);
310         } else if (nodeToRefine instanceof LeafListSchemaNodeBuilder) {
311             refineLeafList((LeafListSchemaNodeBuilder) nodeToRefine, refine, line);
312         } else if (nodeToRefine instanceof ChoiceBuilder) {
313             refineChoice((ChoiceBuilder) nodeToRefine, refine, line);
314         } else if (nodeToRefine instanceof AnyXmlBuilder) {
315             refineAnyxml((AnyXmlBuilder) nodeToRefine, refine, line);
316         }
317     }
318
319 }