blob: 624790ea4a2e48507d51436d8fad71d9ee30b6ee [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
19import java.util.LinkedList;
20import java.util.List;
21
22import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
23import org.onosproject.yangutils.parser.Parsable;
24import org.onosproject.yangutils.parser.ParsableDataType;
Bharat saraswal594bc6d2016-02-22 22:15:21 +053025import org.onosproject.yangutils.translator.CachedFileHandle;
Vinod Kumar S67e7be62016-02-11 20:13:28 +053026
27/*-
28 * The "list" statement is used to define an interior data node in the
29 * schema tree. A list node may exist in multiple instances in the data
30 * tree. Each such instance is known as a list entry. The "list"
31 * statement takes one argument, which is an identifier, followed by a
32 * block of sub-statements that holds detailed list information.
33 *
34 * A list entry is uniquely identified by the values of the list's keys,
35 * if defined.
36 *
37 * The list's sub-statements
38 *
39 * +--------------+---------+-------------+------------------+
40 * | substatement | section | cardinality |data model mapping|
41 * +--------------+---------+-------------+------------------+
42 * | anyxml | 7.10 | 0..n |-not supported |
43 * | choice | 7.9 | 0..n |-child nodes |
44 * | config | 7.19.1 | 0..1 |-boolean |
45 * | container | 7.5 | 0..n |-child nodes |
46 * | description | 7.19.3 | 0..1 |-string |
47 * | grouping | 7.11 | 0..n |-child nodes |
48 * | if-feature | 7.18.2 | 0..n |-TODO |
49 * | key | 7.8.2 | 0..1 |-String list |
50 * | leaf | 7.6 | 0..n |-YangLeaf |
51 * | leaf-list | 7.7 | 0..n |-YangLeafList |
52 * | list | 7.8 | 0..n |-child nodes |
53 * | max-elements | 7.7.4 | 0..1 |-int |
54 * | min-elements | 7.7.3 | 0..1 |-int |
55 * | must | 7.5.3 | 0..n |-TODO |
56 * | ordered-by | 7.7.5 | 0..1 |-TODO |
57 * | reference | 7.19.4 | 0..1 |-string |
58 * | status | 7.19.2 | 0..1 |-YangStatus |
59 * | typedef | 7.3 | 0..n |-child nodes |
60 * | unique | 7.8.3 | 0..n |-TODO |
61 * | uses | 7.12 | 0..n |-child nodes(TODO)|
62 * | when | 7.19.5 | 0..1 |-TODO |
63 * +--------------+---------+-------------+------------------+
64 */
65
66/**
67 * List data represented in YANG.
68 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +053069public class YangList extends YangNode
70 implements YangLeavesHolder, YangCommonInfo, Parsable {
Vinod Kumar S67e7be62016-02-11 20:13:28 +053071
72 /**
73 * name of the YANG list.
74 */
75 private String name;
76
77 /**
78 * If list maintains config data.
79 */
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +053080 private Boolean isConfig;
Vinod Kumar S67e7be62016-02-11 20:13:28 +053081
82 /**
83 * Description of list.
84 */
85 private String description;
86
87 /**
88 * Reference RFC 6020.
89 *
90 * The "key" statement, which MUST be present if the list represents
91 * configuration, and MAY be present otherwise, takes as an argument a
92 * string that specifies a space-separated list of leaf identifiers of this
93 * list. A leaf identifier MUST NOT appear more than once in the key. Each
94 * such leaf identifier MUST refer to a child leaf of the list. The leafs
95 * can be defined directly in sub-statements to the list, or in groupings
96 * used in the list.
97 *
98 * The combined values of all the leafs specified in the key are used to
99 * uniquely identify a list entry. All key leafs MUST be given values when a
100 * list entry is created. Thus, any default values in the key leafs or their
101 * types are ignored. It also implies that any mandatory statement in the
102 * key leafs are ignored.
103 *
104 * A leaf that is part of the key can be of any built-in or derived type,
105 * except it MUST NOT be the built-in type "empty".
106 *
107 * All key leafs in a list MUST have the same value for their "config" as
108 * the list itself.
109 *
110 * List of key leaf names.
111 */
112 private List<String> keyList;
113
114 /**
115 * List of leaves.
116 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530117 private List<YangLeaf> listOfLeaf;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530118
119 /**
120 * List of leaf-lists.
121 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530122 private List<YangLeafList> listOfLeafList;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530123
124 /**
125 * The "max-elements" statement, which is optional, takes as an argument a
126 * positive integer or the string "unbounded", which puts a constraint on
127 * valid list entries. A valid leaf-list or list always has at most
128 * max-elements entries.
129 *
130 * If no "max-elements" statement is present, it defaults to "unbounded".
131 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530132 private int maxElelements = Integer.MAX_VALUE;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530133
134 /**
135 * The "min-elements" statement, which is optional, takes as an argument a
136 * non-negative integer that puts a constraint on valid list entries. A
137 * valid leaf-list or list MUST have at least min-elements entries.
138 *
139 * If no "min-elements" statement is present, it defaults to zero.
140 *
141 * The behavior of the constraint depends on the type of the leaf-list's or
142 * list's closest ancestor node in the schema tree that is not a non-
143 * presence container:
144 *
145 * o If this ancestor is a case node, the constraint is enforced if any
146 * other node from the case exists.
147 *
148 * o Otherwise, it is enforced if the ancestor node exists.
149 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530150 private int minElements = 0;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530151
152 /**
153 * reference.
154 */
155 private String reference;
156
157 /**
158 * Status of the node.
159 */
160
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530161 private YangStatusType status = YangStatusType.CURRENT;
162
163 /**
164 * package of the generated java code.
165 */
166 private String pkg;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530167
168 /**
169 * Constructor.
170 *
171 * @param type list node
172 */
173 public YangList(YangNodeType type) {
174 super(type);
175 }
176
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530177 /**
178 * Get the YANG list name.
179 *
180 * @return YANG list name.
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530181 */
182 @Override
183 public String getName() {
184 return name;
185 }
186
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530187 /**
188 * Set the YANG list name.
189 *
190 * @param name YANG list name.
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530191 */
192 @Override
193 public void setName(String name) {
194 this.name = name;
195 }
196
197 /**
198 * Get the config flag.
199 *
200 * @return the isConfig
201 */
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530202 public Boolean isConfig() {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530203 return isConfig;
204 }
205
206 /**
207 * Set the config flag.
208 *
209 * @param isCfg the config flag.
210 */
211 public void setConfig(boolean isCfg) {
212 isConfig = isCfg;
213 }
214
215 /**
216 * Get the description.
217 *
218 * @return the description.
219 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530220 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530221 public String getDescription() {
222 return description;
223 }
224
225 /**
226 * Set the description.
227 *
228 * @param description set the description.
229 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530230 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530231 public void setDescription(String description) {
232 this.description = description;
233 }
234
235 /**
236 * Get the list of key field names.
237 *
238 * @return the list of key field names.
239 */
240 public List<String> getKeyList() {
241 return keyList;
242 }
243
244 /**
245 * Set the list of key field names.
246 *
247 * @param keyList the list of key field names.
248 */
249 private void setKeyList(List<String> keyList) {
250 this.keyList = keyList;
251 }
252
253 /**
254 * Add a key field name.
255 *
256 * @param key key field name.
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530257 * @throws DataModelException a violation of data model rules.
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530258 */
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530259 public void addKey(String key) throws DataModelException {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530260 if (getKeyList() == null) {
261 setKeyList(new LinkedList<String>());
262 }
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530263
264 if (getKeyList().contains(key)) {
265 throw new DataModelException("A leaf identifier must not appear more than once in the\n" +
266 " key");
267 }
268
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530269 getKeyList().add(key);
270 }
271
272 /**
273 * Get the list of leaves.
274 *
275 * @return the list of leaves.
276 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530277 @Override
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530278 public List<YangLeaf> getListOfLeaf() {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530279 return listOfLeaf;
280 }
281
282 /**
283 * Set the list of leaves.
284 *
285 * @param leafsList the list of leaf to set.
286 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530287 private void setListOfLeaf(List<YangLeaf> leafsList) {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530288 listOfLeaf = leafsList;
289 }
290
291 /**
292 * Add a leaf.
293 *
294 * @param leaf the leaf to be added.
295 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530296 @Override
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530297 public void addLeaf(YangLeaf leaf) {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530298 if (getListOfLeaf() == null) {
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530299 setListOfLeaf(new LinkedList<YangLeaf>());
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530300 }
301
302 getListOfLeaf().add(leaf);
303 }
304
305 /**
306 * Get the list of leaf-list.
307 *
308 * @return the list of leaf-list.
309 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530310 @Override
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530311 public List<YangLeafList> getListOfLeafList() {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530312 return listOfLeafList;
313 }
314
315 /**
316 * Set the list of leaf-list.
317 *
318 * @param listOfLeafList the list of leaf-list to set.
319 */
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530320 private void setListOfLeafList(List<YangLeafList> listOfLeafList) {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530321 this.listOfLeafList = listOfLeafList;
322 }
323
324 /**
325 * Add a leaf-list.
326 *
327 * @param leafList the leaf-list to be added.
328 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530329 @Override
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530330 public void addLeafList(YangLeafList leafList) {
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530331 if (getListOfLeafList() == null) {
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530332 setListOfLeafList(new LinkedList<YangLeafList>());
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530333 }
334
335 getListOfLeafList().add(leafList);
336 }
337
338 /**
339 * Get the max elements.
340 *
341 * @return the max elements.
342 */
343 public int getMaxElelements() {
344 return maxElelements;
345 }
346
347 /**
348 * Set the max elements.
349 *
350 * @param maxElelements the max elements.
351 */
352 public void setMaxElelements(int maxElelements) {
353 this.maxElelements = maxElelements;
354 }
355
356 /**
357 * Get the minimum elements.
358 *
359 * @return the minimum elements.
360 */
361 public int getMinElements() {
362 return minElements;
363 }
364
365 /**
366 * Set the minimum elements.
367 *
368 * @param minElements the minimum elements.
369 */
370 public void setMinElements(int minElements) {
371 this.minElements = minElements;
372 }
373
374 /**
375 * Get the textual reference.
376 *
377 * @return the reference.
378 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530379 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530380 public String getReference() {
381 return reference;
382 }
383
384 /**
385 * Set the textual reference.
386 *
387 * @param reference the reference to set.
388 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530389 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530390 public void setReference(String reference) {
391 this.reference = reference;
392 }
393
394 /**
395 * Get the status.
396 *
397 * @return the status.
398 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530399 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530400 public YangStatusType getStatus() {
401 return status;
402 }
403
404 /**
405 * Set the status.
406 *
407 * @param status the status to set.
408 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530409 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530410 public void setStatus(YangStatusType status) {
411 this.status = status;
412 }
413
414 /**
415 * Returns the type of the parsed data.
416 *
417 * @return returns LIST_DATA.
418 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530419 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530420 public ParsableDataType getParsableDataType() {
421 return ParsableDataType.LIST_DATA;
422 }
423
424 /**
425 * Validate the data on entering the corresponding parse tree node.
426 *
427 * @throws DataModelException a violation of data model rules.
428 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530429 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530430 public void validateDataOnEntry() throws DataModelException {
431 // TODO auto-generated method stub, to be implemented by parser
432 }
433
434 /**
435 * Validate the data on exiting the corresponding parse tree node.
436 *
437 * @throws DataModelException a violation of data model rules.
438 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530439 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530440 public void validateDataOnExit() throws DataModelException {
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530441 List<String> keyList = getKeyList();
442 List<YangLeaf> leaves = getListOfLeaf();
443 List<YangLeafList> leafLists = getListOfLeafList();
444
445 setDefaultConfigValueToChild(leaves, leafLists);
446 validateConfig(leaves, leafLists);
447
448 /* A list must have atleast one key leaf if config is true */
449 if ((isConfig)
450 && ((keyList == null) || (leaves == null && leafLists == null))) {
451 throw new DataModelException("A list must have atleast one key leaf if config is true;");
452 } else if (keyList != null) {
453 if (leaves != null) {
454 validateLeafKey(leaves, keyList);
455 }
456
457 if (leafLists != null) {
458 validateLeafListKey(leafLists, keyList);
459 }
460 }
461 }
462
463 /**
464 * Sets the config's value to all leaf if leaf's config statement is not specified.
465 *
466 * @param leaves list of leaf attributes of YANG list.
467 * @param leafLists list of leaf-list attributes of YANG list.
468 */
469 private void setDefaultConfigValueToChild(List<YangLeaf> leaves, List<YangLeafList> leafLists) {
470
471 /* If "config" is not specified, the default is the same as the parent
472 schema node's "config" value.*/
473 if (leaves != null) {
474 for (YangLeaf leaf : leaves) {
475 if (leaf.isConfig() == null) {
476 leaf.setConfig(isConfig);
477 }
478 }
479 }
480
481 /* If "config" is not specified, the default is the same as the parent
482 schema node's "config" value.*/
483 if (leafLists != null) {
484 for (YangLeafList leafList : leafLists) {
485 if (leafList.isConfig() == null) {
486 leafList.setConfig(isConfig);
487 }
488 }
489 }
490 }
491
492 /**
493 * Validates config statement of YANG list.
494 *
495 * @param leaves list of leaf attributes of YANG list.
496 * @param leafLists list of leaf-list attributes of YANG list.
497 * @throws DataModelException a violation of data model rules.
498 */
499 private void validateConfig(List<YangLeaf> leaves, List<YangLeafList> leafLists) throws DataModelException {
500
501 /* If a node has "config" set to "false", no node underneath it can have
502 "config" set to "true".*/
503 if ((!isConfig) && (leaves != null)) {
504 for (YangLeaf leaf : leaves) {
505 if (leaf.isConfig()) {
506 throw new DataModelException("If a list has \"config\" set to \"false\", no node underneath " +
507 "it can have \"config\" set to \"true\".");
508 }
509 }
510 }
511
512 if ((!isConfig) && (leafLists != null)) {
513 for (YangLeafList leafList : leafLists) {
514 if (leafList.isConfig()) {
515 throw new DataModelException("If a list has \"config\" set to \"false\", no node underneath " +
516 "it can have \"config\" set to \"true\".");
517 }
518 }
519 }
520 }
521
522 /**
523 * Validates key statement of list.
524 *
525 * @param leaves list of leaf attributes of list.
526 * @param keyList list of key attributes of list.
527 * @throws DataModelException a violation of data model rules.
528 */
529 private void validateLeafKey(List<YangLeaf> leaves, List<String> keyList) throws DataModelException {
530 boolean leafFound = false;
531 List<YangLeaf> keyLeaves = new LinkedList<>();
532
533 /* 1. Leaf identifier must refer to a child leaf of the list
534 2. A leaf that is part of the key must not be the built-in type "empty". */
535 for (String key : keyList) {
536 for (YangLeaf leaf : leaves) {
537 if (key.equals(leaf.getLeafName())) {
538 if (leaf.getDataType().getDataTypeName().replace("\"", "").equals("empty")) {
539 throw new DataModelException(" A leaf that is part of the key must not be the built-in " +
540 "type \"empty\".");
541 }
542 leafFound = true;
543 keyLeaves.add(leaf);
544 break;
545 }
546 }
547 if (!leafFound) {
548 throw new DataModelException("Leaf identifier must refer to a child leaf of the list");
549 }
550 leafFound = false;
551 }
552
553 /* All key leafs in a list MUST have the same value for their "config"
554 as the list itself. */
555 for (YangLeaf keyLeaf : keyLeaves) {
556 if (isConfig != keyLeaf.isConfig()) {
557 throw new DataModelException("All key leafs in a list must have the same value for their" +
558 " \"config\" as the list itself.");
559 }
560 }
561 }
562
563 /**
564 * Validates key statement of list.
565 *
566 * @param leafLists list of leaf-list attributes of list.
567 * @param keyList list of key attributes of list.
568 * @throws DataModelException a violation of data model rules.
569 */
570 private void validateLeafListKey(List<YangLeafList> leafLists, List<String> keyList) throws DataModelException {
571 boolean leafFound = false;
572 List<YangLeafList> keyLeafLists = new LinkedList<>();
573
574 /* 1. Leaf identifier must refer to a child leaf of the list
575 2. A leaf that is part of the key must not be the built-in type "empty". */
576 for (String key : keyList) {
577 for (YangLeafList leafList : leafLists) {
578 if (key.equals(leafList.getLeafName())) {
579 if (leafList.getDataType().getDataTypeName().replace("\"", "").equals("empty")) {
580 throw new DataModelException(" A leaf-list that is part of the key must not be the built-in " +
581 "type \"empty\".");
582 }
583 leafFound = true;
584 keyLeafLists.add(leafList);
585 break;
586 }
587 }
588 if (!leafFound) {
589 throw new DataModelException("Leaf-list identifier must refer to a child leaf of the list");
590 }
591 leafFound = false;
592 }
593
594 /* All key leafs in a list MUST have the same value for their "config"
595 as the list itself. */
596 for (YangLeafList keyLeafList : keyLeafLists) {
597 if (isConfig() != keyLeafList.isConfig()) {
598 throw new DataModelException("All key leaf-lists in a list must have the same value for their" +
599 " \"config\" as the list itself.");
600 }
601 }
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530602 }
603
604 /* (non-Javadoc)
605 * @see org.onosproject.yangutils.translator.CodeGenerator#generateJavaCodeEntry()
606 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530607 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530608 public void generateJavaCodeEntry() {
609 // TODO Auto-generated method stub
610
611 }
612
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530613 /**
614 * Free the resources used to generate the java file corresponding to YANG
615 * list info.
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530616 */
Bharat saraswal870c56f2016-02-20 21:57:16 +0530617 @Override
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530618 public void generateJavaCodeExit() {
619 // TODO Auto-generated method stub
620
621 }
622
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530623 /**
624 * Get the mapped java package.
625 *
626 * @return the java package
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530627 */
628 @Override
629 public String getPackage() {
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530630 return pkg;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530631 }
632
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530633 /**
634 * Set the mapped java package.
635 *
636 * @param pakg the package to set
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530637 */
638 @Override
Vinod Kumar S0c330cd2016-02-23 22:36:57 +0530639 public void setPackage(String pakg) {
640 pkg = pakg;
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530641
642 }
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530643
644 @Override
645 public CachedFileHandle getFileHandle() {
646 // TODO Auto-generated method stub
647 return null;
648 }
649
650 @Override
651 public void setFileHandle(CachedFileHandle fileHandle) {
652 // TODO Auto-generated method stub
653
654 }
Vinod Kumar S67e7be62016-02-11 20:13:28 +0530655}