e3f02b8dc265471afb28c70c27ce356366d1b119
[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.util.List;
11 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
12 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
13 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
14 import org.opendaylight.yangtools.yang.parser.builder.api.DocumentedNodeBuilder;
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     private 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 && !defaultStr.isEmpty()) {
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     private 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     private 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             checkRefineMinMax(name, min, max, moduleName, line);
190         } else if (node instanceof LeafSchemaNodeBuilder) {
191             checkRefinePresence(node, presence, moduleName, line);
192             checkRefineMinMax(name, min, max, moduleName, line);
193         } else if (node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder) {
194             checkRefineDefault(node, defaultStr, moduleName, line);
195             checkRefinePresence(node, presence, moduleName, line);
196             checkRefineMandatory(node, mandatory, moduleName, line);
197         } else if (node instanceof GroupingBuilder || node instanceof TypeDefinitionBuilder
198                 || node instanceof UsesNodeBuilder) {
199             checkRefineDefault(node, defaultStr, moduleName, line);
200             checkRefinePresence(node, presence, moduleName, line);
201             checkRefineMandatory(node, mandatory, moduleName, line);
202             checkRefineMust(node, must, moduleName, line);
203             checkRefineMinMax(name, min, max, moduleName, line);
204         }
205     }
206
207     private static void checkRefineDefault(final SchemaNodeBuilder node, final String defaultStr, final String moduleName, final int line) {
208         if (defaultStr != null) {
209             throw new YangParseException(moduleName, line, "Can not refine 'default' for '"
210                     + node.getQName().getLocalName() + "'.");
211         }
212     }
213
214     private static void checkRefineMandatory(final SchemaNodeBuilder node, final Boolean mandatory, final String moduleName, final int line) {
215         if (mandatory != null) {
216             throw new YangParseException(moduleName, line, "Can not refine 'mandatory' for '"
217                     + node.getQName().getLocalName() + "'.");
218         }
219     }
220
221     private static void checkRefinePresence(final SchemaNodeBuilder node, final Boolean presence, final String moduleName, final int line) {
222         if (presence != null) {
223             throw new YangParseException(moduleName, line, "Can not refine 'presence' for '"
224                     + node.getQName().getLocalName() + "'.");
225         }
226     }
227
228     private static void checkRefineMust(final SchemaNodeBuilder node, final MustDefinition must, final String moduleName, final int line) {
229         if (must != null) {
230             throw new YangParseException(moduleName, line, "Can not refine 'must' for '"
231                     + node.getQName().getLocalName() + "'.");
232         }
233     }
234
235     private static void checkRefineMinMax(final String refineTargetName, final Integer min, final Integer max, final String moduleName, final int line) {
236         if (min != null || max != null) {
237             throw new YangParseException(moduleName, line, "Can not refine 'min-elements' or 'max-elements' for '"
238                     + refineTargetName + "'.");
239         }
240     }
241
242     /**
243      * Perform refine operation of following parameters:
244      * <ul>
245      * <li>description</li>
246      * <li>reference</li>
247      * <li>config</li>
248      * </ul>
249      *
250      * These parameters may be refined for any node.
251      *
252      * @param node
253      *            node to refine
254      * @param refine
255      *            refine object containing information about refine process
256      */
257     private static void refineDefault(final Builder node, final RefineBuilder refine) {
258         final String moduleName = refine.getModuleName();
259         final int line = refine.getLine();
260
261
262         final DocumentedNodeBuilder documentedNode;
263         if(node instanceof DocumentedNodeBuilder) {
264             documentedNode = ((DocumentedNodeBuilder) node);
265         } else {
266             documentedNode = null;
267         }
268
269         String description = refine.getDescription();
270
271
272         if (description != null) {
273             if(documentedNode != null) {
274                 documentedNode.setDescription(description);
275             } else {
276                 throw new YangParseException(moduleName, line, String.format("Cannot refine description in of target %s",refine.getTargetPathString()));
277             }
278
279         }
280
281         String reference = refine.getReference();
282         if (reference != null) {
283             if(documentedNode != null) {
284                 documentedNode.setReference(reference);
285             } else {
286                 throw new YangParseException(moduleName, line, String.format("Cannot refine reference in of target %s",refine.getTargetPathString()));
287             }
288         }
289
290         Boolean config = refine.isConfiguration();
291         if (config != null) {
292             if(node instanceof DataSchemaNodeBuilder) {
293                 ((DataSchemaNodeBuilder) node).setConfiguration(config);
294             } else {
295                 throw new YangParseException(moduleName, line, String.format("Cannot refine config of target %s ",refine.getTargetPathString()));
296             }
297         }
298     }
299
300     /**
301      * Perform refine operation on given node.
302      *
303      * @param nodeToRefine
304      *            builder of node to refine
305      * @param refine
306      *            refine object containing information about refine process
307      */
308     static void performRefine(final SchemaNodeBuilder nodeToRefine, final RefineBuilder refine) {
309         checkRefine(nodeToRefine, refine);
310         refineDefault(nodeToRefine, refine);
311         if (nodeToRefine instanceof LeafSchemaNodeBuilder) {
312             refineLeaf((LeafSchemaNodeBuilder) nodeToRefine, refine);
313         } else if (nodeToRefine instanceof ContainerSchemaNodeBuilder) {
314             refineContainer((ContainerSchemaNodeBuilder) nodeToRefine, refine);
315         } else if (nodeToRefine instanceof ListSchemaNodeBuilder) {
316             refineList((ListSchemaNodeBuilder) nodeToRefine, refine);
317         } else if (nodeToRefine instanceof LeafListSchemaNodeBuilder) {
318             refineLeafList((LeafListSchemaNodeBuilder) nodeToRefine, refine);
319         } else if (nodeToRefine instanceof ChoiceBuilder) {
320             refineChoice((ChoiceBuilder) nodeToRefine, refine);
321         } else if (nodeToRefine instanceof AnyXmlBuilder) {
322             refineAnyxml((AnyXmlBuilder) nodeToRefine, refine);
323         }
324     }
325
326 }