blob: a86f9aea2b0703ef7ab31e85c61ce4cc7dcae41e [file] [log] [blame]
Bharat saraswalb1170bd2016-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
janani b23ccc312016-07-14 19:35:22 +053019import org.onosproject.yangutils.datamodel.YangAtomicPath;
20import org.onosproject.yangutils.datamodel.YangAugment;
21import org.onosproject.yangutils.datamodel.YangCase;
22import org.onosproject.yangutils.datamodel.YangChoice;
23import org.onosproject.yangutils.datamodel.YangGrouping;
24import org.onosproject.yangutils.datamodel.YangImport;
25import org.onosproject.yangutils.datamodel.YangInclude;
26import org.onosproject.yangutils.datamodel.YangInput;
27import org.onosproject.yangutils.datamodel.YangLeaf;
28import org.onosproject.yangutils.datamodel.YangLeafList;
29import org.onosproject.yangutils.datamodel.YangLeafRef;
30import org.onosproject.yangutils.datamodel.YangLeavesHolder;
31import org.onosproject.yangutils.datamodel.YangModule;
32import org.onosproject.yangutils.datamodel.YangNode;
33import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
34import org.onosproject.yangutils.datamodel.YangOutput;
35import org.onosproject.yangutils.datamodel.YangSubModule;
36import org.onosproject.yangutils.datamodel.YangTypeDef;
37import org.onosproject.yangutils.datamodel.YangUses;
38import org.onosproject.yangutils.linker.exceptions.LinkerException;
39
Bharat saraswalb1170bd2016-07-14 13:26:18 +053040import java.util.ArrayList;
41import java.util.HashMap;
42import java.util.Iterator;
43import java.util.List;
44import java.util.Map;
45import java.util.Stack;
46
Bharat saraswalb551aae2016-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 b23ccc312016-07-14 19:35:22 +053052import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
53import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
Bharat saraswalb551aae2016-07-14 15:18:20 +053054
Bharat saraswalb1170bd2016-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 saraswalb1170bd2016-07-14 13:26:18 +053062 private List<YangAtomicPath> absPaths;
63 private YangNode rootNode;
Bharat saraswalb551aae2016-07-14 15:18:20 +053064 private Map<YangAtomicPath, PrefixResolverType> prefixResolverTypes;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053065 private String curPrefix;
66 private Map<YangAtomicPath, YangNode> resolvedNodes;
67
68 /**
69 * Creates an instance of x-path linker.
70 */
71 public YangXpathLinker() {
72 absPaths = new ArrayList<>();
73 setResolvedNodes(new HashMap<>());
74 }
75
76 /**
Bharat saraswalb551aae2016-07-14 15:18:20 +053077 * Returns prefix resolver list.
78 *
79 * @return prefix resolver list
80 */
81 public Map<YangAtomicPath, PrefixResolverType> getPrefixResolverTypes() {
82 return prefixResolverTypes;
83 }
84
85 /**
86 * Sets prefix resolver list.
87 *
88 * @param prefixResolverTypes prefix resolver list.
89 */
90 public void setPrefixResolverTypes(Map<YangAtomicPath, PrefixResolverType> prefixResolverTypes) {
91 this.prefixResolverTypes = prefixResolverTypes;
92 }
93
94 /**
95 * Adds to the prefix resolver type map.
96 *
97 * @param type resolver type
98 * @param path absolute path
99 */
100 private void addToPrefixResolverList(PrefixResolverType type, YangAtomicPath path) {
101 getPrefixResolverTypes().put(path, type);
102 }
103
104 /**
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530105 * Returns list of target nodes paths.
106 *
107 * @return target nodes paths
108 */
109 private List<YangAtomicPath> getAbsPaths() {
110 return absPaths;
111 }
112
113 /**
114 * Sets target nodes paths.
115 *
116 * @param absPaths target nodes paths
117 */
118 private void setAbsPaths(List<YangAtomicPath> absPaths) {
119 this.absPaths = absPaths;
120 }
121
122 /**
123 * Returns current prefix.
124 *
125 * @return current prefix
126 */
127 private String getCurPrefix() {
128 return curPrefix;
129 }
130
131 /**
132 * Sets current prefix.
133 *
134 * @param curPrefix current prefix
135 */
136 private void setCurPrefix(String curPrefix) {
137 this.curPrefix = curPrefix;
138 }
139
140 /**
141 * Return root node.
142 *
143 * @return root Node
144 */
145 private YangNode getRootNode() {
146 return rootNode;
147 }
148
149 /**
150 * Sets root node.
151 *
152 * @param rootNode root node
153 */
154 private void setRootNode(YangNode rootNode) {
155 this.rootNode = rootNode;
156 }
157
158 /**
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530159 * Returns resolved nodes.
160 *
161 * @return resolved nodes
162 */
163 public Map<YangAtomicPath, YangNode> getResolvedNodes() {
164 return resolvedNodes;
165 }
166
167 /**
168 * Sets resolved nodes.
169 *
170 * @param resolvedNodes resolved nodes
171 */
172 private void setResolvedNodes(Map<YangAtomicPath, YangNode> resolvedNodes) {
173 this.resolvedNodes = resolvedNodes;
174 }
175
176 /**
177 * Adds node to resolved nodes.
178 *
179 * @param path absolute path
180 * @param node resolved node
181 */
182 private void addToResolvedNodes(YangAtomicPath path, YangNode node) {
183 getResolvedNodes().put(path, node);
184 }
185
186 /**
187 * Returns list of augment nodes.
188 *
189 * @param node root node
190 * @return list of augment nodes
191 */
192 public List<YangAugment> getListOfYangAugment(YangNode node) {
193 node = node.getChild();
194 List<YangAugment> augments = new ArrayList<>();
195 while (node != null) {
196 if (node instanceof YangAugment) {
197 augments.add((YangAugment) node);
198 }
199 node = node.getNextSibling();
200 }
201 return augments;
202 }
203
204 /**
205 * Process absolute node path for target leaf.
206 *
janani b23ccc312016-07-14 19:35:22 +0530207 * @param atomicPaths atomic path node list
208 * @param root root node
209 * @param leafref instance of YANG leafref
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530210 * @return linked target node
211 */
janani b23ccc312016-07-14 19:35:22 +0530212 public T processLeafRefXpathLinking(List<YangAtomicPath> atomicPaths, YangNode root, YangLeafRef leafref) {
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530213
214 YangNode targetNode = null;
215 setRootNode(root);
Bharat saraswalb551aae2016-07-14 15:18:20 +0530216 setPrefixResolverTypes(new HashMap<>());
janani b23ccc312016-07-14 19:35:22 +0530217 parsePrefixResolverList(atomicPaths);
218 YangAtomicPath leafRefPath = atomicPaths.get(atomicPaths.size() - 1);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530219
220 // When leaf-ref path contains only one absolute path.
janani b23ccc312016-07-14 19:35:22 +0530221 if (atomicPaths.size() == 1) {
222 targetNode = getTargetNodewhenSizeIsOne(atomicPaths);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530223 } else {
janani b23ccc312016-07-14 19:35:22 +0530224 atomicPaths.remove(atomicPaths.size() - 1);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530225
janani b23ccc312016-07-14 19:35:22 +0530226 setAbsPaths(atomicPaths);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530227 targetNode = parseData(root);
228 }
229 if (targetNode == null) {
Bharat saraswalb551aae2016-07-14 15:18:20 +0530230 targetNode = searchInSubModule(root);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530231 }
232
janani b23ccc312016-07-14 19:35:22 +0530233 // Invalid path presence in the node list is checked.
234 validateInvalidNodesInThePath(leafref);
235
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530236 if (targetNode != null) {
237 YangLeaf targetLeaf = searchReferredLeaf(targetNode, leafRefPath.getNodeIdentifier().getName());
238 if (targetLeaf == null) {
239 YangLeafList targetLeafList = searchReferredLeafList(targetNode,
240 leafRefPath.getNodeIdentifier().getName());
241 if (targetLeafList != null) {
242 return (T) targetLeafList;
243 } else {
janani b23ccc312016-07-14 19:35:22 +0530244 LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
245 "leaf/leaf-list for given leafref path "
246 + leafref.getPath());
247 linkerException.setCharPosition(leafref.getCharPosition());
248 linkerException.setLine(leafref.getLineNumber());
249 throw linkerException;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530250 }
251 }
252 return (T) targetLeaf;
253 }
254 return null;
255 }
256
257 /**
janani b23ccc312016-07-14 19:35:22 +0530258 * Validates the nodes in the path for any invalid node.
259 *
260 * @param leafref instance of YANG leafref
261 */
262 private void validateInvalidNodesInThePath(YangLeafRef leafref) {
263 Map<YangAtomicPath, YangNode> nodes = getResolvedNodes();
264 Iterator<Map.Entry<YangAtomicPath, YangNode>> nodesIterator = nodes.entrySet().iterator();
265 while (nodesIterator.hasNext()) {
266 Map.Entry<YangAtomicPath, YangNode> nodeInList = nodesIterator.next();
267 YangNode nodeInPath = nodeInList.getValue();
268
269 if (nodeInPath instanceof YangGrouping || nodeInPath instanceof YangUses
270 || nodeInPath instanceof YangTypeDef || nodeInPath instanceof YangCase
271 || nodeInPath instanceof YangChoice) {
272 LinkerException linkerException = new LinkerException("YANG file error: The target node, in the " +
273 "leafref path " + leafref.getPath() + ", is invalid.");
274 linkerException.setCharPosition(leafref.getCharPosition());
275 linkerException.setLine(leafref.getLineNumber());
276 throw linkerException;
277 }
278 }
279 }
280
281 /**
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530282 * Returns target node when leaf-ref has only one absolute path in list.
283 *
284 * @param absPaths absolute paths
285 * @return target node
286 */
287 private YangNode getTargetNodewhenSizeIsOne(List<YangAtomicPath> absPaths) {
288 if (absPaths.get(0).getNodeIdentifier().getPrefix() != null
289 && !absPaths.get(0).getNodeIdentifier().getPrefix().equals(getRootsPrefix(getRootNode()))) {
290 return getImportedNode(getRootNode(), absPaths.get(0).getNodeIdentifier());
291 }
292 return getRootNode();
293
294 }
295
296 /**
297 * Process absolute node path linking for augment.
298 *
299 * @param absPaths absolute path node list
Bharat saraswalb551aae2016-07-14 15:18:20 +0530300 * @param root root node
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530301 * @return linked target node
302 */
303 public YangNode processAugmentXpathLinking(List<YangAtomicPath> absPaths, YangNode root) {
304
305 setAbsPaths(absPaths);
306 setRootNode(root);
Bharat saraswalb551aae2016-07-14 15:18:20 +0530307 setPrefixResolverTypes(new HashMap<>());
308 parsePrefixResolverList(absPaths);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530309
310 YangNode targetNode = parseData(root);
311
312 if (targetNode == null) {
Bharat saraswalb551aae2016-07-14 15:18:20 +0530313 targetNode = searchInSubModule(root);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530314 }
315 return targetNode;
316
317 }
318
319 /**
320 * Searches for the referred leaf in target node.
321 *
322 * @param targetNode target node
Bharat saraswalb551aae2016-07-14 15:18:20 +0530323 * @param leafName leaf name
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530324 * @return target leaf
325 */
326 private YangLeaf searchReferredLeaf(YangNode targetNode, String leafName) {
327 if (!(targetNode instanceof YangLeavesHolder)) {
328 throw new LinkerException("Refered node " + targetNode.getName() +
329 "should be of type leaves holder ");
330 }
331 YangLeavesHolder holder = (YangLeavesHolder) targetNode;
332 List<YangLeaf> leaves = holder.getListOfLeaf();
janani b23ccc312016-07-14 19:35:22 +0530333 if (leaves != null && !leaves.isEmpty()) {
334 Iterator<YangLeaf> leafIterator = leaves.listIterator();
335 while (leafIterator.hasNext()) {
336 YangLeaf leaf = leafIterator.next();
337 if (leaf.getName().equals(leafName)) {
338 return leaf;
339 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530340 }
341 }
342 return null;
343 }
344
345 /**
346 * Searches for the referred leaf-list in target node.
347 *
Bharat saraswalb551aae2016-07-14 15:18:20 +0530348 * @param targetNode target node
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530349 * @param leafListName leaf-list name
350 * @return target leaf-list
351 */
352 private YangLeafList searchReferredLeafList(YangNode targetNode, String leafListName) {
353 if (!(targetNode instanceof YangLeavesHolder)) {
354 throw new LinkerException("Refered node " + targetNode.getName() +
355 "should be of type leaves holder ");
356 }
357 YangLeavesHolder holder = (YangLeavesHolder) targetNode;
358 List<YangLeafList> leavesList = holder.getListOfLeafList();
janani b23ccc312016-07-14 19:35:22 +0530359 if (leavesList != null && !leavesList.isEmpty()) {
360 Iterator<YangLeafList> leafListIterator = leavesList.listIterator();
361 while (leafListIterator.hasNext()) {
362 YangLeafList leafList = leafListIterator.next();
363 if (leafList.getName().equals(leafListName)) {
364 return leafList;
365 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530366 }
367 }
368 return null;
369 }
370
371 /**
372 * Process linking using for node identifier for inter/intra file.
373 *
374 * @param root root node
375 * @return linked target node
376 */
377 private YangNode parseData(YangNode root) {
378 String rootPrefix = getRootsPrefix(root);
379 Iterator<YangAtomicPath> pathIterator = getAbsPaths().iterator();
380 YangAtomicPath path = pathIterator.next();
381 if (path.getNodeIdentifier().getPrefix() != null
382 && !path.getNodeIdentifier().getPrefix().equals(rootPrefix)) {
383 return parsePath(getImportedNode(root, path.getNodeIdentifier()));
384 } else {
385 return parsePath(root);
386 }
387 }
388
389 /**
390 * Process linking of target node in root node.
391 *
392 * @param root root node
393 * @return linked target node
394 */
395 private YangNode parsePath(YangNode root) {
396
397 YangNode tempNode = root;
398 Stack<YangNode> linkerStack = new Stack<>();
399 Iterator<YangAtomicPath> pathIterator = getAbsPaths().iterator();
400 YangAtomicPath tempPath = pathIterator.next();
401 setCurPrefix(tempPath.getNodeIdentifier().getPrefix());
402 int index = 0;
Bharat saraswalb551aae2016-07-14 15:18:20 +0530403 YangNode tempAugment;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530404 do {
405
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530406 if (tempPath.getNodeIdentifier().getPrefix() == null) {
407 tempAugment = resolveIntraFileAugment(tempPath, root);
408 } else {
409 tempAugment = resolveInterFileAugment(tempPath, root);
410 }
411
412 if (tempAugment != null) {
413 linkerStack.push(tempNode);
414 tempNode = tempAugment;
415 }
416
417 tempNode = searchTargetNode(tempNode, tempPath.getNodeIdentifier());
418 if (tempNode == null && linkerStack.size() != 0) {
419 tempNode = linkerStack.peek();
420 linkerStack.pop();
421 tempNode = searchTargetNode(tempNode, tempPath.getNodeIdentifier());
422 }
423
424 if (tempNode != null) {
425 addToResolvedNodes(tempPath, tempNode);
426 }
427
428 if (index == getAbsPaths().size() - 1) {
429 break;
430 }
431 tempPath = pathIterator.next();
432 index++;
433 } while (validate(tempNode, index));
434 return tempNode;
435 }
436
437 /**
438 * Resolves intra file augment linking.
439 *
440 * @param tempPath temporary absolute path
Bharat saraswalb551aae2016-07-14 15:18:20 +0530441 * @param root root node
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530442 * @return linked target node
443 */
444 private YangNode resolveIntraFileAugment(YangAtomicPath tempPath, YangNode root) {
Bharat saraswalb551aae2016-07-14 15:18:20 +0530445 YangNode tempAugment;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530446 if (getCurPrefix() != tempPath.getNodeIdentifier().getPrefix()) {
Bharat saraswalb551aae2016-07-14 15:18:20 +0530447 root = getIncludedNode(getRootNode(), tempPath.getNodeIdentifier().getName());
448 if (root == null) {
449 root = getIncludedNode(getRootNode(), getAugmentNodeIdentifier(tempPath.getNodeIdentifier(), absPaths,
450 getRootNode()));
451 if (root == null) {
452 root = getRootNode();
453 }
454 }
455 } else {
456 if (getCurPrefix() != null) {
457 root = getImportedNode(root, tempPath.getNodeIdentifier());
458 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530459 }
460
461 setCurPrefix(tempPath.getNodeIdentifier().getPrefix());
462 tempAugment = getAugment(tempPath.getNodeIdentifier(), root, getAbsPaths());
463 if (tempAugment == null) {
464 tempAugment = getAugment(tempPath.getNodeIdentifier(), getRootNode(), getAbsPaths());
465 }
466 return tempAugment;
467 }
468
469 /**
470 * Resolves inter file augment linking.
471 *
472 * @param tempPath temporary absolute path
Bharat saraswalb551aae2016-07-14 15:18:20 +0530473 * @param root root node
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530474 * @return linked target node
475 */
476 private YangNode resolveInterFileAugment(YangAtomicPath tempPath, YangNode root) {
477
Bharat saraswalb551aae2016-07-14 15:18:20 +0530478 YangNode tempAugment;
479 if (!tempPath.getNodeIdentifier().getPrefix().equals(getCurPrefix())) {
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530480 setCurPrefix(tempPath.getNodeIdentifier().getPrefix());
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530481 root = getImportedNode(getRootNode(), tempPath.getNodeIdentifier());
482 }
483 tempAugment = getAugment(tempPath.getNodeIdentifier(), root, getAbsPaths());
Bharat saraswalb551aae2016-07-14 15:18:20 +0530484 if (tempAugment == null) {
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530485 return resolveInterToInterFileAugment(root);
486 }
487 return tempAugment;
488 }
489
490 /**
491 * Resolves augment when prefix changed from inter file to inter file.
492 * it may be possible that the prefix used in imported module is different the
493 * given list of node identifiers.
494 *
495 * @param root root node
496 * @return target node
497 */
498 private YangNode resolveInterToInterFileAugment(YangNode root) {
499 List<YangAugment> augments = getListOfYangAugment(root);
500 int index;
501 List<YangAtomicPath> absPaths = new ArrayList<>();
502 for (YangAugment augment : augments) {
503 index = 0;
504
505 for (YangAtomicPath path : augment.getTargetNode()) {
506
507 if (!searchForAugmentInImportedNode(path.getNodeIdentifier(), index)) {
508 absPaths.clear();
509 break;
510 }
511 absPaths.add(path);
512 index++;
513 }
514 if (!absPaths.isEmpty() && absPaths.size() == getAbsPaths().size() - 1) {
515 return augment;
516 } else {
517 absPaths.clear();
518 }
519 }
520 return null;
521 }
522
523 /**
524 * Searches for the augment node in imported module when prefix has changed from
525 * inter file to inter file.
Bharat saraswalb551aae2016-07-14 15:18:20 +0530526 *
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530527 * @param nodeId node id
Bharat saraswalb551aae2016-07-14 15:18:20 +0530528 * @param index index
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530529 * @return true if found
530 */
531 private boolean searchForAugmentInImportedNode(YangNodeIdentifier nodeId, int index) {
532 YangNodeIdentifier tempNodeId = getAbsPaths().get(index).getNodeIdentifier();
533 return nodeId.getName().equals(tempNodeId.getName());
534 }
535
536 /**
537 * Returns augment node.
538 *
539 * @param tempNodeId temporary absolute path id
Bharat saraswalb551aae2016-07-14 15:18:20 +0530540 * @param root root node
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530541 * @return linked target node
542 */
543 private YangNode getAugment(YangNodeIdentifier tempNodeId, YangNode root, List<YangAtomicPath> absPaths) {
Bharat saraswalb551aae2016-07-14 15:18:20 +0530544 String augmentName = getAugmentNodeIdentifier(tempNodeId, absPaths, root);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530545 if (augmentName != null) {
546 return searchAugmentNode(root, augmentName);
547 }
548 return null;
549 }
550
551 /**
552 * Process linking using import list.
553 *
Bharat saraswalb551aae2016-07-14 15:18:20 +0530554 * @param root root node
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530555 * @param nodeId node identifier
556 * @return linked target node
557 */
558 private YangNode getImportedNode(YangNode root, YangNodeIdentifier nodeId) {
559
Bharat saraswalb551aae2016-07-14 15:18:20 +0530560 List<YangImport> importList;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530561
562 if (root instanceof YangModule) {
563 importList = ((YangModule) root).getImportList();
564 } else {
565 importList = ((YangSubModule) root).getImportList();
566 }
567
568 for (YangImport imported : importList) {
569 if (imported.getPrefixId().equals(nodeId.getPrefix())) {
570 return imported.getImportedNode();
571 }
572 }
573
574 return root;
575 }
576
577 /**
Bharat saraswalb551aae2016-07-14 15:18:20 +0530578 * Searches in sub-module node.
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530579 *
580 * @param root root node
Bharat saraswalb551aae2016-07-14 15:18:20 +0530581 * @return target linked node
582 */
583 private YangNode searchInSubModule(YangNode root) {
584 List<YangInclude> includeList;
585 YangNode tempNode;
586 if (root instanceof YangModule) {
587 includeList = ((YangModule) root).getIncludeList();
588 } else {
589 includeList = ((YangSubModule) root).getIncludeList();
590 }
591
592 for (YangInclude included : includeList) {
593 tempNode = parseData(included.getIncludedNode());
594 if (tempNode != null) {
595 return tempNode;
596 }
597 }
598 return null;
599 }
600
601 /**
602 * Process linking using include list.
603 *
604 * @param root root node
605 * @param tempPathName temporary path node name
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530606 * @return linked target node
607 */
Bharat saraswalb551aae2016-07-14 15:18:20 +0530608 private YangNode getIncludedNode(YangNode root, String tempPathName) {
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530609
Bharat saraswalb551aae2016-07-14 15:18:20 +0530610 List<YangInclude> includeList;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530611
612 if (root instanceof YangModule) {
613 includeList = ((YangModule) root).getIncludeList();
614 } else {
615 includeList = ((YangSubModule) root).getIncludeList();
616 }
617
618 for (YangInclude included : includeList) {
Bharat saraswalb551aae2016-07-14 15:18:20 +0530619 if (verifyChildNode(included.getIncludedNode(), tempPathName)) {
620 return included.getIncludedNode();
621 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530622 }
623
Bharat saraswalb551aae2016-07-14 15:18:20 +0530624 return null;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530625 }
626
627 /**
Bharat saraswalb551aae2016-07-14 15:18:20 +0530628 * Verifies for child nodes in sub module.
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530629 *
Bharat saraswalb551aae2016-07-14 15:18:20 +0530630 * @param node submodule node
631 * @param name name of child node
632 * @return true if child node found
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530633 */
Bharat saraswalb551aae2016-07-14 15:18:20 +0530634 private boolean verifyChildNode(YangNode node, String name) {
635 node = node.getChild();
636 while (node != null) {
637 if (node.getName().equals(name)) {
638 return true;
639 }
640 node = node.getNextSibling();
641 }
642 return false;
643 }
644
645
646 /**
647 * Returns augment's node id.
648 *
649 * @param nodeId node identifier
650 * @param absPaths absolute paths
651 * @param root root node
652 * @return augment's node id
653 */
654 private String getAugmentNodeIdentifier(YangNodeIdentifier nodeId, List<YangAtomicPath> absPaths, YangNode root) {
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530655
656 Iterator<YangAtomicPath> nodeIdIterator = absPaths.iterator();
Bharat saraswalb551aae2016-07-14 15:18:20 +0530657 YangAtomicPath tempNodeId;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530658 StringBuilder builder = new StringBuilder();
Bharat saraswalb551aae2016-07-14 15:18:20 +0530659 String id;
660 PrefixResolverType type;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530661 while (nodeIdIterator.hasNext()) {
662 tempNodeId = nodeIdIterator.next();
663 if (!tempNodeId.getNodeIdentifier().equals(nodeId)) {
Bharat saraswalb551aae2016-07-14 15:18:20 +0530664 type = getPrefixResolverTypes().get(tempNodeId);
665 switch (type) {
666 case INTER_TO_INTRA:
667 id = "/" + tempNodeId.getNodeIdentifier().getName();
668 break;
669 case INTRA_TO_INTER:
670 if (!getRootsPrefix(root).equals(tempNodeId.getNodeIdentifier().getPrefix())) {
671 id = "/" + tempNodeId.getNodeIdentifier().getPrefix() + ":" + tempNodeId.getNodeIdentifier()
672 .getName();
673 } else {
674 id = "/" + tempNodeId.getNodeIdentifier().getName();
675 }
676 break;
677 case INTER_TO_INTER:
678 id = "/" + tempNodeId.getNodeIdentifier().getPrefix() + ":" + tempNodeId.getNodeIdentifier()
679 .getName();
680 break;
681 case NO_PREFIX_CHANGE_FOR_INTRA:
682 id = "/" + tempNodeId.getNodeIdentifier().getName();
683 break;
684 case NO_PREFIX_CHANGE_FOR_INTER:
685 if (!getRootsPrefix(root).equals(tempNodeId.getNodeIdentifier().getPrefix())) {
686 id = "/" + tempNodeId.getNodeIdentifier().getPrefix() + ":" + tempNodeId.getNodeIdentifier()
687 .getName();
688 } else {
689 id = "/" + tempNodeId.getNodeIdentifier().getName();
690 }
691 break;
692 default:
693 id = "/" + tempNodeId.getNodeIdentifier().getName();
694 break;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530695 }
Bharat saraswalb551aae2016-07-14 15:18:20 +0530696 builder.append(id);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530697 } else {
698 return builder.toString();
699 }
700 }
701 return null;
702 }
703
704 /**
705 * Searches augment node in root node.
706 *
Bharat saraswalb551aae2016-07-14 15:18:20 +0530707 * @param node root node
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530708 * @param tempNodeId node identifier
709 * @return target augment node
710 */
Bharat saraswalb551aae2016-07-14 15:18:20 +0530711
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530712 private YangNode searchAugmentNode(YangNode node, String tempNodeId) {
713 node = node.getChild();
714 while (node != null) {
715 if (node instanceof YangAugment) {
Bharat saraswalb551aae2016-07-14 15:18:20 +0530716 if (node.getName().equals(tempNodeId)) {
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530717 return node;
718 }
719 }
720 node = node.getNextSibling();
721 }
722 return null;
723 }
724
725 /**
726 * Validates for target node if target node found or not.
727 *
728 * @param tempNode temporary node
Bharat saraswalb551aae2016-07-14 15:18:20 +0530729 * @param index current index of list
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530730 * @return false if target node found
731 */
732 private boolean validate(YangNode tempNode, int index) {
733
734 int size = getAbsPaths().size();
735 if (tempNode != null && index != size) {
736 return true;
Bharat saraswalb551aae2016-07-14 15:18:20 +0530737 } else if (tempNode != null) {
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530738 return false;
739 // this is your target node.
Bharat saraswalb551aae2016-07-14 15:18:20 +0530740 } else if (index != size) {
741 return true;
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530742 // this could be in submodule as well.
743 }
744 return false;
745 }
746
747 /**
748 * Searches target node in root node.
749 *
Bharat saraswalb551aae2016-07-14 15:18:20 +0530750 * @param node root node
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530751 * @param curNodeId YANG node identifier
752 * @return linked target node
753 */
754 private YangNode searchTargetNode(YangNode node, YangNodeIdentifier curNodeId) {
755
756 if (node != null) {
757 node = node.getChild();
758 }
759
760 while (node != null) {
janani b23ccc312016-07-14 19:35:22 +0530761 if (node instanceof YangInput) {
762 if (curNodeId.getName().equalsIgnoreCase(INPUT)) {
763 return node;
764 }
765 } else if (node instanceof YangOutput) {
766 if (curNodeId.getName().equalsIgnoreCase(OUTPUT)) {
767 return node;
768 }
769 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530770 if (node.getName().equals(curNodeId.getName())) {
771 return node;
772 }
773 node = node.getNextSibling();
774 }
775 return null;
776 }
777
778 /**
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530779 * Returns root prefix.
780 *
781 * @param root root node
782 * @return root prefix
783 */
784 private String getRootsPrefix(YangNode root) {
785 if (root instanceof YangModule) {
786 return ((YangModule) root).getPrefix();
787 } else {
788 return ((YangSubModule) root).getPrefix();
789 }
790 }
791
Bharat saraswalb551aae2016-07-14 15:18:20 +0530792 /**
793 * Resolves prefix and provides prefix resolver list.
794 *
795 * @param absolutePaths absolute paths
796 */
797 private void parsePrefixResolverList(List<YangAtomicPath> absolutePaths) {
798 Iterator<YangAtomicPath> pathIterator = absolutePaths.iterator();
799 YangAtomicPath absPath;
800 String prePrefix;
801 String curPrefix = null;
802 while (pathIterator.hasNext()) {
803 prePrefix = curPrefix;
804 absPath = pathIterator.next();
805 curPrefix = absPath.getNodeIdentifier().getPrefix();
806 if (curPrefix != null) {
807 if (!curPrefix.equals(prePrefix)) {
808 if (prePrefix != null) {
809 addToPrefixResolverList(INTER_TO_INTER, absPath);
810 } else {
811 addToPrefixResolverList(INTRA_TO_INTER, absPath);
812 }
813 } else {
814 addToPrefixResolverList(NO_PREFIX_CHANGE_FOR_INTER, absPath);
815 }
816 } else {
817 if (prePrefix != null) {
818 addToPrefixResolverList(INTER_TO_INTRA, absPath);
819 } else {
820 addToPrefixResolverList(NO_PREFIX_CHANGE_FOR_INTRA, absPath);
821 }
822 }
823 }
824
825 }
826
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530827}