[ONOS-4842] Leafref implementation for augment and uses
Change-Id: I919553a64d683aff65a8f16e2de783702dd5a45f
diff --git a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangEntityToResolveInfoImpl.java b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangEntityToResolveInfoImpl.java
deleted file mode 100644
index d33dfd7..0000000
--- a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangEntityToResolveInfoImpl.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.yangutils.linker.impl;
-
-import java.io.Serializable;
-
-import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
-import org.onosproject.yangutils.datamodel.YangIfFeature;
-import org.onosproject.yangutils.datamodel.YangBase;
-import org.onosproject.yangutils.datamodel.YangIdentityRef;
-import org.onosproject.yangutils.datamodel.YangNode;
-import org.onosproject.yangutils.datamodel.YangType;
-import org.onosproject.yangutils.datamodel.YangUses;
-import org.onosproject.yangutils.linker.exceptions.LinkerException;
-
-/**
- * Represents implementation of information about entity being resolved.
- *
- * @param <T> type of entity being resolved, uses / grouping
- */
-public class YangEntityToResolveInfoImpl<T> implements YangEntityToResolveInfo<T>, Serializable {
-
- private static final long serialVersionUID = 806201659L;
-
- // Parsable node for which resolution is to be performed.
- private T entityToResolve;
-
- // Holder of the YANG construct for which resolution has to be carried out.
- private YangNode holderOfEntityToResolve;
-
- @Override
- public T getEntityToResolve() {
- return entityToResolve;
- }
-
- @Override
- public void setEntityToResolve(T entityToResolve) {
- this.entityToResolve = entityToResolve;
- }
-
- @Override
- public YangNode getHolderOfEntityToResolve() {
- return holderOfEntityToResolve;
- }
-
- @Override
- public void setHolderOfEntityToResolve(YangNode holderOfEntityToResolve) {
- this.holderOfEntityToResolve = holderOfEntityToResolve;
- }
-
- /**
- * Retrieves the prefix of the entity.
- *
- * @return entities prefix
- * @throws LinkerException linker error
- */
- public String getEntityPrefix()
- throws LinkerException {
- if (getEntityToResolve() == null) {
- return null;
- }
-
- String prefix;
- T entityToBeResolved = getEntityToResolve();
- if (entityToBeResolved instanceof YangType) {
- prefix = ((YangType<?>) entityToBeResolved).getPrefix();
- } else if (entityToBeResolved instanceof YangUses) {
- prefix = ((YangUses) entityToBeResolved).getPrefix();
- } else if (entityToBeResolved instanceof YangIfFeature) {
- prefix = ((YangIfFeature) entityToBeResolved).getPrefix();
- } else if (entityToBeResolved instanceof YangBase) {
- prefix = ((YangBase) entityToBeResolved).getBaseIdentifier().getPrefix();
- } else if (entityToBeResolved instanceof YangIdentityRef) {
- prefix = ((YangIdentityRef) entityToBeResolved).getBaseIdentity().getPrefix();
- } else {
- throw new LinkerException("Linker Exception: Entity to resolved is other than type/uses");
- }
- return prefix;
- }
-}
diff --git a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
index 8cfe779..7b8c6ce 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
@@ -177,11 +177,11 @@
((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_DERIVED_DATA_TYPE);
((YangReferenceResolver) yangNode)
- .resolveInterFileLinking(ResolvableType.YANG_LEAFREF);
- ((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_BASE);
((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_IDENTITYREF);
+ ((YangReferenceResolver) yangNode)
+ .resolveInterFileLinking(ResolvableType.YANG_LEAFREF);
} catch (DataModelException e) {
String errorInfo = "Error in file: " + yangNode.getName() + " at line: "
+ e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE + e.getMessage();
diff --git a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java
index 76098fb..614c260 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java
@@ -16,18 +16,28 @@
package org.onosproject.yangutils.linker.impl;
-import java.util.List;
-
import org.onosproject.yangutils.datamodel.YangAugment;
import org.onosproject.yangutils.datamodel.YangAugmentableNode;
import org.onosproject.yangutils.datamodel.YangAugmentedInfo;
+import org.onosproject.yangutils.datamodel.YangCase;
import org.onosproject.yangutils.datamodel.YangChoice;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangLeavesHolder;
import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
+import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import static org.onosproject.yangutils.utils.UtilConstants.COLON;
+import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
+import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
+
/**
* Represent utilities for YANG linker.
*/
@@ -36,6 +46,10 @@
private YangLinkerUtils() {
}
+ private static final int IDENTIFIER_LENGTH = 64;
+ private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
+ private static final String XML = "xml";
+
/**
* Detects collision between target nodes leaf/leaf-list or child node with augmented leaf/leaf-list or child node.
*
@@ -119,4 +133,99 @@
detectCollision((YangAugment) info, augment);
}
}
+
+ /**
+ * Returns list of path names that are needed from augment.
+ *
+ * @param augment instance of YANG augment
+ * @param remainingAncestors ancestor count to move in augment path
+ * @return list of path names needed in leafref
+ */
+ public static List<String> getPathWithAugment(YangAugment augment, int remainingAncestors) {
+ String augmentName = augment.getName();
+ List<String> listOfPathName = new ArrayList<>();
+ if (augmentName.contains(SLASH_FOR_STRING)) {
+ String[] augmentNodeNames = augmentName.split(SLASH_FOR_STRING);
+ for (String valueInAugment : augmentNodeNames) {
+ if (valueInAugment != null && valueInAugment != EMPTY_STRING && !valueInAugment.isEmpty()) {
+ listOfPathName.add(valueInAugment);
+ }
+ }
+ }
+ for (int countOfAncestor = 0; countOfAncestor < remainingAncestors; countOfAncestor++) {
+ listOfPathName.remove(listOfPathName.size() - 1);
+ }
+ return listOfPathName;
+ }
+
+ /**
+ * Skips the invalid nodes which cannot have data from YANG.
+ *
+ * @param currentParent current parent node reference
+ * @param leafref instance of YANG leafref
+ * @return parent node which can hold data
+ * @throws LinkerException a violation of linker rules
+ */
+ public static YangNode skipInvalidDataNodes(YangNode currentParent, YangLeafRef leafref) throws LinkerException {
+ while (currentParent instanceof YangChoice || currentParent instanceof YangCase) {
+ if (currentParent.getParent() == null) {
+ throw new LinkerException("YANG file error: The target node, in the leafref path " +
+ leafref.getPath() + ", is invalid.");
+ }
+ currentParent = currentParent.getParent();
+ }
+ return currentParent;
+ }
+
+ /**
+ * Checks and return valid node identifier.
+ *
+ * @param nodeIdentifierString string from yang file
+ * @param yangConstruct yang construct for creating error message
+ * @return valid node identifier
+ */
+ public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString,
+ YangConstructType yangConstruct) {
+ String[] tmpData = nodeIdentifierString.split(Pattern.quote(COLON));
+ if (tmpData.length == 1) {
+ YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
+ nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct));
+ return nodeIdentifier;
+ } else if (tmpData.length == 2) {
+ YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
+ nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct));
+ nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct));
+ return nodeIdentifier;
+ } else {
+ throw new LinkerException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
+ " is not valid.");
+ }
+ }
+
+ /**
+ * Validates identifier and returns concatenated string if string contains plus symbol.
+ *
+ * @param identifier string from yang file
+ * @param yangConstruct yang construct for creating error message=
+ * @return concatenated string after removing double quotes
+ */
+ public static String getValidIdentifier(String identifier, YangConstructType yangConstruct) {
+
+ if (identifier.length() > IDENTIFIER_LENGTH) {
+ throw new LinkerException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " name " + identifier + " is " +
+ "greater than 64 characters.");
+ } else if (!IDENTIFIER_PATTERN.matcher(identifier).matches()) {
+ throw new LinkerException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " name " + identifier + " is not " +
+ "valid.");
+ } else if (identifier.toLowerCase().startsWith(XML)) {
+ throw new LinkerException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " identifier " + identifier +
+ " must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
+ } else {
+ return identifier;
+ }
+ }
}
diff --git a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
index a502dd8..923bdfe 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
@@ -16,11 +16,6 @@
package org.onosproject.yangutils.linker.impl;
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Stack;
-
import org.onosproject.yangutils.datamodel.Resolvable;
import org.onosproject.yangutils.datamodel.ResolvableType;
import org.onosproject.yangutils.datamodel.YangAtomicPath;
@@ -29,6 +24,7 @@
import org.onosproject.yangutils.datamodel.YangBase;
import org.onosproject.yangutils.datamodel.YangDerivedInfo;
import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
+import org.onosproject.yangutils.datamodel.YangEntityToResolveInfoImpl;
import org.onosproject.yangutils.datamodel.YangFeature;
import org.onosproject.yangutils.datamodel.YangFeatureHolder;
import org.onosproject.yangutils.datamodel.YangGrouping;
@@ -41,14 +37,11 @@
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangLeafRef;
-import org.onosproject.yangutils.datamodel.YangLeavesHolder;
-import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
import org.onosproject.yangutils.datamodel.YangOutput;
import org.onosproject.yangutils.datamodel.YangPathArgType;
-import org.onosproject.yangutils.datamodel.YangPathPredicate;
import org.onosproject.yangutils.datamodel.YangReferenceResolver;
import org.onosproject.yangutils.datamodel.YangRelativePath;
import org.onosproject.yangutils.datamodel.YangResolutionInfo;
@@ -60,10 +53,18 @@
import org.onosproject.yangutils.datamodel.YangXPathResolver;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
+import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.linker.YangLinkingPhase;
import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.LINKED;
@@ -73,7 +74,11 @@
import static org.onosproject.yangutils.linker.YangLinkingPhase.INTER_FILE;
import static org.onosproject.yangutils.linker.YangLinkingPhase.INTRA_FILE;
import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
+import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getPathWithAugment;
+import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getValidNodeIdentifier;
+import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.skipInvalidDataNodes;
import static org.onosproject.yangutils.utils.UtilConstants.BASE_LINKER_ERROR;
+import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
@@ -82,6 +87,7 @@
import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
+import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_LINKER_ERROR;
/**
@@ -328,13 +334,14 @@
yangType.setDataTypeName(LEAFREF);
yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
+ leafRefInTypeDef.setParentNodeOfLeafref(potentialAncestorWithReferredNode);
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
- potentialAncestorWithReferredNode,
- getLineNumber(), getCharPosition());
+ potentialAncestorWithReferredNode,
+ getLineNumber(), getCharPosition());
getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
- ResolvableType.YANG_LEAFREF);
+ ResolvableType.YANG_LEAFREF);
getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
} else if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.IDENTITYREF) {
@@ -350,9 +357,9 @@
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(identityRefInTypeDef,
- potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
+ potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
- ResolvableType.YANG_IDENTITYREF);
+ ResolvableType.YANG_IDENTITYREF);
getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_IDENTITYREF);
}
}
@@ -362,7 +369,13 @@
*/
private void resolveTopOfStack(YangLinkingPhase linkingPhase)
throws DataModelException {
- ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
+ List<T> entityToResolve = (List<T>) ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
+ if (entityToResolve != null && !entityToResolve.isEmpty()) {
+ Iterator<T> entityToResolveIterator = entityToResolve.listIterator();
+ while (entityToResolveIterator.hasNext()) {
+ addUnresolvedEntitiesToStack(entityToResolveIterator.next());
+ }
+ }
if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
&& ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
// Sets the resolution status in inside the type/uses/if-feature/leafref.
@@ -371,6 +384,31 @@
}
/**
+ * Adds the unresolved entities to the resolution list.
+ *
+ * @param entityToResolve entity to resolve
+ * @throws DataModelException a violation of data model rules
+ */
+ private void addUnresolvedEntitiesToStack(T entityToResolve) throws DataModelException {
+ if (entityToResolve instanceof YangEntityToResolveInfoImpl) {
+ YangEntityToResolveInfoImpl entityToResolveInfo = (YangEntityToResolveInfoImpl) entityToResolve;
+ if (entityToResolveInfo.getEntityToResolve() instanceof YangLeafRef) {
+ YangLeafRef leafref = (YangLeafRef) entityToResolveInfo.getEntityToResolve();
+ YangNode parentNodeOfLeafref = entityToResolveInfo.getHolderOfEntityToResolve();
+ leafref.setParentNodeOfLeafref(parentNodeOfLeafref);
+ if (leafref.getResolvableStatus() == UNRESOLVED) {
+ leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
+ }
+ // Add resolution information to the list.
+ YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafref,
+ parentNodeOfLeafref, entityToResolveInfo.getLineNumber(),
+ entityToResolveInfo.getCharPosition());
+ addResolutionInfo(resolutionInfoImpl);
+ }
+ }
+ }
+
+ /**
* Resolves linking for a node child and siblings.
*
* @throws DataModelException data model error
@@ -378,6 +416,10 @@
private void linkTopOfStackReferenceUpdateStack()
throws DataModelException {
+ if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
+ ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
+ return;
+ }
/*
* Check if self file reference is there, this will not check for the
* scenario when prefix is not present and type/uses is present in
@@ -398,9 +440,6 @@
if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
return;
- } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
- resolveSelfFileLinkingForLeafref(potentialAncestorWithReferredNode);
- return;
} else if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
(getCurrentEntityToResolveFromStack() instanceof YangBase)) {
resolveSelfFileLinkingForBaseAndIdentityref();
@@ -435,69 +474,6 @@
}
/**
- * Resolves self file linking for leafref.
- *
- * @param potentialAncestorWithReferredNode leafref holder node
- * @throws DataModelException a violation of data model rules
- */
- private void resolveSelfFileLinkingForLeafref(YangNode potentialAncestorWithReferredNode)
- throws DataModelException {
-
- YangNode ancestorWithTheReferredNode = potentialAncestorWithReferredNode;
- YangLeafRef leafref = (YangLeafRef) getCurrentEntityToResolveFromStack();
- boolean referredLeafFound = false;
-
- /*
- * Takes absolute path and takes the root node as module/sub-module,
- * then sends the list of nodes for finding the target leaf.
- */
- if (leafref.getPathType() == YangPathArgType.ABSOLUTE_PATH) {
- List<YangAtomicPath> atomicPathList = leafref.getAtomicPath();
- if (atomicPathList != null && !atomicPathList.isEmpty()) {
- Iterator<YangAtomicPath> listOfYangAtomicPath = atomicPathList.listIterator();
- if (getCurReferenceResolver() instanceof YangModule) {
- YangModule rootNode = (YangModule) getCurReferenceResolver();
- // Sends list of nodes for finding the target leaf.
- referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
- referredLeafFound, potentialAncestorWithReferredNode);
- } else if (getCurReferenceResolver() instanceof YangSubModule) {
- YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
- // Sends list of nodes for finding the target leaf.
- referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
- referredLeafFound, potentialAncestorWithReferredNode);
- }
- }
- /*
- * Takes relative path, goes to the parent node by using the
- * ancestor count and sends the list of nodes for finding the target
- * leaf.
- */
- } else if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
- YangRelativePath yangRelativePath = leafref.getRelativePath();
- int parentNodes = yangRelativePath.getAncestorNodeCount();
- List<YangAtomicPath> atomicPathList = yangRelativePath.getAtomicPathList();
- if (atomicPathList != null && !atomicPathList.isEmpty()) {
- Iterator<YangAtomicPath> listOfAtomicPath = atomicPathList.listIterator();
- // Gets the root node from ancestor count.
- YangNode rootparentNode = getRootNodeWithAncestorCount(parentNodes, ancestorWithTheReferredNode);
- // Sends list of nodes for finding the target leaf.
- referredLeafFound = isLeafReferenceFound(listOfAtomicPath, rootparentNode,
- referredLeafFound, potentialAncestorWithReferredNode);
- }
- }
- if (referredLeafFound) {
- return;
- }
- /*
- * In case prefix is not present it's a candidate for inter-file
- * resolution via include list.
- */
- if (getRefPrefix() == null) {
- ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
- }
- }
-
- /**
* Resolves self file linking for base/identityref.
*
* @throws DataModelException a violation of data model rules
@@ -509,7 +485,7 @@
String nodeName = null;
if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
- nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
+ nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
}
if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
@@ -595,61 +571,9 @@
}
/**
- * Returns the status of the referred leaf/leaf-list found for leafref.
- *
- * @param listOfYangAtomicPath list of atomic paths
- * @param ancestorWithTheReferredNode the parent node of leafref
- * @param referredLeafFound status of referred leaf/leaf-list
- * @param potentialAncestorWithReferredNode holder of the leafref leaf
- * @return status of referred leaf
- * @throws DataModelException a violation of data model rules
- */
- private boolean isLeafReferenceFound(Iterator<YangAtomicPath> listOfYangAtomicPath,
- YangNode ancestorWithTheReferredNode, boolean referredLeafFound, YangNode potentialAncestorWithReferredNode)
- throws DataModelException {
-
- while (listOfYangAtomicPath.hasNext()) {
- YangAtomicPath atomicPath = listOfYangAtomicPath.next();
- String nodeName = atomicPath.getNodeIdentifier().getName();
-
- // When child is not present, only leaf/leaf-list is available in the node.
- if (ancestorWithTheReferredNode.getChild() == null) {
- referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode, nodeName, (T) LINKED);
- break;
- }
- ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
-
- // Checks all the siblings under the node and returns the matched node.
- YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(ancestorWithTheReferredNode, nodeName);
-
- // When node is not found in all the siblings, leaf-list may be the node we have to find.
- if (nodeFound == null) {
- referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode.getParent(), nodeName,
- (T) LINKED);
- } else {
- ancestorWithTheReferredNode = nodeFound;
-
- // For the node check if path predicate is present and fill its values.
- List<YangPathPredicate> pathPredicateList = atomicPath.getPathPredicatesList();
- if (pathPredicateList != null && !pathPredicateList.isEmpty()) {
- Iterator<YangPathPredicate> listOfYangPathPredicate = pathPredicateList.listIterator();
- fillPathPredicatesForTheNode(ancestorWithTheReferredNode, listOfYangPathPredicate,
- potentialAncestorWithReferredNode);
- }
- }
-
- // If leaf is also not found and node is also not found return the status as false.
- if (!referredLeafFound && nodeFound == null) {
- break;
- }
- }
- return referredLeafFound;
- }
-
- /**
* Returns the status of the referred identity found for base/identityref.
*
- * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
+ * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
* @param ancestorWithTheReferredNode the parent node of base/identityref
* @return status of referred base/identityref
* @throws DataModelException a violation of data model rules
@@ -682,166 +606,9 @@
}
/**
- * Fills the referred leaf or leaf-list inside the path predicates.
- *
- * @param ancestorWithTheReferredNode the actual node where YANG list will be present
- * @param listOfYangPathPredicate the path predicates present for the node
- * @param potentialAncestorWithReferredNode the current leaf node parent
- * @throws DataModelException a violation of data model rules
- */
- private void fillPathPredicatesForTheNode(YangNode ancestorWithTheReferredNode,
- Iterator<YangPathPredicate> listOfYangPathPredicate, YangNode potentialAncestorWithReferredNode)
- throws DataModelException {
-
- while (listOfYangPathPredicate.hasNext()) {
- if (!(ancestorWithTheReferredNode instanceof YangList)) {
- throw new DataModelException("YANG file error: The path predicates are applicable only for list");
- }
- YangPathPredicate pathPredicate = listOfYangPathPredicate.next();
- YangNodeIdentifier leftNode = pathPredicate.getNodeIdentifier();
- YangRelativePath relativePath = pathPredicate.getRightRelativePath();
-
- // Checks that the left axis is filled in the path predicate.
- boolean isLeftLeafOrLeafListSetForLeftAxis = getLeftLeafOrLeafListInPredicate(
- (YangList) ancestorWithTheReferredNode, pathPredicate, leftNode);
- if (!isLeftLeafOrLeafListSetForLeftAxis) {
- throw new DataModelException(
- "YANG file error: The path predicate is not referring to an existing leaf/leaflist");
- }
- int parentNodes = relativePath.getAncestorNodeCount();
-
- // Finds the root node for the right relative path.
- YangNode rootParentNode = getRootNodeWithAncestorCount(parentNodes, potentialAncestorWithReferredNode);
-
- // Finds the leaf/leaf-list from the right side relative path.
- resolveRightAxisNodeInPathPredicate(relativePath, rootParentNode, pathPredicate);
- }
- }
-
- /**
- * Resolves the right axis node in the path predicate.
- *
- * @param relativePath the relative path in the path predicate
- * @param rootParentNode parent node from where the node has to be found
- * @param pathPredicate data tree reference in YANG list
- * @throws DataModelException a violation of data model rules
- */
- private void resolveRightAxisNodeInPathPredicate(YangRelativePath relativePath, YangNode rootParentNode,
- YangPathPredicate pathPredicate) throws DataModelException {
-
- List<YangAtomicPath> absolutePathList = relativePath.getAtomicPathList();
- if (absolutePathList != null && !absolutePathList.isEmpty()) {
- Iterator<YangAtomicPath> listOfYangAtomicPathForRightRelative = absolutePathList.listIterator();
- while (listOfYangAtomicPathForRightRelative.hasNext()) {
- boolean isRightAxisNodeFound = false;
- YangAtomicPath absolutePathInPredicate = listOfYangAtomicPathForRightRelative.next();
- String nodeNameInAtomicPath = absolutePathInPredicate.getNodeIdentifier().getName();
-
- // When child is not there check the leaf/leaf-list.
- if (rootParentNode.getChild() == null) {
- isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode,
- nodeNameInAtomicPath, (T) pathPredicate);
- if (!isRightAxisNodeFound) {
- throw new DataModelException(
- "YANG file error: The path predicates is not referring to an existing leaf/leaflist");
- }
- break;
- }
- rootParentNode = rootParentNode.getChild();
- YangNode nodeFoundInTheRelativePath = isReferredNodeInSiblingProcessedForLeafref(
- rootParentNode, nodeNameInAtomicPath);
-
- if (nodeFoundInTheRelativePath == null) {
-
- // When node is not found check the leaf/leaf-list.
- isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode.getParent(),
- nodeNameInAtomicPath, (T) pathPredicate);
- } else {
- rootParentNode = nodeFoundInTheRelativePath;
- }
- if (!isRightAxisNodeFound && nodeFoundInTheRelativePath == null) {
- throw new DataModelException(
- "YANG file error: The path predicates is not referring to an existing leaf/leaflist");
- }
- }
- }
- }
-
- /**
- * Returns the status, if referred leaf/leaf-list is found.
- *
- * @param ancestorWithTheReferredNode the parent node of leaf/leaf-list
- * @param nodeName the name of the leaf/leaf-list
- * @param statusOrPathPredicate the status to be set for the leaf-ref or the path predicate
- * @return status of the target node is found
- * @throws DataModelException a violation of data model rules
- */
- private boolean isReferredLeafOrLeafListFound(YangNode ancestorWithTheReferredNode, String nodeName,
- T statusOrPathPredicate) throws DataModelException {
-
- if (!(ancestorWithTheReferredNode instanceof YangLeavesHolder)) {
- throw new DataModelException("Yang file error: The target node of leafref is invalid.");
- }
- YangLeavesHolder leavesHolder = (YangLeavesHolder) ancestorWithTheReferredNode;
- if (leavesHolder.getListOfLeaf() != null) {
- Iterator<YangLeaf> yangLeavesList = leavesHolder.getListOfLeaf().listIterator();
- while (yangLeavesList.hasNext()) {
- YangLeaf yangleaf = yangLeavesList.next();
- if (yangleaf.getName().contentEquals(nodeName)) {
- if (statusOrPathPredicate instanceof ResolvableStatus) {
- ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
-
- // Sets the referred leaf to YANG leafref.
- ((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangleaf);
-
- // Adds reference link of entity to the node under resolution.
- addReferredEntityLink(ancestorWithTheReferredNode, status);
- addUnResolvedLeafRefTypeToStack((T) yangleaf, ancestorWithTheReferredNode);
- return true;
- } else if (statusOrPathPredicate instanceof YangPathPredicate) {
- YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
-
- // Sets the right axis node.
- pathPredicate.setRightAxisNode(yangleaf);
- return true;
- } else {
- throw new DataModelException("YANG file error: The target node of leafref is invalid.");
- }
- }
- }
- }
- if (leavesHolder.getListOfLeafList() != null) {
- Iterator<YangLeafList> yangLeafListList = leavesHolder.getListOfLeafList().listIterator();
- while (yangLeafListList.hasNext()) {
- YangLeafList yangLeaflist = yangLeafListList.next();
- if (yangLeaflist.getName().contentEquals(nodeName)) {
- if (statusOrPathPredicate instanceof ResolvableStatus) {
- ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
-
- // Sets the referred leaf-list to YANG leafref.
- ((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangLeaflist);
-
- // Adds reference link of entity to the node under resolution.
- addReferredEntityLink(ancestorWithTheReferredNode, status);
- addUnResolvedLeafRefTypeToStack((T) yangLeaflist, ancestorWithTheReferredNode);
- return true;
- } else if (statusOrPathPredicate instanceof YangPathPredicate) {
- YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
- pathPredicate.setRightAxisNode(yangLeaflist);
- return true;
- } else {
- throw new DataModelException("YANG file error: The target node of leafref is invalid.");
- }
- }
- }
- }
- return false;
- }
-
- /**
* Adds the unresolved constructs to stack which has to be resolved for leafref.
*
- * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
+ * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
* @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
*/
private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
@@ -880,40 +647,6 @@
}
/**
- * Returns true if referred leaf/leaf-list is found in a particular node. This is for path in path predicate.
- *
- * @param listForLeaf list node where referred leaf is found
- * @param pathPredicate path predicate instance where the value of nodes to be found are available
- * @param leftNode node identifier of the left side parameter in path predicate
- * @return status of the leaf/leaf-list found
- */
- private boolean getLeftLeafOrLeafListInPredicate(YangList listForLeaf, YangPathPredicate pathPredicate,
- YangNodeIdentifier leftNode) {
-
- if (listForLeaf.getListOfLeaf() != null) {
- Iterator<YangLeaf> yangLeavesUnderList = listForLeaf.getListOfLeaf().listIterator();
- while (yangLeavesUnderList.hasNext()) {
- YangLeaf yangleafUnderList = yangLeavesUnderList.next();
- if (yangleafUnderList.getName().contentEquals(leftNode.getName())) {
- pathPredicate.setLeftAxisNode(yangleafUnderList);
- return true;
- }
- }
- }
- if (listForLeaf.getListOfLeafList() != null) {
- Iterator<YangLeafList> yangLeavesListUnderList = listForLeaf.getListOfLeafList().listIterator();
- while (yangLeavesListUnderList.hasNext()) {
- YangLeafList yangleafListUnderList = yangLeavesListUnderList.next();
- if (yangleafListUnderList.getName().contentEquals(leftNode.getName())) {
- pathPredicate.setLeftAxisNode(yangleafListUnderList);
- return true;
- }
- }
- }
- return false;
- }
-
- /**
* Returns feature holder(module/sub-module node) .
*
* @param potentialAncestorWithReferredNode if-feature holder node
@@ -984,7 +717,7 @@
* @throws DataModelException data model errors
*/
private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode potentialReferredNode,
- String referredNodeName) throws DataModelException {
+ String referredNodeName) throws DataModelException {
while (potentialReferredNode != null) {
if (potentialReferredNode instanceof YangIdentity) {
@@ -1002,7 +735,7 @@
* Checks if the current reference node name and the name in the path are equal.
*
* @param currentReferredNode the node where the reference is pointed
- * @param nameOfNodeinPath name of the node in the path
+ * @param nameOfNodeinPath name of the node in the path
* @return status of the match between the name
* @throws DataModelException a violation of data model rules
*/
@@ -1023,7 +756,7 @@
/**
* Checks if the current reference node name and the name in the base/identityref base are equal.
*
- * @param currentReferredNode the node where the reference is pointed
+ * @param currentReferredNode the node where the reference is pointed
* @param nameOfIdentityRefBase name of the base in the base/identityref base
* @return status of the match between the name
* @throws DataModelException a violation of data model rules
@@ -1122,7 +855,7 @@
}
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
- "uses/base/identityref");
+ "uses/base/identityref");
}
return false;
}
@@ -1211,7 +944,7 @@
((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
- "/uses/base/identityref");
+ "/uses/base/identityref");
}
// Sets the resolution status in inside the type/uses.
@@ -1260,7 +993,7 @@
addUnResolvedBaseToStack(referredNode);
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
- "base/identityref");
+ "base/identityref");
}
}
@@ -1439,9 +1172,9 @@
throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
}
- if (entityToResolve instanceof YangXPathResolver) {
+ if (entityToResolve instanceof YangXPathResolver && !(entityToResolve instanceof YangLeafRef)) {
//Process x-path linking.
- processXPathLinking(getEntityToResolveInfo(), dataModelRootNode);
+ processXPathLinking(entityToResolve, dataModelRootNode);
} else {
@@ -1458,13 +1191,14 @@
/**
* Process x-path linking for augment and leaf-ref.
*
- * @param entityToResolveInfo entity to resolve
- * @param root root node
+ * @param entityToResolve entity to resolve
+ * @param root root node
*/
- private void processXPathLinking(YangEntityToResolveInfoImpl<T> entityToResolveInfo,
+ private void processXPathLinking(T entityToResolve,
YangReferenceResolver root) {
+
YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
- T entityToResolve = entityToResolveInfo.getEntityToResolve();
+
if (entityToResolve instanceof YangAugment) {
YangNode targetNode = null;
YangAugment augment = (YangAugment) entityToResolve;
@@ -1488,23 +1222,29 @@
} else if (entityToResolve instanceof YangLeafRef) {
YangLeafRef leafRef = (YangLeafRef) entityToResolve;
Object target = xPathLinker.processLeafRefXpathLinking(leafRef.getAtomicPath(),
- (YangNode) root);
+ (YangNode) root, leafRef);
if (target != null) {
YangLeaf leaf = null;
YangLeafList leafList = null;
leafRef.setReferredLeafOrLeafList(target);
if (target instanceof YangLeaf) {
leaf = (YangLeaf) target;
- leafRef.setEffectiveDataType(leaf.getDataType());
+ leafRef.setResolvableStatus(INTER_FILE_LINKED);
+ addUnResolvedLeafRefTypeToStack((T) leaf, getEntityToResolveInfo().getHolderOfEntityToResolve());
} else {
leafList = (YangLeafList) target;
- leafRef.setEffectiveDataType(leafList.getDataType());
+ leafRef.setResolvableStatus(INTER_FILE_LINKED);
+ addUnResolvedLeafRefTypeToStack((T) leafList,
+ getEntityToResolveInfo().getHolderOfEntityToResolve());
}
- leafRef.setResolvableStatus(RESOLVED);
//TODO: add logic for leaf-ref for path predicates.
} else {
- throw new LinkerException("YANG file error: Unable to find base leaf/leaf-list for given leafref "
+ LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
+ "leaf/leaf-list for given leafref path "
+ leafRef.getPath());
+ linkerException.setCharPosition(leafRef.getCharPosition());
+ linkerException.setLine(leafRef.getLineNumber());
+ throw linkerException;
}
}
}
@@ -1524,36 +1264,13 @@
refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
- } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
- refPrefix = refPrefixForLeafRef();
} else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
} else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
- "type/uses/base/identityref");
- }
- return refPrefix;
- }
-
- /**
- * Returns the referenced prefix for leafref under resolution.
- *
- * @return referenced prefix of leafref under resolution
- */
- private String refPrefixForLeafRef() {
-
- String refPrefix;
- if (((YangLeafRef) getCurrentEntityToResolveFromStack()).getPathType() == YangPathArgType.ABSOLUTE_PATH) {
- List<YangAtomicPath> theList = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getAtomicPath();
- YangAtomicPath absPath = theList.iterator().next();
- refPrefix = absPath.getNodeIdentifier().getPrefix();
- } else {
- YangRelativePath relativePath = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getRelativePath();
- List<YangAtomicPath> theList = relativePath.getAtomicPathList();
- YangAtomicPath absPath = theList.iterator().next();
- refPrefix = absPath.getNodeIdentifier().getPrefix();
+ "type/uses/base/identityref");
}
return refPrefix;
}
@@ -1638,6 +1355,12 @@
private void linkInterFileTopOfStackRefUpdateStack()
throws DataModelException {
+ if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
+ // When leafref path comes with relative path, it will be converted to absolute path.
+ setAbsolutePathFromRelativePathInLeafref(getCurrentEntityToResolveFromStack());
+ processXPathLinking(getCurrentEntityToResolveFromStack(), getCurReferenceResolver());
+ return;
+ }
/*
* Obtain the referred node of top of stack entity under resolution
*/
@@ -1688,27 +1411,141 @@
dataModelException.setCharPosition(getCharPosition());
throw dataModelException;
} else {
- /*
- * If referred node is already linked, then just change the status
- * and push to the stack.
- */
- if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
- ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
- if (referredNode instanceof YangLeaf) {
- YangLeaf yangleaf = (YangLeaf) referredNode;
- addUnResolvedLeafRefTypeToStack((T) yangleaf, (YangNode) yangleaf.getContainedIn());
- } else if (referredNode instanceof YangLeafList) {
- YangLeafList yangLeafList = (YangLeafList) referredNode;
- addUnResolvedLeafRefTypeToStack((T) yangLeafList, (YangNode) yangLeafList.getContainedIn());
+ ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
+ addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
+ }
+ }
+
+ /**
+ * Sets the leafref with absolute path from the relative path.
+ *
+ * @param resolutionInfo information about the YANG construct which has to be resolved
+ * @throws DataModelException a violation of data model rules
+ */
+ public void setAbsolutePathFromRelativePathInLeafref(T resolutionInfo) throws DataModelException {
+ if (resolutionInfo instanceof YangLeafRef) {
+
+ YangNode parentOfLeafref = ((YangLeafRef) resolutionInfo).getParentNodeOfLeafref();
+ YangLeafRef leafref = (YangLeafRef) resolutionInfo;
+
+ // Checks if the leafref has relative path in it.
+ if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
+ YangRelativePath relativePath = leafref.getRelativePath();
+ List<YangAtomicPath> absoluteInRelative = relativePath.getAtomicPathList();
+ int numberOfAncestors = relativePath.getAncestorNodeCount();
+
+ // Gets the root node from the ancestor count.
+ T nodeOrAugmentList = getRootNodeWithAncestorCountForLeafref(numberOfAncestors, parentOfLeafref,
+ leafref);
+ if (nodeOrAugmentList instanceof YangNode) {
+ String pathNameToBePrefixed = EMPTY_STRING;
+ YangNode rootNode = (YangNode) nodeOrAugmentList;
+ // Forms a new absolute path from the relative path
+ while (!(rootNode instanceof YangReferenceResolver)) {
+ pathNameToBePrefixed = rootNode.getName() + SLASH_FOR_STRING + pathNameToBePrefixed;
+ rootNode = rootNode.getParent();
+ if (rootNode == null) {
+ throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
+ }
+ }
+ fillAbsolutePathValuesInLeafref(leafref, pathNameToBePrefixed, absoluteInRelative);
+ } else {
+ List<String> listOfAugment = (List<String>) nodeOrAugmentList;
+ Iterator<String> listOfAugmentIterator = listOfAugment.listIterator();
+ String augment = EMPTY_STRING;
+ while (listOfAugmentIterator.hasNext()) {
+ augment = augment + SLASH_FOR_STRING + listOfAugmentIterator.next();
+ }
+ fillAbsolutePathValuesInLeafref(leafref, augment, absoluteInRelative);
}
- } else {
- ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
- addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
}
}
}
/**
+ * Fills the absolute path values in the leafref from relative path.
+ *
+ * @param leafref instance of YANG leafref
+ * @param pathNameToBePrefixed path name which has to be prefixed to relative path
+ * @param atomicPathsInRelative atomic paths in relative
+ * @throws DataModelException a violation of data model rules
+ */
+ private void fillAbsolutePathValuesInLeafref(YangLeafRef leafref, String pathNameToBePrefixed,
+ List<YangAtomicPath> atomicPathsInRelative) throws DataModelException {
+
+ leafref.setPathType(YangPathArgType.ABSOLUTE_PATH);
+ String[] pathName = new String[0];
+ if (pathNameToBePrefixed != EMPTY_STRING && pathNameToBePrefixed != null) {
+ pathName = pathNameToBePrefixed.split(SLASH_FOR_STRING);
+ }
+ List<YangAtomicPath> finalListForAbsolute = new LinkedList<>();
+ for (String value : pathName) {
+ if (value != null && !value.isEmpty() && value != EMPTY_STRING) {
+ YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(value, YangConstructType.PATH_DATA);
+ YangAtomicPath atomicPath = new YangAtomicPath();
+ atomicPath.setNodeIdentifier(nodeIdentifier);
+ finalListForAbsolute.add(atomicPath);
+ }
+ }
+ if (atomicPathsInRelative != null && !atomicPathsInRelative.isEmpty()) {
+ Iterator<YangAtomicPath> atomicPathIterator = atomicPathsInRelative.listIterator();
+ while (atomicPathIterator.hasNext()) {
+ YangAtomicPath yangAtomicPath = atomicPathIterator.next();
+ finalListForAbsolute.add(yangAtomicPath);
+ }
+ leafref.setAtomicPath(finalListForAbsolute);
+ } else {
+ DataModelException dataModelException = new DataModelException("YANG file error: The target node, in the " +
+ "leafref path " + leafref.getPath() + ", is invalid.");
+ dataModelException.setCharPosition(leafref.getCharPosition());
+ dataModelException.setLine(leafref.getLineNumber());
+ throw dataModelException;
+ }
+ }
+
+ /**
+ * Returns the root parent with respect to the ancestor count from leafref.
+ *
+ * @param ancestorCount count of node where parent node can be reached
+ * @param currentParent current parent node
+ * @param leafref instance of YANG leafref
+ * @return node where the ancestor count stops or augment path name list
+ * @throws DataModelException a violation of data model rules
+ */
+ private T getRootNodeWithAncestorCountForLeafref(int ancestorCount, YangNode currentParent, YangLeafRef leafref)
+ throws DataModelException {
+
+ int currentParentCount = 1;
+ currentParent = skipInvalidDataNodes(currentParent, leafref);
+ if (currentParent instanceof YangAugment) {
+ YangAugment augment = (YangAugment) currentParent;
+ List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
+ return (T) valueInAugment;
+ } else {
+ while (currentParentCount < ancestorCount) {
+ YangNode currentSkippedParent = skipInvalidDataNodes(currentParent, leafref);
+ if (currentSkippedParent == currentParent) {
+ if (currentParent.getParent() == null) {
+ throw new DataModelException("YANG file error: The target node, in the leafref path "
+ + leafref.getPath() + ", is invalid.");
+ }
+ currentParent = currentParent.getParent();
+ } else {
+ currentParent = currentSkippedParent;
+ continue;
+ }
+ currentParentCount = currentParentCount + 1;
+ if (currentParent instanceof YangAugment) {
+ YangAugment augment = (YangAugment) currentParent;
+ List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
+ return (T) valueInAugment;
+ }
+ }
+ }
+ return (T) currentParent;
+ }
+
+ /**
* Finds and resolves with include list.
*
* @return true if resolved, false otherwise
@@ -1728,15 +1565,6 @@
linkedNode = findRefGrouping(yangInclude.getIncludedNode());
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
linkedNode = findRefFeature(yangInclude.getIncludedNode());
- } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
- boolean referredNode = findRefLeaf(yangInclude.getIncludedNode());
- /*
- * Update the current reference resolver to external
- * module/sub-module containing the referred typedef/grouping.
- */
- setCurReferenceResolver((YangReferenceResolver) yangInclude.getIncludedNode());
-
- return referredNode;
} else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
linkedNode = findRefIdentity(yangInclude.getIncludedNode());
} else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
@@ -1785,16 +1613,6 @@
linkedNode = findRefGrouping(yangImport.getImportedNode());
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
linkedNode = findRefFeature(yangImport.getImportedNode());
- } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
- boolean referredNode = findRefLeaf(yangImport.getImportedNode());
- /*
- * Update the current reference resolver to external
- * module/sub-module containing the referred
- * typedef/grouping.
- */
- setCurReferenceResolver((YangReferenceResolver) yangImport.getImportedNode());
-
- return referredNode;
} else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
linkedNode = findRefIdentity(yangImport.getImportedNode());
} else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
@@ -1826,44 +1644,6 @@
}
/**
- * Returns the status of referred leaf.
- *
- * @param importedNode the root node from a YANG file
- * @return status of the referred leaf
- * @throws DataModelException
- */
- private boolean findRefLeaf(YangNode importedNode) throws DataModelException {
-
- boolean isReferredNodeFound = false;
- List<YangAtomicPath> absolutePathList = ((YangLeafRef) getCurrentEntityToResolveFromStack())
- .getAtomicPath();
- if (absolutePathList != null && !absolutePathList.isEmpty()) {
- Iterator<YangAtomicPath> listOfYangAtomicPath = absolutePathList.listIterator();
-
- while (listOfYangAtomicPath.hasNext()) {
- YangAtomicPath absolutePath = listOfYangAtomicPath.next();
- String nodeName = absolutePath.getNodeIdentifier().getName();
-
- if (importedNode.getChild() == null) {
- isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode, nodeName, (T) INTER_FILE_LINKED);
- break;
- }
- importedNode = importedNode.getChild();
-
- YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(importedNode, nodeName);
- if (nodeFound == null) {
- isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode.getParent(), nodeName,
- (T) INTER_FILE_LINKED);
- } else {
- importedNode = nodeFound;
- }
- }
- }
- // TODO: Path predicates filling for inter file has to be done.
- return isReferredNodeFound;
- }
-
- /**
* Returns referred typedef/grouping node.
*
* @return referred typedef/grouping node
@@ -1887,7 +1667,7 @@
return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
- "/uses/base/identityref");
+ "/uses/base/identityref");
}
}
@@ -1986,7 +1766,7 @@
if (tmpNode instanceof YangIdentity) {
if (tmpNode.getName()
.equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
- .getBaseIdentity().getName())) {
+ .getBaseIdentity().getName())) {
return tmpNode;
}
}
diff --git a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangXpathLinker.java b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangXpathLinker.java
index e0d6c7b..a86f9ae 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangXpathLinker.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangXpathLinker.java
@@ -16,6 +16,27 @@
package org.onosproject.yangutils.linker.impl;
+import org.onosproject.yangutils.datamodel.YangAtomicPath;
+import org.onosproject.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangCase;
+import org.onosproject.yangutils.datamodel.YangChoice;
+import org.onosproject.yangutils.datamodel.YangGrouping;
+import org.onosproject.yangutils.datamodel.YangImport;
+import org.onosproject.yangutils.datamodel.YangInclude;
+import org.onosproject.yangutils.datamodel.YangInput;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafList;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
+import org.onosproject.yangutils.datamodel.YangLeavesHolder;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
+import org.onosproject.yangutils.datamodel.YangOutput;
+import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.YangTypeDef;
+import org.onosproject.yangutils.datamodel.YangUses;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -23,24 +44,13 @@
import java.util.Map;
import java.util.Stack;
-import org.onosproject.yangutils.datamodel.YangAtomicPath;
-import org.onosproject.yangutils.datamodel.YangAugment;
-import org.onosproject.yangutils.datamodel.YangImport;
-import org.onosproject.yangutils.datamodel.YangInclude;
-import org.onosproject.yangutils.datamodel.YangLeaf;
-import org.onosproject.yangutils.datamodel.YangLeafList;
-import org.onosproject.yangutils.datamodel.YangLeavesHolder;
-import org.onosproject.yangutils.datamodel.YangModule;
-import org.onosproject.yangutils.datamodel.YangNode;
-import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
-import org.onosproject.yangutils.datamodel.YangSubModule;
-import org.onosproject.yangutils.linker.exceptions.LinkerException;
-
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.INTER_TO_INTER;
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.INTER_TO_INTRA;
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.INTRA_TO_INTER;
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.NO_PREFIX_CHANGE_FOR_INTER;
import static org.onosproject.yangutils.linker.impl.PrefixResolverType.NO_PREFIX_CHANGE_FOR_INTRA;
+import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
+import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
/**
* Represents x-path linking.
@@ -194,31 +204,35 @@
/**
* Process absolute node path for target leaf.
*
- * @param absPaths absolute path node list
- * @param root root node
+ * @param atomicPaths atomic path node list
+ * @param root root node
+ * @param leafref instance of YANG leafref
* @return linked target node
*/
- T processLeafRefXpathLinking(List<YangAtomicPath> absPaths, YangNode root) {
+ public T processLeafRefXpathLinking(List<YangAtomicPath> atomicPaths, YangNode root, YangLeafRef leafref) {
YangNode targetNode = null;
setRootNode(root);
setPrefixResolverTypes(new HashMap<>());
- parsePrefixResolverList(absPaths);
- YangAtomicPath leafRefPath = absPaths.get(absPaths.size() - 1);
+ parsePrefixResolverList(atomicPaths);
+ YangAtomicPath leafRefPath = atomicPaths.get(atomicPaths.size() - 1);
// When leaf-ref path contains only one absolute path.
- if (absPaths.size() == 1) {
- targetNode = getTargetNodewhenSizeIsOne(absPaths);
+ if (atomicPaths.size() == 1) {
+ targetNode = getTargetNodewhenSizeIsOne(atomicPaths);
} else {
- absPaths.remove(absPaths.size() - 1);
+ atomicPaths.remove(atomicPaths.size() - 1);
- setAbsPaths(absPaths);
+ setAbsPaths(atomicPaths);
targetNode = parseData(root);
}
if (targetNode == null) {
targetNode = searchInSubModule(root);
}
+ // Invalid path presence in the node list is checked.
+ validateInvalidNodesInThePath(leafref);
+
if (targetNode != null) {
YangLeaf targetLeaf = searchReferredLeaf(targetNode, leafRefPath.getNodeIdentifier().getName());
if (targetLeaf == null) {
@@ -227,9 +241,12 @@
if (targetLeafList != null) {
return (T) targetLeafList;
} else {
- throw new LinkerException(
- "YANG file error: Unable to find base leaf/leaf-list for given leafref "
- + leafRefPath.getNodeIdentifier().getName());
+ LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
+ "leaf/leaf-list for given leafref path "
+ + leafref.getPath());
+ linkerException.setCharPosition(leafref.getCharPosition());
+ linkerException.setLine(leafref.getLineNumber());
+ throw linkerException;
}
}
return (T) targetLeaf;
@@ -238,6 +255,30 @@
}
/**
+ * Validates the nodes in the path for any invalid node.
+ *
+ * @param leafref instance of YANG leafref
+ */
+ private void validateInvalidNodesInThePath(YangLeafRef leafref) {
+ Map<YangAtomicPath, YangNode> nodes = getResolvedNodes();
+ Iterator<Map.Entry<YangAtomicPath, YangNode>> nodesIterator = nodes.entrySet().iterator();
+ while (nodesIterator.hasNext()) {
+ Map.Entry<YangAtomicPath, YangNode> nodeInList = nodesIterator.next();
+ YangNode nodeInPath = nodeInList.getValue();
+
+ if (nodeInPath instanceof YangGrouping || nodeInPath instanceof YangUses
+ || nodeInPath instanceof YangTypeDef || nodeInPath instanceof YangCase
+ || nodeInPath instanceof YangChoice) {
+ LinkerException linkerException = new LinkerException("YANG file error: The target node, in the " +
+ "leafref path " + leafref.getPath() + ", is invalid.");
+ linkerException.setCharPosition(leafref.getCharPosition());
+ linkerException.setLine(leafref.getLineNumber());
+ throw linkerException;
+ }
+ }
+ }
+
+ /**
* Returns target node when leaf-ref has only one absolute path in list.
*
* @param absPaths absolute paths
@@ -289,9 +330,13 @@
}
YangLeavesHolder holder = (YangLeavesHolder) targetNode;
List<YangLeaf> leaves = holder.getListOfLeaf();
- for (YangLeaf leaf : leaves) {
- if (leaf.getName().equals(leafName)) {
- return leaf;
+ if (leaves != null && !leaves.isEmpty()) {
+ Iterator<YangLeaf> leafIterator = leaves.listIterator();
+ while (leafIterator.hasNext()) {
+ YangLeaf leaf = leafIterator.next();
+ if (leaf.getName().equals(leafName)) {
+ return leaf;
+ }
}
}
return null;
@@ -311,9 +356,13 @@
}
YangLeavesHolder holder = (YangLeavesHolder) targetNode;
List<YangLeafList> leavesList = holder.getListOfLeafList();
- for (YangLeafList leafList : leavesList) {
- if (leafList.getName().equals(leafListName)) {
- return leafList;
+ if (leavesList != null && !leavesList.isEmpty()) {
+ Iterator<YangLeafList> leafListIterator = leavesList.listIterator();
+ while (leafListIterator.hasNext()) {
+ YangLeafList leafList = leafListIterator.next();
+ if (leafList.getName().equals(leafListName)) {
+ return leafList;
+ }
}
}
return null;
@@ -709,6 +758,15 @@
}
while (node != null) {
+ if (node instanceof YangInput) {
+ if (curNodeId.getName().equalsIgnoreCase(INPUT)) {
+ return node;
+ }
+ } else if (node instanceof YangOutput) {
+ if (curNodeId.getName().equalsIgnoreCase(OUTPUT)) {
+ return node;
+ }
+ }
if (node.getName().equals(curNodeId.getName())) {
return node;
}
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
index 26e41c6..7b0d17f 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
@@ -16,8 +16,6 @@
package org.onosproject.yangutils.parser.impl;
-import java.util.Stack;
-
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
@@ -42,12 +40,14 @@
import org.onosproject.yangutils.parser.impl.listeners.DescriptionListener;
import org.onosproject.yangutils.parser.impl.listeners.EnumListener;
import org.onosproject.yangutils.parser.impl.listeners.EnumerationListener;
+import org.onosproject.yangutils.parser.impl.listeners.ErrorAppTagListener;
+import org.onosproject.yangutils.parser.impl.listeners.ErrorMessageListener;
import org.onosproject.yangutils.parser.impl.listeners.FeatureListener;
import org.onosproject.yangutils.parser.impl.listeners.FractionDigitsListener;
import org.onosproject.yangutils.parser.impl.listeners.GroupingListener;
+import org.onosproject.yangutils.parser.impl.listeners.IdentityListener;
import org.onosproject.yangutils.parser.impl.listeners.IdentityrefListener;
import org.onosproject.yangutils.parser.impl.listeners.IfFeatureListener;
-import org.onosproject.yangutils.parser.impl.listeners.IdentityListener;
import org.onosproject.yangutils.parser.impl.listeners.ImportListener;
import org.onosproject.yangutils.parser.impl.listeners.IncludeListener;
import org.onosproject.yangutils.parser.impl.listeners.InputListener;
@@ -83,13 +83,15 @@
import org.onosproject.yangutils.parser.impl.listeners.TypeDefListener;
import org.onosproject.yangutils.parser.impl.listeners.TypeListener;
import org.onosproject.yangutils.parser.impl.listeners.UnionListener;
+import org.onosproject.yangutils.parser.impl.listeners.UniqueListener;
import org.onosproject.yangutils.parser.impl.listeners.UnitsListener;
import org.onosproject.yangutils.parser.impl.listeners.UsesListener;
import org.onosproject.yangutils.parser.impl.listeners.ValueListener;
import org.onosproject.yangutils.parser.impl.listeners.VersionListener;
import org.onosproject.yangutils.parser.impl.listeners.WhenListener;
-import org.onosproject.yangutils.parser.impl.listeners.ErrorMessageListener;
-import org.onosproject.yangutils.parser.impl.listeners.ErrorAppTagListener;
+
+import java.util.Stack;
+
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.handleUnsupportedYangConstruct;
import static org.onosproject.yangutils.utils.UtilConstants.CURRENTLY_UNSUPPORTED;
import static org.onosproject.yangutils.utils.UtilConstants.UNSUPPORTED_YANG_CONSTRUCT;
@@ -109,6 +111,34 @@
private YangNode rootNode;
/**
+ * Parent depth of grouping count for any node.
+ */
+ private int groupingDepth;
+
+ /**
+ * Returns number of grouping parents, by a node, at any level.
+ *
+ * @return depth of grouping
+ */
+ public int getGroupingDepth() {
+ return groupingDepth;
+ }
+
+ /**
+ * Sets number of grouping parents by a node at any level.
+ */
+ public void increaseGroupingDepth() {
+ groupingDepth++;
+ }
+
+ /**
+ * Sets number of grouping parents by a node at any level.
+ */
+ public void decreaseGroupingDepth() {
+ groupingDepth--;
+ }
+
+ /**
* Returns stack of parsable data.
*
* @return stack of parsable data
@@ -956,7 +986,7 @@
@Override
public void enterUniqueStatement(GeneratedYangParser.UniqueStatementContext ctx) {
- handleUnsupportedYangConstruct(YangConstructType.UNIQUE_DATA, ctx, CURRENTLY_UNSUPPORTED);
+ UniqueListener.processUniqueEntry(this, ctx);
}
@Override
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java
index 5171e2f..04d7f50 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java
@@ -106,6 +106,8 @@
// Validate sub statement cardinality.
validateSubStatementsCardinality(ctx);
+ // Increase the grouping count by one.
+ listener.increaseGroupingDepth();
Parsable curData = listener.getParsedDataStack().peek();
// Check for identifier collision
@@ -149,6 +151,8 @@
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, GROUPING_DATA, ctx.identifier().getText(), EXIT);
+ // Decrease the grouping count by one.
+ listener.decreaseGroupingDepth();
if (listener.getParsedDataStack().peek() instanceof YangGrouping) {
listener.getParsedDataStack().pop();
} else {
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
index 6ada8c5..ef4237b 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
@@ -100,6 +100,8 @@
YangLeafRef<?> leafRef = new YangLeafRef<>();
+ leafRef.setLineNumber(errorLine);
+ leafRef.setCharPosition(errorPosition);
Parsable typeData = listener.getParsedDataStack().pop();
if (!(typeData instanceof YangType)) {
@@ -130,11 +132,13 @@
}
leafRef.setResolvableStatus(UNRESOLVED);
-
- // Add resolution information to the list.
- YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
- (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
- addToResolutionList(resolutionInfo);
+ leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeaf);
+ if (listener.getGroupingDepth() == 0) {
+ // Add resolution information to the list.
+ YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
+ (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
+ addToResolutionList(resolutionInfo);
+ }
break;
case LEAF_LIST_DATA:
@@ -151,14 +155,19 @@
}
leafRef.setResolvableStatus(UNRESOLVED);
+ leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafList);
- // Add resolution information to the list.
- YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
- (YangNode) parentNodeOfLeafList, errorLine, errorPosition);
- addToResolutionList(resolutionInfoImpl);
+ if (listener.getGroupingDepth() == 0) {
+ // Add resolution information to the list.
+ YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
+ (YangNode) parentNodeOfLeafList, errorLine, errorPosition);
+ addToResolutionList(resolutionInfoImpl);
+ }
break;
case TYPEDEF_DATA:
+ Parsable parentNodeOfLeafref = listener.getParsedDataStack().peek();
+ leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafref);
/*
* Do not add the leaf ref to resolution list. It needs to be
* added to resolution list, when leaf/leaf list references to
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java
index d0e7300..1891595 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java
@@ -54,6 +54,7 @@
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIdentifier;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.validateUniqueInList;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityMaxOne;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityNonZero;
@@ -174,6 +175,7 @@
YangList yangList = (YangList) listener.getParsedDataStack().peek();
try {
yangList.validateDataOnExit();
+ validateUniqueInList(yangList, ctx);
} catch (DataModelException e) {
throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
LIST_DATA, ctx.identifier().getText(), EXIT, e.getMessage()));
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UniqueListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UniqueListener.java
new file mode 100644
index 0000000..59920fe
--- /dev/null
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UniqueListener.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yangutils.parser.impl.listeners;
+
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.datamodel.utils.Parsable;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+
+import static org.onosproject.yangutils.datamodel.utils.YangConstructType.UNIQUE_DATA;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
+ .constructExtendedListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
+ .constructListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
+
+/*
+ * Reference: RFC6020 and YANG ANTLR Grammar
+ *
+ * ABNF grammar as per RFC6020
+ * unique-stmt = unique-keyword sep unique-arg-str stmtend
+ *
+ * ANTLR grammar rule
+ * uniqueStatement: UNIQUE_KEYWORD unique STMTEND;
+ * unique : string;
+ */
+
+/**
+ * Represesnts listener based call back function corresponding to the "unique" rule
+ * defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
+ */
+public final class UniqueListener {
+
+ /**
+ * Creates a new unique listener.
+ */
+ private UniqueListener() {
+ }
+
+ /**
+ * It is called when parser receives an input matching the grammar rule
+ * (unique), perform validations and updates the data model tree.
+ *
+ * @param listener listener's object
+ * @param ctx context object of the grammar rule
+ */
+ public static void processUniqueEntry(TreeWalkListener listener,
+ GeneratedYangParser.UniqueStatementContext ctx) {
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, UNIQUE_DATA, ctx.unique().getText(), ENTRY);
+
+ Parsable tmpData = listener.getParsedDataStack().peek();
+ if (listener.getParsedDataStack().peek() instanceof YangList) {
+ YangList yangList = (YangList) tmpData;
+ String tmpUniqueValue = removeQuotesAndHandleConcat(ctx.unique().getText());
+
+ if (tmpUniqueValue.contains(" ")) {
+ String[] uniqueValues = tmpUniqueValue.split(" ");
+ for (String uniqueValue : uniqueValues) {
+ try {
+ yangList.addUnique(uniqueValue);
+ } catch (DataModelException e) {
+ throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
+ UNIQUE_DATA,
+ ctx.unique().getText(), ENTRY, e.getMessage()));
+ }
+ }
+ } else {
+ try {
+ yangList.addUnique(tmpUniqueValue);
+ } catch (DataModelException e) {
+ throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA, UNIQUE_DATA,
+ ctx.unique().getText(), ENTRY, e.getMessage()));
+ }
+ }
+ } else {
+ throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, UNIQUE_DATA, ctx.unique().getText(),
+ ENTRY));
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java
index 2240c16..6e27a1b 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java
@@ -137,6 +137,7 @@
YangUses usesNode = getYangUsesNode(JAVA_GENERATION);
YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.string().getText(), USES_DATA, ctx);
usesNode.setNodeIdentifier(nodeIdentifier);
+ usesNode.setCurrentGroupingDepth(listener.getGroupingDepth());
YangNode curNode = (YangNode) curData;
try {
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
index 5ad6133..aa38b87 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
@@ -16,25 +16,34 @@
package org.onosproject.yangutils.parser.impl.parserutils;
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.onosproject.yangutils.datamodel.YangAtomicPath;
+import org.onosproject.yangutils.datamodel.YangImport;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
+import org.onosproject.yangutils.datamodel.YangLeavesHolder;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
+import org.onosproject.yangutils.datamodel.YangPathPredicate;
+import org.onosproject.yangutils.datamodel.YangReferenceResolver;
+import org.onosproject.yangutils.datamodel.YangRelativePath;
+import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.utils.YangConstructType;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
-import org.antlr.v4.runtime.ParserRuleContext;
-import org.onosproject.yangutils.datamodel.YangAtomicPath;
-import org.onosproject.yangutils.datamodel.YangLeafRef;
-import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
-import org.onosproject.yangutils.datamodel.YangPathPredicate;
-import org.onosproject.yangutils.datamodel.YangRelativePath;
-import org.onosproject.yangutils.datamodel.utils.YangConstructType;
-import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
-import org.onosproject.yangutils.parser.exceptions.ParserException;
-
import static org.onosproject.yangutils.datamodel.YangPathArgType.ABSOLUTE_PATH;
import static org.onosproject.yangutils.datamodel.YangPathArgType.RELATIVE_PATH;
import static org.onosproject.yangutils.datamodel.YangPathOperator.EQUALTO;
@@ -98,9 +107,9 @@
/**
* Validates identifier and returns concatenated string if string contains plus symbol.
*
- * @param identifier string from yang file
+ * @param identifier string from yang file
* @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
+ * @param ctx yang construct's context to get the line number and character position
* @return concatenated string after removing double quotes
*/
public static String getValidIdentifier(String identifier, YangConstructType yangConstruct, ParserRuleContext ctx) {
@@ -132,14 +141,14 @@
/**
* Validates identifier and returns concatenated string if string contains plus symbol.
*
- * @param identifier string from yang file
+ * @param identifier string from yang file
* @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
- * @param yangLeafRef instance of leafref where the path argument has to be set
+ * @param ctx yang construct's context to get the line number and character position
+ * @param yangLeafRef instance of leafref where the path argument has to be set
* @return concatenated string after removing double quotes
*/
public static String getValidIdentifierForLeafref(String identifier, YangConstructType yangConstruct,
- ParserRuleContext ctx, YangLeafRef yangLeafRef) {
+ ParserRuleContext ctx, YangLeafRef yangLeafRef) {
String identifierString = removeQuotesAndHandleConcat(identifier);
ParserException parserException;
@@ -211,13 +220,13 @@
/**
* Validates non negative integer value.
*
- * @param integerValue integer to be validated
+ * @param integerValue integer to be validated
* @param yangConstruct yang construct for creating error message
- * @param ctx context object of the grammar rule
+ * @param ctx context object of the grammar rule
* @return valid non negative integer value
*/
public static int getValidNonNegativeIntegerValue(String integerValue, YangConstructType yangConstruct,
- ParserRuleContext ctx) {
+ ParserRuleContext ctx) {
String value = removeQuotesAndHandleConcat(integerValue);
if (!value.matches(NON_NEGATIVE_INTEGER_PATTERN)) {
@@ -246,13 +255,13 @@
/**
* Validates integer value.
*
- * @param integerValue integer to be validated
+ * @param integerValue integer to be validated
* @param yangConstruct yang construct for creating error message
- * @param ctx context object of the grammar rule
+ * @param ctx context object of the grammar rule
* @return valid integer value
*/
public static int getValidIntegerValue(String integerValue, YangConstructType yangConstruct,
- ParserRuleContext ctx) {
+ ParserRuleContext ctx) {
String value = removeQuotesAndHandleConcat(integerValue);
if (!INTEGER_PATTERN.matcher(value).matches()) {
@@ -281,13 +290,13 @@
/**
* Validates boolean value.
*
- * @param booleanValue value to be validated
+ * @param booleanValue value to be validated
* @param yangConstruct yang construct for creating error message
- * @param ctx context object of the grammar rule
+ * @param ctx context object of the grammar rule
* @return boolean value either true or false
*/
public static boolean getValidBooleanValue(String booleanValue, YangConstructType yangConstruct,
- ParserRuleContext ctx) {
+ ParserRuleContext ctx) {
String value = removeQuotesAndHandleConcat(booleanValue);
if (value.equals(TRUE)) {
@@ -329,12 +338,12 @@
* Checks and return valid node identifier.
*
* @param nodeIdentifierString string from yang file
- * @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
* @return valid node identifier
*/
public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString,
- YangConstructType yangConstruct, ParserRuleContext ctx) {
+ YangConstructType yangConstruct, ParserRuleContext ctx) {
String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
if (tmpData.length == 1) {
@@ -360,13 +369,14 @@
* Checks and return valid node identifier specific to nodes in leafref path.
*
* @param nodeIdentifierString string from yang file
- * @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
- * @param yangLeafRef instance of leafref where the path argument has to be set
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
+ * @param yangLeafRef instance of leafref where the path argument has to be set
* @return valid node identifier
*/
public static YangNodeIdentifier getValidNodeIdentifierForLeafref(String nodeIdentifierString,
- YangConstructType yangConstruct, ParserRuleContext ctx, YangLeafRef yangLeafRef) {
+ YangConstructType yangConstruct,
+ ParserRuleContext ctx, YangLeafRef yangLeafRef) {
String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
@@ -392,13 +402,13 @@
/**
* Validates the path argument. It can be either absolute or relative path.
*
- * @param pathString the path string from the path type
+ * @param pathString the path string from the path type
* @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
- * @param yangLeafRef instance of leafref where the path argument has to be set
+ * @param ctx yang construct's context to get the line number and character position
+ * @param yangLeafRef instance of leafref where the path argument has to be set
*/
public static void validatePathArgument(String pathString, YangConstructType yangConstruct,
- ParserRuleContext ctx, YangLeafRef yangLeafRef) {
+ ParserRuleContext ctx, YangLeafRef yangLeafRef) {
String completePathString = removeQuotesAndHandleConcat(pathString);
yangLeafRef.setPath(completePathString);
@@ -406,6 +416,7 @@
yangLeafRef.setPathType(ABSOLUTE_PATH);
List<YangAtomicPath> yangAtomicPathListList = validateAbsolutePath(completePathString, yangConstruct, ctx,
yangLeafRef);
+ validatePrefixAndYangNode(yangAtomicPathListList, yangLeafRef);
yangLeafRef.setAtomicPath(yangAtomicPathListList);
} else if (completePathString.startsWith(ANCESTOR_ACCESSOR)) {
yangLeafRef.setPathType(RELATIVE_PATH);
@@ -421,15 +432,239 @@
}
/**
+ * Validates the prefixes in the leafref and assigns them to the respective imported name in map.
+ *
+ * @param yangAtomicPathList list of atomic poth
+ * @param yangLeafRef instance YANG leafref
+ */
+ private static void validatePrefixAndYangNode(List<YangAtomicPath> yangAtomicPathList, YangLeafRef yangLeafRef) {
+ Iterator<YangAtomicPath> yangAtomicPathIterator = yangAtomicPathList.listIterator();
+ while (yangAtomicPathIterator.hasNext()) {
+ YangAtomicPath atomicPath = yangAtomicPathIterator.next();
+ String prefix = atomicPath.getNodeIdentifier().getPrefix();
+ YangNode parentNodeOfLeafref = yangLeafRef.getParentNodeOfLeafref();
+ YangNode moduleOrSubModule = getModuleOrSubmoduleInFileOfTheCurrentNode(parentNodeOfLeafref);
+ YangModule moduleNode = null;
+ if (moduleOrSubModule instanceof YangModule) {
+ moduleNode = (YangModule) moduleOrSubModule;
+ }
+ if (moduleNode != null) {
+ updatePrefixWithTheImportedList(moduleNode, prefix, yangLeafRef);
+ }
+ }
+ }
+
+ /**
+ * Updates the prefix with the imported list in the module.
+ *
+ * @param moduleNode root node of the leafref
+ * @param prefixInPath prefix in the path
+ * @param yangLeafRef instance YANG leafref
+ */
+ private static void updatePrefixWithTheImportedList(YangModule moduleNode, String prefixInPath, YangLeafRef
+ yangLeafRef) {
+ if (prefixInPath != null && prefixInPath != EMPTY_STRING && !prefixInPath.equals(moduleNode.getPrefix())) {
+ List<YangImport> moduleImportList = moduleNode.getImportList();
+ if (moduleImportList != null && !moduleImportList.isEmpty()) {
+ Iterator<YangImport> yangImportIterator = moduleImportList.listIterator();
+ while (yangImportIterator.hasNext()) {
+ YangImport yangImport = yangImportIterator.next();
+ if (yangImport.getPrefixId().equals(prefixInPath)) {
+ HashMap prefixMap = new HashMap();
+ prefixMap.put(prefixInPath, yangImport.getModuleName());
+ yangLeafRef.setPrefixAndItsImportedModule(prefixMap);
+ }
+ }
+ }
+ } else {
+ HashMap prefixMap = new HashMap();
+ prefixMap.put(prefixInPath, moduleNode.getName());
+ yangLeafRef.setPrefixAndItsImportedModule(prefixMap);
+ }
+ }
+
+ /**
+ * Returns module or submodule node from the current node.
+ *
+ * @param node current node
+ * @return root node
+ */
+ private static YangNode getModuleOrSubmoduleInFileOfTheCurrentNode(YangNode node) {
+ while (!(node instanceof YangModule) && !(node instanceof YangSubModule)) {
+ if (node == null) {
+ throw new ParserException("Internal datamodel error: Datamodel tree is not correct");
+ }
+ node = node.getParent();
+ }
+ return node;
+ }
+
+ /**
+ * Validates the unique syntax from the reference path.
+ *
+ * @param uniquePath path of unique
+ * @param prefixOfFile current file's prefix
+ * @param ctx yang construct's context to get the line number and character position
+ * @return list of absolute path
+ */
+ private static List<YangAtomicPath> validateUniqueValues(String uniquePath, String prefixOfFile,
+ ParserRuleContext ctx) {
+ List<YangAtomicPath> atomicPath = new LinkedList<>();
+ String[] pathInUnique = uniquePath.split(SLASH_FOR_STRING);
+ for (String uniqueValue : pathInUnique) {
+ YangAtomicPath yangAtomicPathPath = new YangAtomicPath();
+ YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(uniqueValue, YangConstructType.UNIQUE_DATA, ctx);
+ yangAtomicPathPath.setNodeIdentifier(nodeIdentifier);
+ atomicPath.add(yangAtomicPathPath);
+ if (nodeIdentifier.getPrefix() != null && nodeIdentifier.getPrefix() != prefixOfFile) {
+ ParserException parserException = new ParserException("YANG file error : A leaf reference, in unique," +
+ " must refer to a leaf in the list");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+ }
+ return atomicPath;
+ }
+
+ /**
+ * Validates unique field from the list.
+ *
+ * @param yangList instance of YANG list
+ * @param ctx yang construct's context to get the line number and character position
+ */
+ public static void validateUniqueInList(YangList yangList, ParserRuleContext ctx) {
+ YangLeaf leaf;
+ // Returns the prefix for the file where unique is present.
+ String prefixOfTheFile = getPrefixInFileOfTheCurrentNode(yangList);
+ List<String> uniques = yangList.getUniqueList();
+ if (uniques != null && !uniques.isEmpty()) {
+ Iterator<String> uniqueList = uniques.listIterator();
+ while (uniqueList.hasNext()) {
+ String pathInUnique = uniqueList.next();
+ List<YangAtomicPath> atomicPathInUnique = validateUniqueValues(pathInUnique, prefixOfTheFile, ctx);
+ YangAtomicPath leafInPath = atomicPathInUnique.get(atomicPathInUnique.size() - 1);
+ if (atomicPathInUnique.size() == 1) {
+ leaf = getReferenceLeafFromUnique(yangList, leafInPath);
+ } else {
+ atomicPathInUnique.remove(atomicPathInUnique.size() - 1);
+ YangNode holderOfLeaf = getNodeUnderListFromPath(atomicPathInUnique, yangList, ctx);
+ leaf = getReferenceLeafFromUnique(holderOfLeaf, leafInPath);
+ }
+ if (leaf == null) {
+ ParserException parserException = new ParserException("YANG file error : A leaf reference, in " +
+ "unique," +
+ " must refer to a leaf under the list");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the last node under the unique path.
+ *
+ * @param uniquePath atomic path list
+ * @param node root node from where it starts searching
+ * @param ctx yang construct's context to get the line number and character position
+ * @return last node in the list
+ */
+ private static YangNode getNodeUnderListFromPath(List<YangAtomicPath> uniquePath, YangNode node,
+ ParserRuleContext ctx) {
+ Iterator<YangAtomicPath> nodesInReference = uniquePath.listIterator();
+ YangNode potentialReferredNode = node.getChild();
+ while (nodesInReference.hasNext()) {
+ YangAtomicPath nodeInUnique = nodesInReference.next();
+ YangNode referredNode = getReferredNodeFromTheUniqueNodes(nodeInUnique.getNodeIdentifier(),
+ potentialReferredNode);
+ if (referredNode == null) {
+ ParserException parserException = new ParserException("YANG file error : The target node in unique " +
+ "reference path is invalid");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ } else {
+ potentialReferredNode = referredNode.getChild();
+ }
+ }
+ return potentialReferredNode;
+ }
+
+ /**
+ * Returns the node that matches with the name of the node in path.
+ *
+ * @param nodeInUnique node name in path
+ * @param potentialReferredNode node under which it has to match
+ * @return referred node
+ */
+ private static YangNode getReferredNodeFromTheUniqueNodes(YangNodeIdentifier nodeInUnique, YangNode
+ potentialReferredNode) {
+ while (potentialReferredNode != null) {
+ // Check if the potential referred node is the actual referred node
+ if (potentialReferredNode.getName().equals(nodeInUnique.getName())) {
+ return potentialReferredNode;
+ }
+ potentialReferredNode = potentialReferredNode.getNextSibling();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the leaf which unique refers.
+ *
+ * @param nodeForLeaf last node where leaf is referred
+ * @param leafInUnique leaf in unique path
+ * @return YANG leaf
+ */
+ private static YangLeaf getReferenceLeafFromUnique(YangNode nodeForLeaf, YangAtomicPath leafInUnique) {
+ YangLeavesHolder leavesHolder = (YangLeavesHolder) nodeForLeaf;
+ List<YangLeaf> leaves = leavesHolder.getListOfLeaf();
+ if (leaves != null && !leaves.isEmpty()) {
+ for (YangLeaf leaf : leaves) {
+ if (leafInUnique.getNodeIdentifier().getName().equals(leaf.getName())) {
+ return leaf;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the prefix of the current file.
+ *
+ * @param node node where it needs to find the root node
+ * @return prefix of root node
+ */
+ public static String getPrefixInFileOfTheCurrentNode(YangNode node) {
+ String prefixInFile;
+ while (!(node instanceof YangReferenceResolver)) {
+ node = node.getParent();
+ if (node == null) {
+ throw new ParserException("Internal datamodel error: Datamodel tree is not correct");
+ }
+ }
+ if (node instanceof YangModule) {
+ YangModule yangModule = (YangModule) node;
+ prefixInFile = yangModule.getPrefix();
+ } else {
+ YangSubModule yangSubModule = (YangSubModule) node;
+ prefixInFile = yangSubModule.getPrefix();
+ }
+ return prefixInFile;
+ }
+
+ /**
* Validates the relative path.
*
* @param completePathString the path string of relative path
- * @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
- * @param yangLeafRef instance of leafref where the path argument has to be set
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
+ * @param yangLeafRef instance of leafref where the path argument has to be set
*/
private static void validateRelativePath(String completePathString, YangConstructType yangConstruct,
- ParserRuleContext ctx, YangLeafRef yangLeafRef) {
+ ParserRuleContext ctx, YangLeafRef yangLeafRef) {
YangRelativePath relativePath = new YangRelativePath();
int numberOfAncestors = 0;
@@ -449,6 +684,7 @@
List<YangAtomicPath> atomicPath = validateAbsolutePath(SLASH_FOR_STRING + completePathString,
yangConstruct,
ctx, yangLeafRef);
+ validatePrefixAndYangNode(atomicPath, yangLeafRef);
relativePath.setAtomicPathList(atomicPath);
yangLeafRef.setRelativePath(relativePath);
}
@@ -457,13 +693,14 @@
* Validates the absolute path.
*
* @param completePathString the path string of absolute path
- * @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
- * @param yangLeafRef instance of leafref where the path argument has to be set
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
+ * @param yangLeafRef instance of leafref where the path argument has to be set
* @return list of object of node in absolute path
*/
private static List<YangAtomicPath> validateAbsolutePath(String completePathString,
- YangConstructType yangConstruct, ParserRuleContext ctx, YangLeafRef yangLeafRef) {
+ YangConstructType yangConstruct, ParserRuleContext
+ ctx, YangLeafRef yangLeafRef) {
List<YangAtomicPath> absolutePathList = new LinkedList<>();
YangPathPredicate yangPathPredicate = new YangPathPredicate();
@@ -555,16 +792,17 @@
/**
* Validates path predicate in the absolute path's node.
*
- * @param pathPredicate list of path predicates in the node of absolute path
- * @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
+ * @param pathPredicate list of path predicates in the node of absolute path
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
* @param yangPathPredicate instance of path predicate where it has to be set
- * @param yangLeafRef instance of leafref where the path argument has to be set
+ * @param yangLeafRef instance of leafref where the path argument has to be set
* @return list of object of path predicates in absolute path's node
*/
private static List<YangPathPredicate> validatePathPredicate(List<String> pathPredicate,
- YangConstructType yangConstruct, ParserRuleContext ctx, YangPathPredicate yangPathPredicate,
- YangLeafRef yangLeafRef) {
+ YangConstructType yangConstruct, ParserRuleContext
+ ctx, YangPathPredicate yangPathPredicate,
+ YangLeafRef yangLeafRef) {
Iterator<String> pathPredicateString = pathPredicate.iterator();
List<String> pathEqualityExpression = new ArrayList<>();
@@ -585,15 +823,17 @@
* Validates the path equality expression.
*
* @param pathEqualityExpression list of path equality expression in the path predicates of the node
- * @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
- * @param yangPathPredicate instance of path predicate where it has to be set
- * @param yangLeafRef instance of leafref where the path argument has to be set
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
+ * @param yangPathPredicate instance of path predicate where it has to be set
+ * @param yangLeafRef instance of leafref where the path argument has to be set
* @return list of object of path predicates in absolute path's node
*/
private static List<YangPathPredicate> validatePathEqualityExpression(List<String> pathEqualityExpression,
- YangConstructType yangConstruct, ParserRuleContext ctx, YangPathPredicate yangPathPredicate,
- YangLeafRef yangLeafRef) {
+ YangConstructType yangConstruct,
+ ParserRuleContext ctx, YangPathPredicate
+ yangPathPredicate,
+ YangLeafRef yangLeafRef) {
Iterator<String> pathEqualityExpressionString = pathEqualityExpression.iterator();
List<YangPathPredicate> yangPathPredicateList = new ArrayList<>();
@@ -620,13 +860,14 @@
* Validate the path key expression.
*
* @param rightRelativePath relative path in the path predicate
- * @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
- * @param yangLeafRef instance of leafref where the path argument has to be set
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
+ * @param yangLeafRef instance of leafref where the path argument has to be set
* @return object of right relative path in path predicate
*/
private static YangRelativePath validatePathKeyExpression(String rightRelativePath,
- YangConstructType yangConstruct, ParserRuleContext ctx, YangLeafRef yangLeafRef) {
+ YangConstructType yangConstruct, ParserRuleContext ctx,
+ YangLeafRef yangLeafRef) {
YangRelativePath yangRelativePath = new YangRelativePath();
String[] relativePath = rightRelativePath.split(SLASH_FOR_STRING);
@@ -650,13 +891,15 @@
* Validates the relative path key expression.
*
* @param rightAbsolutePath absolute path nodes present in the relative path
- * @param yangConstruct yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
- * @param yangLeafRef instance of leafref where the path argument has to be set
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
+ * @param yangLeafRef instance of leafref where the path argument has to be set
* @return list of object of absolute path nodes present in the relative path
*/
private static List<YangAtomicPath> validateRelativePathKeyExpression(List<String> rightAbsolutePath,
- YangConstructType yangConstruct, ParserRuleContext ctx, YangLeafRef yangLeafRef) {
+ YangConstructType yangConstruct,
+ ParserRuleContext ctx, YangLeafRef
+ yangLeafRef) {
List<YangAtomicPath> atomicPathList = new ArrayList<>();
YangNodeIdentifier yangNodeIdentifier;
@@ -704,13 +947,14 @@
/**
* Checks and return valid absolute schema node id.
*
- * @param argumentString string from yang file
+ * @param argumentString string from yang file
* @param yangConstructType yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
+ * @param ctx yang construct's context to get the line number and character position
* @return target nodes list of absolute schema node id
*/
public static List<YangAtomicPath> getValidAbsoluteSchemaNodeId(String argumentString,
- YangConstructType yangConstructType, ParserRuleContext ctx) {
+ YangConstructType yangConstructType,
+ ParserRuleContext ctx) {
List<YangAtomicPath> targetNodes = new ArrayList<>();
YangNodeIdentifier yangNodeIdentifier;
@@ -739,11 +983,11 @@
* Throws parser exception for unsupported YANG constructs.
*
* @param yangConstructType yang construct for creating error message
- * @param ctx yang construct's context to get the line number and character position
- * @param errorInfo error information
+ * @param ctx yang construct's context to get the line number and character position
+ * @param errorInfo error information
*/
public static void handleUnsupportedYangConstruct(YangConstructType yangConstructType,
- ParserRuleContext ctx, String errorInfo) {
+ ParserRuleContext ctx, String errorInfo) {
ParserException parserException = new ParserException(YANG_FILE_ERROR
+ QUOTES + YangConstructType.getYangConstructType(yangConstructType) + QUOTES
+ errorInfo);