[ONOS-4063 to 68] Intra YANG file Linking Implementation and Intra YANG file Linking Framework

Change-Id: I06e602c351ab54178bf90b8676af71a70e42371f
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 e736631..c4609dc 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
@@ -16,11 +16,14 @@
 
 package org.onosproject.yangutils.datamodel.utils;
 
+import java.util.List;
 import org.onosproject.yangutils.datamodel.CollisionDetector;
+import org.onosproject.yangutils.datamodel.HasResolutionInfo;
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangLeafList;
 import org.onosproject.yangutils.datamodel.YangLeavesHolder;
 import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangResolutionInfo;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.utils.YangConstructType;
 
@@ -39,27 +42,23 @@
      * Detects the colliding identifier name in a given YANG node and its child.
      *
      * @param identifierName name for which collision detection is to be
-     *            checked.
-     * @param dataType type of YANG node asking for detecting collision.
-     * @param node instance of calling node.
-     * @throws DataModelException a violation of data model rules.
+     *            checked
+     * @param dataType type of YANG node asking for detecting collision
+     * @param node instance of calling node
+     * @throws DataModelException a violation of data model rules
      */
     public static void detectCollidingChildUtil(String identifierName, YangConstructType dataType, YangNode node)
             throws DataModelException {
-        if (((YangLeavesHolder) node).getListOfLeaf() != null) {
-            for (YangLeaf leaf : ((YangLeavesHolder) node).getListOfLeaf()) {
-                if (leaf.getLeafName().equals(identifierName)) {
-                    throw new DataModelException("YANG file error: Duplicate input identifier detected, same as leaf \""
-                            + leaf.getLeafName() + "\"");
-                }
+        if (dataType == YangConstructType.LEAF_DATA) {
+            YangLeavesHolder leavesHolder = (YangLeavesHolder) node;
+            if (leavesHolder.getListOfLeaf() != null) {
+                detectCollidingLeaf(leavesHolder, identifierName);
             }
         }
-        if (((YangLeavesHolder) node).getListOfLeafList() != null) {
-            for (YangLeafList leafList : ((YangLeavesHolder) node).getListOfLeafList()) {
-                if (leafList.getLeafName().equals(identifierName)) {
-                    throw new DataModelException("YANG file error: Duplicate input identifier detected, same as leaf " +
-                            "list \"" + leafList.getLeafName() + "\"");
-                }
+        if (dataType == YangConstructType.LEAF_LIST_DATA) {
+            if (((YangLeavesHolder) node).getListOfLeafList() != null) {
+                YangLeavesHolder leavesHolder = (YangLeavesHolder) node;
+                detectCollidingLeafList(leavesHolder, identifierName);
             }
         }
         node = node.getChild();
@@ -70,4 +69,78 @@
             node = node.getNextSibling();
         }
     }
+
+    /**
+     * Detects the colliding identifier name in a given leaf node.
+     *
+     * @param leavesHolder leaves node against which collision to be checked
+     * @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) throws
+            DataModelException {
+        for (YangLeaf leaf : leavesHolder.getListOfLeaf()) {
+            if (leaf.getLeafName().equals(identifierName)) {
+                throw new DataModelException("YANG file error: Duplicate input identifier detected, same as leaf \""
+                        + leaf.getLeafName() + "\"");
+            }
+        }
+    }
+
+    /**
+     * Detects the colliding identifier name in a given leaf-list node.
+     *
+     * @param leavesHolder leaves node against which collision to be checked
+     * @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) throws
+            DataModelException {
+        for (YangLeafList leafList : leavesHolder.getListOfLeafList()) {
+            if (leafList.getLeafName().equals(identifierName)) {
+                throw new DataModelException("YANG file error: Duplicate input identifier detected, same as leaf " +
+                        "list \"" + leafList.getLeafName() + "\"");
+            }
+        }
+    }
+
+    /**
+     * Add a resolution information.
+     *
+     * @param resolutionInfo information about the YANG construct which has to
+     *                       be resolved
+     * @throws DataModelException a violation of data model rules
+     */
+    public static void addResolutionInfo(YangResolutionInfo resolutionInfo) throws DataModelException {
+        /* get the module node to add maintain the list of nested reference */
+        YangNode curNode = resolutionInfo.getHolderOfEntityToResolve();
+        while (!(curNode instanceof HasResolutionInfo)) {
+            curNode = curNode.getParent();
+            if (curNode == null) {
+                throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
+            }
+        }
+        HasResolutionInfo resolutionNode = (HasResolutionInfo) curNode;
+        resolutionNode.addToResolutionList(resolutionInfo);
+    }
+
+    /**
+     * Resolve linking for a resolution list.
+     *
+     * @param resolutionList resolution list for which linking to be done
+     * @param resolutionInfoNode module/sub-module node
+     * @throws DataModelException a violation of data model rules
+     */
+    public static void resolveLinkingForResolutionList(List<YangResolutionInfo> resolutionList,
+                                                       HasResolutionInfo resolutionInfoNode)
+            throws DataModelException {
+        for (YangResolutionInfo resolutionInfo : resolutionList) {
+            if (resolutionInfo.getPrefix() == null ||
+                    resolutionInfo.getPrefix().equals(resolutionInfoNode.getPrefix())) {
+                resolutionInfo.resolveLinkingForResolutionInfo(resolutionInfoNode.getPrefix());
+            }
+        }
+    }
 }