blob: c38bbbce39ed31cf534b3e8184e492409b340ec5 [file] [log] [blame]
Vinod Kumar S67e7be62016-02-11 20:13:28 +05301/*
2 * Copyright 2016 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yangutils.datamodel;
18
Bharat saraswal870c56f2016-02-20 21:57:16 +053019import java.io.IOException;
Vinod Kumar S67e7be62016-02-11 20:13:28 +053020import java.util.LinkedList;
21import java.util.List;
22
23import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
24import org.onosproject.yangutils.parser.Parsable;
25import org.onosproject.yangutils.parser.ParsableDataType;
Bharat saraswal870c56f2016-02-20 21:57:16 +053026import org.onosproject.yangutils.translator.CachedFileHandle;
27import org.onosproject.yangutils.translator.GeneratedFileType;
28import org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax;
29import org.onosproject.yangutils.utils.io.impl.FileSystemUtil;
Vinod Kumar S67e7be62016-02-11 20:13:28 +053030/*-
31 * Reference RFC 6020.
32 *
33 * The "container" statement is used to define an interior data node in the
34 * schema tree. It takes one argument, which is an identifier, followed by a
35 * block of sub-statements that holds detailed container information.
36 *
37 * A container node does not have a value, but it has a list of child nodes in
38 * the data tree. The child nodes are defined in the container's sub-statements.
39 *
40 * Containers with Presence
41 *
42 * YANG supports two styles of containers, those that exist only for organizing
43 * the hierarchy of data nodes, and those whose presence in the configuration
44 * has an explicit meaning.
45 *
46 * In the first style, the container has no meaning of its own, existing only to
47 * contain child nodes. This is the default style.
48 *
49 * For example, the set of scrambling options for Synchronous Optical Network
50 * (SONET) interfaces may be placed inside a "scrambling" container to enhance
51 * the organization of the configuration hierarchy, and to keep these nodes
52 * together. The "scrambling" node itself has no meaning, so removing the node
53 * when it becomes empty relieves the user from performing this task.
54 *
55 * In the second style, the presence of the container itself is configuration
56 * data, representing a single bit of configuration data. The container acts as
57 * both a configuration knob and a means of organizing related configuration.
58 * These containers are explicitly created and deleted.
59 *
60 * YANG calls this style a "presence container" and it is indicated using the
61 * "presence" statement, which takes as its argument a text string indicating
62 * what the presence of the node means.
63 *
64 * The container's Substatements
65 *
66 * +--------------+---------+-------------+------------------+
67 * | substatement | section | cardinality |data model mapping|
68 * +--------------+---------+-------------+------------------+
69 * | anyxml | 7.10 | 0..n | -not supported |
70 * | choice | 7.9 | 0..n | -child nodes |
71 * | config | 7.19.1 | 0..1 | -boolean |
72 * | container | 7.5 | 0..n | -child nodes |
73 * | description | 7.19.3 | 0..1 | -string |
74 * | grouping | 7.11 | 0..n | -child nodes |
75 * | if-feature | 7.18.2 | 0..n | -TODO |
76 * | leaf | 7.6 | 0..n | -YangLeaf |
77 * | leaf-list | 7.7 | 0..n | -YangLeafList |
78 * | list | 7.8 | 0..n | -child nodes |
79 * | must | 7.5.3 | 0..n | -TODO |
80 * | presence | 7.5.5 | 0..1 | -boolean |
81 * | reference | 7.19.4 | 0..1 | -string |
82 * | status | 7.19.2 | 0..1 | -YangStatus |
83 * | typedef | 7.3 | 0..n | -child nodes |
84 * | uses | 7.12 | 0..n | -child nodes |
85 * | when | 7.19.5 | 0..1 | -TODO |
86 * +--------------+---------+-------------+------------------+
87 */
88
89/**
90 * Data model node to maintain information defined in YANG container.
91 */
92public class YangContainer extends YangNode implements YangLeavesHolder, YangCommonInfo, Parsable {
93
94 /**
95 * Name of the container.
96 */
97 private String name;
98
99 /**
100 * If container maintains config data.
101 */
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530102 private Boolean isConfig;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530103
104 /**
105 * Description of container.
106 */
107 private String description;
108
109 /**
110 * List of leaves contained.
111 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530112 private List<YangLeaf> listOfLeaf;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530113
114 /**
115 * List of leaf-lists contained.
116 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530117 private List<YangLeafList> listOfLeafList;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530118
119 /**
120 * If it is a presence container, then the textual documentation of presence
121 * usage.
122 */
123 private String presence;
124
125 /**
126 * Reference of the module.
127 */
128 private String reference;
129
130 /**
131 * Status of the node.
132 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530133 private YangStatusType status = YangStatusType.CURRENT;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530134
135 /**
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530136 * Package of the generated java code.
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530137 */
138 private String pkg;
139
140 /**
141 * Cached Java File Handle.
142 */
143 private CachedFileHandle fileHandle;
144
145 /**
146 * Create a container node.
147 */
148 public YangContainer() {
149 super(YangNodeType.CONTAINER_NODE);
150 }
151
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530152 /**
153 * Get the YANG name of container.
154 *
155 * @return the name of container as defined in YANG file.
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530156 */
157 @Override
158 public String getName() {
159 return name;
160 }
161
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530162 /**
163 * Set the YANG name of container.
164 *
165 * @param name the name of container as defined in YANG file.
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530166 */
167 @Override
168 public void setName(String name) {
169 this.name = name;
170 }
171
172 /**
173 * Get the config flag.
174 *
175 * @return the isConfig
176 */
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530177 public Boolean isConfig() {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530178 return isConfig;
179 }
180
181 /**
182 * Set the config flag.
183 *
184 * @param isCfg the config flag.
185 */
186 public void setConfig(boolean isCfg) {
187 isConfig = isCfg;
188 }
189
190 /**
191 * Get the description.
192 *
193 * @return the description.
194 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530195 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530196 public String getDescription() {
197 return description;
198 }
199
200 /**
201 * Set the description.
202 *
203 * @param description set the description.
204 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530205 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530206 public void setDescription(String description) {
207 this.description = description;
208 }
209
210 /**
211 * Get the list of leaves.
212 *
213 * @return the list of leaves.
214 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530215 @Override
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530216 public List<YangLeaf> getListOfLeaf() {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530217 return listOfLeaf;
218 }
219
220 /**
221 * Set the list of leaves.
222 *
223 * @param leafsList the list of leaf to set.
224 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530225 private void setListOfLeaf(List<YangLeaf> leafsList) {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530226 listOfLeaf = leafsList;
227 }
228
229 /**
230 * Add a leaf.
231 *
232 * @param leaf the leaf to be added.
233 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530234 @Override
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530235 public void addLeaf(YangLeaf leaf) {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530236 if (getListOfLeaf() == null) {
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530237 setListOfLeaf(new LinkedList<YangLeaf>());
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530238 }
239
240 getListOfLeaf().add(leaf);
241 }
242
243 /**
244 * Get the list of leaf-list.
245 *
246 * @return the list of leaf-list.
247 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530248 @Override
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530249 public List<YangLeafList> getListOfLeafList() {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530250 return listOfLeafList;
251 }
252
253 /**
254 * Set the list of leaf-list.
255 *
256 * @param listOfLeafList the list of leaf-list to set.
257 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530258 private void setListOfLeafList(List<YangLeafList> listOfLeafList) {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530259 this.listOfLeafList = listOfLeafList;
260 }
261
262 /**
263 * Add a leaf-list.
264 *
265 * @param leafList the leaf-list to be added.
266 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530267 @Override
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530268 public void addLeafList(YangLeafList leafList) {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530269 if (getListOfLeafList() == null) {
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530270 setListOfLeafList(new LinkedList<YangLeafList>());
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530271 }
272
273 getListOfLeafList().add(leafList);
274 }
275
276 /**
277 * Get the presence string if present.
278 *
279 * @return the isPressence.
280 */
281 public String getPresence() {
282 return presence;
283 }
284
285 /**
286 * Set the presence string.
287 *
288 * @param presence the presence flag
289 */
290 public void setPresence(String presence) {
291 this.presence = presence;
292 }
293
294 /**
295 * Get the textual reference.
296 *
297 * @return the reference.
298 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530299 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530300 public String getReference() {
301 return reference;
302 }
303
304 /**
305 * Set the textual reference.
306 *
307 * @param reference the reference to set.
308 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530309 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530310 public void setReference(String reference) {
311 this.reference = reference;
312 }
313
314 /**
315 * Get the status.
316 *
317 * @return the status.
318 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530319 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530320 public YangStatusType getStatus() {
321 return status;
322 }
323
324 /**
325 * Set the status.
326 *
327 * @param status the status to set.
328 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530329 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530330 public void setStatus(YangStatusType status) {
331 this.status = status;
332 }
333
334 /**
335 * Get the cached file handle.
336 *
337 * @return the fileHandle
338 */
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530339 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530340 public CachedFileHandle getFileHandle() {
341 return fileHandle;
342 }
343
344 /**
345 * Set the cached file handle.
346 *
347 * @param handle the fileHandle to set
348 */
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530349 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530350 public void setFileHandle(CachedFileHandle handle) {
351 fileHandle = handle;
352 }
353
354 /**
355 * Returns the type of the data.
356 *
357 * @return returns CONTAINER_DATA.
358 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530359 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530360 public ParsableDataType getParsableDataType() {
361 return ParsableDataType.CONTAINER_DATA;
362 }
363
364 /**
365 * Validate the data on entering the corresponding parse tree node.
366 *
367 * @throws DataModelException a violation of data model rules.
368 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530369 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530370 public void validateDataOnEntry() throws DataModelException {
371 // TODO auto-generated method stub, to be implemented by parser
372 }
373
374 /**
375 * Validate the data on exiting the corresponding parse tree node.
376 *
377 * @throws DataModelException a violation of data model rules.
378 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530379 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530380 public void validateDataOnExit() throws DataModelException {
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530381 List<YangLeaf> leaves = getListOfLeaf();
382 List<YangLeafList> leafLists = getListOfLeafList();
383
384 setDefaultConfigValueToChild(leaves, leafLists);
385 validateConfig(leaves, leafLists);
386 }
387
388 /**
389 * Sets the config's value to all leaf if leaf's config statement is not specified.
390 *
391 * @param leaves list of leaf attributes of container.
392 * @param leafLists list of leaf-list attributes of container.
393 */
394 private void setDefaultConfigValueToChild(List<YangLeaf> leaves, List<YangLeafList> leafLists) {
395
396 /* If "config" is not specified, the default is the same as the parent
397 schema node's "config" value.*/
398 if (leaves != null) {
399 for (YangLeaf leaf : leaves) {
400 if (leaf.isConfig() == null) {
401 leaf.setConfig(isConfig);
402 }
403 }
404 }
405
406 /* If "config" is not specified, the default is the same as the parent
407 schema node's "config" value.*/
408 if (leafLists != null) {
409 for (YangLeafList leafList : leafLists) {
410 if (leafList.isConfig() == null) {
411 leafList.setConfig(isConfig);
412 }
413 }
414 }
415 }
416
417 /**
418 * Validates config statement of container.
419 *
420 * @param leaves list of leaf attributes of container.
421 * @param leafLists list of leaf-list attributes of container.
422 * @throws DataModelException a violation of data model rules.
423 */
424 private void validateConfig(List<YangLeaf> leaves, List<YangLeafList> leafLists) throws DataModelException {
425
426 /* If a node has "config" set to "false", no node underneath it can have
427 "config" set to "true".*/
428 if ((!isConfig) && (leaves != null)) {
429 for (YangLeaf leaf : leaves) {
430 if (leaf.isConfig()) {
431 throw new DataModelException("If a container has \"config\" set to \"false\", no node underneath " +
432 "it can have \"config\" set to \"true\".");
433 }
434 }
435 }
436
437 if ((!isConfig) && (leafLists != null)) {
438 for (YangLeafList leafList : leafLists) {
439 if (leafList.isConfig()) {
440 throw new DataModelException("If a container has \"config\" set to \"false\", no node underneath " +
441 "it can have \"config\" set to \"true\".");
442 }
443 }
444 }
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530445 }
446
447 /**
448 * Get the mapped java package.
449 *
450 * @return the java package
451 */
452 @Override
453 public String getPackage() {
454 return pkg;
455 }
456
457 /**
458 * Set the mapped java package.
459 *
460 * @param pcg the package to set
461 */
462 @Override
463 public void setPackage(String pcg) {
464 pkg = pcg;
465 }
466
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530467 /**
468 * Generate the java code corresponding to YANG container.
469 *
470 * @throws IOException when fails to generate the source files.
471 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530472 @Override
473 public void generateJavaCodeEntry() throws IOException {
474 YangNode parent = getParent();
475 String modPkg = JavaIdentifierSyntax.getPackageFromParent(parent.getPackage(), getName());
476 setPackage(modPkg);
477
478 CachedFileHandle handle = null;
479 try {
480 FileSystemUtil.createPackage(getPackage(), getName());
481 handle = FileSystemUtil.createSourceFiles(getPackage(), getName(), GeneratedFileType.ALL);
482 } catch (IOException e) {
483 throw new IOException("Failed to create the source files.");
484 }
485 setFileHandle(handle);
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530486 addAttributeInParent();
487 }
488
489 /**
490 * Adds current node attribute to parent file.
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530491 */
492 private void addAttributeInParent() {
493 if (getParent() != null) {
494 getParent().getFileHandle().setChildsPackage(getPackage());
495 getParent().getFileHandle().addAttributeInfo(null, getName(), false);
496 }
497 }
498
499 @Override
500 public void generateJavaCodeExit() throws IOException {
501 addLeavesAttributes();
Bharat saraswal870c56f2016-02-20 21:57:16 +0530502 addLeafListAttributes();
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530503 getFileHandle().close();
504 return;
Bharat saraswal870c56f2016-02-20 21:57:16 +0530505 }
506
507 /**
508 * Adds leaf attributes in generated files.
509 */
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530510 private void addLeavesAttributes() {
Bharat saraswal870c56f2016-02-20 21:57:16 +0530511
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530512 List<YangLeaf> leaves = getListOfLeaf();
Bharat saraswal870c56f2016-02-20 21:57:16 +0530513 if (leaves != null) {
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530514 for (YangLeaf leaf : leaves) {
Bharat saraswal870c56f2016-02-20 21:57:16 +0530515 getFileHandle().addAttributeInfo(leaf.getDataType(), leaf.getLeafName(), false);
516 }
517 }
518 }
519
520 /**
521 * Adds leaf list's attributes in generated files.
522 */
523 private void addLeafListAttributes() {
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530524 List<YangLeafList> leavesList = getListOfLeafList();
Bharat saraswal870c56f2016-02-20 21:57:16 +0530525 if (leavesList != null) {
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530526 for (YangLeafList leafList : leavesList) {
Bharat saraswal870c56f2016-02-20 21:57:16 +0530527 getFileHandle().addAttributeInfo(leafList.getDataType(), leafList.getLeafName(), true);
528 }
529 }
530 return;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530531 }
532}