blob: 89d2dbef77f929ed0b2419d258fe51cf65bbb38a [file] [log] [blame]
Bharat saraswald14cbe82016-07-14 13:26: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.yangutils.linker.impl;
18
Bharat saraswal039f59c2016-07-14 21:57:13 +053019import java.util.ArrayList;
20import java.util.HashMap;
21import java.util.Iterator;
22import java.util.List;
23import java.util.Map;
24import java.util.Stack;
Bharat saraswale304c252016-08-16 20:56:20 +053025
janani bebb143d2016-07-14 19:35:22 +053026import org.onosproject.yangutils.datamodel.YangAtomicPath;
27import org.onosproject.yangutils.datamodel.YangAugment;
28import org.onosproject.yangutils.datamodel.YangCase;
29import org.onosproject.yangutils.datamodel.YangChoice;
30import org.onosproject.yangutils.datamodel.YangGrouping;
31import org.onosproject.yangutils.datamodel.YangImport;
32import org.onosproject.yangutils.datamodel.YangInclude;
33import org.onosproject.yangutils.datamodel.YangInput;
34import org.onosproject.yangutils.datamodel.YangLeaf;
35import org.onosproject.yangutils.datamodel.YangLeafList;
36import org.onosproject.yangutils.datamodel.YangLeafRef;
37import org.onosproject.yangutils.datamodel.YangLeavesHolder;
38import org.onosproject.yangutils.datamodel.YangModule;
39import org.onosproject.yangutils.datamodel.YangNode;
40import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
41import org.onosproject.yangutils.datamodel.YangOutput;
42import org.onosproject.yangutils.datamodel.YangSubModule;
43import org.onosproject.yangutils.datamodel.YangTypeDef;
44import org.onosproject.yangutils.datamodel.YangUses;
45import org.onosproject.yangutils.linker.exceptions.LinkerException;
46
Bharat saraswalaf413b82016-07-14 15:18:20 +053047import static org.onosproject.yangutils.linker.impl.PrefixResolverType.INTER_TO_INTER;
48import static org.onosproject.yangutils.linker.impl.PrefixResolverType.INTER_TO_INTRA;
49import static org.onosproject.yangutils.linker.impl.PrefixResolverType.INTRA_TO_INTER;
50import static org.onosproject.yangutils.linker.impl.PrefixResolverType.NO_PREFIX_CHANGE_FOR_INTER;
51import static org.onosproject.yangutils.linker.impl.PrefixResolverType.NO_PREFIX_CHANGE_FOR_INTRA;
janani bebb143d2016-07-14 19:35:22 +053052import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
53import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
Bharat saraswalaf413b82016-07-14 15:18:20 +053054
Bharat saraswald14cbe82016-07-14 13:26:18 +053055/**
56 * Represents x-path linking.
57 *
58 * @param <T> x-path linking can be done for target node or for target leaf/leaf-list
59 */
60public class YangXpathLinker<T> {
61
Bharat saraswald14cbe82016-07-14 13:26:18 +053062 private List<YangAtomicPath> absPaths;
63 private YangNode rootNode;
Bharat saraswalaf413b82016-07-14 15:18:20 +053064 private Map<YangAtomicPath, PrefixResolverType> prefixResolverTypes;
Bharat saraswald14cbe82016-07-14 13:26:18 +053065 private String curPrefix;
Bharat saraswald14cbe82016-07-14 13:26:18 +053066
67 /**
68 * Creates an instance of x-path linker.
69 */
70 public YangXpathLinker() {
71 absPaths = new ArrayList<>();
Bharat saraswald14cbe82016-07-14 13:26:18 +053072 }
73
74 /**
Bharat saraswalaf413b82016-07-14 15:18:20 +053075 * Returns prefix resolver list.
76 *
77 * @return prefix resolver list
78 */
Bharat saraswal64e7e232016-07-14 23:33:55 +053079 private Map<YangAtomicPath, PrefixResolverType> getPrefixResolverTypes() {
Bharat saraswalaf413b82016-07-14 15:18:20 +053080 return prefixResolverTypes;
81 }
82
83 /**
84 * Sets prefix resolver list.
85 *
86 * @param prefixResolverTypes prefix resolver list.
87 */
Bharat saraswal64e7e232016-07-14 23:33:55 +053088 private void setPrefixResolverTypes(Map<YangAtomicPath, PrefixResolverType> prefixResolverTypes) {
Bharat saraswalaf413b82016-07-14 15:18:20 +053089 this.prefixResolverTypes = prefixResolverTypes;
90 }
91
92 /**
93 * Adds to the prefix resolver type map.
94 *
95 * @param type resolver type
96 * @param path absolute path
97 */
98 private void addToPrefixResolverList(PrefixResolverType type, YangAtomicPath path) {
99 getPrefixResolverTypes().put(path, type);
100 }
101
102 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530103 * Returns list of target nodes paths.
104 *
105 * @return target nodes paths
106 */
107 private List<YangAtomicPath> getAbsPaths() {
108 return absPaths;
109 }
110
111 /**
112 * Sets target nodes paths.
113 *
114 * @param absPaths target nodes paths
115 */
116 private void setAbsPaths(List<YangAtomicPath> absPaths) {
117 this.absPaths = absPaths;
118 }
119
120 /**
janani bade77ae2016-08-17 16:33:07 +0530121 * Adds target nodes paths.
122 *
123 * @param absPaths target nodes paths
124 */
125 private void addAbsPaths(YangAtomicPath absPaths) {
126 getAbsPaths().add(absPaths);
127 }
128
129 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530130 * Returns current prefix.
131 *
132 * @return current prefix
133 */
134 private String getCurPrefix() {
135 return curPrefix;
136 }
137
138 /**
139 * Sets current prefix.
140 *
141 * @param curPrefix current prefix
142 */
143 private void setCurPrefix(String curPrefix) {
144 this.curPrefix = curPrefix;
145 }
146
147 /**
148 * Return root node.
149 *
150 * @return root Node
151 */
152 private YangNode getRootNode() {
153 return rootNode;
154 }
155
156 /**
157 * Sets root node.
158 *
159 * @param rootNode root node
160 */
161 private void setRootNode(YangNode rootNode) {
162 this.rootNode = rootNode;
163 }
164
165 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530166 * Adds node to resolved nodes.
167 *
168 * @param path absolute path
169 * @param node resolved node
170 */
171 private void addToResolvedNodes(YangAtomicPath path, YangNode node) {
Bharat saraswal039f59c2016-07-14 21:57:13 +0530172 path.setResolvedNode(node);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530173 }
174
175 /**
176 * Returns list of augment nodes.
177 *
178 * @param node root node
179 * @return list of augment nodes
180 */
181 public List<YangAugment> getListOfYangAugment(YangNode node) {
182 node = node.getChild();
183 List<YangAugment> augments = new ArrayList<>();
184 while (node != null) {
185 if (node instanceof YangAugment) {
186 augments.add((YangAugment) node);
187 }
188 node = node.getNextSibling();
189 }
190 return augments;
191 }
192
193 /**
194 * Process absolute node path for target leaf.
195 *
janani bebb143d2016-07-14 19:35:22 +0530196 * @param atomicPaths atomic path node list
Bharat saraswale304c252016-08-16 20:56:20 +0530197 * @param root root node
198 * @param leafref instance of YANG leafref
Bharat saraswald14cbe82016-07-14 13:26:18 +0530199 * @return linked target node
200 */
Bharat saraswal64e7e232016-07-14 23:33:55 +0530201 T processLeafRefXpathLinking(List<YangAtomicPath> atomicPaths, YangNode root, YangLeafRef leafref) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530202
Bharat saraswal039f59c2016-07-14 21:57:13 +0530203 YangNode targetNode;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530204 setRootNode(root);
Bharat saraswalaf413b82016-07-14 15:18:20 +0530205 setPrefixResolverTypes(new HashMap<>());
janani bebb143d2016-07-14 19:35:22 +0530206 parsePrefixResolverList(atomicPaths);
207 YangAtomicPath leafRefPath = atomicPaths.get(atomicPaths.size() - 1);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530208
209 // When leaf-ref path contains only one absolute path.
janani bebb143d2016-07-14 19:35:22 +0530210 if (atomicPaths.size() == 1) {
211 targetNode = getTargetNodewhenSizeIsOne(atomicPaths);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530212 } else {
janani bade77ae2016-08-17 16:33:07 +0530213 for (YangAtomicPath atomicPath : atomicPaths) {
214 if (atomicPath != leafRefPath) {
215 addAbsPaths(atomicPath);
216 }
217 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530218 targetNode = parseData(root);
219 }
220 if (targetNode == null) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530221 targetNode = searchInSubModule(root);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530222 }
223
janani bebb143d2016-07-14 19:35:22 +0530224 // Invalid path presence in the node list is checked.
225 validateInvalidNodesInThePath(leafref);
226
Bharat saraswald14cbe82016-07-14 13:26:18 +0530227 if (targetNode != null) {
228 YangLeaf targetLeaf = searchReferredLeaf(targetNode, leafRefPath.getNodeIdentifier().getName());
229 if (targetLeaf == null) {
230 YangLeafList targetLeafList = searchReferredLeafList(targetNode,
231 leafRefPath.getNodeIdentifier().getName());
232 if (targetLeafList != null) {
233 return (T) targetLeafList;
234 } else {
janani bebb143d2016-07-14 19:35:22 +0530235 LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
236 "leaf/leaf-list for given leafref path "
237 + leafref.getPath());
238 linkerException.setCharPosition(leafref.getCharPosition());
239 linkerException.setLine(leafref.getLineNumber());
240 throw linkerException;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530241 }
242 }
243 return (T) targetLeaf;
244 }
245 return null;
246 }
247
248 /**
janani bebb143d2016-07-14 19:35:22 +0530249 * Validates the nodes in the path for any invalid node.
250 *
251 * @param leafref instance of YANG leafref
252 */
253 private void validateInvalidNodesInThePath(YangLeafRef leafref) {
Bharat saraswal039f59c2016-07-14 21:57:13 +0530254 for (YangAtomicPath absolutePath : (Iterable<YangAtomicPath>) leafref.getAtomicPath()) {
255 YangNode nodeInPath = absolutePath.getResolvedNode();
janani bebb143d2016-07-14 19:35:22 +0530256
257 if (nodeInPath instanceof YangGrouping || nodeInPath instanceof YangUses
258 || nodeInPath instanceof YangTypeDef || nodeInPath instanceof YangCase
259 || nodeInPath instanceof YangChoice) {
260 LinkerException linkerException = new LinkerException("YANG file error: The target node, in the " +
261 "leafref path " + leafref.getPath() + ", is invalid.");
262 linkerException.setCharPosition(leafref.getCharPosition());
263 linkerException.setLine(leafref.getLineNumber());
264 throw linkerException;
265 }
266 }
267 }
268
269 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530270 * Returns target node when leaf-ref has only one absolute path in list.
271 *
272 * @param absPaths absolute paths
273 * @return target node
274 */
275 private YangNode getTargetNodewhenSizeIsOne(List<YangAtomicPath> absPaths) {
276 if (absPaths.get(0).getNodeIdentifier().getPrefix() != null
277 && !absPaths.get(0).getNodeIdentifier().getPrefix().equals(getRootsPrefix(getRootNode()))) {
278 return getImportedNode(getRootNode(), absPaths.get(0).getNodeIdentifier());
279 }
280 return getRootNode();
281
282 }
283
284 /**
285 * Process absolute node path linking for augment.
286 *
287 * @param absPaths absolute path node list
Bharat saraswalaf413b82016-07-14 15:18:20 +0530288 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530289 * @return linked target node
290 */
291 public YangNode processAugmentXpathLinking(List<YangAtomicPath> absPaths, YangNode root) {
292
293 setAbsPaths(absPaths);
294 setRootNode(root);
Bharat saraswalaf413b82016-07-14 15:18:20 +0530295 setPrefixResolverTypes(new HashMap<>());
296 parsePrefixResolverList(absPaths);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530297
298 YangNode targetNode = parseData(root);
299
300 if (targetNode == null) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530301 targetNode = searchInSubModule(root);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530302 }
303 return targetNode;
304
305 }
306
307 /**
308 * Searches for the referred leaf in target node.
309 *
310 * @param targetNode target node
Bharat saraswalaf413b82016-07-14 15:18:20 +0530311 * @param leafName leaf name
Bharat saraswald14cbe82016-07-14 13:26:18 +0530312 * @return target leaf
313 */
314 private YangLeaf searchReferredLeaf(YangNode targetNode, String leafName) {
315 if (!(targetNode instanceof YangLeavesHolder)) {
316 throw new LinkerException("Refered node " + targetNode.getName() +
317 "should be of type leaves holder ");
318 }
319 YangLeavesHolder holder = (YangLeavesHolder) targetNode;
320 List<YangLeaf> leaves = holder.getListOfLeaf();
janani bebb143d2016-07-14 19:35:22 +0530321 if (leaves != null && !leaves.isEmpty()) {
Bharat saraswal039f59c2016-07-14 21:57:13 +0530322 for (YangLeaf leaf : leaves) {
janani bebb143d2016-07-14 19:35:22 +0530323 if (leaf.getName().equals(leafName)) {
324 return leaf;
325 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530326 }
327 }
328 return null;
329 }
330
331 /**
332 * Searches for the referred leaf-list in target node.
333 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530334 * @param targetNode target node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530335 * @param leafListName leaf-list name
336 * @return target leaf-list
337 */
338 private YangLeafList searchReferredLeafList(YangNode targetNode, String leafListName) {
339 if (!(targetNode instanceof YangLeavesHolder)) {
340 throw new LinkerException("Refered node " + targetNode.getName() +
341 "should be of type leaves holder ");
342 }
343 YangLeavesHolder holder = (YangLeavesHolder) targetNode;
344 List<YangLeafList> leavesList = holder.getListOfLeafList();
janani bebb143d2016-07-14 19:35:22 +0530345 if (leavesList != null && !leavesList.isEmpty()) {
Bharat saraswal039f59c2016-07-14 21:57:13 +0530346 for (YangLeafList leafList : leavesList) {
janani bebb143d2016-07-14 19:35:22 +0530347 if (leafList.getName().equals(leafListName)) {
348 return leafList;
349 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530350 }
351 }
352 return null;
353 }
354
355 /**
356 * Process linking using for node identifier for inter/intra file.
357 *
358 * @param root root node
359 * @return linked target node
360 */
361 private YangNode parseData(YangNode root) {
362 String rootPrefix = getRootsPrefix(root);
363 Iterator<YangAtomicPath> pathIterator = getAbsPaths().iterator();
364 YangAtomicPath path = pathIterator.next();
365 if (path.getNodeIdentifier().getPrefix() != null
366 && !path.getNodeIdentifier().getPrefix().equals(rootPrefix)) {
367 return parsePath(getImportedNode(root, path.getNodeIdentifier()));
368 } else {
369 return parsePath(root);
370 }
371 }
372
373 /**
374 * Process linking of target node in root node.
375 *
376 * @param root root node
377 * @return linked target node
378 */
379 private YangNode parsePath(YangNode root) {
380
381 YangNode tempNode = root;
382 Stack<YangNode> linkerStack = new Stack<>();
383 Iterator<YangAtomicPath> pathIterator = getAbsPaths().iterator();
384 YangAtomicPath tempPath = pathIterator.next();
385 setCurPrefix(tempPath.getNodeIdentifier().getPrefix());
386 int index = 0;
Bharat saraswalaf413b82016-07-14 15:18:20 +0530387 YangNode tempAugment;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530388 do {
389
Bharat saraswald14cbe82016-07-14 13:26:18 +0530390 if (tempPath.getNodeIdentifier().getPrefix() == null) {
391 tempAugment = resolveIntraFileAugment(tempPath, root);
392 } else {
393 tempAugment = resolveInterFileAugment(tempPath, root);
394 }
395
396 if (tempAugment != null) {
397 linkerStack.push(tempNode);
398 tempNode = tempAugment;
399 }
400
401 tempNode = searchTargetNode(tempNode, tempPath.getNodeIdentifier());
402 if (tempNode == null && linkerStack.size() != 0) {
403 tempNode = linkerStack.peek();
404 linkerStack.pop();
405 tempNode = searchTargetNode(tempNode, tempPath.getNodeIdentifier());
406 }
407
408 if (tempNode != null) {
409 addToResolvedNodes(tempPath, tempNode);
410 }
411
412 if (index == getAbsPaths().size() - 1) {
413 break;
414 }
415 tempPath = pathIterator.next();
416 index++;
417 } while (validate(tempNode, index));
418 return tempNode;
419 }
420
421 /**
422 * Resolves intra file augment linking.
423 *
424 * @param tempPath temporary absolute path
Bharat saraswalaf413b82016-07-14 15:18:20 +0530425 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530426 * @return linked target node
427 */
428 private YangNode resolveIntraFileAugment(YangAtomicPath tempPath, YangNode root) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530429 YangNode tempAugment;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530430 if (getCurPrefix() != tempPath.getNodeIdentifier().getPrefix()) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530431 root = getIncludedNode(getRootNode(), tempPath.getNodeIdentifier().getName());
432 if (root == null) {
433 root = getIncludedNode(getRootNode(), getAugmentNodeIdentifier(tempPath.getNodeIdentifier(), absPaths,
434 getRootNode()));
435 if (root == null) {
436 root = getRootNode();
437 }
438 }
439 } else {
440 if (getCurPrefix() != null) {
441 root = getImportedNode(root, tempPath.getNodeIdentifier());
442 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530443 }
444
445 setCurPrefix(tempPath.getNodeIdentifier().getPrefix());
446 tempAugment = getAugment(tempPath.getNodeIdentifier(), root, getAbsPaths());
447 if (tempAugment == null) {
448 tempAugment = getAugment(tempPath.getNodeIdentifier(), getRootNode(), getAbsPaths());
449 }
450 return tempAugment;
451 }
452
453 /**
454 * Resolves inter file augment linking.
455 *
456 * @param tempPath temporary absolute path
Bharat saraswalaf413b82016-07-14 15:18:20 +0530457 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530458 * @return linked target node
459 */
460 private YangNode resolveInterFileAugment(YangAtomicPath tempPath, YangNode root) {
461
Bharat saraswalaf413b82016-07-14 15:18:20 +0530462 YangNode tempAugment;
463 if (!tempPath.getNodeIdentifier().getPrefix().equals(getCurPrefix())) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530464 setCurPrefix(tempPath.getNodeIdentifier().getPrefix());
Bharat saraswald14cbe82016-07-14 13:26:18 +0530465 root = getImportedNode(getRootNode(), tempPath.getNodeIdentifier());
466 }
467 tempAugment = getAugment(tempPath.getNodeIdentifier(), root, getAbsPaths());
Bharat saraswalaf413b82016-07-14 15:18:20 +0530468 if (tempAugment == null) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530469 return resolveInterToInterFileAugment(root);
470 }
471 return tempAugment;
472 }
473
474 /**
475 * Resolves augment when prefix changed from inter file to inter file.
476 * it may be possible that the prefix used in imported module is different the
477 * given list of node identifiers.
478 *
479 * @param root root node
480 * @return target node
481 */
482 private YangNode resolveInterToInterFileAugment(YangNode root) {
483 List<YangAugment> augments = getListOfYangAugment(root);
484 int index;
485 List<YangAtomicPath> absPaths = new ArrayList<>();
486 for (YangAugment augment : augments) {
487 index = 0;
488
489 for (YangAtomicPath path : augment.getTargetNode()) {
490
491 if (!searchForAugmentInImportedNode(path.getNodeIdentifier(), index)) {
492 absPaths.clear();
493 break;
494 }
495 absPaths.add(path);
496 index++;
497 }
498 if (!absPaths.isEmpty() && absPaths.size() == getAbsPaths().size() - 1) {
499 return augment;
500 } else {
501 absPaths.clear();
502 }
503 }
504 return null;
505 }
506
507 /**
508 * Searches for the augment node in imported module when prefix has changed from
509 * inter file to inter file.
Bharat saraswalaf413b82016-07-14 15:18:20 +0530510 *
Bharat saraswald14cbe82016-07-14 13:26:18 +0530511 * @param nodeId node id
Bharat saraswalaf413b82016-07-14 15:18:20 +0530512 * @param index index
Bharat saraswald14cbe82016-07-14 13:26:18 +0530513 * @return true if found
514 */
515 private boolean searchForAugmentInImportedNode(YangNodeIdentifier nodeId, int index) {
Bharat saraswale304c252016-08-16 20:56:20 +0530516 if (index == getAbsPaths().size()) {
517 return false;
518 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530519 YangNodeIdentifier tempNodeId = getAbsPaths().get(index).getNodeIdentifier();
520 return nodeId.getName().equals(tempNodeId.getName());
521 }
522
523 /**
524 * Returns augment node.
525 *
526 * @param tempNodeId temporary absolute path id
Bharat saraswalaf413b82016-07-14 15:18:20 +0530527 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530528 * @return linked target node
529 */
530 private YangNode getAugment(YangNodeIdentifier tempNodeId, YangNode root, List<YangAtomicPath> absPaths) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530531 String augmentName = getAugmentNodeIdentifier(tempNodeId, absPaths, root);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530532 if (augmentName != null) {
533 return searchAugmentNode(root, augmentName);
534 }
535 return null;
536 }
537
538 /**
539 * Process linking using import list.
540 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530541 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530542 * @param nodeId node identifier
543 * @return linked target node
544 */
545 private YangNode getImportedNode(YangNode root, YangNodeIdentifier nodeId) {
546
Bharat saraswalaf413b82016-07-14 15:18:20 +0530547 List<YangImport> importList;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530548
549 if (root instanceof YangModule) {
550 importList = ((YangModule) root).getImportList();
551 } else {
552 importList = ((YangSubModule) root).getImportList();
553 }
554
555 for (YangImport imported : importList) {
556 if (imported.getPrefixId().equals(nodeId.getPrefix())) {
557 return imported.getImportedNode();
558 }
559 }
560
561 return root;
562 }
563
564 /**
Bharat saraswalaf413b82016-07-14 15:18:20 +0530565 * Searches in sub-module node.
Bharat saraswald14cbe82016-07-14 13:26:18 +0530566 *
567 * @param root root node
Bharat saraswalaf413b82016-07-14 15:18:20 +0530568 * @return target linked node
569 */
570 private YangNode searchInSubModule(YangNode root) {
571 List<YangInclude> includeList;
572 YangNode tempNode;
573 if (root instanceof YangModule) {
574 includeList = ((YangModule) root).getIncludeList();
575 } else {
576 includeList = ((YangSubModule) root).getIncludeList();
577 }
578
579 for (YangInclude included : includeList) {
580 tempNode = parseData(included.getIncludedNode());
581 if (tempNode != null) {
582 return tempNode;
583 }
584 }
585 return null;
586 }
587
588 /**
589 * Process linking using include list.
590 *
591 * @param root root node
592 * @param tempPathName temporary path node name
Bharat saraswald14cbe82016-07-14 13:26:18 +0530593 * @return linked target node
594 */
Bharat saraswalaf413b82016-07-14 15:18:20 +0530595 private YangNode getIncludedNode(YangNode root, String tempPathName) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530596
Bharat saraswalaf413b82016-07-14 15:18:20 +0530597 List<YangInclude> includeList;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530598
599 if (root instanceof YangModule) {
600 includeList = ((YangModule) root).getIncludeList();
601 } else {
602 includeList = ((YangSubModule) root).getIncludeList();
603 }
604
605 for (YangInclude included : includeList) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530606 if (verifyChildNode(included.getIncludedNode(), tempPathName)) {
607 return included.getIncludedNode();
608 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530609 }
610
Bharat saraswalaf413b82016-07-14 15:18:20 +0530611 return null;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530612 }
613
614 /**
Bharat saraswalaf413b82016-07-14 15:18:20 +0530615 * Verifies for child nodes in sub module.
Bharat saraswald14cbe82016-07-14 13:26:18 +0530616 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530617 * @param node submodule node
618 * @param name name of child node
619 * @return true if child node found
Bharat saraswald14cbe82016-07-14 13:26:18 +0530620 */
Bharat saraswalaf413b82016-07-14 15:18:20 +0530621 private boolean verifyChildNode(YangNode node, String name) {
622 node = node.getChild();
623 while (node != null) {
624 if (node.getName().equals(name)) {
625 return true;
626 }
627 node = node.getNextSibling();
628 }
629 return false;
630 }
631
632
633 /**
634 * Returns augment's node id.
635 *
636 * @param nodeId node identifier
637 * @param absPaths absolute paths
638 * @param root root node
639 * @return augment's node id
640 */
641 private String getAugmentNodeIdentifier(YangNodeIdentifier nodeId, List<YangAtomicPath> absPaths, YangNode root) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530642
643 Iterator<YangAtomicPath> nodeIdIterator = absPaths.iterator();
Bharat saraswalaf413b82016-07-14 15:18:20 +0530644 YangAtomicPath tempNodeId;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530645 StringBuilder builder = new StringBuilder();
Bharat saraswalaf413b82016-07-14 15:18:20 +0530646 String id;
647 PrefixResolverType type;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530648 while (nodeIdIterator.hasNext()) {
649 tempNodeId = nodeIdIterator.next();
650 if (!tempNodeId.getNodeIdentifier().equals(nodeId)) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530651 type = getPrefixResolverTypes().get(tempNodeId);
652 switch (type) {
653 case INTER_TO_INTRA:
654 id = "/" + tempNodeId.getNodeIdentifier().getName();
655 break;
656 case INTRA_TO_INTER:
657 if (!getRootsPrefix(root).equals(tempNodeId.getNodeIdentifier().getPrefix())) {
658 id = "/" + tempNodeId.getNodeIdentifier().getPrefix() + ":" + tempNodeId.getNodeIdentifier()
659 .getName();
660 } else {
661 id = "/" + tempNodeId.getNodeIdentifier().getName();
662 }
663 break;
664 case INTER_TO_INTER:
665 id = "/" + tempNodeId.getNodeIdentifier().getPrefix() + ":" + tempNodeId.getNodeIdentifier()
666 .getName();
667 break;
668 case NO_PREFIX_CHANGE_FOR_INTRA:
669 id = "/" + tempNodeId.getNodeIdentifier().getName();
670 break;
671 case NO_PREFIX_CHANGE_FOR_INTER:
672 if (!getRootsPrefix(root).equals(tempNodeId.getNodeIdentifier().getPrefix())) {
673 id = "/" + tempNodeId.getNodeIdentifier().getPrefix() + ":" + tempNodeId.getNodeIdentifier()
674 .getName();
675 } else {
676 id = "/" + tempNodeId.getNodeIdentifier().getName();
677 }
678 break;
679 default:
680 id = "/" + tempNodeId.getNodeIdentifier().getName();
681 break;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530682 }
Bharat saraswalaf413b82016-07-14 15:18:20 +0530683 builder.append(id);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530684 } else {
685 return builder.toString();
686 }
687 }
688 return null;
689 }
690
691 /**
692 * Searches augment node in root node.
693 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530694 * @param node root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530695 * @param tempNodeId node identifier
696 * @return target augment node
697 */
Bharat saraswalaf413b82016-07-14 15:18:20 +0530698
Bharat saraswald14cbe82016-07-14 13:26:18 +0530699 private YangNode searchAugmentNode(YangNode node, String tempNodeId) {
700 node = node.getChild();
701 while (node != null) {
702 if (node instanceof YangAugment) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530703 if (node.getName().equals(tempNodeId)) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530704 return node;
705 }
706 }
707 node = node.getNextSibling();
708 }
709 return null;
710 }
711
712 /**
713 * Validates for target node if target node found or not.
714 *
715 * @param tempNode temporary node
Bharat saraswalaf413b82016-07-14 15:18:20 +0530716 * @param index current index of list
Bharat saraswald14cbe82016-07-14 13:26:18 +0530717 * @return false if target node found
718 */
719 private boolean validate(YangNode tempNode, int index) {
720
721 int size = getAbsPaths().size();
722 if (tempNode != null && index != size) {
723 return true;
Bharat saraswalaf413b82016-07-14 15:18:20 +0530724 } else if (tempNode != null) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530725 return false;
726 // this is your target node.
Bharat saraswalaf413b82016-07-14 15:18:20 +0530727 } else if (index != size) {
728 return true;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530729 // this could be in submodule as well.
730 }
731 return false;
732 }
733
734 /**
735 * Searches target node in root node.
736 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530737 * @param node root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530738 * @param curNodeId YANG node identifier
739 * @return linked target node
740 */
741 private YangNode searchTargetNode(YangNode node, YangNodeIdentifier curNodeId) {
742
743 if (node != null) {
744 node = node.getChild();
745 }
746
747 while (node != null) {
janani bebb143d2016-07-14 19:35:22 +0530748 if (node instanceof YangInput) {
749 if (curNodeId.getName().equalsIgnoreCase(INPUT)) {
750 return node;
751 }
752 } else if (node instanceof YangOutput) {
753 if (curNodeId.getName().equalsIgnoreCase(OUTPUT)) {
754 return node;
755 }
756 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530757 if (node.getName().equals(curNodeId.getName())) {
758 return node;
759 }
760 node = node.getNextSibling();
761 }
762 return null;
763 }
764
765 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530766 * Returns root prefix.
767 *
768 * @param root root node
769 * @return root prefix
770 */
771 private String getRootsPrefix(YangNode root) {
772 if (root instanceof YangModule) {
773 return ((YangModule) root).getPrefix();
774 } else {
775 return ((YangSubModule) root).getPrefix();
776 }
777 }
778
Bharat saraswalaf413b82016-07-14 15:18:20 +0530779 /**
780 * Resolves prefix and provides prefix resolver list.
781 *
782 * @param absolutePaths absolute paths
783 */
784 private void parsePrefixResolverList(List<YangAtomicPath> absolutePaths) {
785 Iterator<YangAtomicPath> pathIterator = absolutePaths.iterator();
786 YangAtomicPath absPath;
787 String prePrefix;
788 String curPrefix = null;
789 while (pathIterator.hasNext()) {
790 prePrefix = curPrefix;
791 absPath = pathIterator.next();
792 curPrefix = absPath.getNodeIdentifier().getPrefix();
793 if (curPrefix != null) {
794 if (!curPrefix.equals(prePrefix)) {
795 if (prePrefix != null) {
796 addToPrefixResolverList(INTER_TO_INTER, absPath);
797 } else {
798 addToPrefixResolverList(INTRA_TO_INTER, absPath);
799 }
800 } else {
801 addToPrefixResolverList(NO_PREFIX_CHANGE_FOR_INTER, absPath);
802 }
803 } else {
804 if (prePrefix != null) {
805 addToPrefixResolverList(INTER_TO_INTRA, absPath);
806 } else {
807 addToPrefixResolverList(NO_PREFIX_CHANGE_FOR_INTRA, absPath);
808 }
809 }
810 }
811
812 }
813
Bharat saraswald14cbe82016-07-14 13:26:18 +0530814}