blob: 75e00f20d83e1d31b066573c2a33a8924018afba [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;
sonu gupta1bb37b82016-11-11 16:51:18 +053028import org.onosproject.yms.ydt.YdtContextOperationType;
29import org.onosproject.yms.ydt.YdtType;
30import org.onosproject.yms.ydt.YmsOperationType;
31
sonu guptaeff184b2016-11-24 12:43:49 +053032import java.util.HashSet;
sonu gupta1bb37b82016-11-11 16:51:18 +053033import java.util.Iterator;
34import java.util.List;
35import java.util.Map;
36import java.util.Set;
37
sonu gupta1bb37b82016-11-11 16:51:18 +053038import static org.onosproject.yms.app.ydt.AppNodeFactory.getAppContext;
39import static org.onosproject.yms.app.ydt.RequestedCallType.LEAF;
sonu guptaeff184b2016-11-24 12:43:49 +053040import static org.onosproject.yms.app.ydt.RequestedCallType.NON_LEAF;
sonu gupta1bb37b82016-11-11 16:51:18 +053041import static org.onosproject.yms.app.ydt.RequestedCardinality.MULTI_INSTANCE;
42import static org.onosproject.yms.app.ydt.RequestedCardinality.MULTI_INSTANCE_LEAF;
43import static org.onosproject.yms.app.ydt.RequestedCardinality.SINGLE_INSTANCE;
44import static org.onosproject.yms.app.ydt.RequestedCardinality.UNKNOWN;
45import static org.onosproject.yms.app.ydt.YdtConstants.errorMsg;
sonu guptaeff184b2016-11-24 12:43:49 +053046import static org.onosproject.yms.app.ydt.YdtNodeFactory.getNode;
47import static org.onosproject.yms.app.ydt.YdtNodeFactory.getYangSchemaNodeTypeSpecificContext;
48import static org.onosproject.yms.app.ydt.YdtUtils.checkElementCount;
49import static org.onosproject.yms.app.ydt.YdtUtils.freeRestResources;
50import static org.onosproject.yms.app.ydt.YdtUtils.getAppOpTypeFromYdtOpType;
51import static org.onosproject.yms.app.ydt.YdtUtils.getAugmentingSchemaNode;
52import static org.onosproject.yms.app.ydt.YdtUtils.getNodeIdentifier;
53import static org.onosproject.yms.app.ydt.YdtUtils.getValidOpType;
sonu gupta1bb37b82016-11-11 16:51:18 +053054import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
sonu gupta1bb37b82016-11-11 16:51:18 +053055import static org.onosproject.yms.ydt.YdtContextOperationType.REMOVE;
56import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_LEAF_VALUE_NODE;
57import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
58
59/**
60 * Represents YANG request work bench which contains all parameters for
61 * request handling and methods to build and obtain YANG data tree
62 * which is data (sub)instance representation, abstract of protocol.
63 */
64public class YangRequestWorkBench implements YdtExtendedBuilder {
65
sonu guptaeff184b2016-11-24 12:43:49 +053066 // Ydt formatted error string
sonu gupta1bb37b82016-11-11 16:51:18 +053067 private static final String FMT_NOT_EXIST =
68 "Application with name \"%s\" doesn't exist.";
sonu guptaeff184b2016-11-24 12:43:49 +053069
70 // Ydt error strings.
71 private static final String E_USE_ADD_LEAF =
72 "Requested Node should be created using addLeaf interface.";
73
sonu gupta1bb37b82016-11-11 16:51:18 +053074 private static final String E_INVOKE_PARENT =
sonu guptaeff184b2016-11-24 12:43:49 +053075 "Can't invoke get parent at logical root node.";
sonu gupta1bb37b82016-11-11 16:51:18 +053076
77 /*
sonu guptaeff184b2016-11-24 12:43:49 +053078 * Reference for the current context node in YANG data tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053079 */
80 private YdtNode curNode;
81
82 /*
sonu guptaeff184b2016-11-24 12:43:49 +053083 * Reference for the logical root node in YANG data tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053084 */
85 private YdtNode rootNode;
86
87 /*
sonu guptaeff184b2016-11-24 12:43:49 +053088 * Reference for the current context in ydt application tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053089 */
90 private YdtAppContext appCurNode;
91
92 /*
sonu guptaeff184b2016-11-24 12:43:49 +053093 * Reference for the logical root node context in ydt application tree.
sonu gupta1bb37b82016-11-11 16:51:18 +053094 */
95 private YdtAppContext appRootNode;
96
97 /**
98 * Root Node Tag attribute in YANG data tree, kept to maintain the root
99 * tag attributes in YDT.
100 * <p>
101 * First key param of map represent tagName name of tag attribute.
102 * Second param of map represent tagValue value of tag attribute
103 */
104 private Map<String, String> rootTagAttributeMap;
105
106 /*
107 * YANG schema registry reference.
108 */
109 private YangSchemaRegistry registry = null;
110
111 /*
112 * YMS operation type.
113 */
114 private final YmsOperationType ymsOperationType;
115
116 /*
117 * YDT default operation type.
118 */
119 private YdtContextOperationType ydtDefaultOpType;
120
121 /*
122 * Flag to identify data validation need to be done by YDT or not.
123 */
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530124 private boolean validate = false;
sonu gupta1bb37b82016-11-11 16:51:18 +0530125 // TODO validate need to be handle later with interaction type basis in
126 // future when it will be supported
127
sonu guptaeff184b2016-11-24 12:43:49 +0530128 /*
129 * Reference for application tree node set.
130 * This set contains the method name's generated for an augmented
131 * target node to avoid the duplicate entries in YDT application tree for
132 * multiple augmented nodes under a single XPATH.
133 */
134 private Set<String> augGenMethodSet;
sonu gupta1bb37b82016-11-11 16:51:18 +0530135
136 /**
137 * Creates an instance of YANG request work bench which is use to initialize
138 * logical rootNode and and schema registry.
139 *
140 * @param name name of logical container of a protocol
141 * which is a holder of the complete tree
142 * @param namespace namespace of logical container
143 * @param opType type of operation done by using YANG
144 * interface
sonu guptaeff184b2016-11-24 12:43:49 +0530145 * @param reg Yang schema registry
sonu gupta1bb37b82016-11-11 16:51:18 +0530146 * @param isValidate Flag to identify data validation need to be
147 * done by YDT or not
148 */
149 public YangRequestWorkBench(String name, String namespace,
150 YmsOperationType opType,
sonu guptaeff184b2016-11-24 12:43:49 +0530151 YangSchemaRegistry reg,
sonu gupta1bb37b82016-11-11 16:51:18 +0530152 boolean isValidate) {
sonu guptaeff184b2016-11-24 12:43:49 +0530153
154 setRootNode(new YdtLogicalNode(name, namespace));
155 registry = reg;
sonu gupta1bb37b82016-11-11 16:51:18 +0530156 ymsOperationType = opType;
157 validate = isValidate;
sonu gupta1bb37b82016-11-11 16:51:18 +0530158
sonu guptaeff184b2016-11-24 12:43:49 +0530159 setAppRootNode(getAppContext(true));
sonu gupta1bb37b82016-11-11 16:51:18 +0530160 }
161
162 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530163 * Sets the logical root node for ydt.
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530164 *
sonu guptaeff184b2016-11-24 12:43:49 +0530165 * @param node ydt logical root node
sonu gupta1bb37b82016-11-11 16:51:18 +0530166 */
167 private void setRootNode(YdtNode node) {
168 rootNode = node;
169 curNode = node;
170 }
171
172 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530173 * Sets the logical root node for ydt application tree.
sonu gupta1bb37b82016-11-11 16:51:18 +0530174 *
sonu guptaeff184b2016-11-24 12:43:49 +0530175 * @param node ydt application context logical root node
sonu gupta1bb37b82016-11-11 16:51:18 +0530176 */
177 private void setAppRootNode(YdtAppContext node) {
178 appRootNode = node;
179 appCurNode = node;
180 }
181
182 /**
183 * Returns the YANG schema registry of Ydt.
184 * This method will be used by ytb.
185 *
186 * @return YANG schema registry
187 */
188 public YangSchemaRegistry getYangSchemaRegistry() {
189 return registry;
190 }
191
192 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530193 * Returns the ydt app context tree logical root node.
194 * This method will be used by yab and ytb.
sonu gupta1bb37b82016-11-11 16:51:18 +0530195 *
sonu guptaeff184b2016-11-24 12:43:49 +0530196 * @return YdtAppContext app tree logical root node
sonu gupta1bb37b82016-11-11 16:51:18 +0530197 */
198 public YdtAppContext getAppRootNode() {
199 return appRootNode;
200 }
201
202 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530203 * Returns the ydt module node with requested node identifier.
sonu gupta1bb37b82016-11-11 16:51:18 +0530204 *
sonu guptaeff184b2016-11-24 12:43:49 +0530205 * @param id module/application node identifier
sonu gupta1bb37b82016-11-11 16:51:18 +0530206 * @return YANG data tree node
sonu guptaeff184b2016-11-24 12:43:49 +0530207 * @throws YdtException when user requested node schema doesn't exist or
208 * requested node is already part of the tree
sonu gupta1bb37b82016-11-11 16:51:18 +0530209 */
sonu guptaeff184b2016-11-24 12:43:49 +0530210 private YdtNode moduleHandler(YangSchemaNodeIdentifier id)
211 throws YdtException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530212
sonu guptaeff184b2016-11-24 12:43:49 +0530213 YangSchemaNode node =
214 registry.getYangSchemaNodeUsingSchemaName(id.getName());
sonu gupta1bb37b82016-11-11 16:51:18 +0530215
sonu guptaeff184b2016-11-24 12:43:49 +0530216 String namespace = id.getNameSpace().getModuleNamespace();
217
218 /*
219 * Checking received schema node is having same namespace as
220 * requested by user or not.
221 */
222 if (node == null || namespace != null &&
223 !namespace.equals(node.getYangSchemaNodeIdentifier()
224 .getNameSpace()
225 .getModuleNamespace())) {
226 throw new YdtException(errorMsg(FMT_NOT_EXIST, id.getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530227 }
228
sonu guptaeff184b2016-11-24 12:43:49 +0530229 /*
230 * If yms operation is for query then no validation need to be
231 * performed.
232 */
233 if (ymsOperationType != YmsOperationType.QUERY_REQUEST) {
234 // Checking whether module node is already exits in YDT or not.
235 try {
236 curNode.getCollidingChild(id);
237 } catch (YdtException e) {
238 throw new YdtException(e.getLocalizedMessage());
239 }
240 }
241
242 YdtNode newNode = new YdtSingleInstanceNode(node);
sonu gupta1bb37b82016-11-11 16:51:18 +0530243 newNode.setYangSchemaNode(node);
sonu gupta1bb37b82016-11-11 16:51:18 +0530244 return newNode;
245 }
246
247 @Override
248 public void setRootTagAttributeMap(Map<String, String> attributeTag) {
249 rootTagAttributeMap = attributeTag;
250 }
251
252 @Override
253 public Map<String, String> getRootTagAttributeMap() {
254 if (rootTagAttributeMap != null) {
255 return ImmutableMap.copyOf(rootTagAttributeMap);
256 }
257 return null;
258 }
259
260 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530261 public void addChild(String name, String namespace)
262 throws IllegalArgumentException {
263 addChild(name, namespace, UNKNOWN, null, NON_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530264 }
265
266 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530267 public void addChild(String name, String namespace, YdtType ydtType)
268 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530269 addChild(name, namespace, ydtType, null);
270 }
271
272 @Override
273 public void addChild(String name, String namespace,
sonu guptaeff184b2016-11-24 12:43:49 +0530274 YdtContextOperationType opType)
275 throws IllegalArgumentException {
276 addChild(name, namespace, UNKNOWN, opType, NON_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530277 }
278
279 @Override
280 public void addChild(String name, String namespace, YdtType ydtType,
sonu guptaeff184b2016-11-24 12:43:49 +0530281 YdtContextOperationType opType)
282 throws IllegalArgumentException {
283 RequestedCardinality cardinality;
sonu gupta1bb37b82016-11-11 16:51:18 +0530284 switch (ydtType) {
285 case MULTI_INSTANCE_NODE:
286 cardinality = MULTI_INSTANCE;
287 break;
288 case SINGLE_INSTANCE_NODE:
289 cardinality = SINGLE_INSTANCE;
290 break;
291 default:
sonu guptaeff184b2016-11-24 12:43:49 +0530292 throw new IllegalArgumentException(E_USE_ADD_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530293 }
sonu guptaeff184b2016-11-24 12:43:49 +0530294 addChild(name, namespace, cardinality, opType, NON_LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530295 }
296
297 /**
298 * Adds a last child to YANG data tree; this method is to be used by all
299 * protocols internally which are aware or unaware of the nature
300 * (single/multiple) of node.
301 *
302 * @param name name of child to be added
303 * @param namespace namespace of child to be added
304 * @param cardinality type of YANG data tree node operation
305 * @param opType type of requested operation over a node
306 * @param callType to identify the whether its a leaf or other node
sonu guptaeff184b2016-11-24 12:43:49 +0530307 * @throws IllegalArgumentException when method has been passed an illegal
308 * or inappropriate argument.
sonu gupta1bb37b82016-11-11 16:51:18 +0530309 */
310 private void addChild(String name, String namespace,
311 RequestedCardinality cardinality,
312 YdtContextOperationType opType,
sonu guptaeff184b2016-11-24 12:43:49 +0530313 RequestedCallType callType)
314 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530315
sonu guptaeff184b2016-11-24 12:43:49 +0530316 YdtNode newNode;
317 boolean contextSwitch = false;
sonu gupta1bb37b82016-11-11 16:51:18 +0530318 YangSchemaNode augmentingSchema = null;
sonu guptaeff184b2016-11-24 12:43:49 +0530319 YangSchemaNodeIdentifier id = getNodeIdentifier(name, namespace);
sonu gupta1bb37b82016-11-11 16:51:18 +0530320
sonu guptaeff184b2016-11-24 12:43:49 +0530321 try {
322 // Module/sub-module node handler.
323 if (curNode.equals(rootNode)) {
324 newNode = moduleHandler(id);
sonu gupta1bb37b82016-11-11 16:51:18 +0530325 } else {
sonu guptaeff184b2016-11-24 12:43:49 +0530326
327 YangSchemaNode schemaNode;
328 YangSchemaNodeContextInfo contextInfo;
329
330 // If namespace given by user null, then take namespace from parent.
331 if (namespace == null) {
332 id.setNameSpace(curNode.getYangSchemaNode().getNameSpace());
sonu gupta1bb37b82016-11-11 16:51:18 +0530333 }
sonu guptaeff184b2016-11-24 12:43:49 +0530334
335 /*
336 * Get the already exiting YDT node in YDT tree with same
337 * nodeIdentifier
338 */
339 newNode = curNode.getCollidingChild(id);
340
341 /*
342 * If colliding child doesn't exist ,
343 * then query yang data model for schema of given node.
344 */
345 if (newNode == null) {
346 /*
347 * Get Yang Schema node context info which is having
348 * YangSchemaNode and ContextSwitchedNode.
349 */
350 contextInfo = curNode.getSchemaNodeContextInfo(id);
351
352 if (contextInfo.getContextSwitchedNode() != null) {
353 augmentingSchema = getAugmentingSchemaNode(
354 id, contextInfo);
355 if (augmentingSchema != null) {
356 /*
357 * As two tree(YDT and YDT Application Tree) are getting
358 * prepared in parallel, So setting context switch
359 * flag it will help ydt to keep the track whether
360 * ydtApp tree also need to be traversed back to parent
361 * or not with YDT tree traverse to parent call.
362 */
363 contextSwitch = true;
364 }
365 }
366 schemaNode = contextInfo.getSchemaNode();
367 } else {
368 /*
369 * If colliding child exist , then it will be leaf-list or list.
370 * If its leaf-list then return and add new requested
371 * value/valueSet in same node else take yang data model
372 * information from colliding child.
373 */
374 if (newNode.getYdtType() == MULTI_INSTANCE_LEAF_VALUE_NODE) {
375 curNode = newNode;
376 return;
377 }
378 schemaNode = newNode.getYangSchemaNode();
379 }
380
381 /*
382 * For yms query request node specific validation are not
383 * required as rest-conf can call addChild api for leaf/leaf-list
384 * node addition also in ydt.
385 */
386 if (ymsOperationType == YmsOperationType.QUERY_REQUEST) {
387 newNode = getYangSchemaNodeTypeSpecificContext(schemaNode);
388 } else {
389 newNode = getNode(schemaNode, cardinality, callType);
390 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530391 }
sonu guptaeff184b2016-11-24 12:43:49 +0530392
393 opType = getValidOpType(opType, ydtDefaultOpType, newNode, curNode);
394
395 newNode.setYdtContextOperationType(opType);
396
397 curNode.addChild(newNode, true);
398 } catch (YdtException e) {
399 freeRestResources(rootNode);
400 throw new IllegalArgumentException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530401 }
402
sonu gupta1bb37b82016-11-11 16:51:18 +0530403 // Update parent ydt node map.
sonu guptaeff184b2016-11-24 12:43:49 +0530404 curNode.updateYdtMap(newNode);
sonu gupta1bb37b82016-11-11 16:51:18 +0530405
sonu guptaeff184b2016-11-24 12:43:49 +0530406 processAppTree(opType, newNode, augmentingSchema, contextSwitch);
sonu gupta1bb37b82016-11-11 16:51:18 +0530407
sonu guptaeff184b2016-11-24 12:43:49 +0530408 curNode = newNode;
sonu gupta1bb37b82016-11-11 16:51:18 +0530409 }
410
411 /**
412 * Processes application tree on the bases of requested ydt node.
413 *
414 * @param opType user requested operation type
415 * @param childNode requested ydt node
416 * @param augmentingSchema schema of last augmenting node
sonu guptaeff184b2016-11-24 12:43:49 +0530417 * @param contextSwitch true, for module node call; false for modules
sonu gupta1bb37b82016-11-11 16:51:18 +0530418 * sub-node calls
419 */
420 private void processAppTree(
421 YdtContextOperationType opType, YdtNode childNode,
sonu guptaeff184b2016-11-24 12:43:49 +0530422 YangSchemaNode augmentingSchema, boolean contextSwitch) {
sonu gupta1bb37b82016-11-11 16:51:18 +0530423
sonu guptaeff184b2016-11-24 12:43:49 +0530424 if (curNode == rootNode) {
425 augGenMethodSet = new HashSet<>();
sonu gupta1bb37b82016-11-11 16:51:18 +0530426 }
sonu guptaeff184b2016-11-24 12:43:49 +0530427
sonu gupta1bb37b82016-11-11 16:51:18 +0530428 if (opType == null) {
429 opType = curNode.getYdtContextOperationType();
430 } else {
431 // Updating operation type for parent nodes
432 appCurNode.updateAppOperationType(opType);
433 }
434
435 /*
sonu guptaeff184b2016-11-24 12:43:49 +0530436 * This is to avoid multiple entries of single augmented target.
sonu gupta1bb37b82016-11-11 16:51:18 +0530437 */
sonu guptaeff184b2016-11-24 12:43:49 +0530438 if (augmentingSchema != null) {
439 if (!augGenMethodSet.add(((YangAugment) augmentingSchema)
440 .getSetterMethodName())) {
441 return;
442 }
443 }
444
445 /*
446 * Create entry of module node in ydt app tree.
447 * Or if context switch happened then also add entry for same
448 * augmented ydt node in the ydt application tree.
449 */
450 if (curNode.equals(rootNode) || contextSwitch) {
sonu gupta1bb37b82016-11-11 16:51:18 +0530451 addChildInAppTree(childNode, augmentingSchema, opType,
sonu guptaeff184b2016-11-24 12:43:49 +0530452 contextSwitch);
sonu gupta1bb37b82016-11-11 16:51:18 +0530453
454 // Setting app tree node operation.
455 appCurNode.setOperationType(getAppOpTypeFromYdtOpType(opType));
456 }
457
458 // Updating the delete operation list in app tree.
459 if (opType == DELETE || opType == REMOVE) {
460 appCurNode.addDeleteNode(childNode);
461 }
462 }
463
sonu gupta1bb37b82016-11-11 16:51:18 +0530464
465 /**
466 * Adds a last child to YANG app data tree.this method is to be used
467 * internally by other ydt interfaces.
468 *
469 * @param childNode node to be added in tree
470 * @param schemaNode last augmenting module node
471 * @param childOpType operation type of node
472 * @param isContextSwitch true, for module node call; false for modules
473 * sub-node calls
474 */
475 private void addChildInAppTree(YdtNode childNode,
476 YangSchemaNode schemaNode,
477 YdtContextOperationType childOpType,
478 boolean isContextSwitch) {
479
480 YdtAppNodeOperationType opType;
481
482 DefaultYdtAppContext appContext = getAppContext(isContextSwitch);
483
484 // Add context switched child in ydt App tree.
485 appCurNode.addChild(appContext);
sonu guptaeff184b2016-11-24 12:43:49 +0530486
sonu gupta1bb37b82016-11-11 16:51:18 +0530487 appCurNode = appContext;
488
sonu gupta1bb37b82016-11-11 16:51:18 +0530489 opType = getAppOpTypeFromYdtOpType(childOpType);
490
491 appCurNode.setAppData(childNode, schemaNode);
492
493 appCurNode.setOperationType(opType);
494
495 childNode.setAppContextSwitch();
496 }
497
sonu gupta1bb37b82016-11-11 16:51:18 +0530498 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530499 public void addLeaf(String name, String namespace, String value)
500 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530501 addLeaf(name, namespace, value, null, UNKNOWN);
502 }
503
504 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530505 public void addLeaf(String name, String namespace, Set<String> valueSet)
506 throws IllegalArgumentException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530507 addLeaf(name, namespace, null, valueSet, MULTI_INSTANCE_LEAF);
508 }
509
510 /**
511 * Adds a last leaf with list of values/single value to YANG data tree.
512 * This method is used by all protocols which knows the nature
513 * (single/multiple) or not.
514 * Value of leaf can be null which indicates selection node in get
515 * operation.
516 *
517 * @param name name of child to be added
518 * @param namespace namespace of child to be added, if it's
519 * null, parent's
520 * namespace will be applied to child
521 * @param value value of the child
522 * @param valueSet list of value of the child
523 * @param cardinality type of YANG data tree node operation
sonu guptaeff184b2016-11-24 12:43:49 +0530524 * @throws IllegalArgumentException when method has been passed an illegal
525 * or inappropriate argument.
sonu gupta1bb37b82016-11-11 16:51:18 +0530526 */
527 private void addLeaf(String name, String namespace, String value,
528 Set<String> valueSet,
sonu guptaeff184b2016-11-24 12:43:49 +0530529 RequestedCardinality cardinality)
530 throws IllegalArgumentException {
531 try {
532 addChild(name, namespace, cardinality, null, LEAF);
sonu gupta1bb37b82016-11-11 16:51:18 +0530533
sonu guptaeff184b2016-11-24 12:43:49 +0530534 // After successful addition of child node updating the values in same.
535 if (value != null) {
536 curNode.addValue(value);
537 } else if (valueSet != null) {
538 curNode.addValueSet(valueSet);
539 }
540 } catch (YdtException e) {
541 freeRestResources(rootNode);
542 throw new IllegalArgumentException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530543 }
544 }
545
546 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530547 public void traverseToParent() throws IllegalStateException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530548 // If traverse back to parent for logical root node comes
549 if (curNode.equals(rootNode)) {
sonu guptaeff184b2016-11-24 12:43:49 +0530550 freeRestResources(rootNode);
551 throw new IllegalStateException(E_INVOKE_PARENT);
sonu gupta1bb37b82016-11-11 16:51:18 +0530552 }
553
sonu guptaeff184b2016-11-24 12:43:49 +0530554 try {
sonu gupta1bb37b82016-11-11 16:51:18 +0530555
sonu guptaeff184b2016-11-24 12:43:49 +0530556 // If node is of multiInstanceNode type then check key uniqueness.
557 if (curNode.getYdtType() == MULTI_INSTANCE_NODE) {
558 curNode.createKeyNodeList();
559 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530560
sonu guptaeff184b2016-11-24 12:43:49 +0530561 /*
562 * Check application switch for curNode if set,
563 * then traverseToParent in YDT application tree.
564 */
565 if (curNode.getParent().equals(rootNode) ||
566 curNode.getAppContextSwitch()) {
567 traverseToAppTreeParent();
568 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530569
sonu guptaeff184b2016-11-24 12:43:49 +0530570 /*
571 * Validate all multi Instance inside current context,
572 * This is not valid for leaf and leaf-list node.
573 */
574 if (curNode instanceof YdtMultiInstanceNode ||
575 curNode instanceof YdtSingleInstanceNode) {
576 curNode.validateMultiInstanceNode();
577 }
578
579 curNode = curNode.getParent();
580 } catch (YdtException e) {
581 freeRestResources(rootNode);
582 throw new IllegalStateException(e.getLocalizedMessage());
583 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530584 }
585
586 /**
587 * Traverses up in YANG application tree to the parent node,
588 * This will be used when Ydt current context switch flag is set.
589 */
590 private void traverseToAppTreeParent() {
591 appCurNode = appCurNode.getParent();
592 }
593
594 @Override
janani b9069eb42016-11-24 17:50:08 +0530595 public YdtExtendedContext getCurNode() {
sonu gupta1bb37b82016-11-11 16:51:18 +0530596 return curNode;
597 }
598
599 @Override
600 public void setDefaultEditOperationType(
601 YdtContextOperationType opType) {
602 ydtDefaultOpType = opType;
603 }
604
605 @Override
606 public YdtExtendedContext getRootNode() {
607 return rootNode;
608 }
609
610 @Override
611 public YmsOperationType getYmsOperationType() {
612 return ymsOperationType;
613 }
614
615 @Override
616 public void addMultiInstanceChild(String name, String namespace,
617 List<String> keysValueList,
sonu guptaeff184b2016-11-24 12:43:49 +0530618 YdtContextOperationType opType)
619 throws IllegalArgumentException {
620
sonu gupta1bb37b82016-11-11 16:51:18 +0530621 addChild(name, namespace, UNKNOWN, opType,
622 RequestedCallType.MULTI_INSTANCE);
623 int inputCount = keysValueList.size();
sonu gupta1bb37b82016-11-11 16:51:18 +0530624
sonu guptaeff184b2016-11-24 12:43:49 +0530625 try {
626 if (curNode.getYdtType() == MULTI_INSTANCE_LEAF_VALUE_NODE) {
627
628 /*
629 * Calculating the current leaf-list node array size by adding
630 * existing elements count and new supplied elements by user for
631 * the same.
632 */
633 // TODO instance count for leaf list need to be handled.
634// if (curNode.getValueSet().size() + inputCount > expectedCount) {
635// curNode.errorHandler(
636// errorMsg(FMT_MANY_INS, name, expectedCount), rootNode);
637// }
638
639 /*
640 * After successful addition of child node updating
641 * the values in same.
642 */
643 for (String value : keysValueList) {
644 curNode.addValue(value);
sonu gupta1bb37b82016-11-11 16:51:18 +0530645 }
sonu guptaeff184b2016-11-24 12:43:49 +0530646 } else if (curNode.getYdtType() == MULTI_INSTANCE_NODE) {
sonu gupta1bb37b82016-11-11 16:51:18 +0530647
sonu guptaeff184b2016-11-24 12:43:49 +0530648 YangList yangListHolder = (YangList) curNode.getYangSchemaNode();
649 List<String> schemaKeyList = yangListHolder.getKeyList();
650 int expectedCount = schemaKeyList.size();
651 checkElementCount(name, expectedCount, inputCount);
652
653 //After validation adding the key nodes under the list node.
654 Iterator<String> sklIter = schemaKeyList.iterator();
655 Iterator<String> kvlIter = keysValueList.iterator();
656 String keyEleName;
657
658 while (kvlIter.hasNext()) {
659 String value = kvlIter.next();
660 keyEleName = sklIter.next();
661 addLeaf(keyEleName, namespace, value);
662 if (kvlIter.hasNext()) {
663 traverseToParentWithoutValidation();
664 }
665 }
666
667 curNode = curNode.getParent();
668 }
669 } catch (YdtException e) {
670 freeRestResources(rootNode);
671 throw new IllegalArgumentException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530672 }
673 }
674
675 /**
676 * Adds a last child to YANG data tree, this method is to be used by
677 * YANG object builder sub-calls internally.
678 *
679 * @param opType type of requested operation over a node
680 * @return returns added ydt node in YDT tree
681 */
682 private YdtNode addExtendedChildNode(YdtContextOperationType opType,
683 YangSchemaNode schemaNode) {
684
sonu guptaeff184b2016-11-24 12:43:49 +0530685 YdtNode childNode = getYangSchemaNodeTypeSpecificContext(schemaNode);
sonu gupta1bb37b82016-11-11 16:51:18 +0530686
687 childNode.setYangSchemaNode(schemaNode);
688
689 childNode.setYdtContextOperationType(opType);
690
691 curNode.addChild(childNode, true);
692
693 curNode = childNode;
694
695 return childNode;
696 }
697
698 @Override
699 public YdtExtendedContext addChild(YdtContextOperationType opType,
700 YangSchemaNode schemaNode) {
701 return addExtendedChildNode(opType, schemaNode);
702 }
703
704 @Override
705 public YdtExtendedContext addLeafList(Set<String> valueSet,
706 YangSchemaNode schemaNode) {
707 YdtNode childNode = addExtendedChildNode(null, schemaNode);
708
sonu guptaeff184b2016-11-24 12:43:49 +0530709 /*
710 * After successful addition of child node updating the values in
711 * valueSet.
712 */
sonu gupta1bb37b82016-11-11 16:51:18 +0530713 childNode.addValueSetWithoutValidation(valueSet);
714 return childNode;
715 }
716
717 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530718 public YdtExtendedContext addLeaf(String value, YangSchemaNode schemaNode) {
719
sonu gupta1bb37b82016-11-11 16:51:18 +0530720 YdtNode childNode = addExtendedChildNode(null, schemaNode);
721
722 // After successful addition of child node updating the values in same.
sonu guptaeff184b2016-11-24 12:43:49 +0530723 childNode.addValueWithoutValidation(value, ((YangLeaf) schemaNode)
724 .isKeyLeaf());
sonu gupta1bb37b82016-11-11 16:51:18 +0530725 return childNode;
726 }
727
728 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530729 public void traverseToParentWithoutValidation()
730 throws IllegalStateException {
731 // If traverse back to parent for logical root node comes.
sonu gupta1bb37b82016-11-11 16:51:18 +0530732 if (curNode.equals(rootNode)) {
sonu guptaeff184b2016-11-24 12:43:49 +0530733 freeRestResources(rootNode);
734 throw new IllegalStateException(E_INVOKE_PARENT);
sonu gupta1bb37b82016-11-11 16:51:18 +0530735 }
736 curNode = curNode.getParent();
737 }
sonu guptaeff184b2016-11-24 12:43:49 +0530738
739 /**
740 * Returns the method name's set for an augmented target node in an
741 * application tree.
742 *
743 * @return augGenMethodSet set of method name's
744 */
745 public Set<String> getAugGenMethodSet() {
746 return augGenMethodSet;
747 }
748
749 /**
750 * Sets the method name's set for an augmented target node in an
751 * application tree.
752 *
753 * @param augGenMethodSet set of method name's
754 */
755 public void setAugGenMethodSet(Set<String> augGenMethodSet) {
756 this.augGenMethodSet = augGenMethodSet;
757 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530758}