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