blob: dc360283d6b7a08dfc7318caf2160c4d805377e8 [file] [log] [blame]
sonu gupta1bb37b82016-11-11 16:51:18 +05301/*
2 * Copyright 2016-present 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.yms.app.ydt;
18
19import com.google.common.collect.ImmutableMap;
sonu guptaeff184b2016-11-24 12:43:49 +053020import org.onosproject.yangutils.datamodel.YangAugment;
21import org.onosproject.yangutils.datamodel.YangLeaf;
sonu gupta1bb37b82016-11-11 16:51:18 +053022import org.onosproject.yangutils.datamodel.YangList;
23import org.onosproject.yangutils.datamodel.YangSchemaNode;
24import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
25import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
sonu guptaeff184b2016-11-24 12:43:49 +053026import org.onosproject.yms.app.ydt.exceptions.YdtException;
sonu gupta1bb37b82016-11-11 16:51:18 +053027import org.onosproject.yms.app.ysr.YangSchemaRegistry;
28import org.onosproject.yms.ydt.YdtContext;
29import org.onosproject.yms.ydt.YdtContextOperationType;
30import org.onosproject.yms.ydt.YdtType;
31import org.onosproject.yms.ydt.YmsOperationType;
32
sonu guptaeff184b2016-11-24 12:43:49 +053033import java.util.HashSet;
sonu gupta1bb37b82016-11-11 16:51:18 +053034import java.util.Iterator;
35import java.util.List;
36import java.util.Map;
37import java.util.Set;
38
sonu gupta1bb37b82016-11-11 16:51:18 +053039import static org.onosproject.yms.app.ydt.AppNodeFactory.getAppContext;
40import static org.onosproject.yms.app.ydt.RequestedCallType.LEAF;
sonu guptaeff184b2016-11-24 12:43:49 +053041import static org.onosproject.yms.app.ydt.RequestedCallType.NON_LEAF;
sonu gupta1bb37b82016-11-11 16:51:18 +053042import static org.onosproject.yms.app.ydt.RequestedCardinality.MULTI_INSTANCE;
43import static org.onosproject.yms.app.ydt.RequestedCardinality.MULTI_INSTANCE_LEAF;
44import static org.onosproject.yms.app.ydt.RequestedCardinality.SINGLE_INSTANCE;
45import static org.onosproject.yms.app.ydt.RequestedCardinality.UNKNOWN;
46import static org.onosproject.yms.app.ydt.YdtConstants.errorMsg;
sonu guptaeff184b2016-11-24 12:43:49 +053047import static org.onosproject.yms.app.ydt.YdtNodeFactory.getNode;
48import static org.onosproject.yms.app.ydt.YdtNodeFactory.getYangSchemaNodeTypeSpecificContext;
49import static org.onosproject.yms.app.ydt.YdtUtils.checkElementCount;
50import static org.onosproject.yms.app.ydt.YdtUtils.freeRestResources;
51import static org.onosproject.yms.app.ydt.YdtUtils.getAppOpTypeFromYdtOpType;
52import static org.onosproject.yms.app.ydt.YdtUtils.getAugmentingSchemaNode;
53import static org.onosproject.yms.app.ydt.YdtUtils.getNodeIdentifier;
54import static org.onosproject.yms.app.ydt.YdtUtils.getValidOpType;
sonu gupta1bb37b82016-11-11 16:51:18 +053055import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
sonu gupta1bb37b82016-11-11 16:51:18 +053056import static org.onosproject.yms.ydt.YdtContextOperationType.REMOVE;
57import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_LEAF_VALUE_NODE;
58import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
59
60/**
61 * Represents YANG request work bench which contains all parameters for
62 * request handling and methods to build and obtain YANG data tree
63 * which is data (sub)instance representation, abstract of protocol.
64 */
65public class YangRequestWorkBench implements YdtExtendedBuilder {
66
sonu guptaeff184b2016-11-24 12:43:49 +053067 // Ydt formatted error string
sonu gupta1bb37b82016-11-11 16:51:18 +053068 private static final String FMT_NOT_EXIST =
69 "Application with name \"%s\" doesn't exist.";
sonu guptaeff184b2016-11-24 12:43:49 +053070
71 // Ydt error strings.
72 private static final String E_USE_ADD_LEAF =
73 "Requested Node should be created using addLeaf interface.";
74
sonu gupta1bb37b82016-11-11 16:51:18 +053075 private static final String E_INVOKE_PARENT =
sonu guptaeff184b2016-11-24 12:43:49 +053076 "Can't invoke get parent at logical root node.";
sonu gupta1bb37b82016-11-11 16:51:18 +053077
78 /*
sonu guptaeff184b2016-11-24 12:43:49 +053079 * Reference for the current context node in YANG data tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053080 */
81 private YdtNode curNode;
82
83 /*
sonu guptaeff184b2016-11-24 12:43:49 +053084 * Reference for the logical root node in YANG data tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053085 */
86 private YdtNode rootNode;
87
88 /*
sonu guptaeff184b2016-11-24 12:43:49 +053089 * Reference for the current context in ydt application tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053090 */
91 private YdtAppContext appCurNode;
92
93 /*
sonu guptaeff184b2016-11-24 12:43:49 +053094 * Reference for the logical root node context in ydt application tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053095 */
96 private YdtAppContext appRootNode;
97
98 /**
99 * Root Node Tag attribute in YANG data tree, kept to maintain the root
100 * tag attributes in YDT.
101 * <p>
102 * First key param of map represent tagName name of tag attribute.
103 * Second param of map represent tagValue value of tag attribute
104 */
105 private Map<String, String> rootTagAttributeMap;
106
107 /*
108 * YANG schema registry reference.
109 */
110 private YangSchemaRegistry registry = null;
111
112 /*
113 * YMS operation type.
114 */
115 private final YmsOperationType ymsOperationType;
116
117 /*
118 * YDT default operation type.
119 */
120 private YdtContextOperationType ydtDefaultOpType;
121
122 /*
123 * Flag to identify data validation need to be done by YDT or not.
124 */
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530125 private boolean validate = false;
sonu gupta1bb37b82016-11-11 16:51:18 +0530126 // TODO validate need to be handle later with interaction type basis in
127 // future when it will be supported
128
sonu guptaeff184b2016-11-24 12:43:49 +0530129 /*
130 * Reference for application tree node set.
131 * This set contains the method name's generated for an augmented
132 * target node to avoid the duplicate entries in YDT application tree for
133 * multiple augmented nodes under a single XPATH.
134 */
135 private Set<String> augGenMethodSet;
sonu gupta1bb37b82016-11-11 16:51:18 +0530136
137 /**
138 * Creates an instance of YANG request work bench which is use to initialize
139 * logical rootNode and and schema registry.
140 *
141 * @param name name of logical container of a protocol
142 * which is a holder of the complete tree
143 * @param namespace namespace of logical container
144 * @param opType type of operation done by using YANG
145 * interface
sonu guptaeff184b2016-11-24 12:43:49 +0530146 * @param reg Yang schema registry
sonu gupta1bb37b82016-11-11 16:51:18 +0530147 * @param isValidate Flag to identify data validation need to be
148 * done by YDT or not
149 */
150 public YangRequestWorkBench(String name, String namespace,
151 YmsOperationType opType,
sonu guptaeff184b2016-11-24 12:43:49 +0530152 YangSchemaRegistry reg,
sonu gupta1bb37b82016-11-11 16:51:18 +0530153 boolean isValidate) {
sonu guptaeff184b2016-11-24 12:43:49 +0530154
155 setRootNode(new YdtLogicalNode(name, namespace));
156 registry = reg;
sonu gupta1bb37b82016-11-11 16:51:18 +0530157 ymsOperationType = opType;
158 validate = isValidate;
sonu gupta1bb37b82016-11-11 16:51:18 +0530159
sonu guptaeff184b2016-11-24 12:43:49 +0530160 setAppRootNode(getAppContext(true));
sonu gupta1bb37b82016-11-11 16:51:18 +0530161 }
162
163 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530164 * Sets the logical root node for ydt.
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530165 *
sonu guptaeff184b2016-11-24 12:43:49 +0530166 * @param node ydt logical root node
sonu gupta1bb37b82016-11-11 16:51:18 +0530167 */
168 private void setRootNode(YdtNode node) {
169 rootNode = node;
170 curNode = node;
171 }
172
173 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530174 * Sets the logical root node for ydt application tree.
sonu gupta1bb37b82016-11-11 16:51:18 +0530175 *
sonu guptaeff184b2016-11-24 12:43:49 +0530176 * @param node ydt application context logical root node
sonu gupta1bb37b82016-11-11 16:51:18 +0530177 */
178 private void setAppRootNode(YdtAppContext node) {
179 appRootNode = node;
180 appCurNode = node;
181 }
182
183 /**
184 * Returns the YANG schema registry of Ydt.
185 * This method will be used by ytb.
186 *
187 * @return YANG schema registry
188 */
189 public YangSchemaRegistry getYangSchemaRegistry() {
190 return registry;
191 }
192
193 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530194 * Returns the ydt app context tree logical root node.
195 * This method will be used by yab and ytb.
sonu gupta1bb37b82016-11-11 16:51:18 +0530196 *
sonu guptaeff184b2016-11-24 12:43:49 +0530197 * @return YdtAppContext app tree logical root node
sonu gupta1bb37b82016-11-11 16:51:18 +0530198 */
199 public YdtAppContext getAppRootNode() {
200 return appRootNode;
201 }
202
203 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530204 * Returns the ydt module node with requested node identifier.
sonu gupta1bb37b82016-11-11 16:51:18 +0530205 *
sonu guptaeff184b2016-11-24 12:43:49 +0530206 * @param id module/application node identifier
sonu gupta1bb37b82016-11-11 16:51:18 +0530207 * @return YANG data tree node
sonu guptaeff184b2016-11-24 12:43:49 +0530208 * @throws YdtException when user requested node schema doesn't exist or
209 * requested node is already part of the tree
sonu gupta1bb37b82016-11-11 16:51:18 +0530210 */
sonu guptaeff184b2016-11-24 12:43:49 +0530211 private YdtNode moduleHandler(YangSchemaNodeIdentifier id)
212 throws YdtException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530213
sonu guptaeff184b2016-11-24 12:43:49 +0530214 YangSchemaNode node =
215 registry.getYangSchemaNodeUsingSchemaName(id.getName());
sonu gupta1bb37b82016-11-11 16:51:18 +0530216
sonu guptaeff184b2016-11-24 12:43:49 +0530217 String namespace = id.getNameSpace().getModuleNamespace();
218
219 /*
220 * Checking received schema node is having same namespace as
221 * requested by user or not.
222 */
223 if (node == null || namespace != null &&
224 !namespace.equals(node.getYangSchemaNodeIdentifier()
225 .getNameSpace()
226 .getModuleNamespace())) {
227 throw new YdtException(errorMsg(FMT_NOT_EXIST, id.getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530228 }
229
sonu guptaeff184b2016-11-24 12:43:49 +0530230 /*
231 * If yms operation is for query then no validation need to be
232 * performed.
233 */
234 if (ymsOperationType != YmsOperationType.QUERY_REQUEST) {
235 // Checking whether module node is already exits in YDT or not.
236 try {
237 curNode.getCollidingChild(id);
238 } catch (YdtException e) {
239 throw new YdtException(e.getLocalizedMessage());
240 }
241 }
242
243 YdtNode newNode = new YdtSingleInstanceNode(node);
sonu gupta1bb37b82016-11-11 16:51:18 +0530244 newNode.setYangSchemaNode(node);
sonu gupta1bb37b82016-11-11 16:51:18 +0530245 return newNode;
246 }
247
248 @Override
249 public void setRootTagAttributeMap(Map<String, String> attributeTag) {
250 rootTagAttributeMap = attributeTag;
251 }
252
253 @Override
254 public Map<String, String> getRootTagAttributeMap() {
255 if (rootTagAttributeMap != null) {
256 return ImmutableMap.copyOf(rootTagAttributeMap);
257 }
258 return null;
259 }
260
261 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530262 public void addChild(String name, String namespace)
263 throws IllegalArgumentException {
264 addChild(name, namespace, UNKNOWN, null, NON_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530265 }
266
267 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530268 public void addChild(String name, String namespace, YdtType ydtType)
269 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530270 addChild(name, namespace, ydtType, null);
271 }
272
273 @Override
274 public void addChild(String name, String namespace,
sonu guptaeff184b2016-11-24 12:43:49 +0530275 YdtContextOperationType opType)
276 throws IllegalArgumentException {
277 addChild(name, namespace, UNKNOWN, opType, NON_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530278 }
279
280 @Override
281 public void addChild(String name, String namespace, YdtType ydtType,
sonu guptaeff184b2016-11-24 12:43:49 +0530282 YdtContextOperationType opType)
283 throws IllegalArgumentException {
284 RequestedCardinality cardinality;
sonu gupta1bb37b82016-11-11 16:51:18 +0530285 switch (ydtType) {
286 case MULTI_INSTANCE_NODE:
287 cardinality = MULTI_INSTANCE;
288 break;
289 case SINGLE_INSTANCE_NODE:
290 cardinality = SINGLE_INSTANCE;
291 break;
292 default:
sonu guptaeff184b2016-11-24 12:43:49 +0530293 throw new IllegalArgumentException(E_USE_ADD_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530294 }
sonu guptaeff184b2016-11-24 12:43:49 +0530295 addChild(name, namespace, cardinality, opType, NON_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530296 }
297
298 /**
299 * Adds a last child to YANG data tree; this method is to be used by all
300 * protocols internally which are aware or unaware of the nature
301 * (single/multiple) of node.
302 *
303 * @param name name of child to be added
304 * @param namespace namespace of child to be added
305 * @param cardinality type of YANG data tree node operation
306 * @param opType type of requested operation over a node
307 * @param callType to identify the whether its a leaf or other node
sonu guptaeff184b2016-11-24 12:43:49 +0530308 * @throws IllegalArgumentException when method has been passed an illegal
309 * or inappropriate argument.
sonu gupta1bb37b82016-11-11 16:51:18 +0530310 */
311 private void addChild(String name, String namespace,
312 RequestedCardinality cardinality,
313 YdtContextOperationType opType,
sonu guptaeff184b2016-11-24 12:43:49 +0530314 RequestedCallType callType)
315 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530316
sonu guptaeff184b2016-11-24 12:43:49 +0530317 YdtNode newNode;
318 boolean contextSwitch = false;
sonu gupta1bb37b82016-11-11 16:51:18 +0530319 YangSchemaNode augmentingSchema = null;
sonu guptaeff184b2016-11-24 12:43:49 +0530320 YangSchemaNodeIdentifier id = getNodeIdentifier(name, namespace);
sonu gupta1bb37b82016-11-11 16:51:18 +0530321
sonu guptaeff184b2016-11-24 12:43:49 +0530322 try {
323 // Module/sub-module node handler.
324 if (curNode.equals(rootNode)) {
325 newNode = moduleHandler(id);
sonu gupta1bb37b82016-11-11 16:51:18 +0530326 } else {
sonu guptaeff184b2016-11-24 12:43:49 +0530327
328 YangSchemaNode schemaNode;
329 YangSchemaNodeContextInfo contextInfo;
330
331 // If namespace given by user null, then take namespace from parent.
332 if (namespace == null) {
333 id.setNameSpace(curNode.getYangSchemaNode().getNameSpace());
sonu gupta1bb37b82016-11-11 16:51:18 +0530334 }
sonu guptaeff184b2016-11-24 12:43:49 +0530335
336 /*
337 * Get the already exiting YDT node in YDT tree with same
338 * nodeIdentifier
339 */
340 newNode = curNode.getCollidingChild(id);
341
342 /*
343 * If colliding child doesn't exist ,
344 * then query yang data model for schema of given node.
345 */
346 if (newNode == null) {
347 /*
348 * Get Yang Schema node context info which is having
349 * YangSchemaNode and ContextSwitchedNode.
350 */
351 contextInfo = curNode.getSchemaNodeContextInfo(id);
352
353 if (contextInfo.getContextSwitchedNode() != null) {
354 augmentingSchema = getAugmentingSchemaNode(
355 id, contextInfo);
356 if (augmentingSchema != null) {
357 /*
358 * As two tree(YDT and YDT Application Tree) are getting
359 * prepared in parallel, So setting context switch
360 * flag it will help ydt to keep the track whether
361 * ydtApp tree also need to be traversed back to parent
362 * or not with YDT tree traverse to parent call.
363 */
364 contextSwitch = true;
365 }
366 }
367 schemaNode = contextInfo.getSchemaNode();
368 } else {
369 /*
370 * If colliding child exist , then it will be leaf-list or list.
371 * If its leaf-list then return and add new requested
372 * value/valueSet in same node else take yang data model
373 * information from colliding child.
374 */
375 if (newNode.getYdtType() == MULTI_INSTANCE_LEAF_VALUE_NODE) {
376 curNode = newNode;
377 return;
378 }
379 schemaNode = newNode.getYangSchemaNode();
380 }
381
382 /*
383 * For yms query request node specific validation are not
384 * required as rest-conf can call addChild api for leaf/leaf-list
385 * node addition also in ydt.
386 */
387 if (ymsOperationType == YmsOperationType.QUERY_REQUEST) {
388 newNode = getYangSchemaNodeTypeSpecificContext(schemaNode);
389 } else {
390 newNode = getNode(schemaNode, cardinality, callType);
391 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530392 }
sonu guptaeff184b2016-11-24 12:43:49 +0530393
394 opType = getValidOpType(opType, ydtDefaultOpType, newNode, curNode);
395
396 newNode.setYdtContextOperationType(opType);
397
398 curNode.addChild(newNode, true);
399 } catch (YdtException e) {
400 freeRestResources(rootNode);
401 throw new IllegalArgumentException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530402 }
403
sonu gupta1bb37b82016-11-11 16:51:18 +0530404 // Update parent ydt node map.
sonu guptaeff184b2016-11-24 12:43:49 +0530405 curNode.updateYdtMap(newNode);
sonu gupta1bb37b82016-11-11 16:51:18 +0530406
sonu guptaeff184b2016-11-24 12:43:49 +0530407 processAppTree(opType, newNode, augmentingSchema, contextSwitch);
sonu gupta1bb37b82016-11-11 16:51:18 +0530408
sonu guptaeff184b2016-11-24 12:43:49 +0530409 curNode = newNode;
sonu gupta1bb37b82016-11-11 16:51:18 +0530410 }
411
412 /**
413 * Processes application tree on the bases of requested ydt node.
414 *
415 * @param opType user requested operation type
416 * @param childNode requested ydt node
417 * @param augmentingSchema schema of last augmenting node
sonu guptaeff184b2016-11-24 12:43:49 +0530418 * @param contextSwitch true, for module node call; false for modules
sonu gupta1bb37b82016-11-11 16:51:18 +0530419 * sub-node calls
420 */
421 private void processAppTree(
422 YdtContextOperationType opType, YdtNode childNode,
sonu guptaeff184b2016-11-24 12:43:49 +0530423 YangSchemaNode augmentingSchema, boolean contextSwitch) {
sonu gupta1bb37b82016-11-11 16:51:18 +0530424
sonu guptaeff184b2016-11-24 12:43:49 +0530425 if (curNode == rootNode) {
426 augGenMethodSet = new HashSet<>();
sonu gupta1bb37b82016-11-11 16:51:18 +0530427 }
sonu guptaeff184b2016-11-24 12:43:49 +0530428
sonu gupta1bb37b82016-11-11 16:51:18 +0530429 if (opType == null) {
430 opType = curNode.getYdtContextOperationType();
431 } else {
432 // Updating operation type for parent nodes
433 appCurNode.updateAppOperationType(opType);
434 }
435
436 /*
sonu guptaeff184b2016-11-24 12:43:49 +0530437 * This is to avoid multiple entries of single augmented target.
sonu gupta1bb37b82016-11-11 16:51:18 +0530438 */
sonu guptaeff184b2016-11-24 12:43:49 +0530439 if (augmentingSchema != null) {
440 if (!augGenMethodSet.add(((YangAugment) augmentingSchema)
441 .getSetterMethodName())) {
442 return;
443 }
444 }
445
446 /*
447 * Create entry of module node in ydt app tree.
448 * Or if context switch happened then also add entry for same
449 * augmented ydt node in the ydt application tree.
450 */
451 if (curNode.equals(rootNode) || contextSwitch) {
sonu gupta1bb37b82016-11-11 16:51:18 +0530452 addChildInAppTree(childNode, augmentingSchema, opType,
sonu guptaeff184b2016-11-24 12:43:49 +0530453 contextSwitch);
sonu gupta1bb37b82016-11-11 16:51:18 +0530454
455 // Setting app tree node operation.
456 appCurNode.setOperationType(getAppOpTypeFromYdtOpType(opType));
457 }
458
459 // Updating the delete operation list in app tree.
460 if (opType == DELETE || opType == REMOVE) {
461 appCurNode.addDeleteNode(childNode);
462 }
463 }
464
sonu gupta1bb37b82016-11-11 16:51:18 +0530465
466 /**
467 * Adds a last child to YANG app data tree.this method is to be used
468 * internally by other ydt interfaces.
469 *
470 * @param childNode node to be added in tree
471 * @param schemaNode last augmenting module node
472 * @param childOpType operation type of node
473 * @param isContextSwitch true, for module node call; false for modules
474 * sub-node calls
475 */
476 private void addChildInAppTree(YdtNode childNode,
477 YangSchemaNode schemaNode,
478 YdtContextOperationType childOpType,
479 boolean isContextSwitch) {
480
481 YdtAppNodeOperationType opType;
482
483 DefaultYdtAppContext appContext = getAppContext(isContextSwitch);
484
485 // Add context switched child in ydt App tree.
486 appCurNode.addChild(appContext);
sonu guptaeff184b2016-11-24 12:43:49 +0530487
sonu gupta1bb37b82016-11-11 16:51:18 +0530488 appCurNode = appContext;
489
sonu gupta1bb37b82016-11-11 16:51:18 +0530490 opType = getAppOpTypeFromYdtOpType(childOpType);
491
492 appCurNode.setAppData(childNode, schemaNode);
493
494 appCurNode.setOperationType(opType);
495
496 childNode.setAppContextSwitch();
497 }
498
sonu gupta1bb37b82016-11-11 16:51:18 +0530499 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530500 public void addLeaf(String name, String namespace, String value)
501 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530502 addLeaf(name, namespace, value, null, UNKNOWN);
503 }
504
505 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530506 public void addLeaf(String name, String namespace, Set<String> valueSet)
507 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530508 addLeaf(name, namespace, null, valueSet, MULTI_INSTANCE_LEAF);
509 }
510
511 /**
512 * Adds a last leaf with list of values/single value to YANG data tree.
513 * This method is used by all protocols which knows the nature
514 * (single/multiple) or not.
515 * Value of leaf can be null which indicates selection node in get
516 * operation.
517 *
518 * @param name name of child to be added
519 * @param namespace namespace of child to be added, if it's
520 * null, parent's
521 * namespace will be applied to child
522 * @param value value of the child
523 * @param valueSet list of value of the child
524 * @param cardinality type of YANG data tree node operation
sonu guptaeff184b2016-11-24 12:43:49 +0530525 * @throws IllegalArgumentException when method has been passed an illegal
526 * or inappropriate argument.
sonu gupta1bb37b82016-11-11 16:51:18 +0530527 */
528 private void addLeaf(String name, String namespace, String value,
529 Set<String> valueSet,
sonu guptaeff184b2016-11-24 12:43:49 +0530530 RequestedCardinality cardinality)
531 throws IllegalArgumentException {
532 try {
533 addChild(name, namespace, cardinality, null, LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530534
sonu guptaeff184b2016-11-24 12:43:49 +0530535 // After successful addition of child node updating the values in same.
536 if (value != null) {
537 curNode.addValue(value);
538 } else if (valueSet != null) {
539 curNode.addValueSet(valueSet);
540 }
541 } catch (YdtException e) {
542 freeRestResources(rootNode);
543 throw new IllegalArgumentException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530544 }
545 }
546
547 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530548 public void traverseToParent() throws IllegalStateException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530549 // If traverse back to parent for logical root node comes
550 if (curNode.equals(rootNode)) {
sonu guptaeff184b2016-11-24 12:43:49 +0530551 freeRestResources(rootNode);
552 throw new IllegalStateException(E_INVOKE_PARENT);
sonu gupta1bb37b82016-11-11 16:51:18 +0530553 }
554
sonu guptaeff184b2016-11-24 12:43:49 +0530555 try {
sonu gupta1bb37b82016-11-11 16:51:18 +0530556
sonu guptaeff184b2016-11-24 12:43:49 +0530557 // If node is of multiInstanceNode type then check key uniqueness.
558 if (curNode.getYdtType() == MULTI_INSTANCE_NODE) {
559 curNode.createKeyNodeList();
560 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530561
sonu guptaeff184b2016-11-24 12:43:49 +0530562 /*
563 * Check application switch for curNode if set,
564 * then traverseToParent in YDT application tree.
565 */
566 if (curNode.getParent().equals(rootNode) ||
567 curNode.getAppContextSwitch()) {
568 traverseToAppTreeParent();
569 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530570
sonu guptaeff184b2016-11-24 12:43:49 +0530571 /*
572 * Validate all multi Instance inside current context,
573 * This is not valid for leaf and leaf-list node.
574 */
575 if (curNode instanceof YdtMultiInstanceNode ||
576 curNode instanceof YdtSingleInstanceNode) {
577 curNode.validateMultiInstanceNode();
578 }
579
580 curNode = curNode.getParent();
581 } catch (YdtException e) {
582 freeRestResources(rootNode);
583 throw new IllegalStateException(e.getLocalizedMessage());
584 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530585 }
586
587 /**
588 * Traverses up in YANG application tree to the parent node,
589 * This will be used when Ydt current context switch flag is set.
590 */
591 private void traverseToAppTreeParent() {
592 appCurNode = appCurNode.getParent();
593 }
594
595 @Override
596 public YdtContext getCurNode() {
597 return curNode;
598 }
599
600 @Override
601 public void setDefaultEditOperationType(
602 YdtContextOperationType opType) {
603 ydtDefaultOpType = opType;
604 }
605
606 @Override
607 public YdtExtendedContext getRootNode() {
608 return rootNode;
609 }
610
611 @Override
612 public YmsOperationType getYmsOperationType() {
613 return ymsOperationType;
614 }
615
616 @Override
617 public void addMultiInstanceChild(String name, String namespace,
618 List<String> keysValueList,
sonu guptaeff184b2016-11-24 12:43:49 +0530619 YdtContextOperationType opType)
620 throws IllegalArgumentException {
621
sonu gupta1bb37b82016-11-11 16:51:18 +0530622 addChild(name, namespace, UNKNOWN, opType,
623 RequestedCallType.MULTI_INSTANCE);
624 int inputCount = keysValueList.size();
sonu gupta1bb37b82016-11-11 16:51:18 +0530625
sonu guptaeff184b2016-11-24 12:43:49 +0530626 try {
627 if (curNode.getYdtType() == MULTI_INSTANCE_LEAF_VALUE_NODE) {
628
629 /*
630 * Calculating the current leaf-list node array size by adding
631 * existing elements count and new supplied elements by user for
632 * the same.
633 */
634 // TODO instance count for leaf list need to be handled.
635// if (curNode.getValueSet().size() + inputCount > expectedCount) {
636// curNode.errorHandler(
637// errorMsg(FMT_MANY_INS, name, expectedCount), rootNode);
638// }
639
640 /*
641 * After successful addition of child node updating
642 * the values in same.
643 */
644 for (String value : keysValueList) {
645 curNode.addValue(value);
sonu gupta1bb37b82016-11-11 16:51:18 +0530646 }
sonu guptaeff184b2016-11-24 12:43:49 +0530647 } else if (curNode.getYdtType() == MULTI_INSTANCE_NODE) {
sonu gupta1bb37b82016-11-11 16:51:18 +0530648
sonu guptaeff184b2016-11-24 12:43:49 +0530649 YangList yangListHolder = (YangList) curNode.getYangSchemaNode();
650 List<String> schemaKeyList = yangListHolder.getKeyList();
651 int expectedCount = schemaKeyList.size();
652 checkElementCount(name, expectedCount, inputCount);
653
654 //After validation adding the key nodes under the list node.
655 Iterator<String> sklIter = schemaKeyList.iterator();
656 Iterator<String> kvlIter = keysValueList.iterator();
657 String keyEleName;
658
659 while (kvlIter.hasNext()) {
660 String value = kvlIter.next();
661 keyEleName = sklIter.next();
662 addLeaf(keyEleName, namespace, value);
663 if (kvlIter.hasNext()) {
664 traverseToParentWithoutValidation();
665 }
666 }
667
668 curNode = curNode.getParent();
669 }
670 } catch (YdtException e) {
671 freeRestResources(rootNode);
672 throw new IllegalArgumentException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530673 }
674 }
675
676 /**
677 * Adds a last child to YANG data tree, this method is to be used by
678 * YANG object builder sub-calls internally.
679 *
680 * @param opType type of requested operation over a node
681 * @return returns added ydt node in YDT tree
682 */
683 private YdtNode addExtendedChildNode(YdtContextOperationType opType,
684 YangSchemaNode schemaNode) {
685
sonu guptaeff184b2016-11-24 12:43:49 +0530686 YdtNode childNode = getYangSchemaNodeTypeSpecificContext(schemaNode);
sonu gupta1bb37b82016-11-11 16:51:18 +0530687
688 childNode.setYangSchemaNode(schemaNode);
689
690 childNode.setYdtContextOperationType(opType);
691
692 curNode.addChild(childNode, true);
693
694 curNode = childNode;
695
696 return childNode;
697 }
698
699 @Override
700 public YdtExtendedContext addChild(YdtContextOperationType opType,
701 YangSchemaNode schemaNode) {
702 return addExtendedChildNode(opType, schemaNode);
703 }
704
705 @Override
706 public YdtExtendedContext addLeafList(Set<String> valueSet,
707 YangSchemaNode schemaNode) {
708 YdtNode childNode = addExtendedChildNode(null, schemaNode);
709
sonu guptaeff184b2016-11-24 12:43:49 +0530710 /*
711 * After successful addition of child node updating the values in
712 * valueSet.
713 */
sonu gupta1bb37b82016-11-11 16:51:18 +0530714 childNode.addValueSetWithoutValidation(valueSet);
715 return childNode;
716 }
717
718 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530719 public YdtExtendedContext addLeaf(String value, YangSchemaNode schemaNode) {
720
sonu gupta1bb37b82016-11-11 16:51:18 +0530721 YdtNode childNode = addExtendedChildNode(null, schemaNode);
722
723 // After successful addition of child node updating the values in same.
sonu guptaeff184b2016-11-24 12:43:49 +0530724 childNode.addValueWithoutValidation(value, ((YangLeaf) schemaNode)
725 .isKeyLeaf());
sonu gupta1bb37b82016-11-11 16:51:18 +0530726 return childNode;
727 }
728
729 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530730 public void traverseToParentWithoutValidation()
731 throws IllegalStateException {
732 // If traverse back to parent for logical root node comes.
sonu gupta1bb37b82016-11-11 16:51:18 +0530733 if (curNode.equals(rootNode)) {
sonu guptaeff184b2016-11-24 12:43:49 +0530734 freeRestResources(rootNode);
735 throw new IllegalStateException(E_INVOKE_PARENT);
sonu gupta1bb37b82016-11-11 16:51:18 +0530736 }
737 curNode = curNode.getParent();
738 }
sonu guptaeff184b2016-11-24 12:43:49 +0530739
740 /**
741 * Returns the method name's set for an augmented target node in an
742 * application tree.
743 *
744 * @return augGenMethodSet set of method name's
745 */
746 public Set<String> getAugGenMethodSet() {
747 return augGenMethodSet;
748 }
749
750 /**
751 * Sets the method name's set for an augmented target node in an
752 * application tree.
753 *
754 * @param augGenMethodSet set of method name's
755 */
756 public void setAugGenMethodSet(Set<String> augGenMethodSet) {
757 this.augGenMethodSet = augGenMethodSet;
758 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530759}