blob: a53e7270a4d4d30d24126aa972af3b82d9cbb35e [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;
VinodKumarS-Huawei3b4cce02016-08-20 21:32:17 +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 saraswale3175d32016-08-31 17:50:11 +053066 private String constructsParentsPrefix;
Bharat saraswald14cbe82016-07-14 13:26:18 +053067
68 /**
69 * Creates an instance of x-path linker.
70 */
71 public YangXpathLinker() {
72 absPaths = new ArrayList<>();
Bharat saraswald14cbe82016-07-14 13:26:18 +053073 }
74
75 /**
Bharat saraswalaf413b82016-07-14 15:18:20 +053076 * Returns prefix resolver list.
77 *
78 * @return prefix resolver list
79 */
Bharat saraswal64e7e232016-07-14 23:33:55 +053080 private Map<YangAtomicPath, PrefixResolverType> getPrefixResolverTypes() {
Bharat saraswalaf413b82016-07-14 15:18:20 +053081 return prefixResolverTypes;
82 }
83
84 /**
85 * Sets prefix resolver list.
86 *
87 * @param prefixResolverTypes prefix resolver list.
88 */
Bharat saraswal64e7e232016-07-14 23:33:55 +053089 private void setPrefixResolverTypes(Map<YangAtomicPath, PrefixResolverType> prefixResolverTypes) {
Bharat saraswalaf413b82016-07-14 15:18:20 +053090 this.prefixResolverTypes = prefixResolverTypes;
91 }
92
93 /**
94 * Adds to the prefix resolver type map.
95 *
96 * @param type resolver type
97 * @param path absolute path
98 */
99 private void addToPrefixResolverList(PrefixResolverType type, YangAtomicPath path) {
100 getPrefixResolverTypes().put(path, type);
101 }
102
103 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530104 * Returns list of target nodes paths.
105 *
106 * @return target nodes paths
107 */
108 private List<YangAtomicPath> getAbsPaths() {
109 return absPaths;
110 }
111
112 /**
113 * Sets target nodes paths.
114 *
115 * @param absPaths target nodes paths
116 */
117 private void setAbsPaths(List<YangAtomicPath> absPaths) {
118 this.absPaths = absPaths;
119 }
120
121 /**
janani bade77ae2016-08-17 16:33:07 +0530122 * Adds target nodes paths.
123 *
124 * @param absPaths target nodes paths
125 */
126 private void addAbsPaths(YangAtomicPath absPaths) {
127 getAbsPaths().add(absPaths);
128 }
129
130 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530131 * Returns current prefix.
132 *
133 * @return current prefix
134 */
135 private String getCurPrefix() {
136 return curPrefix;
137 }
138
139 /**
140 * Sets current prefix.
141 *
142 * @param curPrefix current prefix
143 */
144 private void setCurPrefix(String curPrefix) {
145 this.curPrefix = curPrefix;
146 }
147
148 /**
149 * Return root node.
150 *
151 * @return root Node
152 */
153 private YangNode getRootNode() {
154 return rootNode;
155 }
156
157 /**
158 * Sets root node.
159 *
160 * @param rootNode root node
161 */
162 private void setRootNode(YangNode rootNode) {
163 this.rootNode = rootNode;
164 }
165
166 /**
Bharat saraswale3175d32016-08-31 17:50:11 +0530167 * Returns unresolved construct's parent's prefix.
168 *
169 * @return unresolved construct's parent's prefix
170 */
171 private String getConstructsParentsPrefix() {
172 return constructsParentsPrefix;
173 }
174
175 /**
176 * Sets unresolved construct's parent's prefix.
177 *
178 * @param constructsParentsPrefix unresolved construct's parent's prefix
179 */
180 private void setConstructsParentsPrefix(String constructsParentsPrefix) {
181 this.constructsParentsPrefix = constructsParentsPrefix;
182 }
183
184 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530185 * Adds node to resolved nodes.
186 *
187 * @param path absolute path
188 * @param node resolved node
189 */
190 private void addToResolvedNodes(YangAtomicPath path, YangNode node) {
Bharat saraswal039f59c2016-07-14 21:57:13 +0530191 path.setResolvedNode(node);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530192 }
193
194 /**
195 * Returns list of augment nodes.
196 *
197 * @param node root node
198 * @return list of augment nodes
199 */
200 public List<YangAugment> getListOfYangAugment(YangNode node) {
201 node = node.getChild();
202 List<YangAugment> augments = new ArrayList<>();
203 while (node != null) {
204 if (node instanceof YangAugment) {
205 augments.add((YangAugment) node);
206 }
207 node = node.getNextSibling();
208 }
209 return augments;
210 }
211
212 /**
213 * Process absolute node path for target leaf.
214 *
janani bebb143d2016-07-14 19:35:22 +0530215 * @param atomicPaths atomic path node list
Bharat saraswale304c252016-08-16 20:56:20 +0530216 * @param root root node
217 * @param leafref instance of YANG leafref
Bharat saraswald14cbe82016-07-14 13:26:18 +0530218 * @return linked target node
219 */
Bharat saraswal64e7e232016-07-14 23:33:55 +0530220 T processLeafRefXpathLinking(List<YangAtomicPath> atomicPaths, YangNode root, YangLeafRef leafref) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530221
Bharat saraswal039f59c2016-07-14 21:57:13 +0530222 YangNode targetNode;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530223 setRootNode(root);
Bharat saraswalaf413b82016-07-14 15:18:20 +0530224 setPrefixResolverTypes(new HashMap<>());
janani bebb143d2016-07-14 19:35:22 +0530225 parsePrefixResolverList(atomicPaths);
226 YangAtomicPath leafRefPath = atomicPaths.get(atomicPaths.size() - 1);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530227
228 // When leaf-ref path contains only one absolute path.
janani bebb143d2016-07-14 19:35:22 +0530229 if (atomicPaths.size() == 1) {
230 targetNode = getTargetNodewhenSizeIsOne(atomicPaths);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530231 } else {
janani bade77ae2016-08-17 16:33:07 +0530232 for (YangAtomicPath atomicPath : atomicPaths) {
233 if (atomicPath != leafRefPath) {
234 addAbsPaths(atomicPath);
235 }
236 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530237 targetNode = parseData(root);
238 }
239 if (targetNode == null) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530240 targetNode = searchInSubModule(root);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530241 }
242
janani bebb143d2016-07-14 19:35:22 +0530243 // Invalid path presence in the node list is checked.
244 validateInvalidNodesInThePath(leafref);
245
Bharat saraswald14cbe82016-07-14 13:26:18 +0530246 if (targetNode != null) {
247 YangLeaf targetLeaf = searchReferredLeaf(targetNode, leafRefPath.getNodeIdentifier().getName());
248 if (targetLeaf == null) {
249 YangLeafList targetLeafList = searchReferredLeafList(targetNode,
250 leafRefPath.getNodeIdentifier().getName());
251 if (targetLeafList != null) {
252 return (T) targetLeafList;
253 } else {
janani bebb143d2016-07-14 19:35:22 +0530254 LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
255 "leaf/leaf-list for given leafref path "
256 + leafref.getPath());
257 linkerException.setCharPosition(leafref.getCharPosition());
258 linkerException.setLine(leafref.getLineNumber());
Bharat saraswale3175d32016-08-31 17:50:11 +0530259 linkerException.setFileName(leafref.getFileName());
janani bebb143d2016-07-14 19:35:22 +0530260 throw linkerException;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530261 }
262 }
263 return (T) targetLeaf;
264 }
265 return null;
266 }
267
268 /**
janani bebb143d2016-07-14 19:35:22 +0530269 * Validates the nodes in the path for any invalid node.
270 *
271 * @param leafref instance of YANG leafref
272 */
273 private void validateInvalidNodesInThePath(YangLeafRef leafref) {
Bharat saraswal039f59c2016-07-14 21:57:13 +0530274 for (YangAtomicPath absolutePath : (Iterable<YangAtomicPath>) leafref.getAtomicPath()) {
275 YangNode nodeInPath = absolutePath.getResolvedNode();
janani bebb143d2016-07-14 19:35:22 +0530276
277 if (nodeInPath instanceof YangGrouping || nodeInPath instanceof YangUses
278 || nodeInPath instanceof YangTypeDef || nodeInPath instanceof YangCase
279 || nodeInPath instanceof YangChoice) {
280 LinkerException linkerException = new LinkerException("YANG file error: The target node, in the " +
281 "leafref path " + leafref.getPath() + ", is invalid.");
282 linkerException.setCharPosition(leafref.getCharPosition());
283 linkerException.setLine(leafref.getLineNumber());
Bharat saraswale3175d32016-08-31 17:50:11 +0530284 linkerException.setFileName(leafref.getFileName());
janani bebb143d2016-07-14 19:35:22 +0530285 throw linkerException;
286 }
287 }
288 }
289
290 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530291 * Returns target node when leaf-ref has only one absolute path in list.
292 *
293 * @param absPaths absolute paths
294 * @return target node
295 */
296 private YangNode getTargetNodewhenSizeIsOne(List<YangAtomicPath> absPaths) {
297 if (absPaths.get(0).getNodeIdentifier().getPrefix() != null
298 && !absPaths.get(0).getNodeIdentifier().getPrefix().equals(getRootsPrefix(getRootNode()))) {
299 return getImportedNode(getRootNode(), absPaths.get(0).getNodeIdentifier());
300 }
301 return getRootNode();
302
303 }
304
305 /**
306 * Process absolute node path linking for augment.
307 *
308 * @param absPaths absolute path node list
Bharat saraswalaf413b82016-07-14 15:18:20 +0530309 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530310 * @return linked target node
311 */
312 public YangNode processAugmentXpathLinking(List<YangAtomicPath> absPaths, YangNode root) {
313
314 setAbsPaths(absPaths);
315 setRootNode(root);
Bharat saraswalaf413b82016-07-14 15:18:20 +0530316 setPrefixResolverTypes(new HashMap<>());
317 parsePrefixResolverList(absPaths);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530318
319 YangNode targetNode = parseData(root);
320
321 if (targetNode == null) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530322 targetNode = searchInSubModule(root);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530323 }
324 return targetNode;
325
326 }
327
328 /**
329 * Searches for the referred leaf in target node.
330 *
331 * @param targetNode target node
Bharat saraswalaf413b82016-07-14 15:18:20 +0530332 * @param leafName leaf name
Bharat saraswald14cbe82016-07-14 13:26:18 +0530333 * @return target leaf
334 */
335 private YangLeaf searchReferredLeaf(YangNode targetNode, String leafName) {
336 if (!(targetNode instanceof YangLeavesHolder)) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530337 throw new LinkerException("Referred node " + targetNode.getName() +
Bharat saraswale3175d32016-08-31 17:50:11 +0530338 "should be of type leaves holder in " + targetNode.getLineNumber() +
339 " at " + targetNode.getCharPosition() + " in " + targetNode.getFileName());
Bharat saraswald14cbe82016-07-14 13:26:18 +0530340 }
341 YangLeavesHolder holder = (YangLeavesHolder) targetNode;
342 List<YangLeaf> leaves = holder.getListOfLeaf();
janani bebb143d2016-07-14 19:35:22 +0530343 if (leaves != null && !leaves.isEmpty()) {
Bharat saraswal039f59c2016-07-14 21:57:13 +0530344 for (YangLeaf leaf : leaves) {
janani bebb143d2016-07-14 19:35:22 +0530345 if (leaf.getName().equals(leafName)) {
346 return leaf;
347 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530348 }
349 }
350 return null;
351 }
352
353 /**
354 * Searches for the referred leaf-list in target node.
355 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530356 * @param targetNode target node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530357 * @param leafListName leaf-list name
358 * @return target leaf-list
359 */
360 private YangLeafList searchReferredLeafList(YangNode targetNode, String leafListName) {
361 if (!(targetNode instanceof YangLeavesHolder)) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530362 throw new LinkerException("Referred node " + targetNode.getName() +
Bharat saraswale3175d32016-08-31 17:50:11 +0530363 "should be of type leaves holder in " + targetNode.getLineNumber() +
364 " at " + targetNode.getCharPosition() + " in " + targetNode.getFileName());
Bharat saraswald14cbe82016-07-14 13:26:18 +0530365 }
366 YangLeavesHolder holder = (YangLeavesHolder) targetNode;
367 List<YangLeafList> leavesList = holder.getListOfLeafList();
janani bebb143d2016-07-14 19:35:22 +0530368 if (leavesList != null && !leavesList.isEmpty()) {
Bharat saraswal039f59c2016-07-14 21:57:13 +0530369 for (YangLeafList leafList : leavesList) {
janani bebb143d2016-07-14 19:35:22 +0530370 if (leafList.getName().equals(leafListName)) {
371 return leafList;
372 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530373 }
374 }
375 return null;
376 }
377
378 /**
379 * Process linking using for node identifier for inter/intra file.
380 *
381 * @param root root node
382 * @return linked target node
383 */
384 private YangNode parseData(YangNode root) {
385 String rootPrefix = getRootsPrefix(root);
Bharat saraswale3175d32016-08-31 17:50:11 +0530386 setConstructsParentsPrefix(rootPrefix);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530387 Iterator<YangAtomicPath> pathIterator = getAbsPaths().iterator();
388 YangAtomicPath path = pathIterator.next();
389 if (path.getNodeIdentifier().getPrefix() != null
390 && !path.getNodeIdentifier().getPrefix().equals(rootPrefix)) {
391 return parsePath(getImportedNode(root, path.getNodeIdentifier()));
392 } else {
393 return parsePath(root);
394 }
395 }
396
397 /**
398 * Process linking of target node in root node.
399 *
400 * @param root root node
401 * @return linked target node
402 */
403 private YangNode parsePath(YangNode root) {
404
405 YangNode tempNode = root;
406 Stack<YangNode> linkerStack = new Stack<>();
407 Iterator<YangAtomicPath> pathIterator = getAbsPaths().iterator();
408 YangAtomicPath tempPath = pathIterator.next();
Bharat saraswale3175d32016-08-31 17:50:11 +0530409 YangNodeIdentifier nodeId;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530410 setCurPrefix(tempPath.getNodeIdentifier().getPrefix());
411 int index = 0;
Bharat saraswalaf413b82016-07-14 15:18:20 +0530412 YangNode tempAugment;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530413 do {
Bharat saraswale3175d32016-08-31 17:50:11 +0530414 nodeId = tempPath.getNodeIdentifier();
Bharat saraswald14cbe82016-07-14 13:26:18 +0530415 if (tempPath.getNodeIdentifier().getPrefix() == null) {
416 tempAugment = resolveIntraFileAugment(tempPath, root);
417 } else {
418 tempAugment = resolveInterFileAugment(tempPath, root);
419 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530420 if (tempAugment != null) {
421 linkerStack.push(tempNode);
422 tempNode = tempAugment;
423 }
424
Bharat saraswale3175d32016-08-31 17:50:11 +0530425 tempNode = searchTargetNode(tempNode, nodeId);
426
Bharat saraswald14cbe82016-07-14 13:26:18 +0530427 if (tempNode == null && linkerStack.size() != 0) {
428 tempNode = linkerStack.peek();
429 linkerStack.pop();
Bharat saraswale3175d32016-08-31 17:50:11 +0530430 tempNode = searchTargetNode(tempNode, nodeId);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530431 }
432
433 if (tempNode != null) {
434 addToResolvedNodes(tempPath, tempNode);
435 }
436
437 if (index == getAbsPaths().size() - 1) {
438 break;
439 }
440 tempPath = pathIterator.next();
441 index++;
442 } while (validate(tempNode, index));
443 return tempNode;
444 }
445
446 /**
447 * Resolves intra file augment linking.
448 *
449 * @param tempPath temporary absolute path
Bharat saraswalaf413b82016-07-14 15:18:20 +0530450 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530451 * @return linked target node
452 */
453 private YangNode resolveIntraFileAugment(YangAtomicPath tempPath, YangNode root) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530454 YangNode tempAugment;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530455 if (getCurPrefix() != tempPath.getNodeIdentifier().getPrefix()) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530456 root = getIncludedNode(getRootNode(), tempPath.getNodeIdentifier().getName());
457 if (root == null) {
458 root = getIncludedNode(getRootNode(), getAugmentNodeIdentifier(tempPath.getNodeIdentifier(), absPaths,
459 getRootNode()));
460 if (root == null) {
461 root = getRootNode();
462 }
463 }
464 } else {
465 if (getCurPrefix() != null) {
466 root = getImportedNode(root, tempPath.getNodeIdentifier());
467 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530468 }
469
470 setCurPrefix(tempPath.getNodeIdentifier().getPrefix());
471 tempAugment = getAugment(tempPath.getNodeIdentifier(), root, getAbsPaths());
472 if (tempAugment == null) {
473 tempAugment = getAugment(tempPath.getNodeIdentifier(), getRootNode(), getAbsPaths());
474 }
475 return tempAugment;
476 }
477
478 /**
479 * Resolves inter file augment linking.
480 *
481 * @param tempPath temporary absolute path
Bharat saraswalaf413b82016-07-14 15:18:20 +0530482 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530483 * @return linked target node
484 */
485 private YangNode resolveInterFileAugment(YangAtomicPath tempPath, YangNode root) {
486
Bharat saraswalaf413b82016-07-14 15:18:20 +0530487 YangNode tempAugment;
488 if (!tempPath.getNodeIdentifier().getPrefix().equals(getCurPrefix())) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530489 setCurPrefix(tempPath.getNodeIdentifier().getPrefix());
Bharat saraswald14cbe82016-07-14 13:26:18 +0530490 root = getImportedNode(getRootNode(), tempPath.getNodeIdentifier());
491 }
492 tempAugment = getAugment(tempPath.getNodeIdentifier(), root, getAbsPaths());
Bharat saraswalaf413b82016-07-14 15:18:20 +0530493 if (tempAugment == null) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530494 return resolveInterToInterFileAugment(root);
495 }
496 return tempAugment;
497 }
498
499 /**
500 * Resolves augment when prefix changed from inter file to inter file.
501 * it may be possible that the prefix used in imported module is different the
502 * given list of node identifiers.
503 *
504 * @param root root node
505 * @return target node
506 */
507 private YangNode resolveInterToInterFileAugment(YangNode root) {
508 List<YangAugment> augments = getListOfYangAugment(root);
509 int index;
510 List<YangAtomicPath> absPaths = new ArrayList<>();
511 for (YangAugment augment : augments) {
512 index = 0;
513
514 for (YangAtomicPath path : augment.getTargetNode()) {
515
516 if (!searchForAugmentInImportedNode(path.getNodeIdentifier(), index)) {
517 absPaths.clear();
518 break;
519 }
520 absPaths.add(path);
521 index++;
522 }
523 if (!absPaths.isEmpty() && absPaths.size() == getAbsPaths().size() - 1) {
524 return augment;
525 } else {
526 absPaths.clear();
527 }
528 }
529 return null;
530 }
531
532 /**
533 * Searches for the augment node in imported module when prefix has changed from
534 * inter file to inter file.
Bharat saraswalaf413b82016-07-14 15:18:20 +0530535 *
Bharat saraswald14cbe82016-07-14 13:26:18 +0530536 * @param nodeId node id
Bharat saraswalaf413b82016-07-14 15:18:20 +0530537 * @param index index
Bharat saraswald14cbe82016-07-14 13:26:18 +0530538 * @return true if found
539 */
540 private boolean searchForAugmentInImportedNode(YangNodeIdentifier nodeId, int index) {
Bharat saraswale304c252016-08-16 20:56:20 +0530541 if (index == getAbsPaths().size()) {
542 return false;
543 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530544 YangNodeIdentifier tempNodeId = getAbsPaths().get(index).getNodeIdentifier();
545 return nodeId.getName().equals(tempNodeId.getName());
546 }
547
548 /**
549 * Returns augment node.
550 *
551 * @param tempNodeId temporary absolute path id
Bharat saraswalaf413b82016-07-14 15:18:20 +0530552 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530553 * @return linked target node
554 */
555 private YangNode getAugment(YangNodeIdentifier tempNodeId, YangNode root, List<YangAtomicPath> absPaths) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530556 String augmentName = getAugmentNodeIdentifier(tempNodeId, absPaths, root);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530557 if (augmentName != null) {
558 return searchAugmentNode(root, augmentName);
559 }
560 return null;
561 }
562
563 /**
564 * Process linking using import list.
565 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530566 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530567 * @param nodeId node identifier
568 * @return linked target node
569 */
570 private YangNode getImportedNode(YangNode root, YangNodeIdentifier nodeId) {
571
Bharat saraswalaf413b82016-07-14 15:18:20 +0530572 List<YangImport> importList;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530573
574 if (root instanceof YangModule) {
575 importList = ((YangModule) root).getImportList();
576 } else {
577 importList = ((YangSubModule) root).getImportList();
578 }
579
580 for (YangImport imported : importList) {
581 if (imported.getPrefixId().equals(nodeId.getPrefix())) {
582 return imported.getImportedNode();
583 }
584 }
585
Bharat saraswale3175d32016-08-31 17:50:11 +0530586 if (nodeId.getName() != null && nodeId.getPrefix().equals(getConstructsParentsPrefix())) {
587 return getRootNode();
588 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530589 return root;
590 }
591
592 /**
Bharat saraswalaf413b82016-07-14 15:18:20 +0530593 * Searches in sub-module node.
Bharat saraswald14cbe82016-07-14 13:26:18 +0530594 *
595 * @param root root node
Bharat saraswalaf413b82016-07-14 15:18:20 +0530596 * @return target linked node
597 */
598 private YangNode searchInSubModule(YangNode root) {
599 List<YangInclude> includeList;
600 YangNode tempNode;
601 if (root instanceof YangModule) {
602 includeList = ((YangModule) root).getIncludeList();
603 } else {
604 includeList = ((YangSubModule) root).getIncludeList();
605 }
606
607 for (YangInclude included : includeList) {
608 tempNode = parseData(included.getIncludedNode());
609 if (tempNode != null) {
610 return tempNode;
611 }
612 }
613 return null;
614 }
615
616 /**
617 * Process linking using include list.
618 *
619 * @param root root node
620 * @param tempPathName temporary path node name
Bharat saraswald14cbe82016-07-14 13:26:18 +0530621 * @return linked target node
622 */
Bharat saraswalaf413b82016-07-14 15:18:20 +0530623 private YangNode getIncludedNode(YangNode root, String tempPathName) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530624
Bharat saraswalaf413b82016-07-14 15:18:20 +0530625 List<YangInclude> includeList;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530626
627 if (root instanceof YangModule) {
628 includeList = ((YangModule) root).getIncludeList();
629 } else {
630 includeList = ((YangSubModule) root).getIncludeList();
631 }
632
633 for (YangInclude included : includeList) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530634 if (verifyChildNode(included.getIncludedNode(), tempPathName)) {
635 return included.getIncludedNode();
636 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530637 }
638
Bharat saraswalaf413b82016-07-14 15:18:20 +0530639 return null;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530640 }
641
642 /**
Bharat saraswalaf413b82016-07-14 15:18:20 +0530643 * Verifies for child nodes in sub module.
Bharat saraswald14cbe82016-07-14 13:26:18 +0530644 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530645 * @param node submodule node
646 * @param name name of child node
647 * @return true if child node found
Bharat saraswald14cbe82016-07-14 13:26:18 +0530648 */
Bharat saraswalaf413b82016-07-14 15:18:20 +0530649 private boolean verifyChildNode(YangNode node, String name) {
650 node = node.getChild();
651 while (node != null) {
652 if (node.getName().equals(name)) {
653 return true;
654 }
655 node = node.getNextSibling();
656 }
657 return false;
658 }
659
660
661 /**
662 * Returns augment's node id.
663 *
664 * @param nodeId node identifier
665 * @param absPaths absolute paths
666 * @param root root node
667 * @return augment's node id
668 */
669 private String getAugmentNodeIdentifier(YangNodeIdentifier nodeId, List<YangAtomicPath> absPaths, YangNode root) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530670
671 Iterator<YangAtomicPath> nodeIdIterator = absPaths.iterator();
Bharat saraswalaf413b82016-07-14 15:18:20 +0530672 YangAtomicPath tempNodeId;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530673 StringBuilder builder = new StringBuilder();
Bharat saraswalaf413b82016-07-14 15:18:20 +0530674 String id;
675 PrefixResolverType type;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530676 while (nodeIdIterator.hasNext()) {
677 tempNodeId = nodeIdIterator.next();
678 if (!tempNodeId.getNodeIdentifier().equals(nodeId)) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530679 type = getPrefixResolverTypes().get(tempNodeId);
680 switch (type) {
681 case INTER_TO_INTRA:
682 id = "/" + tempNodeId.getNodeIdentifier().getName();
683 break;
684 case INTRA_TO_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 case INTER_TO_INTER:
693 id = "/" + tempNodeId.getNodeIdentifier().getPrefix() + ":" + tempNodeId.getNodeIdentifier()
694 .getName();
695 break;
696 case NO_PREFIX_CHANGE_FOR_INTRA:
697 id = "/" + tempNodeId.getNodeIdentifier().getName();
698 break;
699 case NO_PREFIX_CHANGE_FOR_INTER:
700 if (!getRootsPrefix(root).equals(tempNodeId.getNodeIdentifier().getPrefix())) {
701 id = "/" + tempNodeId.getNodeIdentifier().getPrefix() + ":" + tempNodeId.getNodeIdentifier()
702 .getName();
703 } else {
704 id = "/" + tempNodeId.getNodeIdentifier().getName();
705 }
706 break;
707 default:
708 id = "/" + tempNodeId.getNodeIdentifier().getName();
709 break;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530710 }
Bharat saraswalaf413b82016-07-14 15:18:20 +0530711 builder.append(id);
Bharat saraswald14cbe82016-07-14 13:26:18 +0530712 } else {
713 return builder.toString();
714 }
715 }
716 return null;
717 }
718
719 /**
720 * Searches augment node in root node.
721 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530722 * @param node root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530723 * @param tempNodeId node identifier
724 * @return target augment node
725 */
Bharat saraswalaf413b82016-07-14 15:18:20 +0530726
Bharat saraswald14cbe82016-07-14 13:26:18 +0530727 private YangNode searchAugmentNode(YangNode node, String tempNodeId) {
728 node = node.getChild();
729 while (node != null) {
730 if (node instanceof YangAugment) {
Bharat saraswalaf413b82016-07-14 15:18:20 +0530731 if (node.getName().equals(tempNodeId)) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530732 return node;
733 }
734 }
735 node = node.getNextSibling();
736 }
737 return null;
738 }
739
740 /**
741 * Validates for target node if target node found or not.
742 *
743 * @param tempNode temporary node
Bharat saraswalaf413b82016-07-14 15:18:20 +0530744 * @param index current index of list
Bharat saraswald14cbe82016-07-14 13:26:18 +0530745 * @return false if target node found
746 */
747 private boolean validate(YangNode tempNode, int index) {
748
749 int size = getAbsPaths().size();
750 if (tempNode != null && index != size) {
751 return true;
Bharat saraswalaf413b82016-07-14 15:18:20 +0530752 } else if (tempNode != null) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530753 return false;
754 // this is your target node.
Bharat saraswalaf413b82016-07-14 15:18:20 +0530755 } else if (index != size) {
756 return true;
Bharat saraswald14cbe82016-07-14 13:26:18 +0530757 // this could be in submodule as well.
758 }
759 return false;
760 }
761
762 /**
763 * Searches target node in root node.
764 *
Bharat saraswalaf413b82016-07-14 15:18:20 +0530765 * @param node root node
Bharat saraswald14cbe82016-07-14 13:26:18 +0530766 * @param curNodeId YANG node identifier
767 * @return linked target node
768 */
769 private YangNode searchTargetNode(YangNode node, YangNodeIdentifier curNodeId) {
770
771 if (node != null) {
772 node = node.getChild();
773 }
774
775 while (node != null) {
janani bebb143d2016-07-14 19:35:22 +0530776 if (node instanceof YangInput) {
777 if (curNodeId.getName().equalsIgnoreCase(INPUT)) {
778 return node;
779 }
780 } else if (node instanceof YangOutput) {
781 if (curNodeId.getName().equalsIgnoreCase(OUTPUT)) {
782 return node;
783 }
784 }
Bharat saraswald14cbe82016-07-14 13:26:18 +0530785 if (node.getName().equals(curNodeId.getName())) {
786 return node;
787 }
788 node = node.getNextSibling();
789 }
790 return null;
791 }
792
793 /**
Bharat saraswald14cbe82016-07-14 13:26:18 +0530794 * Returns root prefix.
795 *
796 * @param root root node
797 * @return root prefix
798 */
799 private String getRootsPrefix(YangNode root) {
800 if (root instanceof YangModule) {
801 return ((YangModule) root).getPrefix();
802 } else {
803 return ((YangSubModule) root).getPrefix();
804 }
805 }
806
Bharat saraswalaf413b82016-07-14 15:18:20 +0530807 /**
808 * Resolves prefix and provides prefix resolver list.
809 *
810 * @param absolutePaths absolute paths
811 */
812 private void parsePrefixResolverList(List<YangAtomicPath> absolutePaths) {
813 Iterator<YangAtomicPath> pathIterator = absolutePaths.iterator();
814 YangAtomicPath absPath;
815 String prePrefix;
816 String curPrefix = null;
817 while (pathIterator.hasNext()) {
818 prePrefix = curPrefix;
819 absPath = pathIterator.next();
820 curPrefix = absPath.getNodeIdentifier().getPrefix();
821 if (curPrefix != null) {
822 if (!curPrefix.equals(prePrefix)) {
823 if (prePrefix != null) {
824 addToPrefixResolverList(INTER_TO_INTER, absPath);
825 } else {
826 addToPrefixResolverList(INTRA_TO_INTER, absPath);
827 }
828 } else {
829 addToPrefixResolverList(NO_PREFIX_CHANGE_FOR_INTER, absPath);
830 }
831 } else {
832 if (prePrefix != null) {
833 addToPrefixResolverList(INTER_TO_INTRA, absPath);
834 } else {
835 addToPrefixResolverList(NO_PREFIX_CHANGE_FOR_INTRA, absPath);
836 }
837 }
838 }
839
840 }
841
Bharat saraswald14cbe82016-07-14 13:26:18 +0530842}