YANG uses and UT
Change-Id: Id3ec5cfed2b8e2a7d2d580786c70b5804f03ecfa
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
index 0413e653..ae29433 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
@@ -16,6 +16,7 @@
package org.onosproject.yangutils.datamodel;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.translator.tojava.TraversalType;
import static org.onosproject.yangutils.translator.tojava.TraversalType.CHILD;
@@ -281,9 +282,11 @@
if (nextNodeToClone == null) {
throw new DataModelException("Internal error: Cloning failed, source tree null pointer reached");
}
-
- if (curTraversal == CHILD) {
+ if (curTraversal != PARENT) {
newNode = nextNodeToClone.clone();
+ detectCollisionWhileCloning(clonedTreeCurNode, newNode, curTraversal);
+ }
+ if (curTraversal == CHILD) {
/**
* add the new node to the cloned tree.
@@ -295,7 +298,6 @@
*/
clonedTreeCurNode = newNode;
} else if (curTraversal == SIBILING) {
- newNode = nextNodeToClone.clone();
clonedTreeCurNode.addNextSibling(newNode);
clonedTreeCurNode = newNode;
@@ -328,6 +330,38 @@
}
/**
+ * Detects collision when the grouping is deep copied to the uses's parent.
+ *
+ * @param currentNode parent/previous sibling node for the new node
+ * @param newNode node which has to be added
+ * @param addAs traversal type of the node
+ * @throws DataModelException data model error
+ */
+ private static void detectCollisionWhileCloning(YangNode currentNode, YangNode newNode, TraversalType addAs)
+ throws DataModelException {
+ if ((!(currentNode instanceof CollisionDetector))
+ || (!(newNode instanceof Parsable))) {
+ throw new DataModelException("Node in data model tree does not support collision detection");
+ }
+
+ CollisionDetector collisionDetector = (CollisionDetector) currentNode;
+ Parsable parsable = (Parsable) newNode;
+ if (addAs == TraversalType.CHILD) {
+ collisionDetector.detectCollidingChild(newNode.getName(), parsable.getYangConstructType());
+ } else if (addAs == TraversalType.SIBILING) {
+ currentNode = currentNode.getParent();
+ if (!(currentNode instanceof CollisionDetector)) {
+ throw new DataModelException("Node in data model tree does not support collision detection");
+ }
+ collisionDetector = (CollisionDetector) currentNode;
+ collisionDetector.detectCollidingChild(newNode.getName(), parsable.getYangConstructType());
+ } else {
+ throw new DataModelException("Errored tree cloning");
+ }
+
+ }
+
+ /**
* Add a new next sibling.
*
* @param newSibling new sibling to be added
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
index 7f9b4a3..16f45c4 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
@@ -19,6 +19,7 @@
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.utils.YangConstructType;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getParentNodeInGenCode;
/*-
@@ -56,7 +57,7 @@
*/
public class YangUses
extends YangNode
- implements YangCommonInfo, Parsable, Resolvable {
+ implements YangCommonInfo, Parsable, Resolvable, CollisionDetector {
/**
* YANG node identifier.
@@ -267,18 +268,23 @@
}
YangNode usesParentNode = getParentNodeInGenCode(this);
- if (!(usesParentNode instanceof YangLeavesHolder)) {
+ if ((!(usesParentNode instanceof YangLeavesHolder))
+ || (!(usesParentNode instanceof CollisionDetector))) {
throw new DataModelException("YANG uses holder construct is wrong");
}
YangLeavesHolder usesParentLeavesHolder = (YangLeavesHolder) usesParentNode;
if (referredGrouping.getListOfLeaf() != null) {
for (YangLeaf leaf : referredGrouping.getListOfLeaf()) {
+ ((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leaf.getLeafName(),
+ YangConstructType.LEAF_DATA);
usesParentLeavesHolder.addLeaf(leaf);
}
}
if (referredGrouping.getListOfLeafList() != null) {
for (YangLeafList leafList : referredGrouping.getListOfLeafList()) {
+ ((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leafList.getLeafName(),
+ YangConstructType.LEAF_LIST_DATA);
usesParentLeavesHolder.addLeafList(leafList);
}
}
@@ -295,4 +301,19 @@
public void setResolvableStatus(ResolvableStatus resolvableStatus) {
this.resolvableStatus = resolvableStatus;
}
+
+ @Override
+ public void detectCollidingChild(String identifierName, YangConstructType dataType) throws DataModelException {
+ detectCollidingChildUtil(identifierName, dataType, this);
+ }
+
+ @Override
+ public void detectSelfCollision(String identifierName, YangConstructType dataType) throws DataModelException {
+
+ if (getName().equals(identifierName)) {
+ throw new DataModelException("YANG file error: Duplicate input identifier detected, same as uses \""
+ + getName() + "\"");
+ }
+ }
+
}
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
index 643eda5..e848299 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
@@ -27,9 +27,9 @@
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangResolutionInfo;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.utils.YangConstructType;
-
/**
* Represents utilities for data model tree.
*/
@@ -53,21 +53,44 @@
public static void detectCollidingChildUtil(String identifierName, YangConstructType dataType, YangNode node)
throws DataModelException {
- if (dataType == YangConstructType.LEAF_DATA) {
- YangLeavesHolder leavesHolder = (YangLeavesHolder) node;
- if (leavesHolder.getListOfLeaf() != null) {
- detectCollidingLeaf(leavesHolder, identifierName);
- }
- }
- if (dataType == YangConstructType.LEAF_LIST_DATA) {
- if (((YangLeavesHolder) node).getListOfLeafList() != null) {
+ if (dataType == YangConstructType.USES_DATA || dataType == YangConstructType.GROUPING_DATA) {
+ detectCollidingForUsesGrouping(identifierName, dataType, node);
+ } else {
+ if (node instanceof YangLeavesHolder) {
YangLeavesHolder leavesHolder = (YangLeavesHolder) node;
- detectCollidingLeafList(leavesHolder, identifierName);
+ detectCollidingLeaf(leavesHolder.getListOfLeaf(), identifierName);
+ detectCollidingLeafList(leavesHolder.getListOfLeafList(), identifierName);
+ }
+ node = node.getChild();
+ while (node != null) {
+ Parsable parsable = (Parsable) node;
+ if (node instanceof CollisionDetector
+ && (parsable.getYangConstructType() != YangConstructType.USES_DATA)
+ && (parsable.getYangConstructType() != YangConstructType.GROUPING_DATA)) {
+ ((CollisionDetector) node).detectSelfCollision(identifierName, dataType);
+ }
+ node = node.getNextSibling();
}
}
+ }
+
+ /**
+ * Detects colliding of uses and grouping only with uses and grouping respectively.
+ *
+ * @param identifierName name for which collision detection is to be
+ * checked
+ * @param dataType type of YANG node asking for detecting collision
+ * @param node node instance of calling node
+ * @throws DataModelException a violation of data model rules
+ */
+ public static void detectCollidingForUsesGrouping(String identifierName, YangConstructType dataType, YangNode node)
+ throws DataModelException {
+
node = node.getChild();
while (node != null) {
- if (node instanceof CollisionDetector) {
+ Parsable parsable = (Parsable) node;
+ if (node instanceof CollisionDetector
+ && (parsable.getYangConstructType() == dataType)) {
((CollisionDetector) node).detectSelfCollision(identifierName, dataType);
}
node = node.getNextSibling();
@@ -77,15 +100,18 @@
/**
* Detects the colliding identifier name in a given leaf node.
*
- * @param leavesHolder leaves node against which collision to be checked
+ * @param listOfLeaf List of leaves to detect collision
* @param identifierName name for which collision detection is to be
* checked
* @throws DataModelException a violation of data model rules
*/
- private static void detectCollidingLeaf(YangLeavesHolder leavesHolder, String identifierName)
+ private static void detectCollidingLeaf(List<YangLeaf> listOfLeaf, String identifierName)
throws DataModelException {
- for (YangLeaf leaf : leavesHolder.getListOfLeaf()) {
+ if (listOfLeaf == null) {
+ return;
+ }
+ for (YangLeaf leaf : listOfLeaf) {
if (leaf.getLeafName().equals(identifierName)) {
throw new DataModelException("YANG file error: Duplicate input identifier detected, same as leaf \""
+ leaf.getLeafName() + "\"");
@@ -96,15 +122,18 @@
/**
* Detects the colliding identifier name in a given leaf-list node.
*
- * @param leavesHolder leaves node against which collision to be checked
+ * @param listOfLeafList list of leaf-lists to detect collision
* @param identifierName name for which collision detection is to be
* checked
* @throws DataModelException a violation of data model rules
*/
- private static void detectCollidingLeafList(YangLeavesHolder leavesHolder, String identifierName)
+ private static void detectCollidingLeafList(List<YangLeafList> listOfLeafList, String identifierName)
throws DataModelException {
- for (YangLeafList leafList : leavesHolder.getListOfLeafList()) {
+ if (listOfLeafList == null) {
+ return;
+ }
+ for (YangLeafList leafList : listOfLeafList) {
if (leafList.getLeafName().equals(identifierName)) {
throw new DataModelException("YANG file error: Duplicate input identifier detected, same as leaf " +
"list \"" + leafList.getLeafName() + "\"");
@@ -122,8 +151,6 @@
public static void addResolutionInfo(YangResolutionInfo resolutionInfo)
throws DataModelException {
-
-
/* get the module node to add maintain the list of nested reference */
YangNode curNode = resolutionInfo.getEntityToResolveInfo()
.getHolderOfEntityToResolve();
@@ -142,6 +169,13 @@
resolutionNode.addToResolutionList(resolutionInfo);
}
+ /**
+ * Evaluates whether the prefix in uses/type is valid.
+ *
+ * @param entityPrefix prefix in the current module/sub-module
+ * @param resolutionNode uses/type node which has the prefix with it
+ * @return whether prefix is valid or not
+ */
private static boolean isPrefixValid(String entityPrefix, HasResolutionInfo resolutionNode) {
if (entityPrefix == null) {
return true;