[ONOS-5402] Resolvable entities under union type, is added to list, after cloning.
Change-Id: Ia96959b3e65e12060926c7f15d170b5e7302fa43
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
index 6458e93..92af172 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
@@ -15,15 +15,17 @@
*/
package org.onosproject.yangutils.datamodel;
-import java.io.Serializable;
-import java.util.Map;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
+import java.io.Serializable;
+import java.util.Map;
+
import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
-import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.cloneLeaves;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.cloneListOfLeaf;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.cloneListOfLeafList;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.updateClonedLeavesUnionEnumRef;
/**
@@ -400,7 +402,8 @@
clonedNode.referredSchemaNode = this;
if (clonedNode instanceof YangLeavesHolder) {
try {
- cloneLeaves((YangLeavesHolder) clonedNode, yangUses);
+ cloneListOfLeaf((YangLeavesHolder) clonedNode, yangUses);
+ cloneListOfLeafList((YangLeavesHolder) clonedNode, yangUses);
} catch (DataModelException e) {
throw new CloneNotSupportedException(e.getMessage());
}
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
index d358fdb..6143483 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
@@ -33,10 +33,9 @@
import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.COLLISION_DETECTION;
import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.USES;
import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.getErrorMsgCollision;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addUnresolvedType;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.getParentNodeInGenCode;
-import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveYangConstructsUnderGroupingForLeaf;
-import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveYangConstructsUnderGroupingForLeafList;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.updateClonedLeavesUnionEnumRef;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
@@ -180,13 +179,14 @@
* @param entityToResolve entity to resolved
* @throws DataModelException a violation of data model rules
*/
- public void addEntityToResolve(YangEntityToResolveInfoImpl entityToResolve)
+ public void addEntityToResolve(
+ List<YangEntityToResolveInfoImpl> entityToResolve)
throws DataModelException {
if (entityToResolveInfoList == null) {
entityToResolveInfoList = new
LinkedList<>();
}
- entityToResolveInfoList.add(entityToResolve);
+ entityToResolveInfoList.addAll(entityToResolve);
}
/**
@@ -387,52 +387,39 @@
" in " + getFileName() + "\"");
}
- YangLeavesHolder usesParentLeavesHolder = (YangLeavesHolder) usesParentNode;
+ YangLeavesHolder usesParent = (YangLeavesHolder) usesParentNode;
if (referredGrouping.getListOfLeaf() != null) {
for (YangLeaf leaf : referredGrouping.getListOfLeaf()) {
YangLeaf clonedLeaf;
try {
- ((CollisionDetector) usesParentLeavesHolder)
+ ((CollisionDetector) usesParent)
.detectCollidingChild(leaf.getName(), LEAF_DATA);
clonedLeaf = leaf.clone();
clonedLeaf.setReferredLeaf(leaf);
- if (getCurrentGroupingDepth() == 0) {
- YangEntityToResolveInfoImpl resolveInfo
- = resolveYangConstructsUnderGroupingForLeaf(
- clonedLeaf, usesParentLeavesHolder, this);
- if (resolveInfo != null) {
- addEntityToResolve(resolveInfo);
- }
- }
+ addUnresolvedType(this, clonedLeaf, (YangNode) usesParent);
} catch (CloneNotSupportedException | DataModelException e) {
throw new DataModelException(e.getMessage());
}
- clonedLeaf.setContainedIn(usesParentLeavesHolder);
- usesParentLeavesHolder.addLeaf(clonedLeaf);
+ clonedLeaf.setContainedIn(usesParent);
+ usesParent.addLeaf(clonedLeaf);
}
}
if (referredGrouping.getListOfLeafList() != null) {
for (YangLeafList leafList : referredGrouping.getListOfLeafList()) {
YangLeafList clonedLeafList;
try {
- ((CollisionDetector) usesParentLeavesHolder)
+ ((CollisionDetector) usesParent)
.detectCollidingChild(leafList.getName(), LEAF_LIST_DATA);
clonedLeafList = leafList.clone();
clonedLeafList.setReferredSchemaLeafList(leafList);
- if (getCurrentGroupingDepth() == 0) {
- YangEntityToResolveInfoImpl resolveInfo =
- resolveYangConstructsUnderGroupingForLeafList(
- clonedLeafList, usesParentLeavesHolder, this);
- if (resolveInfo != null) {
- addEntityToResolve(resolveInfo);
- }
- }
+ addUnresolvedType(this, clonedLeafList,
+ (YangNode) usesParent);
} catch (CloneNotSupportedException | DataModelException e) {
throw new DataModelException(e.getMessage());
}
- clonedLeafList.setContainedIn(usesParentLeavesHolder);
- usesParentLeavesHolder.addLeafList(clonedLeafList);
+ clonedLeafList.setContainedIn(usesParent);
+ usesParent.addLeafList(clonedLeafList);
}
}
@@ -441,7 +428,7 @@
} catch (DataModelException e) {
throw new DataModelException(e.getMessage());
}
- updateClonedLeavesUnionEnumRef(usesParentLeavesHolder);
+ updateClonedLeavesUnionEnumRef(usesParent);
return unmodifiableList(entityToResolveInfoList);
}
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 58a1caf..411e88e 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
@@ -16,22 +16,6 @@
package org.onosproject.yangutils.datamodel.utils;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
import org.onosproject.yangutils.datamodel.CollisionDetector;
import org.onosproject.yangutils.datamodel.ResolvableType;
import org.onosproject.yangutils.datamodel.YangAtomicPath;
@@ -58,6 +42,22 @@
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
/**
* Represents utilities for data model tree.
*/
@@ -337,195 +337,306 @@
}
/**
- * Clones the list of leaves and list of leaf list in the leaves holder.
+ * Adds the list of leaf present under a node to resolution list, after
+ * cloning. Under the cloned node, with cloned leaf, attributes are set
+ * and added to resolution list.
*
- * @param leavesHolder YANG node potentially containing leaves or leaf lists
- * @param yangUses instance of YANG uses
- * @throws CloneNotSupportedException clone is not supported
+ * @param clonedNode holder node
+ * @param yangUses YANG uses
+ * @throws CloneNotSupportedException clone not supported error
* @throws DataModelException data model error
*/
- public static void cloneLeaves(YangLeavesHolder leavesHolder, YangUses yangUses)
+ public static void cloneListOfLeaf(
+ YangLeavesHolder clonedNode, YangUses yangUses)
throws CloneNotSupportedException, DataModelException {
- List<YangLeaf> currentListOfLeaves = leavesHolder.getListOfLeaf();
- if (currentListOfLeaves != null) {
- List<YangLeaf> clonedLeavesList = new LinkedList<>();
- for (YangLeaf leaf : currentListOfLeaves) {
+
+ List<YangLeaf> leaves = clonedNode.getListOfLeaf();
+ if (isListPresent(leaves)) {
+ List<YangLeaf> clonedLeaves = new LinkedList<>();
+ for (YangLeaf leaf : leaves) {
YangLeaf clonedLeaf = leaf.clone();
clonedLeaf.setReferredLeaf(leaf);
- if (yangUses != null && yangUses.getCurrentGroupingDepth() == 0) {
- YangEntityToResolveInfoImpl resolveInfo =
- resolveYangConstructsUnderGroupingForLeaf(clonedLeaf, leavesHolder, yangUses);
- if (resolveInfo != null) {
- yangUses.addEntityToResolve(resolveInfo);
- }
- }
- clonedLeaf.setContainedIn(leavesHolder);
- clonedLeavesList.add(clonedLeaf);
+ addUnresolvedType(yangUses, clonedLeaf, (YangNode) clonedNode);
+ clonedLeaf.setContainedIn(clonedNode);
+ clonedLeaves.add(clonedLeaf);
}
- leavesHolder.setListOfLeaf(clonedLeavesList);
+ clonedNode.setListOfLeaf(clonedLeaves);
}
+ }
- List<YangLeafList> currentListOfLeafList = leavesHolder.getListOfLeafList();
- if (currentListOfLeafList != null) {
- List<YangLeafList> clonedListOfLeafList = new LinkedList<>();
- for (YangLeafList leafList : currentListOfLeafList) {
+ /**
+ * Adds all the unresolved type under leaf/leaf-list to the resolution
+ * list, after cloning. This makes the resolution to happen after cloning
+ * of the grouping. Adds resolution with cloned node holder under which
+ * cloned type is present.
+ *
+ * @param yangUses YANG uses
+ * @param clonedObj cloned type object
+ * @param clonedNode holder node
+ * @throws DataModelException data model error
+ */
+ public static void addUnresolvedType(
+ YangUses yangUses, Object clonedObj,
+ YangNode clonedNode) throws DataModelException {
+
+ List<YangEntityToResolveInfoImpl> infoList;
+ if (yangUses != null && yangUses.getCurrentGroupingDepth() == 0) {
+ infoList = getTypesToBeResolved(clonedObj, clonedNode, yangUses);
+ if (isListPresent(infoList)) {
+ yangUses.addEntityToResolve(infoList);
+ }
+ }
+ }
+
+ /**
+ * Returns true if list 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
+ */
+ private static boolean isListPresent(List listObj) {
+ return listObj != null && !listObj.isEmpty();
+ }
+
+ /**
+ * Adds the list of leaf-list present under a node to resolution list,
+ * after cloning. Under the cloned node, with cloned leaf-list,
+ * attributes are set and added to resolution list.
+ *
+ * @param clonedNode cloned holder
+ * @param yangUses YANG uses
+ * @throws CloneNotSupportedException clone not supported error
+ * @throws DataModelException data model error
+ */
+ public static void cloneListOfLeafList(
+ YangLeavesHolder clonedNode, YangUses yangUses)
+ throws CloneNotSupportedException, DataModelException {
+
+ List<YangLeafList> listOfLeafList = clonedNode.getListOfLeafList();
+ if (isListPresent(listOfLeafList)) {
+ List<YangLeafList> clonedList = new LinkedList<>();
+ for (YangLeafList leafList : listOfLeafList) {
YangLeafList clonedLeafList = leafList.clone();
clonedLeafList.setReferredSchemaLeafList(leafList);
- if (yangUses != null && yangUses.getCurrentGroupingDepth() == 0) {
- YangEntityToResolveInfoImpl resolveInfo =
- resolveYangConstructsUnderGroupingForLeafList(clonedLeafList, leavesHolder,
- yangUses);
- if (resolveInfo != null) {
- yangUses.addEntityToResolve(resolveInfo);
- }
- }
- clonedLeafList.setContainedIn(leavesHolder);
- clonedListOfLeafList.add(clonedLeafList);
+ addUnresolvedType(yangUses, clonedLeafList,
+ (YangNode) clonedNode);
+ clonedLeafList.setContainedIn(clonedNode);
+ clonedList.add(clonedLeafList);
}
- leavesHolder.setListOfLeafList(clonedListOfLeafList);
+ clonedNode.setListOfLeafList(clonedList);
}
}
/**
- * Resolves leafref in leaf, which are under grouping by adding it to the resolution list.
+ * Returns types that has to be resolved for a single leaf/leaf-list.
+ * Identifies the object to be leaf/leaf-list and assigns respective
+ * parameters to resolve the types under leaf/leaf-list.
*
- * @param clonedLeaf cloned leaf in uses from grouping
- * @param leafParentHolder holder of the leaf from uses
- * @param yangUses YANG uses
- * @return entity of leafref which has to be resolved
+ * @param clonedObj leaf/leaf-list object
+ * @param holderNode holder node
+ * @param yangUses YANG uses
+ * @return list of resolvable entities in a leaf/leaf-list
* @throws DataModelException data model error
*/
- public static YangEntityToResolveInfoImpl resolveLeafrefUnderGroupingForLeaf(YangLeaf clonedLeaf,
- YangLeavesHolder leafParentHolder, YangUses yangUses)
- throws
- DataModelException {
- if (clonedLeaf.getDataType().getDataTypeExtendedInfo() instanceof YangLeafRef) {
- YangLeafRef leafrefForCloning = (YangLeafRef) clonedLeaf.getDataType().getDataTypeExtendedInfo();
- // Conversion of prefixes in absolute path while cloning them.
- convertThePrefixesDuringChange(leafrefForCloning, yangUses);
- leafrefForCloning.setParentNodeOfLeafref((YangNode) leafParentHolder);
- YangEntityToResolveInfoImpl yangEntityToResolveInfo = new YangEntityToResolveInfoImpl();
- yangEntityToResolveInfo.setEntityToResolve(leafrefForCloning);
- yangEntityToResolveInfo.setHolderOfEntityToResolve((YangNode) leafParentHolder);
- yangEntityToResolveInfo.setLineNumber(leafrefForCloning.getLineNumber());
- yangEntityToResolveInfo.setCharPosition(leafrefForCloning.getCharPosition());
- return yangEntityToResolveInfo;
+ private static List<YangEntityToResolveInfoImpl> getTypesToBeResolved(
+ Object clonedObj, YangNode holderNode,
+ YangUses yangUses) throws DataModelException {
+
+ YangType type;
+ if (clonedObj instanceof YangLeaf) {
+ YangLeaf clonedLeaf = (YangLeaf) clonedObj;
+ type = clonedLeaf.getDataType();
+ return getUnresolvedTypeList(type.getDataType(), type, holderNode,
+ yangUses, true);
}
- return null;
+ YangLeafList clonedLeafList = (YangLeafList) clonedObj;
+ type = clonedLeafList.getDataType();
+ return getUnresolvedTypeList(type.getDataType(), type, holderNode,
+ yangUses, false);
}
/**
- * Resolves leafRef, identityRef and derived type in leaf, which are under grouping by adding it to the resolution
- * list.
+ * Returns list of resolvable entities from the type of leaf/leaf-list.
+ * If the type is leaf-ref, identity-ref, derived or union with type
+ * resolution required, it has to be resolved from the place where it is
+ * cloned. So, the resolution list added with these entities. When a type
+ * require no resolution then null is returned, so it will never be added
+ * to resolution list.
*
- * @param clonedLeaf cloned leaf in uses from grouping
- * @param leafParentHolder holder of the leaf from uses
- * @param yangUses YANG uses
- * @return entity of leafRef/identityRef/derived type which has to be resolved
+ * @param dataTypes data type of type
+ * @param type type of leaf/leaf-list
+ * @param holder holder node of type
+ * @param yangUses YANG uses
+ * @param isLeaf leaf or leaf-list
+ * @return list of resolvable entities for a leaf/leaf-list.
* @throws DataModelException data model error
*/
- public static YangEntityToResolveInfoImpl resolveYangConstructsUnderGroupingForLeaf(YangLeaf clonedLeaf,
- YangLeavesHolder leafParentHolder, YangUses yangUses)
- throws DataModelException {
- int lineNumber;
- int charPosition;
- YangDataTypes dataTypes = clonedLeaf.getDataType().getDataType();
- YangEntityToResolveInfoImpl yangEntityToResolveInfo = new YangEntityToResolveInfoImpl();
+ private static List<YangEntityToResolveInfoImpl> getUnresolvedTypeList(
+ YangDataTypes dataTypes, YangType type, YangNode holder,
+ YangUses yangUses, boolean isLeaf) throws DataModelException {
+
+ List<YangEntityToResolveInfoImpl> infoList = new ArrayList<>();
+ YangEntityToResolveInfoImpl entity = null;
+ List<YangEntityToResolveInfoImpl> entityList = null;
switch (dataTypes) {
case LEAFREF:
- YangLeafRef leafRefForCloning = (YangLeafRef) clonedLeaf.getDataType().getDataTypeExtendedInfo();
- // Conversion of prefixes in absolute path while cloning them.
- convertThePrefixesDuringChange(leafRefForCloning, yangUses);
- leafRefForCloning.setParentNodeOfLeafref((YangNode) leafParentHolder);
- yangEntityToResolveInfo.setEntityToResolve(leafRefForCloning);
- lineNumber = leafRefForCloning.getCharPosition();
- charPosition = leafRefForCloning.getLineNumber();
+ entity = getLeafRefResolvableEntity(type, yangUses, holder);
break;
case IDENTITYREF:
- YangIdentityRef identityRef = (YangIdentityRef) clonedLeaf.getDataType().getDataTypeExtendedInfo();
- if (identityRef.isIdentityForInterFileGroupingResolution()) {
- return null;
- }
- yangEntityToResolveInfo.setEntityToResolve(identityRef);
- lineNumber = identityRef.getCharPosition();
- charPosition = identityRef.getLineNumber();
+ entity = getIdentityRefResolvableEntity(type, holder);
break;
case DERIVED:
- YangType type = clonedLeaf.getDataType();
- if (type.isTypeForInterFileGroupingResolution()) {
- return null;
- }
- yangEntityToResolveInfo.setEntityToResolve(type);
- lineNumber = type.getCharPosition();
- charPosition = type.getLineNumber();
+ entity = getDerivedResolvableEntity(type, holder, isLeaf);
+ break;
+
+ case UNION:
+ entityList = getUnionResolvableEntity(type, isLeaf);
break;
default:
return null;
}
-
- yangEntityToResolveInfo.setHolderOfEntityToResolve((YangNode) leafParentHolder);
- yangEntityToResolveInfo.setCharPosition(charPosition);
- yangEntityToResolveInfo.setLineNumber(lineNumber);
- return yangEntityToResolveInfo;
+ infoList.add(entity);
+ if (isListPresent(entityList)) {
+ infoList.addAll(entityList);
+ }
+ return infoList;
}
/**
- * Resolves leafRef, identityRef and derived type in leaf-list, which are under grouping by adding it to the
- * resolution list.
+ * Returns resolvable entity when the type is leaf-ref. It changes the
+ * prefixes from grouping to uses, then changes the parent node to the
+ * cloned node, sets needed information to entity such as line number,
+ * position number and holder.
*
- * @param clonedLeafList cloned leaf-list in uses from grouping
- * @param leafParentHolder holder of the leaf from uses
- * @param yangUses YANG uses
- * @return entity of leafRef/identityRef/derived type which has to be resolved
+ * @param type YANG type of leaf-ref
+ * @param yangUses YANG uses
+ * @param holder cloned holder
+ * @return entity to resolve for leaf-ref
* @throws DataModelException data model error
*/
- public static YangEntityToResolveInfoImpl resolveYangConstructsUnderGroupingForLeafList(
- YangLeafList clonedLeafList, YangLeavesHolder leafParentHolder, YangUses yangUses)
+ private static YangEntityToResolveInfoImpl getLeafRefResolvableEntity(
+ YangType type, YangUses yangUses, YangNode holder)
throws DataModelException {
- int lineNumber;
- int charPosition;
- YangDataTypes dataTypes = clonedLeafList.getDataType().getDataType();
- YangEntityToResolveInfoImpl yangEntityToResolveInfo = new YangEntityToResolveInfoImpl();
- switch (dataTypes) {
- case LEAFREF:
- YangLeafRef leafRefForCloning = (YangLeafRef) clonedLeafList.getDataType().getDataTypeExtendedInfo();
- // Conversion of prefixes in absolute path while cloning them.
- convertThePrefixesDuringChange(leafRefForCloning, yangUses);
- leafRefForCloning.setParentNodeOfLeafref((YangNode) leafParentHolder);
- yangEntityToResolveInfo.setEntityToResolve(leafRefForCloning);
- lineNumber = leafRefForCloning.getCharPosition();
- charPosition = leafRefForCloning.getLineNumber();
- break;
- case IDENTITYREF:
- YangIdentityRef identityRef = (YangIdentityRef) clonedLeafList.getDataType().getDataTypeExtendedInfo();
- if (identityRef.isIdentityForInterFileGroupingResolution()) {
- return null;
- }
- yangEntityToResolveInfo.setEntityToResolve(identityRef);
- lineNumber = identityRef.getCharPosition();
- charPosition = identityRef.getLineNumber();
- break;
- case DERIVED:
- YangType type = clonedLeafList.getDataType();
- if (type.isTypeForInterFileGroupingResolution() && type.isTypeNotResolvedTillRootNode()) {
- return null;
- }
- yangEntityToResolveInfo.setEntityToResolve(type);
- lineNumber = type.getCharPosition();
- charPosition = type.getLineNumber();
- break;
- default:
- return null;
+ YangEntityToResolveInfoImpl<YangLeafRef> leafRefInfo =
+ new YangEntityToResolveInfoImpl<>();
+ YangLeafRef leafRef = (YangLeafRef) type.getDataTypeExtendedInfo();
+
+ // Conversion of prefixes in absolute path while cloning them.
+ convertThePrefixesDuringChange(leafRef, yangUses);
+ leafRef.setParentNodeOfLeafref(holder);
+ leafRefInfo.setEntityToResolve(leafRef);
+
+ return setInformationInEntity(
+ leafRefInfo, holder, leafRef.getCharPosition(),
+ leafRef.getLineNumber());
+ }
+
+ /**
+ * Returns resolvable entity when the type is identity-ref. It sets needed
+ * information to entity such as line number,position number and holder.
+ * Returns null when identity is for inter grouping.
+ *
+ * @param type YANG type for identity-ref
+ * @param holder holder node
+ * @return entity to resolve for identity-ref
+ */
+ private static YangEntityToResolveInfoImpl getIdentityRefResolvableEntity(
+ YangType type, YangNode holder) {
+
+ YangEntityToResolveInfoImpl<YangIdentityRef> identityRefInfo =
+ new YangEntityToResolveInfoImpl<>();
+ YangIdentityRef identityRef =
+ (YangIdentityRef) type.getDataTypeExtendedInfo();
+
+ if (identityRef.isIdentityForInterFileGroupingResolution()) {
+ return null;
}
- yangEntityToResolveInfo.setHolderOfEntityToResolve((YangNode) leafParentHolder);
- yangEntityToResolveInfo.setCharPosition(charPosition);
- yangEntityToResolveInfo.setLineNumber(lineNumber);
- return yangEntityToResolveInfo;
+
+ identityRefInfo.setEntityToResolve(identityRef);
+ return setInformationInEntity(
+ identityRefInfo, holder, identityRef.getCharPosition(),
+ identityRef.getLineNumber());
+ }
+
+ /**
+ * Returns resolvable entity when the type is derived. It sets needed
+ * information to entity such as line number,position number and holder.
+ * Returns null when identity is for inter grouping.
+ *
+ * @param type derived YANG type
+ * @param holder holder node
+ * @param isLeaf leaf or leaf-list
+ * @return entity to resolve for derived type
+ */
+ private static YangEntityToResolveInfoImpl getDerivedResolvableEntity(
+ YangType<?> type, YangNode holder, boolean isLeaf) {
+
+ YangEntityToResolveInfoImpl<YangType<?>> derivedInfo =
+ new YangEntityToResolveInfoImpl<>();
+ if (type.isTypeForInterFileGroupingResolution()) {
+ return null;
+ }
+ if (!isLeaf && type.isTypeNotResolvedTillRootNode()) {
+ return null;
+ }
+
+ derivedInfo.setEntityToResolve(type);
+ return setInformationInEntity(
+ derivedInfo, holder, type.getCharPosition(),
+ type.getLineNumber());
+ }
+
+ /**
+ * Sets the information needed for adding the entity into resolution
+ * list, such as line number, position number and cloned holder node.
+ *
+ * @param entity resolvable entity
+ * @param holder cloned holder node
+ * @param charPos character position
+ * @param lineNum line number
+ * @return resolvable entity after setting info
+ */
+ private static YangEntityToResolveInfoImpl<?> setInformationInEntity(
+ YangEntityToResolveInfoImpl<?> entity, YangNode holder,
+ int charPos, int lineNum) {
+
+ entity.setHolderOfEntityToResolve(holder);
+ entity.setCharPosition(charPos);
+ entity.setLineNumber(lineNum);
+ return entity;
+ }
+
+ /**
+ * Returns resolvable entity under union. When types under union have
+ * identity-ref, derived and union, the function call is done recursively
+ * to get resolvable entity and adds it to list.
+ *
+ * @param type union YANG type
+ * @param isLeaf leaf or leaf-list
+ * @return resolvable entity list after setting info
+ * @throws DataModelException data model error
+ */
+ private static List<YangEntityToResolveInfoImpl> getUnionResolvableEntity(
+ YangType type, boolean isLeaf) throws DataModelException {
+
+ YangUnion union = (YangUnion) type.getDataTypeExtendedInfo();
+ List<YangType<?>> typeList = union.getTypeList();
+ List<YangEntityToResolveInfoImpl> unionList = new ArrayList<>();
+ List<YangEntityToResolveInfoImpl> entity;
+
+ for (YangType unionType : typeList) {
+ entity = getUnresolvedTypeList(unionType.getDataType(),
+ unionType, union, null, isLeaf);
+ if (isListPresent(entity)) {
+ unionList.addAll(entity);
+ }
+ }
+ return unionList;
}
/**
diff --git a/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java b/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java
new file mode 100644
index 0000000..038e991
--- /dev/null
+++ b/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/TypeLinkingAfterCloningTest.java
@@ -0,0 +1,616 @@
+/*
+ * 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.YangContainer;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
+import org.onosproject.yangutils.datamodel.YangIdentityRef;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafList;
+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.YangType;
+import org.onosproject.yangutils.datamodel.YangTypeDef;
+import org.onosproject.yangutils.datamodel.YangUnion;
+import org.onosproject.yangutils.linker.impl.YangLinkerManager;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+
+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.datamodel.YangNodeType.MODULE_NODE;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DERIVED;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.STRING;
+import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.updateFilePriority;
+import static org.onosproject.yangutils.utils.io.impl.YangFileScanner.getYangFiles;
+
+/**
+ * Test cases for type linking after cloning happens grouping.
+ */
+public class TypeLinkingAfterCloningTest {
+ private static final String MODULE = "module";
+ private static final String OPEN_ROAD = "org-open-road-m-device";
+ private static final String NODE_ID = "node-id";
+ private static final String LEAF = "leaf";
+ private static final String LEAF_LIST = "leaf-list";
+ private static final String NODE_REF = "node-ref";
+ private static final String FACILITY = "facility";
+ private static final String FACILITY_SYS_LOG = "syslog-facility";
+ private static final String USABILITY_SYS_LOG = "syslog-usability";
+ private static final String AVAILABILITY_SYS_LOG = "syslog-availability";
+ private static final String THIRD = "third";
+ private static final String SECOND = "second";
+ private static final String FIRST = "first";
+ private static final String TYPEDEF = "typedef";
+ private static final String CORRECT = "correct";
+
+ private final YangUtilManager utilMgr = new YangUtilManager();
+ private final YangLinkerManager linkerMgr = new YangLinkerManager();
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ /**
+ * Returns the error message as the node name incorrect, when assert fails.
+ *
+ * @param node YANG node
+ * @param nodeName node name
+ * @return error message as the name is incorrect
+ */
+ private static String getInCrtName(String node, Object nodeName) {
+ return getCapitalCase(node) + "'s name " + nodeName + " is incorrect.";
+ }
+
+ /**
+ * Returns the capital cased first letter of the given string.
+ *
+ * @param name string to be capital cased
+ * @return capital cased string
+ */
+ private static String getCapitalCase(String name) {
+ return name.substring(0, 1).toUpperCase() + name.substring(1);
+ }
+
+ /**
+ * Returns the error message as the node type incorrect, when assert fails.
+ *
+ * @param node YANG node
+ * @param nodeName node name
+ * @return error message as the type is incorrect
+ */
+ private static String getInCrtLeafType(String node, String nodeName) {
+ return "The " + node + " " + nodeName + " has incorrect data type.";
+ }
+
+ /**
+ * Returns the error message, stating the union and identity-ref level in
+ * the type, has not resolved to the referred identity.
+ *
+ * @param unionLvl union level in node
+ * @param idLvl identity-ref level in node
+ * @param baseName referred base
+ * @param node YANG node having type
+ * @param nodeName node name
+ * @return error message for incorrect identity-ref in union.
+ */
+ public static String getInCrtUnionWithIdRef(
+ String unionLvl, String idLvl, String baseName, String node,
+ String nodeName) {
+ return "The " + idLvl + " direct occurrence identity-ref in " +
+ unionLvl + " level union, of " + node + " " + nodeName +
+ " is not " + baseName;
+ }
+
+ /**
+ * Processes leaf-ref after its cloned to uses from grouping.
+ *
+ * @throws IOException io error when finding file
+ */
+ @Test
+ public void processLeafRefAfterCloning() throws IOException {
+
+ String searchDir = "src/test/resources/typelinkingaftercloning" +
+ "/leafref/intrafile";
+ utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ YangNode selfNode;
+
+ // Create YANG node set
+ linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+
+ // Add references to import list.
+ linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+ updateFilePriority(utilMgr.getYangNodeSet());
+
+ // Carry out inter-file linking.
+ linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+
+ Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+
+ selfNode = nodeItr.next();
+
+ ListIterator<YangLeaf> leafItr;
+ YangLeaf leafInfo;
+ ListIterator<YangLeafList> leafListItr;
+ YangLeafList leafListInfo;
+ YangLeafRef leafRef;
+
+ // Checks whether the data model tree returned is of type module.
+ assertThat((selfNode instanceof YangModule), is(true));
+
+ // Checks whether the node type is set properly to module.
+ assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+ assertThat(getInCrtName(MODULE, OPEN_ROAD), selfNode.getName(),
+ is(OPEN_ROAD));
+
+ YangList list = (YangList) selfNode.getChild().getNextSibling()
+ .getNextSibling();
+
+ leafItr = list.getListOfLeaf().listIterator();
+ leafInfo = leafItr.next();
+
+ // Checks whether the information in the leaf is correct under list.
+ assertThat(getInCrtName(LEAF, NODE_ID), leafInfo.getName(),
+ is(NODE_ID));
+ leafRef = (YangLeafRef) leafInfo.getDataType()
+ .getDataTypeExtendedInfo();
+
+ // Checks the effective type for the leaf.
+ assertThat(getInCrtLeafType(LEAF, NODE_ID),
+ leafRef.getEffectiveDataType().getDataType(), is(STRING));
+
+ leafListItr = list.getListOfLeafList().listIterator();
+ leafListInfo = leafListItr.next();
+
+ // Checks whether the information in the leaf-list is correct.
+ assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
+ is(NODE_REF));
+ leafRef = (YangLeafRef) leafListInfo.getDataType()
+ .getDataTypeExtendedInfo();
+
+ assertThat(getInCrtLeafType(LEAF_LIST, NODE_REF),
+ leafRef.getEffectiveDataType().getDataType(), is(DERIVED));
+
+ // Checks whether the information under cloned container is correct.
+ YangContainer container = (YangContainer) list.getChild()
+ .getNextSibling();
+
+ leafItr = container.getListOfLeaf().listIterator();
+ leafInfo = leafItr.next();
+
+ // Checks whether the information in the leaf is correct under cont.
+ assertThat(getInCrtName(LEAF, NODE_ID), leafInfo.getName(),
+ is(NODE_ID));
+ leafRef = (YangLeafRef) leafListInfo.getDataType()
+ .getDataTypeExtendedInfo();
+ assertThat(getInCrtLeafType(LEAF, NODE_ID),
+ leafRef.getEffectiveDataType().getDataType(), is(DERIVED));
+
+ leafListItr = container.getListOfLeafList().listIterator();
+ leafListInfo = leafListItr.next();
+
+ // Checks whether the information in the leaf-list is correct.
+ assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
+ is(NODE_REF));
+ leafRef = (YangLeafRef) leafListInfo.getDataType()
+ .getDataTypeExtendedInfo();
+ assertThat(getInCrtLeafType(LEAF_LIST, NODE_REF),
+ leafRef.getEffectiveDataType().getDataType(),
+ is(STRING));
+ }
+
+ /**
+ * Processed invalid scenario where a leaf-ref is present in union.
+ *
+ * @throws IOException io error when finding file
+ */
+ @Test
+ public void processInvalidLeafRef() throws IOException {
+ thrown.expect(ParserException.class);
+ thrown.expectMessage("Union member type must not be one of the " +
+ "built-in types \"empty\" or " +
+ "\"leafref\"node-id_union");
+ String searchDir = "src/test/resources/typelinkingaftercloning" +
+ "/leafref/invalid";
+ utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+ utilMgr.parseYangFileInfoSet();
+ }
+
+ /**
+ * Processes simple identity-ref after it gets cloned from grouping.
+ *
+ * @throws IOException io error when finding file
+ */
+ @Test
+ public void processIdentityRefAfterCloning() throws IOException {
+
+ String searchDir = "src/test/resources/typelinkingaftercloning" +
+ "/identityref";
+ utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ YangNode selfNode;
+
+ // Create YANG node set
+ linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+
+ // Add references to import list.
+ linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+ updateFilePriority(utilMgr.getYangNodeSet());
+
+ // Carry out inter-file linking.
+ linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+
+ Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+
+ selfNode = nodeItr.next();
+
+ ListIterator<YangLeaf> leafItr;
+ YangLeaf leafInfo;
+ ListIterator<YangLeafList> leafListItr;
+ YangLeafList leafListInfo;
+ YangIdentityRef identityRef;
+ YangUnion union;
+ Iterator<YangType<?>> unionTypeItr;
+ YangType type;
+
+ // Checks whether the data model tree returned is of type module.
+ assertThat((selfNode instanceof YangModule), is(true));
+
+ // Checks whether the node type is set properly to module.
+ assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+ assertThat(getInCrtName(MODULE, OPEN_ROAD), selfNode.getName(),
+ is(OPEN_ROAD));
+
+ YangList list = (YangList) selfNode.getChild().getNextSibling()
+ .getNextSibling().getNextSibling();
+
+ leafItr = list.getListOfLeaf().listIterator();
+ leafInfo = leafItr.next();
+
+ // Checks if the leaf has identity-ref in union.
+ assertThat(getInCrtName(LEAF, FACILITY), leafInfo.getName(),
+ is(FACILITY));
+ union = (YangUnion) leafInfo.getDataType().getDataTypeExtendedInfo();
+ unionTypeItr = union.getTypeList().listIterator();
+ type = unionTypeItr.next();
+ identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+
+ // Checks the effective type for the leaf.
+ assertThat(getInCrtLeafType(LEAF, FACILITY),
+ identityRef.getBaseIdentity().getName(),
+ is(FACILITY_SYS_LOG));
+
+ leafInfo = leafItr.next();
+
+ // Checks whether the information in the leaf is correct under list.
+ assertThat(getInCrtName(LEAF, NODE_ID), leafInfo.getName(),
+ is(NODE_ID));
+ identityRef = (YangIdentityRef) leafInfo.getDataType()
+ .getDataTypeExtendedInfo();
+
+ // Checks the effective type for the leaf.
+ assertThat(getInCrtLeafType(LEAF, NODE_ID),
+ identityRef.getBaseIdentity().getName(),
+ is(FACILITY_SYS_LOG));
+
+ leafListItr = list.getListOfLeafList().listIterator();
+ leafListInfo = leafListItr.next();
+
+ // Checks if the information in the leaf-list is correct under list.
+ assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
+ is(NODE_REF));
+
+ identityRef = (YangIdentityRef) leafListInfo.getDataType()
+ .getDataTypeExtendedInfo();
+
+ // Checks the effective type for the leaf-list.
+ assertThat(getInCrtLeafType(LEAF, NODE_REF),
+ identityRef.getBaseIdentity().getName(),
+ is(FACILITY_SYS_LOG));
+
+ YangContainer container = (YangContainer) list.getChild()
+ .getNextSibling().getNextSibling();
+
+ leafListItr = container.getListOfLeafList().listIterator();
+ leafListInfo = leafListItr.next();
+
+ // Checks the leaf-list information is correct.
+ assertThat(getInCrtName(LEAF_LIST, FACILITY), leafListInfo.getName(),
+ is(FACILITY));
+ union = (YangUnion) leafListInfo.getDataType()
+ .getDataTypeExtendedInfo();
+ unionTypeItr = union.getTypeList().listIterator();
+ type = unionTypeItr.next();
+ identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+
+ // Checks the effective type for the leaf-list.
+ assertThat(getInCrtLeafType(LEAF_LIST, FACILITY),
+ identityRef.getBaseIdentity().getName(),
+ is(FACILITY_SYS_LOG));
+
+ leafListInfo = leafListItr.next();
+
+ // Checks the leaf-list information is correct.
+ assertThat(getInCrtName(LEAF_LIST, NODE_REF), leafListInfo.getName(),
+ is(NODE_REF));
+ identityRef = (YangIdentityRef) leafListInfo.getDataType()
+ .getDataTypeExtendedInfo();
+
+ // Checks the effective type for the leaf.
+ assertThat(getInCrtLeafType(LEAF_LIST, NODE_REF),
+ identityRef.getBaseIdentity().getName(),
+ is(FACILITY_SYS_LOG));
+
+ leafItr = container.getListOfLeaf().listIterator();
+ leafInfo = leafItr.next();
+
+ // Checks the leaf information is correct.
+ assertThat(getInCrtName(LEAF, NODE_ID), leafInfo.getName(),
+ is(NODE_ID));
+ identityRef = (YangIdentityRef) leafListInfo.getDataType()
+ .getDataTypeExtendedInfo();
+
+ assertThat(getInCrtLeafType(LEAF, NODE_ID),
+ identityRef.getBaseIdentity().getName(),
+ is(FACILITY_SYS_LOG));
+
+ }
+
+ /**
+ * Processes union having different recursive level with identity-ref.
+ *
+ * @throws IOException io error when finding file
+ */
+ @Test
+ public void processUnionAfterCloning() throws IOException {
+
+ String searchDir = "src/test/resources/typelinkingaftercloning/union";
+ utilMgr.createYangFileInfoSet(getYangFiles(searchDir));
+ utilMgr.parseYangFileInfoSet();
+ utilMgr.createYangNodeSet();
+ YangNode selfNode;
+
+ // Create YANG node set
+ linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+
+ // Add references to import list.
+ linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+ updateFilePriority(utilMgr.getYangNodeSet());
+
+ // Carry out inter-file linking.
+ linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+ Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+ selfNode = nodeItr.next();
+
+ YangIdentityRef identityRef;
+ YangUnion union;
+ Iterator<YangType<?>> unionTypeItr;
+ YangType type;
+ YangUnion union2;
+ Iterator<YangType<?>> unionTypeItr2;
+ YangType type2;
+ YangUnion union3;
+ Iterator<YangType<?>> unionTypeItr3;
+ YangType type3;
+ YangDerivedInfo derivedInfo;
+ YangTypeDef typeDef;
+ Iterator<YangType<?>> typeDefItr;
+
+ // Checks whether the data model tree returned is of type module.
+ assertThat((selfNode instanceof YangModule), is(true));
+
+ // Checks whether the node type is set properly to module.
+ assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+ assertThat(getInCrtName(MODULE, OPEN_ROAD), selfNode.getName(),
+ is(OPEN_ROAD));
+
+ YangList list = (YangList) selfNode.getChild().getNextSibling()
+ .getNextSibling().getNextSibling().getNextSibling()
+ .getNextSibling().getNextSibling();
+
+ Iterator<YangLeaf> leafItr = list.getListOfLeaf().listIterator();
+ YangLeaf leafInfo = leafItr.next();
+
+ // Checks if the leaf has identity-ref in union.
+ assertThat(getInCrtName(LEAF, FACILITY), leafInfo.getName(),
+ is(FACILITY));
+
+ // Gets the first level union and the list of type in it.
+ union = (YangUnion) leafInfo.getDataType().getDataTypeExtendedInfo();
+ unionTypeItr = union.getTypeList().listIterator();
+ type = unionTypeItr.next();
+
+ // Gets the second level union and types in it.
+ union2 = (YangUnion) type.getDataTypeExtendedInfo();
+ unionTypeItr2 = union2.getTypeList().listIterator();
+ type2 = unionTypeItr2.next();
+
+ // Gets the third level union and types in it.
+ union3 = (YangUnion) type2.getDataTypeExtendedInfo();
+ unionTypeItr3 = union3.getTypeList().listIterator();
+ type3 = unionTypeItr3.next();
+
+ // Checks the first identity-ref in third level union.
+ identityRef = (YangIdentityRef) type3.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ THIRD, FIRST, USABILITY_SYS_LOG, LEAF, FACILITY),
+ identityRef.getBaseIdentity().getName(),
+ is(USABILITY_SYS_LOG));
+
+ // Checks the first identity-ref in second level union.
+ type2 = unionTypeItr2.next();
+ identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ SECOND, FIRST, FACILITY_SYS_LOG, LEAF, FACILITY),
+ identityRef.getBaseIdentity().getName(),
+ is(FACILITY_SYS_LOG));
+
+ // Checks the first identity-ref in first level union.
+ type = unionTypeItr.next();
+ identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ FIRST, FIRST, AVAILABILITY_SYS_LOG, LEAF, FACILITY),
+ identityRef.getBaseIdentity().getName(),
+ is(AVAILABILITY_SYS_LOG));
+
+ // Checks derived type in third level union.
+ type3 = unionTypeItr3.next();
+ derivedInfo = (YangDerivedInfo) type3.getDataTypeExtendedInfo();
+ typeDef = derivedInfo.getReferredTypeDef();
+ typeDefItr = typeDef.getTypeList().listIterator();
+ type = typeDefItr.next();
+
+ // Gets the first level union and the list of type in it.
+ union = (YangUnion) type.getDataTypeExtendedInfo();
+ unionTypeItr = union.getTypeList().listIterator();
+ type = unionTypeItr.next();
+
+ // Gets the first level union and the list of type in it.
+ union2 = (YangUnion) type.getDataTypeExtendedInfo();
+ unionTypeItr2 = union2.getTypeList().listIterator();
+ type2 = unionTypeItr2.next();
+
+ // Checks the first identity-ref in second level union.
+ identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ SECOND, FIRST, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
+ identityRef.getBaseIdentity().getName(),
+ is(AVAILABILITY_SYS_LOG));
+
+ // Checks the second identity-ref in second level union.
+ type2 = unionTypeItr2.next();
+ identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ SECOND, SECOND, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
+ identityRef.getBaseIdentity().getName(),
+ is(AVAILABILITY_SYS_LOG));
+
+ // Checks the first identity-ref in first level union.
+ type = unionTypeItr.next();
+ identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ FIRST, FIRST, USABILITY_SYS_LOG, TYPEDEF, CORRECT),
+ identityRef.getBaseIdentity().getName(),
+ is(USABILITY_SYS_LOG));
+
+ YangContainer container = (YangContainer) list.getChild()
+ .getNextSibling().getNextSibling();
+
+
+ Iterator<YangLeafList> leafListItr = container.getListOfLeafList()
+ .listIterator();
+ YangLeafList leafListInfo = leafListItr.next();
+
+ // Checks if the leaf-list has identity-ref in union.
+ assertThat(getInCrtName(LEAF_LIST, FACILITY), leafListInfo.getName(),
+ is(FACILITY));
+
+ // Gets the first level union and the list of type in it.
+ union = (YangUnion) leafListInfo.getDataType()
+ .getDataTypeExtendedInfo();
+ unionTypeItr = union.getTypeList().listIterator();
+ type = unionTypeItr.next();
+
+ // Gets the second level union and types in it.
+ union2 = (YangUnion) type.getDataTypeExtendedInfo();
+ unionTypeItr2 = union2.getTypeList().listIterator();
+ type2 = unionTypeItr2.next();
+
+ // Gets the third level union and types in it.
+ union3 = (YangUnion) type2.getDataTypeExtendedInfo();
+ unionTypeItr3 = union3.getTypeList().listIterator();
+ type3 = unionTypeItr3.next();
+
+ // Checks the first identity-ref in third level union.
+ identityRef = (YangIdentityRef) type3.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ THIRD, FIRST, USABILITY_SYS_LOG, LEAF_LIST, FACILITY),
+ identityRef.getBaseIdentity().getName(),
+ is(USABILITY_SYS_LOG));
+
+ // Checks the first identity-ref in second level union.
+ type2 = unionTypeItr2.next();
+ identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ SECOND, FIRST, FACILITY_SYS_LOG, LEAF_LIST, FACILITY),
+ identityRef.getBaseIdentity().getName(),
+ is(FACILITY_SYS_LOG));
+
+ // Checks the first identity-ref in first level union.
+ type = unionTypeItr.next();
+ identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ FIRST, FIRST, AVAILABILITY_SYS_LOG, LEAF_LIST, FACILITY),
+ identityRef.getBaseIdentity().getName(),
+ is(AVAILABILITY_SYS_LOG));
+
+ // Checks derived type in third level union.
+ type3 = unionTypeItr3.next();
+ derivedInfo = (YangDerivedInfo) type3.getDataTypeExtendedInfo();
+ typeDef = derivedInfo.getReferredTypeDef();
+ typeDefItr = typeDef.getTypeList().listIterator();
+ type = typeDefItr.next();
+
+ // Gets the first level union and the list of type in it.
+ union = (YangUnion) type.getDataTypeExtendedInfo();
+ unionTypeItr = union.getTypeList().listIterator();
+ type = unionTypeItr.next();
+
+ // Gets the first level union and the list of type in it.
+ union2 = (YangUnion) type.getDataTypeExtendedInfo();
+ unionTypeItr2 = union2.getTypeList().listIterator();
+ type2 = unionTypeItr2.next();
+
+ // Checks the first identity-ref in second level union.
+ identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ SECOND, FIRST, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
+ identityRef.getBaseIdentity().getName(),
+ is(AVAILABILITY_SYS_LOG));
+
+ // Checks the second identity-ref in second level union.
+ type2 = unionTypeItr2.next();
+ identityRef = (YangIdentityRef) type2.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ SECOND, SECOND, AVAILABILITY_SYS_LOG, TYPEDEF, CORRECT),
+ identityRef.getBaseIdentity().getName(),
+ is(AVAILABILITY_SYS_LOG));
+
+ // Checks the first identity-ref in first level union.
+ type = unionTypeItr.next();
+ identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
+ assertThat(getInCrtUnionWithIdRef(
+ FIRST, FIRST, USABILITY_SYS_LOG, TYPEDEF, CORRECT),
+ identityRef.getBaseIdentity().getName(),
+ is(USABILITY_SYS_LOG));
+ }
+}
diff --git a/plugin/src/test/resources/typelinkingaftercloning/identityref/IntraFileIdentityRefAfterCloning.yang b/plugin/src/test/resources/typelinkingaftercloning/identityref/IntraFileIdentityRefAfterCloning.yang
new file mode 100644
index 0000000..9fbc024
--- /dev/null
+++ b/plugin/src/test/resources/typelinkingaftercloning/identityref/IntraFileIdentityRefAfterCloning.yang
@@ -0,0 +1,74 @@
+module org-open-road-m-device {
+ namespace "http://org/openroadm/device";
+ prefix org-open-road-m-device;
+
+ identity syslog-facility {
+ description
+ "The base identity to represent syslog facilities";
+ }
+ typedef value {
+ type identityref {
+ base syslog-facility;
+ }
+ }
+
+ grouping device-common {
+ leaf facility {
+ type union {
+ type identityref {
+ base syslog-facility;
+ }
+ type enumeration {
+ enum "all" {
+ description
+ "This enum describes the case where all
+ facilities are requested.";
+ }
+ }
+ }
+ }
+ leaf node-id {
+ type identityref {
+ base syslog-facility;
+ }
+ description
+ "Globally unique identifier for a device.";
+ config true;
+ }
+ leaf-list node-ref {
+ type value;
+ }
+ container network-ref {
+ leaf-list facility {
+ type union {
+ type identityref {
+ base syslog-facility;
+ }
+ type enumeration {
+ enum "all" {
+ description
+ "This enum describes the case where all
+ facilities are requested.";
+ }
+ }
+ }
+ }
+ leaf-list node-ref {
+ type identityref {
+ base syslog-facility;
+ }
+ description
+ "Globally unique identifier for a device.";
+ config true;
+ }
+ leaf node-id {
+ type value;
+ }
+ }
+ }
+
+ list node {
+ config false;
+ uses device-common;
+ }
+}
diff --git a/plugin/src/test/resources/typelinkingaftercloning/leafref/intrafile/IntraFileLeafrefAfterCloning.yang b/plugin/src/test/resources/typelinkingaftercloning/leafref/intrafile/IntraFileLeafrefAfterCloning.yang
new file mode 100644
index 0000000..a73280d
--- /dev/null
+++ b/plugin/src/test/resources/typelinkingaftercloning/leafref/intrafile/IntraFileLeafrefAfterCloning.yang
@@ -0,0 +1,52 @@
+module org-open-road-m-device {
+ namespace "http://org/openroadm/device";
+ prefix org-open-road-m-device;
+
+ leaf uri {
+ type string;
+ }
+ leaf-list id {
+ type value;
+ }
+ typedef value {
+ type uint8;
+ }
+
+ grouping device-common {
+ leaf node-id {
+ type leafref {
+ path "/uri";
+ }
+ description
+ "Globally unique identifier for a device.";
+ config true;
+ default "open-road-m";
+ }
+ leaf-list node-ref {
+ type leafref {
+ path "/id";
+ }
+ }
+ container network-ref {
+ leaf node-id {
+ type leafref {
+ path "/id";
+ }
+ description
+ "Globally unique identifier for a device.";
+ config true;
+ default "open-road-m";
+ }
+ leaf-list node-ref {
+ type leafref {
+ path "/uri";
+ }
+ }
+ }
+ }
+
+ list node {
+ config false;
+ uses device-common;
+ }
+}
diff --git a/plugin/src/test/resources/typelinkingaftercloning/leafref/invalid/invalidleafref.yang b/plugin/src/test/resources/typelinkingaftercloning/leafref/invalid/invalidleafref.yang
new file mode 100644
index 0000000..79491e1
--- /dev/null
+++ b/plugin/src/test/resources/typelinkingaftercloning/leafref/invalid/invalidleafref.yang
@@ -0,0 +1,28 @@
+module org-open-road-m-device {
+ namespace "http://org/openroadm/device";
+ prefix org-open-road-m-device;
+
+ leaf uri {
+ type string;
+ }
+
+ grouping device-common {
+ leaf node-id {
+ type union {
+ type leafref {
+ path "/uri";
+ }
+ type string;
+ }
+ description
+ "Globally unique identifier for a device.";
+ config true;
+ default "open-road-m";
+ }
+ }
+
+ list node {
+ config false;
+ uses device-common;
+ }
+}
diff --git a/plugin/src/test/resources/typelinkingaftercloning/union/IntraFileUnionAfterCloning.yang b/plugin/src/test/resources/typelinkingaftercloning/union/IntraFileUnionAfterCloning.yang
new file mode 100644
index 0000000..a69a5a1
--- /dev/null
+++ b/plugin/src/test/resources/typelinkingaftercloning/union/IntraFileUnionAfterCloning.yang
@@ -0,0 +1,81 @@
+module org-open-road-m-device {
+ namespace "http://org/openroadm/device";
+ prefix org-open-road-m-device;
+
+ identity syslog-facility {
+ description
+ "The base identity to represent syslog facilities";
+ }
+
+ identity syslog-usability {
+ description
+ "The base identity to represent syslog usabilities";
+ }
+
+ identity syslog-availability {
+ description
+ "The base identity to represent syslog availabilities";
+ }
+
+ typedef value {
+ type identityref {
+ base syslog-availability;
+ }
+ }
+
+ typedef correct {
+ type union {
+ type union {
+ type identityref {
+ base syslog-availability;
+ }
+ type value;
+ }
+ type identityref {
+ base syslog-usability;
+ }
+ }
+ }
+
+ grouping device-common {
+ leaf facility {
+ type union {
+ type union {
+ type union {
+ type identityref {
+ base syslog-usability;
+ }
+ type correct;
+ }
+ type identityref {
+ base syslog-facility;
+ }
+ }
+ type value;
+ }
+ }
+ container network-ref {
+ leaf-list facility {
+ type union {
+ type union {
+ type union {
+ type identityref {
+ base syslog-usability;
+ }
+ type correct;
+ }
+ type identityref {
+ base syslog-facility;
+ }
+ }
+ type value;
+ }
+ }
+ }
+ }
+
+ list node {
+ config false;
+ uses device-common;
+ }
+}