blob: 0cd359ba01e42b293c43eafcf08513b0869e6489 [file] [log] [blame]
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +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
Vidyashree Rama36f2fab2016-07-15 14:06:56 +053019import java.io.Serializable;
20import java.util.Iterator;
21import java.util.LinkedList;
22import java.util.List;
23import java.util.Stack;
Bharat saraswal2d90b0c2016-08-04 02:00:03 +053024
Bharat saraswal96dfef02016-06-16 00:29:12 +053025import org.onosproject.yangutils.datamodel.Resolvable;
janani be18b5342016-07-13 21:06:41 +053026import org.onosproject.yangutils.datamodel.ResolvableType;
Vidyashree Rama36f2fab2016-07-15 14:06:56 +053027import org.onosproject.yangutils.datamodel.TraversalType;
janani be18b5342016-07-13 21:06:41 +053028import org.onosproject.yangutils.datamodel.YangAtomicPath;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053029import org.onosproject.yangutils.datamodel.YangAugment;
30import org.onosproject.yangutils.datamodel.YangAugmentableNode;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053031import org.onosproject.yangutils.datamodel.YangBase;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053032import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053033import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
janani b23ccc312016-07-14 19:35:22 +053034import org.onosproject.yangutils.datamodel.YangEntityToResolveInfoImpl;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053035import org.onosproject.yangutils.datamodel.YangFeature;
36import org.onosproject.yangutils.datamodel.YangFeatureHolder;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053037import org.onosproject.yangutils.datamodel.YangGrouping;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053038import org.onosproject.yangutils.datamodel.YangIdentity;
39import org.onosproject.yangutils.datamodel.YangIdentityRef;
Bharat saraswalb551aae2016-07-14 15:18:20 +053040import org.onosproject.yangutils.datamodel.YangIfFeature;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053041import org.onosproject.yangutils.datamodel.YangImport;
42import org.onosproject.yangutils.datamodel.YangInclude;
janani be18b5342016-07-13 21:06:41 +053043import org.onosproject.yangutils.datamodel.YangInput;
44import org.onosproject.yangutils.datamodel.YangLeaf;
45import org.onosproject.yangutils.datamodel.YangLeafList;
46import org.onosproject.yangutils.datamodel.YangLeafRef;
janani be18b5342016-07-13 21:06:41 +053047import org.onosproject.yangutils.datamodel.YangModule;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053048import org.onosproject.yangutils.datamodel.YangNode;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053049import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
janani be18b5342016-07-13 21:06:41 +053050import org.onosproject.yangutils.datamodel.YangOutput;
51import org.onosproject.yangutils.datamodel.YangPathArgType;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053052import org.onosproject.yangutils.datamodel.YangReferenceResolver;
janani be18b5342016-07-13 21:06:41 +053053import org.onosproject.yangutils.datamodel.YangRelativePath;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053054import org.onosproject.yangutils.datamodel.YangResolutionInfo;
janani be18b5342016-07-13 21:06:41 +053055import org.onosproject.yangutils.datamodel.YangRpc;
56import org.onosproject.yangutils.datamodel.YangSubModule;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053057import org.onosproject.yangutils.datamodel.YangType;
58import org.onosproject.yangutils.datamodel.YangTypeDef;
59import org.onosproject.yangutils.datamodel.YangUses;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053060import org.onosproject.yangutils.datamodel.YangXPathResolver;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053061import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswal96dfef02016-06-16 00:29:12 +053062import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
janani b23ccc312016-07-14 19:35:22 +053063import org.onosproject.yangutils.datamodel.utils.YangConstructType;
janani be18b5342016-07-13 21:06:41 +053064import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +053065import org.onosproject.yangutils.linker.YangLinkingPhase;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053066import org.onosproject.yangutils.linker.exceptions.LinkerException;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053067
Vidyashree Rama36f2fab2016-07-15 14:06:56 +053068import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
69import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
70import static org.onosproject.yangutils.datamodel.TraversalType.ROOT;
71import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
janani b23ccc312016-07-14 19:35:22 +053072import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
Bharat saraswal96dfef02016-06-16 00:29:12 +053073import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
74import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
75import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.LINKED;
76import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053077import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNDEFINED;
Bharat saraswal96dfef02016-06-16 00:29:12 +053078import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +053079import static org.onosproject.yangutils.linker.YangLinkingPhase.INTER_FILE;
80import static org.onosproject.yangutils.linker.YangLinkingPhase.INTRA_FILE;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053081import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
janani b23ccc312016-07-14 19:35:22 +053082import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getPathWithAugment;
83import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getValidNodeIdentifier;
84import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.skipInvalidDataNodes;
Bharat saraswalb551aae2016-07-14 15:18:20 +053085import static org.onosproject.yangutils.utils.UtilConstants.BASE_LINKER_ERROR;
janani b23ccc312016-07-14 19:35:22 +053086import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053087import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
Vidyashree Rama210c01d2016-05-20 16:29:25 +053088import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
Bharat saraswalb551aae2016-07-14 15:18:20 +053089import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
90import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +053091import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
92import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
93import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
94import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
janani b23ccc312016-07-14 19:35:22 +053095import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053096import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_LINKER_ERROR;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053097
98/**
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053099 * Represents implementation of resolution object which will be resolved by
100 * linker.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530101 *
102 * @param <T> type of resolution entity uses / type
103 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530104public class YangResolutionInfoImpl<T>
Bharat saraswal96dfef02016-06-16 00:29:12 +0530105 implements YangResolutionInfo<T>, Serializable {
106
107 private static final long serialVersionUID = 806201658L;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530108
109 /**
110 * Information about the entity that needs to be resolved.
111 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530112 private YangEntityToResolveInfoImpl<T> entityToResolveInfo;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530113
114 /**
115 * Error line number.
116 */
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530117 private transient int lineNumber;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530118
119 /**
120 * Error character position in number.
121 */
Bharat saraswal96dfef02016-06-16 00:29:12 +0530122 private transient int charPosition;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530123
124 /**
125 * Current module/sub-module reference, will be used in inter-file/
126 * inter-jar scenario to get the import/include list.
127 */
Bharat saraswal96dfef02016-06-16 00:29:12 +0530128 private transient YangReferenceResolver curReferenceResolver;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530129
130 /**
131 * Stack for type/uses is maintained for hierarchical references, this is
132 * used during resolution.
133 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530134 private Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530135
136 /**
137 * It is private to ensure the overloaded method be invoked to create an
138 * object.
139 */
140 @SuppressWarnings("unused")
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530141 private YangResolutionInfoImpl() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530142 }
143
144 /**
145 * Creates a resolution information object with all the inputs.
146 *
147 * @param dataNode current parsable data node
148 * @param holderNode parent YANG node
149 * @param lineNumber error line number
150 * @param charPositionInLine error character position in line
151 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530152 public YangResolutionInfoImpl(T dataNode, YangNode holderNode, int lineNumber, int charPositionInLine) {
153 setEntityToResolveInfo(new YangEntityToResolveInfoImpl<>());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530154 getEntityToResolveInfo().setEntityToResolve(dataNode);
155 getEntityToResolveInfo().setHolderOfEntityToResolve(holderNode);
156 this.setLineNumber(lineNumber);
157 this.setCharPosition(charPositionInLine);
158 setPartialResolvedStack(new Stack<>());
159 }
160
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530161 @Override
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530162 public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
163 throws DataModelException {
164
165 setCurReferenceResolver(dataModelRootNode);
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530166 /**
167 * Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or
168 * YANG leafref or YANG base or YANG identityref.
169 */
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530170 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
171
172 // Check if linking is already done
173 if (entityToResolve instanceof Resolvable) {
174 Resolvable resolvable = (Resolvable) entityToResolve;
175 if (resolvable.getResolvableStatus() == RESOLVED) {
176 /**
177 * entity is already resolved, so nothing to do
178 */
179 return;
180 }
181 } else {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530182 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530183 "type/uses/if-feature/leafref/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530184 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530185 // Push the initial entity to resolve in stack.
186 addInPartialResolvedStack(getEntityToResolveInfo());
187
188 linkAndResolvePartialResolvedStack();
janani be18b5342016-07-13 21:06:41 +0530189
190 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530191 }
192
193 /**
194 * Resolves linking with ancestors.
195 *
196 * @throws DataModelException a violation of data model rules
197 */
198 private void linkAndResolvePartialResolvedStack()
199 throws DataModelException {
200
201 while (getPartialResolvedStack().size() != 0) {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530202 /**
203 * Current node to resolve, it can be a YANG type or YANG uses or
204 * YANG if-feature or YANG leafref or YANG base or YANG identityref.
205 */
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530206 T entityToResolve = getCurrentEntityToResolveFromStack();
207 // Check if linking is already done
208 if (entityToResolve instanceof Resolvable) {
209
210 Resolvable resolvable = (Resolvable) entityToResolve;
211 switch (resolvable.getResolvableStatus()) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530212 case RESOLVED: {
213 /*
214 * If the entity is already resolved in the stack, then pop
215 * it and continue with the remaining stack elements to
216 * resolve
217 */
218 getPartialResolvedStack().pop();
219 break;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530220 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530221
222 case LINKED: {
223 /*
224 * If the top of the stack is already linked then resolve
225 * the references and pop the entity and continue with
226 * remaining stack elements to resolve.
227 */
228 resolveTopOfStack(INTRA_FILE);
229 getPartialResolvedStack().pop();
230 break;
231 }
232
233 case INTRA_FILE_RESOLVED: {
234 /*
235 * Pop the top of the stack.
236 */
237 getPartialResolvedStack().pop();
238 break;
239 }
240
241 case UNRESOLVED: {
242 linkTopOfStackReferenceUpdateStack();
243
244 if (resolvable.getResolvableStatus() == UNRESOLVED) {
245 // If current entity is still not resolved, then
246 // linking/resolution has failed.
247 String errorInfo;
248 if (resolvable instanceof YangType) {
249 errorInfo = TYPEDEF_LINKER_ERROR;
250 } else if (resolvable instanceof YangUses) {
251 errorInfo = GROUPING_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +0530252 } else if (resolvable instanceof YangIfFeature) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530253 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530254 } else if (resolvable instanceof YangBase) {
255 errorInfo = BASE_LINKER_ERROR;
256 } else if (resolvable instanceof YangIdentityRef) {
257 errorInfo = IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +0530258 } else {
259 errorInfo = LEAFREF_LINKER_ERROR;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530260 }
261 DataModelException dataModelException =
262 new DataModelException(errorInfo);
263 dataModelException.setLine(getLineNumber());
264 dataModelException.setCharPosition(getCharPosition());
265 throw dataModelException;
266 }
267 break;
268 }
269 default: {
270 throw new DataModelException("Data Model Exception: Unsupported, linker state");
271 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530272
273 }
274
275 } else {
janani be18b5342016-07-13 21:06:41 +0530276 throw new DataModelException(
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530277 "Data Model Exception: Entity to resolved is other than type/uses/if-feature" +
278 "/leafref/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530279 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530280 }
281
282 }
283
284 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530285 * Adds the leafref/identityref type to the type, which has derived type referring to
286 * typedef with leafref/identityref type.
janani be18b5342016-07-13 21:06:41 +0530287 */
288 private void addDerivedRefTypeToRefTypeResolutionList() throws DataModelException {
289
290 YangNode potentialAncestorWithReferredNode = getEntityToResolveInfo().getHolderOfEntityToResolve();
291
292 // If holder is typedef return.
293 if (potentialAncestorWithReferredNode instanceof YangTypeDef) {
294 return;
295 }
296
297 // If entity is not type return.
298 if (!(getEntityToResolveInfo().getEntityToResolve() instanceof YangType)) {
299 return;
300 }
301
302 YangType yangType = (YangType) getEntityToResolveInfo().getEntityToResolve();
303
304 // If type is not resolved return.
305 if (yangType.getResolvableStatus() != RESOLVED) {
306 return;
307 }
308
309 YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType.getDataTypeExtendedInfo();
310
311 /*
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530312 * If the derived types referred type is not leafref/identityref return
janani be18b5342016-07-13 21:06:41 +0530313 */
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530314 if ((derivedInfo.getEffectiveBuiltInType() != YangDataTypes.LEAFREF) &&
315 (derivedInfo.getEffectiveBuiltInType() != YangDataTypes.IDENTITYREF)) {
janani be18b5342016-07-13 21:06:41 +0530316 return;
317 }
318
319 T extendedInfo = (T) derivedInfo.getReferredTypeDef().getTypeDefBaseType().getDataTypeExtendedInfo();
320
321 while (extendedInfo instanceof YangDerivedInfo) {
322 YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
323 extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef().getTypeDefBaseType()
324 .getDataTypeExtendedInfo();
325 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530326
janani be18b5342016-07-13 21:06:41 +0530327 /*
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530328 * Backup the derived types leafref/identityref info, delete all the info in current type,
329 * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
330 * create a leafref/identityref resolution info using the current resolution info and
331 * add to leafref/identityref resolution list.
janani be18b5342016-07-13 21:06:41 +0530332 */
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530333 if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.LEAFREF) {
334 YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
335 yangType.resetYangType();
janani be18b5342016-07-13 21:06:41 +0530336
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530337 yangType.setResolvableStatus(RESOLVED);
338 yangType.setDataType(YangDataTypes.LEAFREF);
339 yangType.setDataTypeName(LEAFREF);
340 yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
341 leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
janani b23ccc312016-07-14 19:35:22 +0530342 leafRefInTypeDef.setParentNodeOfLeafref(potentialAncestorWithReferredNode);
janani be18b5342016-07-13 21:06:41 +0530343
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530344 // Add resolution information to the list.
345 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
janani b23ccc312016-07-14 19:35:22 +0530346 potentialAncestorWithReferredNode,
347 getLineNumber(), getCharPosition());
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530348 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani b23ccc312016-07-14 19:35:22 +0530349 ResolvableType.YANG_LEAFREF);
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530350 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
351
352 } else if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.IDENTITYREF) {
353
354 YangIdentityRef identityRefInTypeDef = (YangIdentityRef) extendedInfo;
355 yangType.resetYangType();
356
357 yangType.setResolvableStatus(RESOLVED);
358 yangType.setDataType(YangDataTypes.IDENTITYREF);
359 yangType.setDataTypeName(IDENTITYREF);
360 yangType.setDataTypeExtendedInfo(identityRefInTypeDef);
361 identityRefInTypeDef.setResolvableStatus(UNRESOLVED);
362
363 // Add resolution information to the list.
364 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(identityRefInTypeDef,
janani b23ccc312016-07-14 19:35:22 +0530365 potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530366 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani b23ccc312016-07-14 19:35:22 +0530367 ResolvableType.YANG_IDENTITYREF);
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530368 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_IDENTITYREF);
369 }
janani be18b5342016-07-13 21:06:41 +0530370 }
371
372 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530373 * Resolves the current entity in the stack.
374 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530375 private void resolveTopOfStack(YangLinkingPhase linkingPhase)
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530376 throws DataModelException {
janani b23ccc312016-07-14 19:35:22 +0530377 List<T> entityToResolve = (List<T>) ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
378 if (entityToResolve != null && !entityToResolve.isEmpty()) {
379 Iterator<T> entityToResolveIterator = entityToResolve.listIterator();
380 while (entityToResolveIterator.hasNext()) {
381 addUnresolvedEntitiesToStack(entityToResolveIterator.next());
382 }
383 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530384 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
385 && ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
janani be18b5342016-07-13 21:06:41 +0530386 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530387 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
388 }
389 }
390
391 /**
janani b23ccc312016-07-14 19:35:22 +0530392 * Adds the unresolved entities to the resolution list.
393 *
394 * @param entityToResolve entity to resolve
395 * @throws DataModelException a violation of data model rules
396 */
397 private void addUnresolvedEntitiesToStack(T entityToResolve) throws DataModelException {
398 if (entityToResolve instanceof YangEntityToResolveInfoImpl) {
399 YangEntityToResolveInfoImpl entityToResolveInfo = (YangEntityToResolveInfoImpl) entityToResolve;
400 if (entityToResolveInfo.getEntityToResolve() instanceof YangLeafRef) {
401 YangLeafRef leafref = (YangLeafRef) entityToResolveInfo.getEntityToResolve();
402 YangNode parentNodeOfLeafref = entityToResolveInfo.getHolderOfEntityToResolve();
403 leafref.setParentNodeOfLeafref(parentNodeOfLeafref);
404 if (leafref.getResolvableStatus() == UNRESOLVED) {
405 leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
406 }
407 // Add resolution information to the list.
408 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafref,
409 parentNodeOfLeafref, entityToResolveInfo.getLineNumber(),
410 entityToResolveInfo.getCharPosition());
411 addResolutionInfo(resolutionInfoImpl);
412 }
413 }
414 }
415
416 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530417 * Resolves linking for a node child and siblings.
418 *
419 * @throws DataModelException data model error
420 */
421 private void linkTopOfStackReferenceUpdateStack()
422 throws DataModelException {
423
janani b23ccc312016-07-14 19:35:22 +0530424 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
425 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
426 return;
427 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530428 /*
429 * Check if self file reference is there, this will not check for the
430 * scenario when prefix is not present and type/uses is present in
431 * sub-module from include list.
432 */
433 if (!isCandidateForSelfFileReference()) {
434 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
435 return;
436 }
437
438 /**
439 * Try to resolve the top of the stack and update partial resolved stack
440 * if there is recursive references
441 */
442 YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
443 .getHolderOfEntityToResolve();
444
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530445 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
446 resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
447 return;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530448 } else if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
449 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
450 resolveSelfFileLinkingForBaseAndIdentityref();
451 return;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530452 } else {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530453
454 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530455 * Traverse up in the ancestor tree to check if the referred node is
456 * defined
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530457 */
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530458 while (potentialAncestorWithReferredNode != null) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530459
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530460 /**
461 * Check for the referred node defined in a ancestor scope
462 */
463 YangNode potentialReferredNode = potentialAncestorWithReferredNode.getChild();
464 if (isReferredNodeInSiblingListProcessed(potentialReferredNode)) {
465 return;
466 }
467
468 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
469 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530470 }
471
472 /*
473 * In case prefix is not present it's a candidate for inter-file
474 * resolution via include list.
475 */
476 if (getRefPrefix() == null) {
477 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
478 }
479 }
480
481 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530482 * Resolves self file linking for base/identityref.
483 *
484 * @throws DataModelException a violation of data model rules
485 */
486 private void resolveSelfFileLinkingForBaseAndIdentityref()
487 throws DataModelException {
488
489 boolean referredIdentityFound = false;
490 String nodeName = null;
491
492 if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
janani b23ccc312016-07-14 19:35:22 +0530493 nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530494 }
495
496 if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
497 nodeName = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName();
498 }
499
500 if (getCurReferenceResolver() instanceof YangModule) {
501 YangModule rootNode = (YangModule) getCurReferenceResolver();
502 // Sends list of nodes for finding the target identity.
503 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
504 } else if (getCurReferenceResolver() instanceof YangSubModule) {
505 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
506 // Sends list of nodes for finding the target identity.
507 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
508 }
509
510 if (referredIdentityFound) {
511 return;
512 }
513
514 /*
515 * In case prefix is not present it's a candidate for inter-file resolution via include list.
516 */
517 if (getRefPrefix() == null) {
518 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
519 }
520 }
521
522 /**
janani be18b5342016-07-13 21:06:41 +0530523 * Returns the root parent with respect to the ancestor count from leafref.
524 *
525 * @param ancestorCount count of node where parent node can be reached
526 * @param currentParent current parent node
527 * @return root node
528 * @throws DataModelException a violation of data model rules
529 */
530 private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
531 throws DataModelException {
532
533 int currentParentCount = 1;
534 while (currentParentCount < ancestorCount) {
535 if (currentParent.getParent() == null) {
536 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
537 }
538 currentParent = currentParent.getParent();
539 currentParentCount = currentParentCount + 1;
540 }
541 return currentParent;
542 }
543
544 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530545 * Resolves self file linking for if-feature.
546 *
547 * @param potentialAncestorWithReferredNode if-feature holder node
548 * @throws DataModelException DataModelException a violation of data model
549 * rules
550 */
551 private void resolveSelfFileLinkingForIfFeature(YangNode potentialAncestorWithReferredNode)
552 throws DataModelException {
553
554 YangFeatureHolder featureHolder = getFeatureHolder(potentialAncestorWithReferredNode);
555 YangNode potentialReferredNode = (YangNode) featureHolder;
556 if (isReferredNode(potentialReferredNode)) {
557
558 // Adds reference link of entity to the node under resolution.
559 addReferredEntityLink(potentialReferredNode, LINKED);
560
561 /**
562 * resolve the reference and update the partial resolution stack
563 * with any further recursive references
564 */
565 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
566 return;
567 }
568
569 /*
570 * In case prefix is not present it's a candidate for inter-file
571 * resolution via include list.
572 */
573 if (getRefPrefix() == null) {
574 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
575 }
576 }
577
janani be18b5342016-07-13 21:06:41 +0530578 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530579 * Returns the status of the referred identity found for base/identityref.
580 *
janani b23ccc312016-07-14 19:35:22 +0530581 * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530582 * @param ancestorWithTheReferredNode the parent node of base/identityref
583 * @return status of referred base/identityref
584 * @throws DataModelException a violation of data model rules
585 */
586 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorWithTheReferredNode)
587 throws DataModelException {
588
589 // When child is not present return.
590 if (ancestorWithTheReferredNode.getChild() == null) {
591 return false;
592 }
593
594 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
595
596 // Checks all the siblings under the node and returns the matched node.
597 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorWithTheReferredNode, nodeName);
598
599 if (nodeFound != null) {
600 // Adds reference link of entity to the node under resolution.
601 addReferredEntityLink(nodeFound, LINKED);
602
603 /**
604 * resolve the reference and update the partial resolution stack with any further recursive references
605 */
606 addUnresolvedRecursiveReferenceToStack(nodeFound);
607 return true;
608 }
609
610 return false;
611 }
612
613 /**
janani be18b5342016-07-13 21:06:41 +0530614 * Adds the unresolved constructs to stack which has to be resolved for leafref.
615 *
janani b23ccc312016-07-14 19:35:22 +0530616 * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
janani be18b5342016-07-13 21:06:41 +0530617 * @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
618 */
619 private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
620
621 YangType referredTypeInLeafOrLeafList;
622 if (yangleafOrLeafList instanceof YangLeaf) {
623 YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
624 referredTypeInLeafOrLeafList = leaf.getDataType();
625 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
626 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
627 unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
628 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
629 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
630 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
631 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
632 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
633 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
634 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
635 }
636 } else {
637 YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
638 referredTypeInLeafOrLeafList = leafList.getDataType();
639 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
640 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
641 unResolvedEntityInfo
642 .setEntityToResolve((YangLeafRef<?>) leafList.getDataType().getDataTypeExtendedInfo());
643 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
644 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
645 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
646 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
647 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
648 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
649 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
650 }
651 }
652 }
653
654 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530655 * Returns feature holder(module/sub-module node) .
656 *
657 * @param potentialAncestorWithReferredNode if-feature holder node
658 */
659 private YangFeatureHolder getFeatureHolder(YangNode potentialAncestorWithReferredNode) {
660 while (potentialAncestorWithReferredNode != null) {
661 if (potentialAncestorWithReferredNode instanceof YangFeatureHolder) {
662 return (YangFeatureHolder) potentialAncestorWithReferredNode;
663 }
664 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
665 }
666 return null;
667 }
668
669 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530670 * Checks if the reference in self file or in external file.
671 *
672 * @return true if self file reference, false otherwise
673 * @throws DataModelException a violation of data model rules
674 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530675 private boolean isCandidateForSelfFileReference()
676 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530677 String prefix = getRefPrefix();
678 return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
679 }
680
681 /**
janani be18b5342016-07-13 21:06:41 +0530682 * Checks for the referred parent node for the leafref path.
683 *
684 * @param potentialReferredNode potential referred node
685 * @return the reffered parent node of leaf/leaf-list
686 * @throws DataModelException data model errors
687 */
688 private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
689 throws DataModelException {
690
691 while (potentialReferredNode != null) {
692 if (potentialReferredNode instanceof YangInput) {
693 if (referredNodeName.equalsIgnoreCase(INPUT)) {
694 return potentialReferredNode;
695 }
696 } else if (potentialReferredNode instanceof YangOutput) {
697 if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
698 return potentialReferredNode;
699 }
700 }
701 // Check if the potential referred node is the actual referred node
702 if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
703 if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
704 if (potentialReferredNode.getParent() instanceof YangRpc) {
705 potentialReferredNode = potentialReferredNode.getNextSibling();
706 } else {
707 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
708 }
709 }
710 return potentialReferredNode;
711 }
712 potentialReferredNode = potentialReferredNode.getNextSibling();
713 }
714 return null;
715 }
716
717 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530718 * Checks for the referred parent node for the base/identity.
719 *
720 * @param potentialReferredNode potential referred node
721 * @return the reffered parent node of base/identity.
722 * @throws DataModelException data model errors
723 */
724 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode potentialReferredNode,
janani b23ccc312016-07-14 19:35:22 +0530725 String referredNodeName) throws DataModelException {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530726
727 while (potentialReferredNode != null) {
728 if (potentialReferredNode instanceof YangIdentity) {
729 // Check if the potential referred node is the actual referred node
730 if (isReferredNodeForIdentity(potentialReferredNode, referredNodeName)) {
731 return potentialReferredNode;
732 }
733 }
734 potentialReferredNode = potentialReferredNode.getNextSibling();
735 }
736 return null;
737 }
738
739 /**
janani be18b5342016-07-13 21:06:41 +0530740 * Checks if the current reference node name and the name in the path are equal.
741 *
742 * @param currentReferredNode the node where the reference is pointed
janani b23ccc312016-07-14 19:35:22 +0530743 * @param nameOfNodeinPath name of the node in the path
janani be18b5342016-07-13 21:06:41 +0530744 * @return status of the match between the name
745 * @throws DataModelException a violation of data model rules
746 */
747 private boolean isReferredNodeForLeafref(YangNode currentReferredNode, String nameOfNodeinPath)
748 throws DataModelException {
749
750 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
751 /*
752 * Check if name of node name matches with the current reference
753 * node.
754 */
755 return currentReferredNode.getName().contentEquals(nameOfNodeinPath);
756 } else {
757 throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref");
758 }
759 }
760
761 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530762 * Checks if the current reference node name and the name in the base/identityref base are equal.
763 *
janani b23ccc312016-07-14 19:35:22 +0530764 * @param currentReferredNode the node where the reference is pointed
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530765 * @param nameOfIdentityRefBase name of the base in the base/identityref base
766 * @return status of the match between the name
767 * @throws DataModelException a violation of data model rules
768 */
769 private boolean isReferredNodeForIdentity(YangNode currentReferredNode, String nameOfIdentityRefBase)
770 throws DataModelException {
771
772 if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
773 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
774 /*
775 * Check if name of node name matches with the current reference node.
776 */
777 return currentReferredNode.getName().contentEquals(nameOfIdentityRefBase);
778 } else {
779 throw new DataModelException("Data Model Exception: Entity to resolved is other than identityref");
780 }
781 }
782
783 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530784 * Checks for the referred node defined in a ancestor scope.
785 *
786 * @param potentialReferredNode potential referred node
787 * @return status of resolution and updating the partial resolved stack with
788 * the any recursive references
janani be18b5342016-07-13 21:06:41 +0530789 * @throws DataModelException a violation of data model rules
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530790 */
791 private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
792 throws DataModelException {
793 while (potentialReferredNode != null) {
794
795 // Check if the potential referred node is the actual referred node
796 if (isReferredNode(potentialReferredNode)) {
797
798 // Adds reference link of entity to the node under resolution.
799 addReferredEntityLink(potentialReferredNode, LINKED);
800
801 /**
802 * resolve the reference and update the partial resolution stack
803 * with any further recursive references
804 */
805 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
806
807 /*
808 * return true, since the reference is linked and any recursive
809 * unresolved references is added to the stack
810 */
811 return true;
812 }
813
814 potentialReferredNode = potentialReferredNode.getNextSibling();
815 }
816 return false;
817 }
818
819 /**
820 * Checks if the potential referred node is the actual referred node.
821 *
822 * @param potentialReferredNode typedef/grouping node
823 * @return true if node is of resolve type otherwise false
824 * @throws DataModelException a violation of data model rules
825 */
826 private boolean isReferredNode(YangNode potentialReferredNode)
827 throws DataModelException {
828 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
829 if (potentialReferredNode instanceof YangTypeDef) {
830 /*
831 * Check if name of node name matches with the entity being
832 * resolved
833 */
834 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
835 }
836 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
837 if (potentialReferredNode instanceof YangGrouping) {
838 /*
839 * Check if name of node name matches with the entity being
840 * resolved
841 */
842 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
843 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530844 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
845 if (potentialReferredNode instanceof YangFeatureHolder) {
846 /*
847 * Check if name of node name matches with the entity being
848 * resolved
849 */
850 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
851 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530852 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
853 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
854 if (potentialReferredNode instanceof YangIdentity) {
855 /*
856 * Check if name of node name matches with the entity being
857 * resolved
858 */
859 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
860 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530861 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530862 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
janani b23ccc312016-07-14 19:35:22 +0530863 "uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530864 }
865 return false;
866 }
867
868 /**
869 * Checks if node name is same as name in resolution info, i.e. name of
870 * typedef/grouping is same as name of type/uses.
871 *
872 * @param node typedef/grouping node
873 * @return true if node name is same as name in resolution info, otherwise
874 * false
875 * @throws DataModelException a violation of data model rules
876 */
877
878 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
879 throws DataModelException {
880 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
881 if (node.getName().contentEquals(
882 ((YangType<?>) getCurrentEntityToResolveFromStack())
883 .getDataTypeName())) {
884 return true;
885 }
886 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
887 if (node.getName().contentEquals(
888 ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
889 return true;
890 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530891 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
892 return isFeatureDefinedInNode(node);
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530893 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
894 if (node.getName().contentEquals(
895 ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
896 return true;
897 }
898 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
899 if (node.getName().contentEquals(
900 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName())) {
901 return true;
902 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530903 } else {
904 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
905 }
906 return false;
907 }
908
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530909 private boolean isFeatureDefinedInNode(YangNode node) throws DataModelException {
910 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
911 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
912 if (featureList != null && !featureList.isEmpty()) {
913 Iterator<YangFeature> iterator = featureList.iterator();
914 while (iterator.hasNext()) {
915 YangFeature feature = iterator.next();
916 if (ifFeature.getName().equals(feature.getName())) {
917 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
918 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeatureHolder(node);
919 return true;
920 }
921 }
922 }
923 return false;
924 }
925
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530926 /**
927 * Adds reference of grouping/typedef in uses/type.
928 *
929 * @param referredNode grouping/typedef node being referred
930 * @param linkedStatus linked status if success.
931 * @throws DataModelException a violation of data model rules
932 */
933 private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
934 throws DataModelException {
935 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswal96dfef02016-06-16 00:29:12 +0530936 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
937 .getDataTypeExtendedInfo();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530938 derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
939 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
940 ((YangUses) getCurrentEntityToResolveFromStack())
941 .setRefGroup((YangGrouping) referredNode);
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530942 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
943 // do nothing , referred node is already set
janani be18b5342016-07-13 21:06:41 +0530944 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
945 // do nothing , referred node is already set
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530946 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
947 ((YangBase) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
948 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
949 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530950 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530951 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani b23ccc312016-07-14 19:35:22 +0530952 "/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530953 }
954
955 // Sets the resolution status in inside the type/uses.
956 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
957 }
958
959 /**
960 * Checks if type/grouping has further reference to typedef/ unresolved
961 * uses. Add it to the partial resolve stack and return the status of
962 * addition to stack.
963 *
964 * @param referredNode grouping/typedef node
965 * @throws DataModelException a violation of data model rules
966 */
967 private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
968 throws DataModelException {
969 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
970 /*
971 * Checks if typedef type is derived
972 */
Bharat saraswal96dfef02016-06-16 00:29:12 +0530973 if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType() == YangDataTypes.DERIVED) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530974
Bharat saraswal96dfef02016-06-16 00:29:12 +0530975 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530976 unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
977 .getTypeDefBaseType());
978 unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530979 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530980 }
981
982 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
983 /*
984 * Search if the grouping has any un resolved uses child, if so
985 * return true, else return false.
986 */
987 addUnResolvedUsesToStack(referredNode);
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530988 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
989 addUnResolvedIfFeatureToStack(referredNode);
janani be18b5342016-07-13 21:06:41 +0530990 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
991 // do nothing , referred node is already set
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530992 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530993 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
994 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
995 /*
996 * Search if the identity has any un resolved base, if so return true, else return false.
997 */
998 addUnResolvedBaseToStack(referredNode);
999 } else {
1000 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
janani b23ccc312016-07-14 19:35:22 +05301001 "base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301002 }
1003 }
1004
1005 /**
1006 * Returns if there is any unresolved uses in grouping.
1007 *
1008 * @param node grouping/typedef node
1009 */
1010 private void addUnResolvedUsesToStack(YangNode node) {
1011
1012 /**
1013 * Search the grouping node's children for presence of uses node.
1014 */
Vidyashree Rama36f2fab2016-07-15 14:06:56 +05301015 TraversalType curTraversal = ROOT;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301016 YangNode curNode = node.getChild();
1017 while (curNode != null) {
Vidyashree Rama36f2fab2016-07-15 14:06:56 +05301018 if (curNode.getName().equals(node.getName())) {
1019 // if we have traversed all the child nodes, then exit from loop
1020 return;
1021 }
1022
1023 // if child nodes has uses, then add it to resolution stack
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301024 if (curNode instanceof YangUses) {
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301025 YangEntityToResolveInfoImpl<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301026 unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
1027 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301028 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301029 }
Vidyashree Rama36f2fab2016-07-15 14:06:56 +05301030
1031 // Traversing all the child nodes of grouping
1032 if (curTraversal != PARENT && curNode.getChild() != null) {
1033 curTraversal = CHILD;
1034 curNode = curNode.getChild();
1035 } else if (curNode.getNextSibling() != null) {
1036 curTraversal = SIBILING;
1037 curNode = curNode.getNextSibling();
1038 } else {
1039 curTraversal = PARENT;
1040 curNode = curNode.getParent();
1041 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301042 }
1043 }
1044
1045 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301046 * Returns if there is any unresolved if-feature in feature.
1047 *
1048 * @param node module/submodule node
1049 */
1050 private void addUnResolvedIfFeatureToStack(YangNode node) {
1051 YangFeature refFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeature();
1052 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
1053 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
1054 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
1055 while (ifFeatureIterator.hasNext()) {
1056 YangIfFeature ifFeature = ifFeatureIterator.next();
1057 YangEntityToResolveInfo<YangIfFeature> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1058 unResolvedEntityInfo.setEntityToResolve(ifFeature);
1059 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1060 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1061 }
1062 }
1063 }
1064
1065 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301066 * Returns if there is any unresolved base in identity.
1067 *
1068 * @param node module/submodule node
1069 */
1070 private void addUnResolvedBaseToStack(YangNode node) {
1071
1072 YangIdentity curNode = (YangIdentity) node;
1073 if (curNode.getBaseNode() != null) {
1074 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
1075 YangEntityToResolveInfoImpl<YangBase> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1076 unResolvedEntityInfo.setEntityToResolve(curNode.getBaseNode());
1077 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1078 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1079
1080 }
1081 }
1082 }
1083
1084
1085 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301086 * Returns stack of YANG type with partially resolved YANG construct
1087 * hierarchy.
1088 *
1089 * @return partial resolved YANG construct stack
1090 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301091 private Stack<YangEntityToResolveInfoImpl<T>> getPartialResolvedStack() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301092 return partialResolvedStack;
1093 }
1094
1095 /**
1096 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1097 *
1098 * @param partialResolvedStack partial resolved YANG construct stack
1099 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301100 private void setPartialResolvedStack(Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301101 this.partialResolvedStack = partialResolvedStack;
1102 }
1103
1104 /**
1105 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1106 *
1107 * @param partialResolvedInfo partial resolved YANG construct stack
1108 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301109 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301110 getPartialResolvedStack().push(partialResolvedInfo);
1111 }
1112
1113 /**
1114 * Retrieves the next entity in the stack that needs to be resolved. It is
1115 * assumed that the caller ensures that the stack is not empty.
1116 *
1117 * @return next entity in the stack that needs to be resolved
1118 */
1119 private T getCurrentEntityToResolveFromStack() {
1120 return getPartialResolvedStack().peek().getEntityToResolve();
1121 }
1122
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301123 @Override
1124 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301125 return entityToResolveInfo;
1126 }
1127
1128 /**
1129 * Sets information about the entity that needs to be resolved.
1130 *
1131 * @param entityToResolveInfo information about the entity that needs to be
1132 * resolved
1133 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301134 private void setEntityToResolveInfo(YangEntityToResolveInfoImpl<T> entityToResolveInfo) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301135 this.entityToResolveInfo = entityToResolveInfo;
1136 }
1137
1138 @Override
1139 public int getLineNumber() {
1140 return lineNumber;
1141 }
1142
1143 @Override
1144 public int getCharPosition() {
1145 return charPosition;
1146 }
1147
1148 @Override
1149 public void setLineNumber(int lineNumber) {
1150 this.lineNumber = lineNumber;
1151 }
1152
1153 @Override
1154 public void setCharPosition(int charPositionInLine) {
1155 this.charPosition = charPositionInLine;
1156 }
1157
1158 /**
1159 * Returns current module/sub-module reference, will be used in inter-file/
1160 * inter-jar scenario to get the import/include list.
1161 *
1162 * @return current module/sub-module reference
1163 */
1164 private YangReferenceResolver getCurReferenceResolver() {
1165 return curReferenceResolver;
1166 }
1167
1168 /**
1169 * Sets current module/sub-module reference, will be used in inter-file/
1170 * inter-jar scenario to get the import/include list.
1171 *
1172 * @param curReferenceResolver current module/sub-module reference
1173 */
1174 private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
1175 this.curReferenceResolver = curReferenceResolver;
1176 }
1177
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301178 @Override
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301179 public void linkInterFile(YangReferenceResolver dataModelRootNode)
1180 throws DataModelException {
1181
1182 setCurReferenceResolver(dataModelRootNode);
1183
1184 // Current node to resolve, it can be a YANG type or YANG uses.
1185 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
1186
1187 // Check if linking is already done
1188 if (entityToResolve instanceof Resolvable) {
1189 Resolvable resolvable = (Resolvable) entityToResolve;
1190 if (resolvable.getResolvableStatus() == RESOLVED) {
1191 return;
1192 }
1193 } else {
1194 throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
1195 }
1196
janani b23ccc312016-07-14 19:35:22 +05301197 if (entityToResolve instanceof YangXPathResolver && !(entityToResolve instanceof YangLeafRef)) {
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301198 //Process x-path linking.
janani b23ccc312016-07-14 19:35:22 +05301199 processXPathLinking(entityToResolve, dataModelRootNode);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301200
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301201 } else {
janani be18b5342016-07-13 21:06:41 +05301202
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301203 // Push the initial entity to resolve in stack.
1204 addInPartialResolvedStack(getEntityToResolveInfo());
1205
1206 // Inter file linking and resolution.
1207 linkInterFileAndResolve();
1208
1209 addDerivedRefTypeToRefTypeResolutionList();
1210 }
1211 }
1212
1213 /**
1214 * Process x-path linking for augment and leaf-ref.
1215 *
janani b23ccc312016-07-14 19:35:22 +05301216 * @param entityToResolve entity to resolve
1217 * @param root root node
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301218 */
janani b23ccc312016-07-14 19:35:22 +05301219 private void processXPathLinking(T entityToResolve,
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301220 YangReferenceResolver root) {
janani b23ccc312016-07-14 19:35:22 +05301221
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301222 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
janani b23ccc312016-07-14 19:35:22 +05301223
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301224 if (entityToResolve instanceof YangAugment) {
Bharat saraswal2d90b0c2016-08-04 02:00:03 +05301225 YangNode targetNode;
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301226 YangAugment augment = (YangAugment) entityToResolve;
1227 targetNode = xPathLinker.processAugmentXpathLinking(augment.getTargetNode(),
1228 (YangNode) root);
1229 if (targetNode != null) {
1230 if (targetNode instanceof YangAugmentableNode) {
1231 detectCollisionForAugmentedNode(targetNode, augment);
1232 ((YangAugmentableNode) targetNode).addAugmentation(augment);
1233 augment.setAugmentedNode(targetNode);
1234 Resolvable resolvable = (Resolvable) entityToResolve;
1235 resolvable.setResolvableStatus(RESOLVED);
1236 } else {
1237 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for "
1238 + augment.getName());
1239 }
1240 } else {
1241 throw new LinkerException("Failed to link " + augment.getName());
1242 }
1243 } else if (entityToResolve instanceof YangLeafRef) {
1244 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
1245 Object target = xPathLinker.processLeafRefXpathLinking(leafRef.getAtomicPath(),
janani b23ccc312016-07-14 19:35:22 +05301246 (YangNode) root, leafRef);
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301247 if (target != null) {
1248 YangLeaf leaf = null;
1249 YangLeafList leafList = null;
1250 leafRef.setReferredLeafOrLeafList(target);
1251 if (target instanceof YangLeaf) {
1252 leaf = (YangLeaf) target;
janani b23ccc312016-07-14 19:35:22 +05301253 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1254 addUnResolvedLeafRefTypeToStack((T) leaf, getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301255 } else {
1256 leafList = (YangLeafList) target;
janani b23ccc312016-07-14 19:35:22 +05301257 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1258 addUnResolvedLeafRefTypeToStack((T) leafList,
1259 getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301260 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301261 //TODO: add logic for leaf-ref for path predicates.
1262 } else {
janani b23ccc312016-07-14 19:35:22 +05301263 LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
1264 "leaf/leaf-list for given leafref path "
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301265 + leafRef.getPath());
janani b23ccc312016-07-14 19:35:22 +05301266 linkerException.setCharPosition(leafRef.getCharPosition());
1267 linkerException.setLine(leafRef.getLineNumber());
1268 throw linkerException;
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301269 }
1270 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301271 }
1272
1273 /**
1274 * Returns the referenced prefix of entity under resolution.
1275 *
1276 * @return referenced prefix of entity under resolution
1277 * @throws DataModelException a violation in data model rule
1278 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301279 private String getRefPrefix()
1280 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301281 String refPrefix;
1282 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1283 refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
1284 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1285 refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301286 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1287 refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301288 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1289 refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
1290 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1291 refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301292 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301293 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
janani b23ccc312016-07-14 19:35:22 +05301294 "type/uses/base/identityref");
janani be18b5342016-07-13 21:06:41 +05301295 }
1296 return refPrefix;
1297 }
1298
1299 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301300 * Performs inter file linking and resolution.
1301 *
1302 * @throws DataModelException a violation in data model rule
1303 */
1304 private void linkInterFileAndResolve()
1305 throws DataModelException {
1306
1307 while (getPartialResolvedStack().size() != 0) {
1308
1309 // Current node to resolve, it can be a YANG type or YANG uses.
1310 T entityToResolve = getCurrentEntityToResolveFromStack();
1311 // Check if linking is already done
1312 if (entityToResolve instanceof Resolvable) {
1313
1314 Resolvable resolvable = (Resolvable) entityToResolve;
1315 switch (resolvable.getResolvableStatus()) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301316 case RESOLVED: {
1317 /*
1318 * If the entity is already resolved in the stack, then pop
1319 * it and continue with the remaining stack elements to
1320 * resolve
1321 */
1322 getPartialResolvedStack().pop();
1323 break;
1324 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301325
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301326 case INTER_FILE_LINKED: {
1327 /*
1328 * If the top of the stack is already linked then resolve
1329 * the references and pop the entity and continue with
1330 * remaining stack elements to resolve
1331 */
1332 resolveTopOfStack(INTER_FILE);
1333 getPartialResolvedStack().pop();
1334 break;
1335 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301336
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301337 case INTRA_FILE_RESOLVED: {
1338 /*
1339 * If the top of the stack is intra file resolved then check
1340 * if top of stack is linked, if not link it using
1341 * import/include list and push the linked referred entity
1342 * to the stack, otherwise only push it to the stack.
1343 */
1344 linkInterFileTopOfStackRefUpdateStack();
1345 break;
1346 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301347
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301348 case UNDEFINED: {
1349 /*
1350 * In case of if-feature resolution, if referred "feature" is not
1351 * defined then the resolvable status will be undefined.
1352 */
1353 getPartialResolvedStack().pop();
1354 break;
1355 }
1356
1357 default: {
1358 throw new DataModelException("Data Model Exception: Unsupported, linker state");
1359 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301360
1361 }
1362
1363 } else {
1364 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1365 }
1366
1367 }
1368
1369 }
1370
1371 /**
1372 * Links the top of the stack if it's inter-file and update stack.
1373 *
1374 * @throws DataModelException data model error
1375 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301376 private void linkInterFileTopOfStackRefUpdateStack()
1377 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301378
janani b23ccc312016-07-14 19:35:22 +05301379 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1380 // When leafref path comes with relative path, it will be converted to absolute path.
1381 setAbsolutePathFromRelativePathInLeafref(getCurrentEntityToResolveFromStack());
1382 processXPathLinking(getCurrentEntityToResolveFromStack(), getCurReferenceResolver());
1383 return;
1384 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301385 /*
1386 * Obtain the referred node of top of stack entity under resolution
1387 */
1388 T referredNode = getRefNode();
1389
1390 /*
1391 * Check for null for scenario when it's not linked and inter-file
1392 * linking is required.
1393 */
1394 if (referredNode == null) {
1395
1396 /*
Bharat saraswal96dfef02016-06-16 00:29:12 +05301397 * Check if prefix is null or not, to identify whether to search in
1398 * import list or include list.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301399 */
Bharat saraswalcad0e652016-05-26 23:48:38 +05301400 if (getRefPrefix() != null && !getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301401 if (resolveWithImport()) {
1402 return;
1403 }
1404 } else {
1405 if (resolveWithInclude()) {
1406 return;
1407 }
1408 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301409
1410 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1411 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
1412 return;
1413 }
janani be18b5342016-07-13 21:06:41 +05301414 // If current entity is still not resolved, then
1415 // linking/resolution has failed.
1416 String errorInfo;
1417 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1418 errorInfo = TYPEDEF_LINKER_ERROR;
1419 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1420 errorInfo = GROUPING_LINKER_ERROR;
1421 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1422 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301423 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1424 errorInfo = BASE_LINKER_ERROR;
1425 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1426 errorInfo = IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +05301427 } else {
1428 errorInfo = LEAFREF_LINKER_ERROR;
1429 }
1430 DataModelException dataModelException = new DataModelException(errorInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301431 dataModelException.setLine(getLineNumber());
1432 dataModelException.setCharPosition(getCharPosition());
1433 throw dataModelException;
1434 } else {
janani b23ccc312016-07-14 19:35:22 +05301435 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1436 addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
1437 }
1438 }
1439
1440 /**
1441 * Sets the leafref with absolute path from the relative path.
1442 *
1443 * @param resolutionInfo information about the YANG construct which has to be resolved
1444 * @throws DataModelException a violation of data model rules
1445 */
Vidyashree Rama36f2fab2016-07-15 14:06:56 +05301446 public void setAbsolutePathFromRelativePathInLeafref(T resolutionInfo) throws DataModelException {
janani b23ccc312016-07-14 19:35:22 +05301447 if (resolutionInfo instanceof YangLeafRef) {
1448
1449 YangNode parentOfLeafref = ((YangLeafRef) resolutionInfo).getParentNodeOfLeafref();
1450 YangLeafRef leafref = (YangLeafRef) resolutionInfo;
1451
1452 // Checks if the leafref has relative path in it.
1453 if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
1454 YangRelativePath relativePath = leafref.getRelativePath();
1455 List<YangAtomicPath> absoluteInRelative = relativePath.getAtomicPathList();
1456 int numberOfAncestors = relativePath.getAncestorNodeCount();
1457
1458 // Gets the root node from the ancestor count.
1459 T nodeOrAugmentList = getRootNodeWithAncestorCountForLeafref(numberOfAncestors, parentOfLeafref,
1460 leafref);
1461 if (nodeOrAugmentList instanceof YangNode) {
1462 String pathNameToBePrefixed = EMPTY_STRING;
1463 YangNode rootNode = (YangNode) nodeOrAugmentList;
1464 // Forms a new absolute path from the relative path
1465 while (!(rootNode instanceof YangReferenceResolver)) {
1466 pathNameToBePrefixed = rootNode.getName() + SLASH_FOR_STRING + pathNameToBePrefixed;
1467 rootNode = rootNode.getParent();
1468 if (rootNode == null) {
1469 throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
1470 }
1471 }
1472 fillAbsolutePathValuesInLeafref(leafref, pathNameToBePrefixed, absoluteInRelative);
1473 } else {
1474 List<String> listOfAugment = (List<String>) nodeOrAugmentList;
1475 Iterator<String> listOfAugmentIterator = listOfAugment.listIterator();
1476 String augment = EMPTY_STRING;
1477 while (listOfAugmentIterator.hasNext()) {
1478 augment = augment + SLASH_FOR_STRING + listOfAugmentIterator.next();
1479 }
1480 fillAbsolutePathValuesInLeafref(leafref, augment, absoluteInRelative);
janani be18b5342016-07-13 21:06:41 +05301481 }
janani be18b5342016-07-13 21:06:41 +05301482 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301483 }
1484 }
1485
1486 /**
janani b23ccc312016-07-14 19:35:22 +05301487 * Fills the absolute path values in the leafref from relative path.
1488 *
Bharat saraswal2d90b0c2016-08-04 02:00:03 +05301489 * @param leafref instance of YANG leafref
1490 * @param pathNameToBePrefixed path name which has to be prefixed to relative path
1491 * @param atomicPathsInRelative atomic paths in relative
janani b23ccc312016-07-14 19:35:22 +05301492 * @throws DataModelException a violation of data model rules
1493 */
1494 private void fillAbsolutePathValuesInLeafref(YangLeafRef leafref, String pathNameToBePrefixed,
1495 List<YangAtomicPath> atomicPathsInRelative) throws DataModelException {
1496
1497 leafref.setPathType(YangPathArgType.ABSOLUTE_PATH);
1498 String[] pathName = new String[0];
1499 if (pathNameToBePrefixed != EMPTY_STRING && pathNameToBePrefixed != null) {
1500 pathName = pathNameToBePrefixed.split(SLASH_FOR_STRING);
1501 }
1502 List<YangAtomicPath> finalListForAbsolute = new LinkedList<>();
1503 for (String value : pathName) {
1504 if (value != null && !value.isEmpty() && value != EMPTY_STRING) {
1505 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(value, YangConstructType.PATH_DATA);
1506 YangAtomicPath atomicPath = new YangAtomicPath();
1507 atomicPath.setNodeIdentifier(nodeIdentifier);
1508 finalListForAbsolute.add(atomicPath);
1509 }
1510 }
1511 if (atomicPathsInRelative != null && !atomicPathsInRelative.isEmpty()) {
1512 Iterator<YangAtomicPath> atomicPathIterator = atomicPathsInRelative.listIterator();
1513 while (atomicPathIterator.hasNext()) {
1514 YangAtomicPath yangAtomicPath = atomicPathIterator.next();
1515 finalListForAbsolute.add(yangAtomicPath);
1516 }
1517 leafref.setAtomicPath(finalListForAbsolute);
1518 } else {
1519 DataModelException dataModelException = new DataModelException("YANG file error: The target node, in the " +
1520 "leafref path " + leafref.getPath() + ", is invalid.");
1521 dataModelException.setCharPosition(leafref.getCharPosition());
1522 dataModelException.setLine(leafref.getLineNumber());
1523 throw dataModelException;
1524 }
1525 }
1526
1527 /**
1528 * Returns the root parent with respect to the ancestor count from leafref.
1529 *
1530 * @param ancestorCount count of node where parent node can be reached
1531 * @param currentParent current parent node
1532 * @param leafref instance of YANG leafref
1533 * @return node where the ancestor count stops or augment path name list
1534 * @throws DataModelException a violation of data model rules
1535 */
1536 private T getRootNodeWithAncestorCountForLeafref(int ancestorCount, YangNode currentParent, YangLeafRef leafref)
1537 throws DataModelException {
1538
1539 int currentParentCount = 1;
1540 currentParent = skipInvalidDataNodes(currentParent, leafref);
1541 if (currentParent instanceof YangAugment) {
1542 YangAugment augment = (YangAugment) currentParent;
1543 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1544 return (T) valueInAugment;
1545 } else {
1546 while (currentParentCount < ancestorCount) {
1547 YangNode currentSkippedParent = skipInvalidDataNodes(currentParent, leafref);
1548 if (currentSkippedParent == currentParent) {
1549 if (currentParent.getParent() == null) {
1550 throw new DataModelException("YANG file error: The target node, in the leafref path "
1551 + leafref.getPath() + ", is invalid.");
1552 }
1553 currentParent = currentParent.getParent();
1554 } else {
1555 currentParent = currentSkippedParent;
1556 continue;
1557 }
1558 currentParentCount = currentParentCount + 1;
1559 if (currentParent instanceof YangAugment) {
1560 YangAugment augment = (YangAugment) currentParent;
1561 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1562 return (T) valueInAugment;
1563 }
1564 }
1565 }
1566 return (T) currentParent;
1567 }
1568
1569 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301570 * Finds and resolves with include list.
1571 *
1572 * @return true if resolved, false otherwise
1573 * @throws DataModelException a violation in data model rule
1574 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301575 private boolean resolveWithInclude()
1576 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301577 /*
1578 * Run through all the nodes in include list and search for referred
1579 * typedef/grouping at the root level.
1580 */
1581 for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
1582 YangNode linkedNode = null;
1583 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1584 linkedNode = findRefTypedef(yangInclude.getIncludedNode());
1585 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1586 linkedNode = findRefGrouping(yangInclude.getIncludedNode());
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301587 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1588 linkedNode = findRefFeature(yangInclude.getIncludedNode());
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301589 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1590 linkedNode = findRefIdentity(yangInclude.getIncludedNode());
1591 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1592 linkedNode = findRefIdentityRef(yangInclude.getIncludedNode());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301593 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301594
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301595 if (linkedNode != null) {
1596 // Add the link to external entity.
1597 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama07c26bb2016-07-28 17:33:15 +05301598
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301599 // Add the type/uses of referred typedef/grouping to the stack.
1600 addUnresolvedRecursiveReferenceToStack(linkedNode);
1601 return true;
1602 }
1603 }
1604 // If referred node can't be found return false.
1605 return false;
1606 }
1607
1608 /**
1609 * Finds and resolves with import list.
1610 *
1611 * @return true if resolved, false otherwise
1612 * @throws DataModelException a violation in data model rule
1613 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301614 private boolean resolveWithImport()
1615 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301616 /*
1617 * Run through import list to find the referred typedef/grouping.
1618 */
1619 for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
1620 /*
1621 * Match the prefix attached to entity under resolution with the
1622 * imported/included module/sub-module's prefix. If found, search
1623 * for the referred typedef/grouping at the root level.
1624 */
1625 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
1626 YangNode linkedNode = null;
1627 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1628 linkedNode = findRefTypedef(yangImport.getImportedNode());
1629 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1630 linkedNode = findRefGrouping(yangImport.getImportedNode());
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301631 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1632 linkedNode = findRefFeature(yangImport.getImportedNode());
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301633 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1634 linkedNode = findRefIdentity(yangImport.getImportedNode());
1635 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1636 linkedNode = findRefIdentityRef(yangImport.getImportedNode());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301637 }
1638 if (linkedNode != null) {
1639 // Add the link to external entity.
1640 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama07c26bb2016-07-28 17:33:15 +05301641
Bharat saraswal96dfef02016-06-16 00:29:12 +05301642 // Add the type/uses of referred typedef/grouping to the
1643 // stack.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301644 addUnresolvedRecursiveReferenceToStack(linkedNode);
1645 return true;
1646 }
1647 /*
1648 * If referred node can't be found at root level break for loop,
1649 * and return false.
1650 */
1651 break;
1652 }
1653 }
1654 // If referred node can't be found return false.
1655 return false;
1656 }
1657
1658 /**
1659 * Returns referred typedef/grouping node.
1660 *
1661 * @return referred typedef/grouping node
1662 * @throws DataModelException a violation in data model rule
1663 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301664 private T getRefNode()
1665 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301666 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswal96dfef02016-06-16 00:29:12 +05301667 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1668 .getDataTypeExtendedInfo();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301669 return (T) derivedInfo.getReferredTypeDef();
1670 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1671 return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301672 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1673 return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
janani be18b5342016-07-13 21:06:41 +05301674 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1675 return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301676 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1677 return (T) ((YangBase) getCurrentEntityToResolveFromStack()).getReferredIdentity();
1678 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1679 return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301680 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301681 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani b23ccc312016-07-14 19:35:22 +05301682 "/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301683 }
1684 }
1685
1686 /**
1687 * Finds the referred grouping node at the root level of imported/included node.
1688 *
1689 * @param refNode module/sub-module node
1690 * @return referred grouping
1691 */
1692 private YangNode findRefGrouping(YangNode refNode) {
1693 YangNode tmpNode = refNode.getChild();
1694 while (tmpNode != null) {
1695 if (tmpNode instanceof YangGrouping) {
1696 if (tmpNode.getName()
1697 .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1698 return tmpNode;
1699 }
1700 }
1701 tmpNode = tmpNode.getNextSibling();
1702 }
1703 return null;
1704 }
1705
1706 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301707 * Finds the referred feature node at the root level of imported/included node.
1708 *
1709 * @param refNode module/sub-module node
1710 * @return referred feature
1711 */
1712 private YangNode findRefFeature(YangNode refNode) {
1713 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1714 List<YangFeature> featureList = ((YangFeatureHolder) refNode).getFeatureList();
1715
1716 if (featureList != null && !featureList.isEmpty()) {
1717 Iterator<YangFeature> iterator = featureList.iterator();
1718 while (iterator.hasNext()) {
1719 YangFeature feature = iterator.next();
1720 if (ifFeature.getName().equals(feature.getName())) {
1721 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1722 return refNode;
1723 }
1724 }
1725 }
1726 return null;
1727 }
1728
1729 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301730 * Finds the referred typedef node at the root level of imported/included node.
1731 *
1732 * @param refNode module/sub-module node
1733 * @return referred typedef
1734 */
1735 private YangNode findRefTypedef(YangNode refNode) {
1736 YangNode tmpNode = refNode.getChild();
1737 while (tmpNode != null) {
1738 if (tmpNode instanceof YangTypeDef) {
1739 if (tmpNode.getName()
1740 .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
1741 return tmpNode;
1742 }
1743 }
1744 tmpNode = tmpNode.getNextSibling();
1745 }
1746 return null;
1747 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301748
1749 /**
1750 * Finds the referred identity node at the root level of imported/included node.
1751 *
1752 * @param refNode module/sub-module node
1753 * @return referred identity
1754 */
1755 private YangNode findRefIdentity(YangNode refNode) {
1756 YangNode tmpNode = refNode.getChild();
1757 while (tmpNode != null) {
1758 if (tmpNode instanceof YangIdentity) {
1759 if (tmpNode.getName()
1760 .equals(((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1761 return tmpNode;
1762 }
1763 }
1764 tmpNode = tmpNode.getNextSibling();
1765 }
1766 return null;
1767 }
1768
1769 /**
1770 * Finds the referred identity node at the root level of imported/included node.
1771 *
1772 * @param refNode module/sub-module node
1773 * @return referred identity
1774 */
1775 private YangNode findRefIdentityRef(YangNode refNode) {
1776 YangNode tmpNode = refNode.getChild();
1777 while (tmpNode != null) {
1778 if (tmpNode instanceof YangIdentity) {
1779 if (tmpNode.getName()
1780 .equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
janani b23ccc312016-07-14 19:35:22 +05301781 .getBaseIdentity().getName())) {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301782 return tmpNode;
1783 }
1784 }
1785 tmpNode = tmpNode.getNextSibling();
1786 }
1787 return null;
1788 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301789}