[ONOS-5483] Leafref with path-predicate linking.
Change-Id: Id1f95e7b82de9d0b9b1717b8a0f96fb8d03939b1
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
index 8c2a812..eefb208 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
@@ -108,12 +108,12 @@
/**
* Parent node of the leafref's leaf.
*/
- private YangNode parentNodeOfLeafref;
+ private YangNode parentNode;
/**
* Prefix in the nodes of the leafref path and its imported node name.
*/
- private Map<String, String> prefixAndItsImportedModule;
+ private Map<String, String> prefixAndNode;
/**
* Flag to indicate whether the leaf ref is inside grouping.
@@ -123,19 +123,19 @@
/**
* Returns the prefix in the leafref path and its imported node name.
*
- * @return the list of leafref prefix and imported node name
+ * @return map of prefix with node
*/
- public Map<String, String> getPrefixAndItsImportedModule() {
- return prefixAndItsImportedModule;
+ public Map<String, String> getPrefixAndNode() {
+ return prefixAndNode;
}
/**
- * Sets the prefix in the leafref path and its imported node name.
+ * Sets the prefix in the leaf-ref path and its imported node name.
*
- * @param prefixAndItsImportedModule the list of leafref prefix and imported node name
+ * @param prefixAndNode prefix with node map
*/
- public void setPrefixAndItsImportedModule(Map<String, String> prefixAndItsImportedModule) {
- this.prefixAndItsImportedModule = prefixAndItsImportedModule;
+ public void setPrefixAndNode(Map<String, String> prefixAndNode) {
+ this.prefixAndNode = prefixAndNode;
}
/**
@@ -143,17 +143,17 @@
*
* @return parent node of the leafref
*/
- public YangNode getParentNodeOfLeafref() {
- return parentNodeOfLeafref;
+ public YangNode getParentNode() {
+ return parentNode;
}
/**
* Sets the parent node from the leafref's leaf.
*
- * @param parentNodeOfLeafref parent node of the leafref
+ * @param parentNode parent node
*/
- public void setParentNodeOfLeafref(YangNode parentNodeOfLeafref) {
- this.parentNodeOfLeafref = parentNodeOfLeafref;
+ public void setParentNode(YangNode parentNode) {
+ this.parentNode = parentNode;
}
/**
@@ -166,7 +166,7 @@
*/
public YangLeafRef() {
yangAppErrorInfo = new YangAppErrorInfo();
- prefixAndItsImportedModule = new HashMap<>();
+ prefixAndNode = new HashMap<>();
atomicPath = new ArrayList<>();
ifFeatureList = new ArrayList<>();
yangAppErrorInfo.setErrorTag(DATA_MISSING_ERROR_TAG);
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangPathPredicate.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangPathPredicate.java
index 2af0e65..da38acd 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangPathPredicate.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangPathPredicate.java
@@ -18,116 +18,126 @@
import java.io.Serializable;
/**
- * Representation of data model node to maintain path predicate in YANG absolute-path or relative-path.
+ * Representation of data model node to maintain path predicate in YANG
+ * absolute-path or relative-path.
*/
-public class YangPathPredicate<T> extends DefaultLocationInfo
+public class YangPathPredicate extends DefaultLocationInfo
implements Serializable {
private static final long serialVersionUID = 806201689L;
- // YANG node identifier.
- private YangNodeIdentifier nodeIdentifier;
+ /**
+ * YANG node id.
+ */
+ private YangNodeIdentifier nodeId;
- // Left axis node will represent the nodeidentifier before equality sign in path predicate.
- private T leftAxisNode;
+ /**
+ * Left axis represents node-id before equality sign.
+ */
+ private Object leftAxisNode;
- // YANG path operator.
- private YangPathOperator pathOperator;
+ /**
+ * YANG path operator.
+ */
+ private YangPathOperator pathOp;
- // YANG relative path.
- private YangRelativePath rightRelativePath;
+ /**
+ * YANG right relative path in path-predicate.
+ */
+ private YangRelativePath relPath;
- // Right axis node will represent the nodeidentifier after equality sign in path predicate.
- private T rightAxisNode;
+ /**
+ * Right axis node represents the node-id after the equality sign.
+ */
+ private Object rightAxisNode;
/**
* Returns the path expression operator.
*
- * @return the path expression operator
+ * @return path operator
*/
- public YangPathOperator getPathOperator() {
- return pathOperator;
+ public YangPathOperator getPathOp() {
+ return pathOp;
}
/**
* Sets the path expression operator.
*
- * @param pathOperator Sets the path expression operator
+ * @param pathOp path operator
*/
- public void setPathOperator(YangPathOperator pathOperator) {
- this.pathOperator = pathOperator;
+ public void setPathOp(YangPathOperator pathOp) {
+ this.pathOp = pathOp;
}
/**
* Returns the right relative path expression.
*
- * @return the right relative path expression
+ * @return relative path
*/
- public YangRelativePath getRightRelativePath() {
- return rightRelativePath;
+ public YangRelativePath getRelPath() {
+ return relPath;
}
/**
* Sets the right relative path expression.
*
- * @param rightRelativePath Sets the right relative path expression
+ * @param relPath relative path
*/
- public void setRightRelativePath(YangRelativePath rightRelativePath) {
- this.rightRelativePath = rightRelativePath;
+ public void setRelPath(YangRelativePath relPath) {
+ this.relPath = relPath;
}
/**
- * Returns the nodeidentifier.
+ * Returns the node identifier.
*
- * @return the nodeidentifier
+ * @return node id
*/
- public YangNodeIdentifier getNodeIdentifier() {
- return nodeIdentifier;
+ public YangNodeIdentifier getNodeId() {
+ return nodeId;
}
/**
* Sets the YANG node identifier.
*
- * @param nodeIdentifier Sets the node identifier
- *
+ * @param nodeId node id
*/
- public void setNodeIdentifier(YangNodeIdentifier nodeIdentifier) {
- this.nodeIdentifier = nodeIdentifier;
+ public void setNodeId(YangNodeIdentifier nodeId) {
+ this.nodeId = nodeId;
}
/**
* Returns the left axis node.
*
- * @return the left axis node
+ * @return left axis node
*/
- public T getLeftAxisNode() {
+ public Object getLeftAxisNode() {
return leftAxisNode;
}
/**
* Sets the left axis node.
*
- * @param leftAxisNode Sets the left axis node
+ * @param leftAxisNode left axis node
*/
- public void setLeftAxisNode(T leftAxisNode) {
+ public void setLeftAxisNode(Object leftAxisNode) {
this.leftAxisNode = leftAxisNode;
}
/**
* Returns the right axis node.
*
- * @return the right axis node
+ * @return right axis node
*/
- public T getRightAxisNode() {
+ public Object getRightAxisNode() {
return rightAxisNode;
}
/**
* Sets the right axis node.
*
- * @param rightAxisNode Sets the right axis node
+ * @param rightAxisNode right axis node
*/
- public void setRightAxisNode(T rightAxisNode) {
+ public void setRightAxisNode(Object rightAxisNode) {
this.rightAxisNode = rightAxisNode;
}
}
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
index 411e88e..5943f17 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
@@ -49,6 +49,7 @@
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
@@ -351,7 +352,7 @@
throws CloneNotSupportedException, DataModelException {
List<YangLeaf> leaves = clonedNode.getListOfLeaf();
- if (isListPresent(leaves)) {
+ if (nonEmpty(leaves)) {
List<YangLeaf> clonedLeaves = new LinkedList<>();
for (YangLeaf leaf : leaves) {
YangLeaf clonedLeaf = leaf.clone();
@@ -382,20 +383,21 @@
List<YangEntityToResolveInfoImpl> infoList;
if (yangUses != null && yangUses.getCurrentGroupingDepth() == 0) {
infoList = getTypesToBeResolved(clonedObj, clonedNode, yangUses);
- if (isListPresent(infoList)) {
+ if (nonEmpty(infoList)) {
yangUses.addEntityToResolve(infoList);
}
}
}
/**
- * Returns true if list object is non-null and non-empty; false otherwise.
+ * Returns true if collection object is non-null and non-empty; false
+ * otherwise.
*
- * @param listObj list object
- * @return true if list object is non-null and non-empty; false otherwise
+ * @param c collection object
+ * @return true if object is non-null and non-empty; false otherwise
*/
- private static boolean isListPresent(List listObj) {
- return listObj != null && !listObj.isEmpty();
+ public static boolean nonEmpty(Collection<?> c) {
+ return c != null && !c.isEmpty();
}
/**
@@ -413,7 +415,7 @@
throws CloneNotSupportedException, DataModelException {
List<YangLeafList> listOfLeafList = clonedNode.getListOfLeafList();
- if (isListPresent(listOfLeafList)) {
+ if (nonEmpty(listOfLeafList)) {
List<YangLeafList> clonedList = new LinkedList<>();
for (YangLeafList leafList : listOfLeafList) {
YangLeafList clonedLeafList = leafList.clone();
@@ -500,7 +502,7 @@
return null;
}
infoList.add(entity);
- if (isListPresent(entityList)) {
+ if (nonEmpty(entityList)) {
infoList.addAll(entityList);
}
return infoList;
@@ -528,7 +530,7 @@
// Conversion of prefixes in absolute path while cloning them.
convertThePrefixesDuringChange(leafRef, yangUses);
- leafRef.setParentNodeOfLeafref(holder);
+ leafRef.setParentNode(holder);
leafRefInfo.setEntityToResolve(leafRef);
return setInformationInEntity(
@@ -632,7 +634,7 @@
for (YangType unionType : typeList) {
entity = getUnresolvedTypeList(unionType.getDataType(),
unionType, union, null, isLeaf);
- if (isListPresent(entity)) {
+ if (nonEmpty(entity)) {
unionList.addAll(entity);
}
}
@@ -653,7 +655,7 @@
Iterator<YangAtomicPath> atomicPathIterator = atomicPathList.listIterator();
while (atomicPathIterator.hasNext()) {
YangAtomicPath atomicPath = atomicPathIterator.next();
- Map<String, String> prefixesAndItsImportNameNode = leafrefForCloning.getPrefixAndItsImportedModule();
+ Map<String, String> prefixesAndItsImportNameNode = leafrefForCloning.getPrefixAndNode();
String prefixInPath = atomicPath.getNodeIdentifier().getPrefix();
String importedNodeName = prefixesAndItsImportNameNode.get(prefixInPath);
assignCurrentLeafedWithNewPrefixes(importedNodeName, atomicPath, yangUses);
diff --git a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java
index 507ebf3..aa55b96 100644
--- a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java
+++ b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java
@@ -32,9 +32,12 @@
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.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.YangType;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.datamodel.YangUses;
@@ -54,7 +57,6 @@
import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
import static org.onosproject.yangutils.datamodel.TraversalType.ROOT;
import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
-import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.CASE;
import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.COLLISION_DETECTION;
import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.FAILED_TO_ADD_CASE;
import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.TARGET_NODE;
@@ -74,6 +76,7 @@
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_LINKER_ERROR;
+import static org.onosproject.yangutils.utils.UtilConstants.INVALID_TREE;
import static org.onosproject.yangutils.utils.UtilConstants.IS_INVALID;
import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_ERROR;
import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
@@ -85,9 +88,24 @@
public final class 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 Pattern IDENTIFIER_PATTERN =
+ Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
private static final String XML = "xml";
+ private static final String INVALID_PATH_PRE =
+ "YANG file error: The path predicate of the leafref has an " +
+ "invalid path in ";
+ private static final String EMPTY_PATH_LIST_ERR =
+ "YANG file error : The atomic path list cannot be empty of the " +
+ "leafref in the path ";
+ private static final String TGT_LEAF_ERR =
+ "YANG file error: There is no leaf/leaf-list in YANG node as " +
+ "mentioned in the path predicate of the leafref path ";
+ private static final String LEAF_REF_LIST_ERR =
+ "YANG file error: Path predicates are only applicable for YANG " +
+ "list. The leafref path has path predicate for non-list " +
+ "node in the path ";
+ // No instantiation.
private YangLinkerUtils() {
}
@@ -257,33 +275,6 @@
.getFileName());
}
- //Detect collision between augment and choice children.
- private void detectCollisionForChoiceNode(YangNode choice, YangNode augment) {
- YangNode choiceChild = choice.getChild();
- YangNode augmentChild = augment.getChild();
-
- List<YangNode> choiceChildren = new ArrayList<>();
- List<YangNode> augmentChildren = new ArrayList<>();
- while (choiceChild != null) {
- choiceChildren.add(choiceChild);
- }
- while (augmentChild != null) {
- augmentChildren.add(augmentChild);
- }
-
- for (YangNode cChild : choiceChildren) {
- for (YangNode aChild : augmentChildren) {
- if (cChild.getName().equals(aChild.getName())) {
- ;
- throw new LinkerException(getErrorMsgCollision(
- COLLISION_DETECTION, cChild.getName(),
- cChild.getLineNumber(), cChild.getCharPosition(),
- CASE, cChild.getFileName()));
- }
- }
- }
- }
-
/**
* Detects collision between target nodes and its all leaf/leaf-list or child node with augmented leaf/leaf-list or
* child node.
@@ -328,25 +319,25 @@
/**
* Skips the invalid nodes which cannot have data from YANG.
*
- * @param currentParent current parent node reference
- * @param leafref instance of YANG leafref
+ * @param curParent current parent
+ * @param leafRef YANG leaf-ref
* @return parent node which can hold data
- * @throws LinkerException a violation of linker rules
+ * @throws LinkerException if linker rules are violated
*/
- static YangNode skipInvalidDataNodes(YangNode currentParent, YangLeafRef leafref)
+ public static YangNode skipInvalidDataNodes(YangNode curParent,
+ YangLeafRef leafRef)
throws LinkerException {
- while (currentParent instanceof YangChoice || currentParent instanceof YangCase) {
- if (currentParent.getParent() == null) {
- LinkerException ex = new LinkerException(
- LEAFREF_ERROR + leafref.getPath() + IS_INVALID);
- ex.setCharPosition(leafref.getCharPosition());
- ex.setLine(leafref.getLineNumber());
- ex.setFileName(leafref.getFileName());
- throw ex;
+
+ YangNode node = curParent;
+ while (node instanceof YangChoice ||
+ node instanceof YangCase) {
+
+ if (node.getParent() == null) {
+ throw new LinkerException(getLeafRefErrorInfo(leafRef));
}
- currentParent = currentParent.getParent();
+ node = node.getParent();
}
- return currentParent;
+ return node;
}
/**
@@ -610,4 +601,254 @@
}
}
+ /**
+ * Fills the path predicates of the leaf-ref with right axis node and
+ * left axis node, after linking the nodes.
+ *
+ * @param leafRef YANG leaf-ref
+ * @throws DataModelException if there is a data model error
+ */
+ public static void fillPathPredicates(YangLeafRef<?> leafRef)
+ throws DataModelException {
+
+ List<YangAtomicPath> atomics = leafRef.getAtomicPath();
+ if (atomics != null) {
+ for (YangAtomicPath atom : atomics) {
+ List<YangPathPredicate> predicates =
+ atom.getPathPredicatesList();
+
+ if (predicates != null) {
+ for (YangPathPredicate predicate : predicates) {
+ setLeftAxisNode(leafRef, atom, predicate);
+ setRightAxisNode(leafRef, predicate);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the left axis node in the YANG path predicate after finding it
+ * under the YANG list node.
+ *
+ * @param leafRef YANG leaf-ref
+ * @param atom atomic path content
+ * @param predicate predicate in the atomic path
+ * @throws DataModelException if there is a data model error
+ */
+ private static void setLeftAxisNode(YangLeafRef<?> leafRef,
+ YangAtomicPath atom,
+ YangPathPredicate predicate)
+ throws DataModelException {
+ YangNode resolvedNode = atom.getResolvedNode();
+ if (!(resolvedNode instanceof YangList)) {
+ throw getDataModelExc(LEAF_REF_LIST_ERR, leafRef);
+ }
+
+ YangNodeIdentifier leftAxisName = predicate.getNodeId();
+ Object target = getTarget(leftAxisName, resolvedNode, leafRef);
+ predicate.setLeftAxisNode(target);
+ }
+
+ /**
+ * Returns the target leaf/leaf-list from the provided YANG node.
+ *
+ * @param leftAxisName name of node
+ * @param node node having target
+ * @param leafRef YANG leaf-ref
+ * @return target leaf/leaf-list
+ * @throws DataModelException if there is a data model error
+ */
+ private static Object getTarget(YangNodeIdentifier leftAxisName,
+ YangNode node, YangLeafRef leafRef)
+ throws DataModelException {
+
+ YangLeaf leaf = getLeaf(leftAxisName, (YangLeavesHolder) node);
+ if (leaf != null) {
+ return leaf;
+ }
+ YangLeafList leafList = getLeafList(leftAxisName,
+ (YangLeavesHolder) node);
+ if (leafList == null) {
+ throw getDataModelExc(TGT_LEAF_ERR, leafRef);
+ }
+ return leafList;
+ }
+
+ /**
+ * Returns the leaf by searching it in the node by the leaf name. Returns
+ * null when the name doesn't match.
+ *
+ * @param name leaf name
+ * @param holder holder of leaf
+ * @return YANG leaf
+ */
+ private static YangLeaf getLeaf(YangNodeIdentifier name,
+ YangLeavesHolder holder) {
+
+ List<YangLeaf> listOfLeaf = holder.getListOfLeaf();
+ if (listOfLeaf != null) {
+ for (YangLeaf yangLeaf : listOfLeaf) {
+ if (yangLeaf.getName().equals(name.getName())) {
+ return yangLeaf;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the leaf-list by searching it in the node by the leaf-list name.
+ * Returns null when the name doesn't match.
+ *
+ * @param name leaf-list name
+ * @param holder holder of leaf-list
+ * @return YANG leaf-list
+ */
+ private static YangLeafList getLeafList(YangNodeIdentifier name,
+ YangLeavesHolder holder) {
+
+ List<YangLeafList> listOfLeafList = holder.getListOfLeafList();
+ if (listOfLeafList != null) {
+ for (YangLeafList yangLeafList : listOfLeafList) {
+ if (yangLeafList.getName().equals(name.getName())) {
+ return yangLeafList;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the root node from which the path with the atomic node names
+ * has to be traversed through. With the ancestor count the nodes are
+ * moved upward.
+ *
+ * @param count ancestor count
+ * @param node current leaf-ref parent
+ * @param leafRef YANG leaf-ref
+ * @return root node from ancestor count
+ * @throws DataModelException if there is a data model error
+ */
+ private static YangNode getRootNode(int count, YangNode node,
+ YangLeafRef leafRef)
+ throws DataModelException {
+
+ YangNode curParent = node;
+ int curCount = 0;
+ while (curCount < count) {
+ curCount = curCount + 1;
+ if (curCount != 1) {
+ if (curParent.getParent() == null) {
+ throw getDataModelExc(INVALID_TREE, leafRef);
+ }
+ curParent = curParent.getParent();
+ }
+ curParent = skipInvalidDataNodes(curParent, leafRef);
+ if (curParent instanceof YangAugment) {
+ YangAugment augment = (YangAugment) curParent;
+ curParent = augment.getAugmentedNode();
+ curCount = curCount + 1;
+ }
+ }
+ return curParent;
+ }
+
+ /**
+ * Returns the last node by traversing through the atomic node id by
+ * leaving the last target leaf/leaf-list.
+ *
+ * @param curNode current node
+ * @param relPath relative path
+ * @param leafRef YANG leaf-ref
+ * @return last YANG node
+ * @throws DataModelException if there is a data model error
+ */
+ private static Object getLastNode(YangNode curNode,
+ YangRelativePath relPath,
+ YangLeafRef leafRef)
+ throws DataModelException {
+
+ YangNode node = curNode;
+ List<YangAtomicPath> atomics = new ArrayList<>();
+ atomics.addAll(relPath.getAtomicPathList());
+
+ if (atomics.isEmpty()) {
+ throw getDataModelExc(EMPTY_PATH_LIST_ERR, leafRef);
+ }
+
+ YangAtomicPath pathTgt = atomics.get(atomics.size() - 1);
+ if (atomics.size() == 1) {
+ return getTarget(pathTgt.getNodeIdentifier(), node, leafRef);
+ }
+
+ atomics.remove(atomics.size() - 1);
+ for (YangAtomicPath atomicPath : atomics) {
+ node = getNode(node.getChild(), atomicPath.getNodeIdentifier());
+ if (node == null) {
+ throw getDataModelExc(INVALID_PATH_PRE, leafRef);
+ }
+ }
+ return getTarget(pathTgt.getNodeIdentifier(), node, leafRef);
+ }
+
+ /**
+ * Returns the node from the parent node by matching it with the atomic
+ * name. If no child node matches the name then it returns null.
+ *
+ * @param curNode current node
+ * @param identifier atomic name
+ * @return node to be traversed
+ */
+ private static YangNode getNode(YangNode curNode,
+ YangNodeIdentifier identifier) {
+ YangNode node = curNode;
+ while (node != null) {
+ if (node.getName().equals(identifier.getName())) {
+ return node;
+ }
+ node = node.getNextSibling();
+ }
+ return null;
+ }
+
+ /**
+ * Sets the right axis node in the YANG path predicate after finding it
+ * from the relative path.
+ *
+ * @param leafRef YANG leaf-ref
+ * @param predicate YANG path predicate
+ * @throws DataModelException if there is a data model error
+ */
+ private static void setRightAxisNode(YangLeafRef leafRef,
+ YangPathPredicate predicate)
+ throws DataModelException {
+
+ YangNode parentNode = leafRef.getParentNode();
+ YangRelativePath relPath = predicate.getRelPath();
+ int ancestor = relPath.getAncestorNodeCount();
+
+ YangNode rootNode = getRootNode(ancestor, parentNode, leafRef);
+ Object target = getLastNode(rootNode, relPath, leafRef);
+ if (target == null) {
+ throw getDataModelExc(INVALID_PATH_PRE, leafRef);
+ }
+ predicate.setRightAxisNode(target);
+ }
+
+ /**
+ * Returns data model error messages for leaf-ref with the path.
+ *
+ * @param msg error message
+ * @param leafRef YANG leaf-ref
+ * @return data model exception
+ */
+ private static DataModelException getDataModelExc(String msg,
+ YangLeafRef leafRef) {
+ DataModelException exc = new DataModelException(
+ msg + leafRef.getPath());
+ exc.setCharPosition(leafRef.getCharPosition());
+ exc.setLine(leafRef.getLineNumber());
+ return exc;
+ }
}
diff --git a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
index 480d8c6..3400cfe 100644
--- a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
+++ b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
@@ -81,6 +81,7 @@
import static org.onosproject.yangutils.linker.impl.XpathLinkingTypes.AUGMENT_LINKING;
import static org.onosproject.yangutils.linker.impl.XpathLinkingTypes.LEAF_REF_LINKING;
import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
+import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.fillPathPredicates;
import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getErrorInfoForLinker;
import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getLeafRefErrorInfo;
import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getPathWithAugment;
@@ -294,7 +295,7 @@
YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
addRefTypeInfo(YangDataTypes.LEAFREF, LEAFREF, extendedInfo,
yangType, refNode, YANG_LEAFREF);
- leafRefInTypeDef.setParentNodeOfLeafref(refNode);
+ leafRefInTypeDef.setParentNode(refNode);
} else {
addRefTypeInfo(YangDataTypes.IDENTITYREF, IDENTITYREF, extendedInfo,
yangType, refNode, YANG_IDENTITYREF);
@@ -379,7 +380,7 @@
.getEntityToResolve();
YangNode parentNodeOfLeafref = entityToResolveInfo
.getHolderOfEntityToResolve();
- leafref.setParentNodeOfLeafref(parentNodeOfLeafref);
+ leafref.setParentNode(parentNodeOfLeafref);
if (leafref.getResolvableStatus() == UNRESOLVED) {
leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
}
@@ -1018,9 +1019,11 @@
*
* @param entityToResolve entity to resolve
* @param root root node
+ * @throws DataModelException if there is a data model error
*/
private void processXPathLinking(T entityToResolve,
- YangReferenceResolver root) {
+ YangReferenceResolver root)
+ throws DataModelException {
YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
@@ -1094,7 +1097,7 @@
addUnResolvedLeafRefTypeToStack(
(T) leafList, entityToResolveInfo.getHolderOfEntityToResolve());
}
- //TODO: add logic for leaf-ref for path predicates.
+ fillPathPredicates(leafRef);
} else {
LinkerException ex = new LinkerException(
FAILED_TO_FIND_LEAD_INFO_HOLDER + leafRef.getPath());
@@ -1266,7 +1269,7 @@
if (resolutionInfo instanceof YangLeafRef) {
YangNode leafParent = ((YangLeafRef) resolutionInfo)
- .getParentNodeOfLeafref();
+ .getParentNode();
YangLeafRef leafref = (YangLeafRef) resolutionInfo;
// Checks if the leafref has relative path in it.
diff --git a/generator/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java b/generator/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java
index d73a0d6..48ea81d 100644
--- a/generator/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java
+++ b/generator/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java
@@ -631,12 +631,12 @@
/**
* Static attribute for ancestor accessor.
*/
- public static final String ANCESTOR_ACCESSOR = "..";
+ public static final String ANCESTOR = "..";
/**
* Static attribute for ancestor accessor along with path.
*/
- public static final String ANCESTOR_ACCESSOR_IN_PATH = "../";
+ public static final String SLASH_ANCESTOR = "../";
/**
* Static attribute for add syntax.
diff --git a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
index 25ac31c..9c1b466 100644
--- a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
+++ b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
@@ -133,7 +133,7 @@
}
leafRef.setResolvableStatus(UNRESOLVED);
- leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeaf);
+ leafRef.setParentNode((YangNode) parentNodeOfLeaf);
if (listener.getGroupingDepth() == 0) {
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
@@ -158,7 +158,7 @@
}
leafRef.setResolvableStatus(UNRESOLVED);
- leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafList);
+ leafRef.setParentNode((YangNode) parentNodeOfLeafList);
if (listener.getGroupingDepth() == 0) {
// Add resolution information to the list.
@@ -172,7 +172,7 @@
case TYPEDEF_DATA:
Parsable parentNodeOfLeafref = listener.getParsedDataStack().peek();
- leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafref);
+ leafRef.setParentNode((YangNode) parentNodeOfLeafref);
if (listener.getGroupingDepth() != 0) {
leafRef.setInGrouping(true);
}
diff --git a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PathListener.java b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PathListener.java
index b02c6f4..681225d 100644
--- a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PathListener.java
+++ b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PathListener.java
@@ -18,17 +18,17 @@
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.utils.Parsable;
-import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser.PathStatementContext;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.validatePathArgument;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.datamodel.utils.YangConstructType.PATH_DATA;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+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.ListenerUtil.validatePath;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
/*
* Reference: RFC6020 and YANG ANTLR Grammar
@@ -43,7 +43,8 @@
*
* ANTLR grammar rule
*
- * leafrefSpecification : (pathStatement (requireInstanceStatement)?) | ((requireInstanceStatement)? pathStatement);
+ * leafrefSpecification : (pathStatement (requireInstanceStatement)?) |
+ * ((requireInstanceStatement)? pathStatement);
*
* pathStatement : PATH_KEYWORD path STMTEND;
*/
@@ -55,9 +56,7 @@
*/
public final class PathListener {
- /**
- * Creates a new path listener.
- */
+ // No instantiation.
private PathListener() {
}
@@ -66,24 +65,26 @@
* (path), performs validation and updates the data model tree.
*
* @param listener listener's object
- * @param ctx context object of the grammar rule
+ * @param ctx context object of the grammar rule
*/
public static void processPathEntry(TreeWalkListener listener,
- GeneratedYangParser.PathStatementContext ctx) {
+ PathStatementContext ctx) {
// Check for stack to be non empty.
- checkStackIsNotEmpty(listener, MISSING_HOLDER, PATH_DATA, ctx.path().getText(), ENTRY);
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, PATH_DATA,
+ ctx.path().getText(), ENTRY);
Parsable curData = listener.getParsedDataStack().peek();
- // Checks the holder of path as leafref, else throws error.
+ // Checks the holder of path as leaf-ref, else throws error.
if (curData instanceof YangLeafRef) {
-
- // Splitting the path argument and updating it in the datamodel tree.
- validatePathArgument(ctx.path().getText(), PATH_DATA, ctx, (YangLeafRef) curData);
+ // Parsing the path and updating in leaf-ref path.
+ validatePath(ctx.path().getText(), PATH_DATA, ctx,
+ (YangLeafRef) curData);
} else {
- throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, PATH_DATA,
- ctx.path().getText(), ENTRY));
+ throw new ParserException(
+ constructListenerErrorMessage(INVALID_HOLDER, PATH_DATA,
+ ctx.path().getText(), ENTRY));
}
}
}
diff --git a/parser/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java b/parser/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
index 65d054c..3c3e08d 100644
--- a/parser/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
+++ b/parser/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
@@ -16,16 +16,6 @@
package org.onosproject.yangutils.parser.impl.parserutils;
-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.YangImport;
@@ -44,15 +34,26 @@
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.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
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;
import static org.onosproject.yangutils.datamodel.utils.YangConstructType.getYangConstructType;
+import static org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser.PathStatementContext;
import static org.onosproject.yangutils.utils.UtilConstants.ADD;
-import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR_ACCESSOR;
-import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR_ACCESSOR_IN_PATH;
+import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR;
import static org.onosproject.yangutils.utils.UtilConstants.CARET;
-import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_CLOSE_SQUARE_BRACKET;
import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_OPEN_SQUARE_BRACKET;
import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_SLASH;
import static org.onosproject.yangutils.utils.UtilConstants.CLOSE_PARENTHESIS;
@@ -60,9 +61,11 @@
import static org.onosproject.yangutils.utils.UtilConstants.CURRENT;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.FALSE;
+import static org.onosproject.yangutils.utils.UtilConstants.INVALID_TREE;
import static org.onosproject.yangutils.utils.UtilConstants.OPEN_SQUARE_BRACKET;
import static org.onosproject.yangutils.utils.UtilConstants.QUOTES;
import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
+import static org.onosproject.yangutils.utils.UtilConstants.SLASH_ANCESTOR;
import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.TRUE;
import static org.onosproject.yangutils.utils.UtilConstants.YANG_FILE_ERROR;
@@ -72,19 +75,27 @@
*/
public final class ListenerUtil {
- private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
- private static final String DATE_PATTERN = "[0-9]{4}-([0-9]{2}|[0-9])-([0-9]{2}|[0-9])";
+ private static final Pattern IDENTIFIER_PATTERN =
+ Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
+ private static final String DATE_PATTERN =
+ "[0-9]{4}-([0-9]{2}|[0-9])-([0-9]{2}|[0-9])";
private static final String NON_NEGATIVE_INTEGER_PATTERN = "[0-9]+";
- private static final Pattern INTEGER_PATTERN = Pattern.compile("[-][0-9]+|[0-9]+");
- private static final Pattern PATH_PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
+ private static final Pattern INTEGER_PATTERN =
+ Pattern.compile("[-][0-9]+|[0-9]+");
+ private static final Pattern PREDICATE =
+ Pattern.compile("\\[(.*?)\\]");
private static final String XML = "xml";
private static final String ONE = "1";
private static final int IDENTIFIER_LENGTH = 64;
private static final String DATE_FORMAT = "yyyy-MM-dd";
+ private static final String REGEX_EQUAL = "[=]";
+ private static final String REGEX_OPEN_BRACE = "[(]";
- /**
- * Creates a new listener util.
- */
+ private static YangConstructType pathType;
+ private static PathStatementContext pathCtx;
+ private static YangLeafRef yangLeafRef;
+
+ // No instantiation.
private ListenerUtil() {
}
@@ -140,42 +151,6 @@
}
/**
- * 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
- * @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) {
-
- String identifierString = removeQuotesAndHandleConcat(identifier);
- ParserException parserException;
-
- if (identifierString.length() > IDENTIFIER_LENGTH) {
- parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
- getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() + " is " +
- "greater than 64 characters.");
- } else if (!IDENTIFIER_PATTERN.matcher(identifierString).matches()) {
- parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
- getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() + " is not " +
- "valid.");
- } else if (identifierString.toLowerCase().startsWith(XML)) {
- parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
- getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
- " must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
- } else {
- return identifierString;
- }
-
- parserException.setLine(ctx.getStart().getLine());
- parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
- throw parserException;
- }
-
- /**
* Validates the revision date.
*
* @param dateToValidate input revision date
@@ -367,137 +342,83 @@
}
/**
- * Checks and return valid node identifier specific to nodes in leafref path.
+ * Validates the prefix of the YANG file where leaf-ref is present and
+ * puts it in the map of node and prefix in leaf-ref.
*
- * @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
- * @return valid node identifier
+ * @param atomicList atomic content list in leaf-ref
+ * @param leafRef YANG leaf-ref
*/
- public static YangNodeIdentifier getValidNodeIdentifierForLeafref(String nodeIdentifierString,
- YangConstructType yangConstruct,
- ParserRuleContext ctx, YangLeafRef yangLeafRef) {
+ private static void valPrefix(List<YangAtomicPath> atomicList,
+ YangLeafRef leafRef) {
- String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
- String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
- if (tmpData.length == 1) {
- YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
- nodeIdentifier.setName(getValidIdentifierForLeafref(tmpData[0], yangConstruct, ctx, yangLeafRef));
- return nodeIdentifier;
- } else if (tmpData.length == 2) {
- YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
- nodeIdentifier.setPrefix(getValidIdentifierForLeafref(tmpData[0], yangConstruct, ctx, yangLeafRef));
- nodeIdentifier.setName(getValidIdentifierForLeafref(tmpData[1], yangConstruct, ctx, yangLeafRef));
- return nodeIdentifier;
- } else {
- ParserException parserException = new ParserException("YANG file error : " +
- getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
- " is not valid.");
- parserException.setLine(ctx.getStart().getLine());
- parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
- throw parserException;
- }
- }
-
- /**
- * Validates the path argument. It can be either absolute or relative path.
- *
- * @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
- */
- public static void validatePathArgument(String pathString, YangConstructType yangConstruct,
- ParserRuleContext ctx, YangLeafRef yangLeafRef) {
-
- String completePathString = removeQuotesAndHandleConcat(pathString);
- yangLeafRef.setPath(completePathString);
- if (completePathString.startsWith(SLASH)) {
- 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);
- validateRelativePath(completePathString, yangConstruct, ctx, yangLeafRef);
- } else {
- ParserException parserException = new ParserException("YANG file error : " +
- getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
- " does not follow valid path syntax");
- parserException.setLine(ctx.getStart().getLine());
- parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
- throw parserException;
- }
- }
-
- /**
- * 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();
+ for (YangAtomicPath atomicPath : atomicList) {
String prefix = atomicPath.getNodeIdentifier().getPrefix();
- YangNode parentNodeOfLeafref = yangLeafRef.getParentNodeOfLeafref();
- YangNode moduleOrSubModule = getModuleOrSubmoduleInFileOfTheCurrentNode(parentNodeOfLeafref);
- YangModule moduleNode = null;
- if (moduleOrSubModule instanceof YangModule) {
- moduleNode = (YangModule) moduleOrSubModule;
+ YangNode parent = leafRef.getParentNode();
+ YangNode rootNode = getRootNode(parent);
+
+ List<YangImport> imports;
+ if (rootNode instanceof YangModule) {
+ imports = ((YangModule) rootNode).getImportList();
+ } else {
+ imports = ((YangSubModule) rootNode).getImportList();
}
- if (moduleNode != null) {
- updatePrefixWithTheImportedList(moduleNode, prefix, yangLeafRef);
- }
+ updatePrefixWithNode(rootNode, imports, prefix, leafRef);
}
}
/**
- * Updates the prefix with the imported list in the module.
+ * Updates the prefix and its respective node in the leaf-ref by taking
+ * the node from the import list of the root node which matches with the
+ * prefix.
*
- * @param moduleNode root node of the leafref
- * @param prefixInPath prefix in the path
- * @param yangLeafRef instance YANG leafref
+ * @param root root node
+ * @param imports import list
+ * @param prefix prefix in path
+ * @param leafRef YANG leaf-ref
*/
- 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);
- }
+ private static void updatePrefixWithNode(YangNode root,
+ List<YangImport> imports,
+ String prefix,
+ YangLeafRef<?> leafRef) {
+
+ Map<String, String> prefixMap = leafRef.getPrefixAndNode();
+ if (prefixMap == null) {
+ prefixMap = new HashMap<>();
+ leafRef.setPrefixAndNode(prefixMap);
+ }
+
+ if (prefix == null ||
+ prefix.equals(((YangReferenceResolver) root).getPrefix())) {
+ prefixMap.put(prefix, root.getName());
+ return;
+ }
+
+ if (imports != null) {
+ for (YangImport yangImp : imports) {
+ if (yangImp.getPrefixId().equals(prefix)) {
+ prefixMap.put(prefix, yangImp.getModuleName());
}
}
- } else {
- HashMap prefixMap = new HashMap();
- prefixMap.put(prefixInPath, moduleNode.getName());
- yangLeafRef.setPrefixAndItsImportedModule(prefixMap);
}
}
/**
- * Returns module or submodule node from the current node.
+ * Returns the root 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");
+ private static YangNode getRootNode(YangNode node) {
+
+ YangNode curNode = node;
+ while (!(curNode instanceof YangModule) &&
+ !(curNode instanceof YangSubModule)) {
+ if (curNode == null) {
+ throw new ParserException(INVALID_TREE);
}
- node = node.getParent();
+ curNode = curNode.getParent();
}
- return node;
+ return curNode;
}
/**
@@ -657,292 +578,19 @@
}
/**
- * Validates the relative path.
+ * Returns the matched first path predicate in a given string. Returns
+ * null if match is not found.
*
- * @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
- */
- private static void validateRelativePath(String completePathString, YangConstructType yangConstruct,
- ParserRuleContext ctx, YangLeafRef yangLeafRef) {
-
- YangRelativePath relativePath = new YangRelativePath();
- int numberOfAncestors = 0;
- while (completePathString.startsWith(ANCESTOR_ACCESSOR_IN_PATH)) {
- completePathString = completePathString.replaceFirst(ANCESTOR_ACCESSOR_IN_PATH, EMPTY_STRING);
- numberOfAncestors = numberOfAncestors + 1;
- }
- if (completePathString == null || completePathString.length() == 0) {
- ParserException parserException = new ParserException("YANG file error : "
- + getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
- " does not follow valid path syntax");
- parserException.setLine(ctx.getStart().getLine());
- parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
- throw parserException;
- }
- relativePath.setAncestorNodeCount(numberOfAncestors);
- List<YangAtomicPath> atomicPath = validateAbsolutePath(SLASH_FOR_STRING + completePathString,
- yangConstruct,
- ctx, yangLeafRef);
- validatePrefixAndYangNode(atomicPath, yangLeafRef);
- relativePath.setAtomicPathList(atomicPath);
- yangLeafRef.setRelativePath(relativePath);
- }
-
- /**
- * 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
- * @return list of object of node in absolute path
- */
- private static List<YangAtomicPath> validateAbsolutePath(String completePathString,
- YangConstructType yangConstruct, ParserRuleContext
- ctx, YangLeafRef yangLeafRef) {
-
- List<YangAtomicPath> absolutePathList = new LinkedList<>();
- YangPathPredicate yangPathPredicate = new YangPathPredicate();
- YangNodeIdentifier yangNodeIdentifier;
-
- while (completePathString != null) {
- String path = completePathString.replaceFirst(SLASH_FOR_STRING, EMPTY_STRING);
- if (path == null || path.length() == 0) {
- ParserException parserException = new ParserException("YANG file error : "
- + getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
- " does not follow valid path syntax");
- parserException.setLine(ctx.getStart().getLine());
- parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
- throw parserException;
- }
- String matchedPathPredicate;
- String nodeIdentifier;
- String[] differentiate = new String[2];
- int forNodeIdentifier = path.indexOf(CHAR_OF_SLASH);
- int forPathPredicate = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
-
- // Checks if path predicate is present for the node.
- if ((forPathPredicate < forNodeIdentifier) && (forPathPredicate != -1)) {
- List<String> pathPredicate = new ArrayList<>();
- matchedPathPredicate = matchForPathPredicate(path);
-
- if (matchedPathPredicate == null || matchedPathPredicate.length() == 0) {
- ParserException parserException = new ParserException("YANG file error : "
- + getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
- " does not follow valid path syntax");
- parserException.setLine(ctx.getStart().getLine());
- parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
- throw parserException;
- }
- int indexOfMatchedFirstOpenBrace = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
- differentiate[0] = path.substring(0, indexOfMatchedFirstOpenBrace);
- differentiate[1] = path.substring(indexOfMatchedFirstOpenBrace);
- pathPredicate.add(matchedPathPredicate);
- nodeIdentifier = differentiate[0];
- // Starts adding all path predicates of a node into the list.
- if (!differentiate[1].isEmpty()) {
- while (differentiate[1].startsWith(OPEN_SQUARE_BRACKET)) {
- matchedPathPredicate = matchForPathPredicate(differentiate[1]);
- if (matchedPathPredicate == null || matchedPathPredicate.length() == 0) {
- ParserException parserException = new ParserException(
- "YANG file error : " + getYangConstructType(yangConstruct) + " "
- + yangLeafRef.getPath() +
- " does not follow valid path syntax");
- parserException.setLine(ctx.getStart().getLine());
- parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
- throw parserException;
- }
- pathPredicate.add(matchedPathPredicate);
- differentiate[1] = differentiate[1].substring(matchedPathPredicate.length());
- }
- }
-
- List<YangPathPredicate> pathPredicateList = validatePathPredicate(pathPredicate, yangConstruct, ctx,
- yangPathPredicate, yangLeafRef);
- YangAtomicPath atomicPath = new YangAtomicPath();
- yangNodeIdentifier = getValidNodeIdentifierForLeafref(nodeIdentifier, yangConstruct, ctx, yangLeafRef);
- atomicPath.setNodeIdentifier(yangNodeIdentifier);
- atomicPath.setPathPredicatesList(pathPredicateList);
- absolutePathList.add(atomicPath);
- } else {
- if (path.contains(SLASH_FOR_STRING)) {
- nodeIdentifier = path.substring(0, path.indexOf(CHAR_OF_SLASH));
- differentiate[1] = path.substring(path.indexOf(CHAR_OF_SLASH));
- } else {
- nodeIdentifier = path;
- differentiate[1] = null;
- }
- yangNodeIdentifier = getValidNodeIdentifierForLeafref(nodeIdentifier, yangConstruct, ctx, yangLeafRef);
-
- YangAtomicPath atomicPath = new YangAtomicPath();
- atomicPath.setNodeIdentifier(yangNodeIdentifier);
- atomicPath.setPathPredicatesList(null);
- absolutePathList.add(atomicPath);
- }
- if (differentiate[1] == null || differentiate[1].length() == 0) {
- completePathString = null;
- } else {
- completePathString = differentiate[1];
- }
- }
- return absolutePathList;
- }
-
- /**
- * 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 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> validatePathPredicate(List<String> pathPredicate,
- YangConstructType yangConstruct, ParserRuleContext
- ctx, YangPathPredicate yangPathPredicate,
- YangLeafRef yangLeafRef) {
-
- Iterator<String> pathPredicateString = pathPredicate.iterator();
- List<String> pathEqualityExpression = new ArrayList<>();
-
- while (pathPredicateString.hasNext()) {
- String pathPredicateForNode = pathPredicateString.next();
- pathPredicateForNode = (pathPredicateForNode.substring(1)).trim();
- pathPredicateForNode = pathPredicateForNode.substring(0,
- pathPredicateForNode.indexOf(CHAR_OF_CLOSE_SQUARE_BRACKET));
- pathEqualityExpression.add(pathPredicateForNode);
- }
- List<YangPathPredicate> validatedPathPredicateList = validatePathEqualityExpression(pathEqualityExpression,
- yangConstruct, ctx, yangPathPredicate, yangLeafRef);
- return validatedPathPredicateList;
- }
-
- /**
- * 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
- * @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) {
-
- Iterator<String> pathEqualityExpressionString = pathEqualityExpression.iterator();
- List<YangPathPredicate> yangPathPredicateList = new ArrayList<>();
-
- while (pathEqualityExpressionString.hasNext()) {
- String pathEqualityExpressionForNode = pathEqualityExpressionString.next();
- String[] pathEqualityExpressionArray = pathEqualityExpressionForNode.split("[=]");
-
- YangNodeIdentifier yangNodeIdentifierForPredicate;
- YangRelativePath yangRelativePath;
- yangNodeIdentifierForPredicate = getValidNodeIdentifierForLeafref(pathEqualityExpressionArray[0].trim(),
- yangConstruct, ctx, yangLeafRef);
- yangRelativePath = validatePathKeyExpression(pathEqualityExpressionArray[1].trim(), yangConstruct, ctx,
- yangLeafRef);
- yangPathPredicate.setNodeIdentifier(yangNodeIdentifierForPredicate);
- yangPathPredicate.setPathOperator(EQUALTO);
- yangPathPredicate.setRightRelativePath(yangRelativePath);
- yangPathPredicateList.add(yangPathPredicate);
- }
- return yangPathPredicateList;
- }
-
- /**
- * 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
- * @return object of right relative path in path predicate
- */
- private static YangRelativePath validatePathKeyExpression(String rightRelativePath,
- YangConstructType yangConstruct, ParserRuleContext ctx,
- YangLeafRef yangLeafRef) {
-
- YangRelativePath yangRelativePath = new YangRelativePath();
- String[] relativePath = rightRelativePath.split(SLASH_FOR_STRING);
- List<String> rightAbsolutePath = new ArrayList<>();
- int accessAncestor = 0;
- for (String path : relativePath) {
- if (path.trim().equals(ANCESTOR_ACCESSOR)) {
- accessAncestor = accessAncestor + 1;
- } else {
- rightAbsolutePath.add(path);
- }
- }
- List<YangAtomicPath> atomicPathInRelativePath = validateRelativePathKeyExpression(rightAbsolutePath,
- yangConstruct, ctx, yangLeafRef);
- yangRelativePath.setAtomicPathList(atomicPathInRelativePath);
- yangRelativePath.setAncestorNodeCount(accessAncestor);
- return yangRelativePath;
- }
-
- /**
- * 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
- * @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) {
-
- List<YangAtomicPath> atomicPathList = new ArrayList<>();
- YangNodeIdentifier yangNodeIdentifier;
-
- Iterator<String> nodes = rightAbsolutePath.iterator();
- String currentInvocationFunction = nodes.next();
- currentInvocationFunction = currentInvocationFunction.trim();
- String[] currentFunction = currentInvocationFunction.split("[(]");
-
- if (!(currentFunction[0].trim().equals(CURRENT)) || !(currentFunction[1].trim().equals(CLOSE_PARENTHESIS))) {
- ParserException parserException = new ParserException("YANG file error : "
- + getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
- " does not follow valid path syntax");
- parserException.setLine(ctx.getStart().getLine());
- parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
- throw parserException;
- }
-
- while (nodes.hasNext()) {
- YangAtomicPath atomicPath = new YangAtomicPath();
- String node = nodes.next();
- yangNodeIdentifier = getValidNodeIdentifierForLeafref(node.trim(), yangConstruct, ctx, yangLeafRef);
- atomicPath.setNodeIdentifier(yangNodeIdentifier);
- atomicPathList.add(atomicPath);
- }
- return atomicPathList;
- }
-
- /**
- * Validates the match for first path predicate in a given string.
- *
- * @param matchRequiredString string for which match has to be done
+ * @param str string to be matched
* @return the matched string
*/
- private static String matchForPathPredicate(String matchRequiredString) {
+ private static String getMatchedPredicate(String str) {
- String matchedString = null;
- java.util.regex.Matcher matcher = PATH_PREDICATE_PATTERN.matcher(matchRequiredString);
+ Matcher matcher = PREDICATE.matcher(str);
if (matcher.find()) {
- matchedString = matcher.group(0);
+ return matcher.group(0);
}
- return matchedString;
+ return null;
}
/**
@@ -983,16 +631,18 @@
/**
* 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 fileName YANG file name
+ * @param type construct type
+ * @param ctx construct context
+ * @param errorInfo error msg
+ * @param fileName YANG file name
*/
- public static void handleUnsupportedYangConstruct(YangConstructType yangConstructType,
- ParserRuleContext ctx, String errorInfo, String fileName) {
- ParserException parserException = new ParserException(YANG_FILE_ERROR
- + QUOTES + getYangConstructType(yangConstructType) + QUOTES
- + errorInfo);
+ public static void handleUnsupportedYangConstruct(YangConstructType type,
+ ParserRuleContext ctx,
+ String errorInfo,
+ String fileName) {
+ ParserException parserException = new ParserException(
+ YANG_FILE_ERROR + QUOTES + getYangConstructType(
+ type) + QUOTES + errorInfo);
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
//FIXME this exception should probably be thrown rather than just logged
@@ -1052,4 +702,274 @@
throw parserException;
}
}
+
+ /**
+ * Validates path under leaf-ref and parses the path and stores in the
+ * leaf-ref.
+ *
+ * @param path path of leaf-ref
+ * @param type construct type
+ * @param ctx construct details
+ * @param leafRef YANG leaf-ref having path
+ */
+ public static void validatePath(String path, YangConstructType type,
+ PathStatementContext ctx,
+ YangLeafRef leafRef) {
+
+ String concatPath = removeQuotesAndHandleConcat(path);
+ pathType = type;
+ pathCtx = ctx;
+ yangLeafRef = leafRef;
+ if (!concatPath.startsWith(SLASH_FOR_STRING) &&
+ !concatPath.startsWith(ANCESTOR)) {
+ throw getPathException();
+ }
+ leafRef.setPath(concatPath);
+ if (concatPath.startsWith(SLASH_FOR_STRING)) {
+ List<YangAtomicPath> atomicList = new LinkedList<>();
+ valAbsPath(concatPath, atomicList);
+ leafRef.setPathType(ABSOLUTE_PATH);
+ valPrefix(atomicList, leafRef);
+ leafRef.setAtomicPath(atomicList);
+ return;
+ }
+ leafRef.setPathType(RELATIVE_PATH);
+ valRelPath(concatPath, leafRef);
+ }
+
+ /**
+ * Validates relative path, parses the string and stores it in the leaf-ref.
+ *
+ * @param path leaf-ref path
+ * @param leafRef YANG leaf-ref
+ */
+ private static void valRelPath(String path, YangLeafRef leafRef) {
+
+ YangRelativePath relPath = new YangRelativePath();
+ int count = 0;
+ while (path.startsWith(SLASH_ANCESTOR)) {
+ path = path.replaceFirst(SLASH_ANCESTOR, EMPTY_STRING);
+ count = count + 1;
+ }
+ if (path.isEmpty()) {
+ throw getPathException();
+ }
+
+ List<YangAtomicPath> atomicList = new ArrayList<>();
+ relPath.setAncestorNodeCount(count);
+ valAbsPath(SLASH_FOR_STRING + path, atomicList);
+ valPrefix(atomicList, leafRef);
+ relPath.setAtomicPathList(atomicList);
+ leafRef.setRelativePath(relPath);
+ }
+
+ /**
+ * Validates absolute path, parses the string and stores it in leaf-ref.
+ *
+ * @param path leaf-ref path
+ * @param atomics atomic content list
+ */
+ private static void valAbsPath(String path, List<YangAtomicPath> atomics) {
+
+ String comPath = path;
+ while (comPath != null) {
+ comPath = comPath.substring(1);
+ if (comPath.isEmpty()) {
+ throw getPathException();
+ }
+ int nodeId = comPath.indexOf(CHAR_OF_SLASH);
+ int predicate = comPath.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
+ if (predicate < nodeId && predicate != -1) {
+ comPath = getPathWithPredicate(comPath, atomics);
+ } else {
+ comPath = getPath(comPath, atomics);
+ }
+ }
+ }
+
+ /**
+ * Returns the remaining path after parsing and the predicates of an atomic
+ * content.
+ *
+ * @param path leaf-ref path
+ * @param atomics atomic content list
+ * @return parsed path after removing one atomic content.
+ */
+ private static String getPathWithPredicate(String path,
+ List<YangAtomicPath> atomics) {
+
+ String[] node = new String[2];
+ int bracket = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
+ node[0] = path.substring(0, bracket);
+ node[1] = path.substring(bracket);
+ return getParsedPath(node[0], node[1], atomics);
+ }
+
+ /**
+ * Returns the path after taking all the path predicates of an atomic
+ * content.
+ *
+ * @param nodeId atomic content nodeId
+ * @param path leaf-ref path
+ * @param atomics atomic content list
+ * @return parsed path after removing one atomic content.
+ */
+ public static String getParsedPath(String nodeId, String path,
+ List<YangAtomicPath> atomics) {
+
+ String comPath = path;
+ List<String> predicateList = new ArrayList<>();
+ while (comPath.startsWith(OPEN_SQUARE_BRACKET)) {
+ String matchedVal = getMatchedPredicate(comPath);
+ if (matchedVal == null || matchedVal.isEmpty()) {
+ throw getPathException();
+ }
+ predicateList.add(matchedVal);
+ comPath = comPath.substring(matchedVal.length());
+ }
+
+ YangAtomicPath atomicPath = new YangAtomicPath();
+ YangNodeIdentifier validId =
+ getValidNodeIdentifier(nodeId, pathType, pathCtx);
+
+ List<YangPathPredicate> predicates = valPathPredicates(predicateList);
+ atomicPath.setNodeIdentifier(validId);
+ atomicPath.setPathPredicatesList(predicates);
+ atomics.add(atomicPath);
+ return comPath;
+ }
+
+ /**
+ * Validates the path predicates of an atomic content after parsing the
+ * predicates and storing it in the leaf-ref.
+ *
+ * @param predicates list of predicates
+ * @return list of path predicates of an atomic content
+ */
+ private static List<YangPathPredicate> valPathPredicates(List<String> predicates) {
+
+ List<YangPathPredicate> result = new ArrayList<>();
+ for (String p : predicates) {
+ p = p.substring(1, p.length() - 1);
+ result.add(valPathEqualityExp(p.trim()));
+ }
+ return result;
+ }
+
+ /**
+ * Validates the path equality expression of a path predicate and after
+ * parsing the string assigns it to the YANG path predicate.
+ *
+ * @param predicate path predicate
+ * @return YANG path predicate
+ */
+ private static YangPathPredicate valPathEqualityExp(String predicate) {
+
+ String[] exp = predicate.split(REGEX_EQUAL);
+ YangNodeIdentifier nodeId =
+ getValidNodeIdentifier(exp[0].trim(), pathType, pathCtx);
+ YangRelativePath relPath = valPathKeyExp(exp[1].trim());
+
+ YangPathPredicate pathPredicate = new YangPathPredicate();
+ pathPredicate.setNodeId(nodeId);
+ pathPredicate.setPathOp(EQUALTO);
+ pathPredicate.setRelPath(relPath);
+ return pathPredicate;
+ }
+
+ /**
+ * Validates the path key expression of the path-predicate and stores it
+ * in the relative path of the leaf-ref.
+ *
+ * @param relPath relative path
+ * @return YANG relative path
+ */
+ private static YangRelativePath valPathKeyExp(String relPath) {
+
+ String[] relative = relPath.split(SLASH_FOR_STRING);
+ int count = 0;
+ List<String> atomicContent = new ArrayList<>();
+ for (String val : relative) {
+ if (val.trim().equals(ANCESTOR)) {
+ count = count + 1;
+ } else {
+ atomicContent.add(val);
+ }
+ }
+
+ YangRelativePath relativePath = new YangRelativePath();
+ relativePath.setAncestorNodeCount(count);
+ relativePath.setAtomicPathList(valRelPathKeyExp(atomicContent));
+ return relativePath;
+ }
+
+ /**
+ * Validates relative path key expression in the right relative path of
+ * the path predicate, by taking every atomic content in it.
+ *
+ * @param content atomic content list
+ * @return YANG atomic content list
+ */
+ private static List<YangAtomicPath> valRelPathKeyExp(List<String> content) {
+
+ String current = content.get(0);
+ String[] curStr = (current.trim()).split(REGEX_OPEN_BRACE);
+ if (!(curStr[0].trim().equals(CURRENT)) ||
+ !(curStr[1].trim().equals(CLOSE_PARENTHESIS))) {
+ throw getPathException();
+ }
+
+ content.remove(0);
+ List<YangAtomicPath> atomicList = new ArrayList<>();
+ for (String relPath : content) {
+ YangNodeIdentifier nodeId =
+ getValidNodeIdentifier(relPath, pathType, pathCtx);
+ YangAtomicPath atomicPath = new YangAtomicPath();
+ atomicPath.setNodeIdentifier(nodeId);
+ atomicList.add(atomicPath);
+ }
+ return atomicList;
+ }
+
+ /**
+ * Returns the remaining path after parsing and processing an atomic
+ * content which doesn't have path-predicate.
+ *
+ * @param path leaf-ref path
+ * @param atomicList atomic content list
+ * @return remaining path after parsing one atomic content
+ */
+ public static String getPath(String path, List<YangAtomicPath> atomicList) {
+
+ String comPath = path;
+ String nodeId;
+ if (comPath.contains(SLASH_FOR_STRING)) {
+ nodeId = comPath.substring(0, comPath.indexOf(CHAR_OF_SLASH));
+ comPath = comPath.substring(comPath.indexOf(CHAR_OF_SLASH));
+ } else {
+ nodeId = comPath;
+ comPath = null;
+ }
+
+ YangNodeIdentifier validNodeId =
+ getValidNodeIdentifier(nodeId, pathType, pathCtx);
+ YangAtomicPath atomicPath = new YangAtomicPath();
+ atomicPath.setNodeIdentifier(validNodeId);
+ atomicList.add(atomicPath);
+ return comPath;
+ }
+
+ /**
+ * Returns the path syntax parser exception.
+ *
+ * @return parser exception
+ */
+ private static ParserException getPathException() {
+ ParserException exception = new ParserException(
+ "YANG file error : Path " + yangLeafRef.getPath() +
+ " does not follow valid path syntax");
+ exception.setLine(pathCtx.getStart().getLine());
+ exception.setCharPosition(pathCtx.getStart().getCharPositionInLine());
+ return exception;
+ }
}
diff --git a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java
index f02fe65..e128979 100644
--- a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java
+++ b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java
@@ -1552,11 +1552,11 @@
List<YangPathPredicate> pathPredicateList = abspath.getPathPredicatesList();
Iterator<YangPathPredicate> pathPredicate = pathPredicateList.listIterator();
YangPathPredicate pathPredicate1 = pathPredicate.next();
- assertThat(pathPredicate1.getNodeIdentifier().getName(), is("name"));
- assertThat(pathPredicate1.getNodeIdentifier().getPrefix(), nullValue());
- assertThat(pathPredicate1.getRightRelativePath().getAncestorNodeCount(), is(1));
- assertThat(pathPredicate1.getPathOperator(), is(YangPathOperator.EQUALTO));
- assertThat(pathPredicate1.getRightRelativePath().getAtomicPathList().listIterator().next().getNodeIdentifier()
+ assertThat(pathPredicate1.getNodeId().getName(), is("name"));
+ assertThat(pathPredicate1.getNodeId().getPrefix(), nullValue());
+ assertThat(pathPredicate1.getRelPath().getAncestorNodeCount(), is(1));
+ assertThat(pathPredicate1.getPathOp(), is(YangPathOperator.EQUALTO));
+ assertThat(pathPredicate1.getRelPath().getAtomicPathList().listIterator().next().getNodeIdentifier()
.getName(), is("ifname"));
//TODO : Fill the path predicates
// assertThat(pathPredicate1.getLeftAxisNode(), is(leafNameInList));
diff --git a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/PathPredicateLinkingTest.java b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/PathPredicateLinkingTest.java
new file mode 100644
index 0000000..e7ae30d
--- /dev/null
+++ b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/PathPredicateLinkingTest.java
@@ -0,0 +1,332 @@
+/*
+ * 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.plugin.manager;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.datamodel.YangAtomicPath;
+import org.onosproject.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangContainer;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangPathPredicate;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.linker.impl.YangLinkerManager;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.updateFilePriority;
+import static org.onosproject.yangutils.utils.io.impl.YangFileScanner.getYangFiles;
+
+/**
+ * Test cases for path predicate linking in leaf-ref.
+ */
+public class PathPredicateLinkingTest {
+
+ private static final String DIR = "src/test/resources/pathpredicate/";
+
+ private final YangUtilManager utilMgr = new YangUtilManager();
+ private final YangLinkerManager linkerMgr = new YangLinkerManager();
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private ListIterator<YangLeaf> leafItr;
+ private YangLeaf ifName;
+ private YangLeaf address;
+ private YangLeaf name;
+ private Iterator<YangAtomicPath> pathItr;
+ private YangAtomicPath atomicPath;
+ private Iterator<YangPathPredicate> predicateItr;
+ private YangPathPredicate predicate;
+
+ /**
+ * Processes simple path predicate which gets linked within the same file
+ * using relative path.
+ *
+ * @throws IOException if violates IO operation
+ */
+ @Test
+ public void processSimplePathPredicate() throws IOException {
+
+ utilMgr.createYangFileInfoSet(getYangFiles(DIR + "simple"));
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ YangNode selfNode;
+
+ linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+ linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+ updateFilePriority(utilMgr.getYangNodeSet());
+
+ linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+ Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+ selfNode = nodeItr.next();
+
+ // Gets the list node.
+ YangList yangList = (YangList) selfNode.getChild();
+ // Gets the container node.
+ YangContainer container = (YangContainer) yangList.getNextSibling();
+
+ leafItr = container.getListOfLeaf().listIterator();
+ ifName = leafItr.next();
+ address = leafItr.next();
+
+ // Gets the address leaf's leaf-ref type.
+ YangLeafRef<?> leafRef2 = (YangLeafRef) address.getDataType()
+ .getDataTypeExtendedInfo();
+ pathItr = leafRef2.getAtomicPath().listIterator();
+ atomicPath = pathItr.next();
+
+ // Gets the path-predicate.
+ predicateItr = atomicPath.getPathPredicatesList().listIterator();
+ predicate = predicateItr.next();
+
+ // Gets the left and right axis node in path-predicate.
+ YangLeaf yangLeftLeaf = (YangLeaf) predicate.getLeftAxisNode();
+ YangLeaf yangRightLeaf = (YangLeaf) predicate.getRightAxisNode();
+
+ leafItr = yangList.getListOfLeaf().listIterator();
+ name = leafItr.next();
+
+ // Checks that right and left path-predicates are correct.
+ assertThat(yangLeftLeaf, is(name));
+ assertThat(yangRightLeaf, is(ifName));
+ }
+
+ /**
+ * Processes simple inter file path predicate which gets linked to another
+ * file using absolute path.
+ *
+ * @throws IOException if violates IO operation
+ */
+ @Test
+ public void processSimpleInterFilePathPredicate() throws IOException {
+
+ utilMgr.createYangFileInfoSet(getYangFiles(DIR + "simpleinterfile"));
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ YangModule selfNode;
+
+ linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+ linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+ updateFilePriority(utilMgr.getYangNodeSet());
+
+ linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+ Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+
+ YangNode rootNode = nodeItr.next();
+ YangModule refNode;
+ if (rootNode.getName().equals("ietf-network")) {
+ selfNode = (YangModule) rootNode;
+ refNode = (YangModule) nodeItr.next();
+ } else {
+ refNode = (YangModule) rootNode;
+ selfNode = (YangModule) nodeItr.next();
+ }
+
+ // Gets the container node.
+ YangContainer container = (YangContainer) selfNode.getChild();
+ // Gets the list node.
+ YangList yangList = (YangList) refNode.getChild();
+
+ leafItr = container.getListOfLeaf().listIterator();
+ ifName = leafItr.next();
+ address = leafItr.next();
+
+ // Gets the address leaf's leaf-ref type.
+ YangLeafRef<?> leafRef2 = (YangLeafRef) address.getDataType()
+ .getDataTypeExtendedInfo();
+ pathItr = leafRef2.getAtomicPath().listIterator();
+ atomicPath = pathItr.next();
+
+ // Gets the path-predicate.
+ predicateItr = atomicPath.getPathPredicatesList().listIterator();
+ predicate = predicateItr.next();
+
+ // Gets the left and right axis node in path-predicate.
+ YangLeaf yangLeftLeaf = (YangLeaf) predicate.getLeftAxisNode();
+ YangLeaf yangRightLeaf = (YangLeaf) predicate.getRightAxisNode();
+
+ leafItr = yangList.getListOfLeaf().listIterator();
+ name = leafItr.next();
+
+ // Checks that right and left path-predicates are correct.
+ assertThat(yangLeftLeaf, is(name));
+ assertThat(yangRightLeaf, is(ifName));
+ }
+
+ /**
+ * Processes inter file path predicate, where leaf-ref is present under
+ * YANG augment.
+ *
+ * @throws IOException if violates IO operation
+ */
+ @Test
+ public void processInterFilePathPredicateFromAugment() throws IOException {
+
+ utilMgr.createYangFileInfoSet(getYangFiles(DIR + "interfileaugment"));
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ YangModule selfNode;
+
+ linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+ linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+ updateFilePriority(utilMgr.getYangNodeSet());
+
+ linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+ Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+
+ YangNode rootNode = nodeItr.next();
+ YangModule refNode;
+ if (rootNode.getName().equals("ietf-network")) {
+ selfNode = (YangModule) rootNode;
+ refNode = (YangModule) nodeItr.next();
+ } else {
+ refNode = (YangModule) rootNode;
+ selfNode = (YangModule) nodeItr.next();
+ }
+
+ // Gets the augment node.
+ YangList list = (YangList) selfNode.getChild().getChild();
+
+ // Gets the augment node.
+ YangAugment augment = (YangAugment) refNode.getChild();
+
+ YangLeaf test;
+ YangLeaf networkId;
+ YangLeaf networkRef;
+
+ leafItr = augment.getListOfLeaf().listIterator();
+ test = leafItr.next();
+
+ YangLeafRef<?> leafRef =
+ (YangLeafRef) test.getDataType().getDataTypeExtendedInfo();
+ pathItr = leafRef.getAtomicPath().listIterator();
+ pathItr.next();
+ atomicPath = pathItr.next();
+
+ // Gets the path-predicate.
+ predicateItr = atomicPath.getPathPredicatesList().listIterator();
+ predicate = predicateItr.next();
+
+ // Gets the left and right axis node in path-predicate.
+ YangLeaf yangLeftLeaf = (YangLeaf) predicate.getLeftAxisNode();
+ YangLeaf yangRightLeaf = (YangLeaf) predicate.getRightAxisNode();
+
+ leafItr = list.getListOfLeaf().listIterator();
+ networkId = leafItr.next();
+ YangContainer reference = (YangContainer) list.getChild();
+ leafItr = reference.getListOfLeaf().listIterator();
+ networkRef = leafItr.next();
+
+ // Checks that right and left path-predicates are correct.
+ assertThat(yangLeftLeaf, is(networkId));
+ assertThat(yangRightLeaf, is(networkRef));
+ }
+
+ /**
+ * Processes an invalid scenario where the target leaf/leaf-list in
+ * path-predicate is not found.
+ *
+ * @throws IOException if violates IO operation
+ */
+ @Test
+ public void processInvalidPathLink() throws IOException {
+ thrown.expect(LinkerException.class);
+ thrown.expectMessage(
+ "YANG file error: There is no leaf/leaf-list in YANG node as " +
+ "mentioned in the path predicate of the leafref path " +
+ "../../interface[ifname = current()/../../ifname]" +
+ "/address/ip");
+
+ utilMgr.createYangFileInfoSet(getYangFiles(DIR + "invalidlinking"));
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+
+ linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+ linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+ updateFilePriority(utilMgr.getYangNodeSet());
+
+ linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+ }
+
+ /**
+ * Processes an invalid scenario where the right axis node doesn't come
+ * under YANG list node.
+ *
+ * @throws IOException if violates IO operation
+ */
+ @Test
+ public void processInvalidPathLinkForList() throws IOException {
+ thrown.expect(LinkerException.class);
+ thrown.expectMessage(
+ "YANG file error: Path predicates are only applicable for " +
+ "YANG list. The leafref path has path predicate for" +
+ " non-list node in the path ../../default-address" +
+ "[ifname = current()/../ifname]/ifname");
+
+ utilMgr.createYangFileInfoSet(getYangFiles(DIR + "invalidlinking2"));
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+
+ linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+ linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+ updateFilePriority(utilMgr.getYangNodeSet());
+
+ linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+ }
+
+ /**
+ * Processes an invalid scenario where the node in path predicate is not
+ * present in the traversal.
+ *
+ * @throws IOException if violates IO operation
+ */
+ @Test
+ public void processInvalidPathLinkForInvalidNode()
+ throws IOException {
+ thrown.expect(LinkerException.class);
+ thrown.expectMessage(
+ "YANG file error: The path predicate of the leafref has an " +
+ "invalid path in ../../interface[name = current()/" +
+ "../../address/ifname]/address/ip");
+
+ utilMgr.createYangFileInfoSet(getYangFiles(DIR + "invalidlinking3"));
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+
+ linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+ linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+ updateFilePriority(utilMgr.getYangNodeSet());
+
+ linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+ }
+}
diff --git a/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-network.yang
new file mode 100644
index 0000000..8e650da
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-network.yang
@@ -0,0 +1,21 @@
+module ietf-network {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+ prefix nd;
+ container networks {
+ list network {
+ key "network-id";
+ leaf network-id {
+ type uint8;
+ }
+ container reference {
+ leaf network-ref {
+ type string;
+ }
+ }
+ leaf node-id {
+ type int8;
+ }
+ }
+ }
+}
diff --git a/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-topology.yang b/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-topology.yang
new file mode 100644
index 0000000..93bfa80
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-topology.yang
@@ -0,0 +1,18 @@
+module ietf-topology {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-te-topology";
+ // replace with IANA namespace when assigned
+ prefix "tet";
+
+ import ietf-network {
+ prefix "nw";
+ }
+ augment "/nw:networks/nw:network" {
+ leaf test {
+ type leafref {
+ path "../../nw:network[nw:network-id = current()/../" +
+ "nw:reference/nw:network-ref]/nw:node-id";
+ }
+ }
+ }
+}
diff --git a/plugin/maven/src/test/resources/pathpredicate/invalidlinking/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/invalidlinking/ietf-network.yang
new file mode 100644
index 0000000..13bcb3e
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/invalidlinking/ietf-network.yang
@@ -0,0 +1,33 @@
+module ietf-network {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+ prefix nd;
+ list interface {
+ key "name";
+ leaf name {
+ type string;
+ }
+ leaf admin-status {
+ type uint8;
+ }
+ list address {
+ key "ip";
+ leaf ip {
+ type int8;
+ }
+ }
+ }
+ container default-address {
+ leaf ifname {
+ type leafref {
+ path "../../interface/name";
+ }
+ }
+ leaf address {
+ type leafref {
+ path "../../interface[ifname = current()/../../ifname]"
+ + "/address/ip";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugin/maven/src/test/resources/pathpredicate/invalidlinking2/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/invalidlinking2/ietf-network.yang
new file mode 100644
index 0000000..7c1881b
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/invalidlinking2/ietf-network.yang
@@ -0,0 +1,33 @@
+module ietf-network {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+ prefix nd;
+ list interface {
+ key "name";
+ leaf name {
+ type string;
+ }
+ leaf admin-status {
+ type uint8;
+ }
+ list address {
+ key "ip";
+ leaf ip {
+ type int8;
+ }
+ }
+ }
+ container default-address {
+ leaf ifname {
+ type leafref {
+ path "../../interface/name";
+ }
+ }
+ leaf address {
+ type leafref {
+ path "../../default-address[ifname = current()/../ifname]/" +
+ "ifname";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugin/maven/src/test/resources/pathpredicate/invalidlinking3/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/invalidlinking3/ietf-network.yang
new file mode 100644
index 0000000..9ebb2ce
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/invalidlinking3/ietf-network.yang
@@ -0,0 +1,33 @@
+module ietf-network {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+ prefix nd;
+ list interface {
+ key "name";
+ leaf name {
+ type string;
+ }
+ leaf admin-status {
+ type uint8;
+ }
+ list address {
+ key "ip";
+ leaf ip {
+ type int8;
+ }
+ }
+ }
+ container default-address {
+ leaf ifname {
+ type leafref {
+ path "../../interface/name";
+ }
+ }
+ leaf address {
+ type leafref {
+ path "../../interface[name = current()/../../address/ifname]"
+ + "/address/ip";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugin/maven/src/test/resources/pathpredicate/simple/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/simple/ietf-network.yang
new file mode 100644
index 0000000..5c1ecdd
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/simple/ietf-network.yang
@@ -0,0 +1,33 @@
+module ietf-network {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+ prefix nd;
+ list interface {
+ key "name";
+ leaf name {
+ type string;
+ }
+ leaf admin-status {
+ type uint8;
+ }
+ list address {
+ key "ip";
+ leaf ip {
+ type int8;
+ }
+ }
+ }
+ container default-address {
+ leaf ifname {
+ type leafref {
+ path "../../interface/name";
+ }
+ }
+ leaf address {
+ type leafref {
+ path "../../interface[name = current()/../ifname]"
+ + "/address/ip";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-network.yang
new file mode 100644
index 0000000..33d77dd
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-network.yang
@@ -0,0 +1,22 @@
+module ietf-network {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+ prefix nd;
+ import ietf-topology {
+ prefix tp;
+ }
+ container default-address {
+ leaf ifname {
+ type leafref {
+ path "/tp:interface/tp:name";
+ }
+ }
+ leaf address {
+ type leafref {
+ path "/tp:interface[tp:name = current()/../nd:ifname]"
+ + "/tp:address/ip";
+ }
+ }
+ }
+}
+
diff --git a/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-topology.yang b/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-topology.yang
new file mode 100644
index 0000000..63db761
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-topology.yang
@@ -0,0 +1,21 @@
+ module ietf-topology {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-topology";
+ prefix tp;
+ list interface {
+ key "name";
+ leaf name {
+ type string;
+ }
+ leaf admin-status {
+ type uint8;
+ }
+ list address {
+ key "ip";
+ leaf ip {
+ type int8;
+ }
+ }
+ }
+ }
+