[ONOS-4839] update file priority for input files

Change-Id: I4aa0cbbfb0f168efd7c1895c9bb0c6589088eefd
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
index 7a963f5..be90e76 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
@@ -29,7 +29,7 @@
  * Represents base class of a node in data model tree.
  */
 public abstract class YangNode
-        implements Cloneable, Serializable, YangDataNode {
+        implements Cloneable, Serializable, YangDataNode, Comparable<YangNode> {
 
     private static final long serialVersionUID = 806201601L;
 
@@ -59,6 +59,29 @@
     private YangNode previousSibling;
 
     /**
+     * Priority of the node.
+     */
+    private int priority;
+
+    /**
+     * Returns the priority of the node.
+     *
+     * @return priority of the node
+     */
+    public int getPriority() {
+        return priority;
+    }
+
+    /**
+     * Sets the priority of the node.
+     *
+     * @param priority of the node
+     */
+    public void setPriority(int priority) {
+        this.priority = priority;
+    }
+
+    /**
      * Returns the nodes name.
      *
      * @return nodes name
@@ -234,6 +257,14 @@
         }
     }
 
+    @Override
+    public int compareTo(YangNode otherNode) {
+        if (priority == otherNode.getPriority()) {
+            return 1;
+        }
+        return ((Integer) otherNode.getPriority()).compareTo(priority);
+    }
+
     /**
      * Clones the current node contents and create a new node.
      *
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
index f63d8df..8cfe779 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
@@ -16,9 +16,15 @@
 
 package org.onosproject.yangutils.linker.impl;
 
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 import org.onosproject.yangutils.datamodel.ResolvableType;
+import org.onosproject.yangutils.datamodel.YangImport;
+import org.onosproject.yangutils.datamodel.YangInclude;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangReferenceResolver;
 import org.onosproject.yangutils.datamodel.YangSubModule;
@@ -73,6 +79,9 @@
         // Add reference to include list.
         addRefToYangFilesIncludeList(yangNodeSet);
 
+        // Update the priority for all the files.
+        updateFilePriority(yangNodeSet);
+
         // TODO check for circular import/include.
 
         // Carry out inter-file linking.
@@ -154,7 +163,10 @@
      */
     public void processInterFileLinking(Set<YangNode> yangNodeSet)
             throws LinkerException {
-        for (YangNode yangNode : yangNodeSet) {
+        List<YangNode> yangNodeSortedList = new LinkedList<>();
+        yangNodeSortedList.addAll(yangNodeSet);
+        Collections.sort(yangNodeSortedList);
+        for (YangNode yangNode : yangNodeSortedList) {
             try {
                 ((YangReferenceResolver) yangNode)
                         .resolveInterFileLinking(ResolvableType.YANG_IF_FEATURE);
@@ -178,4 +190,53 @@
             }
         }
     }
+
+    /**
+     * Updates the priority for all the input files.
+     *
+     * @param yangNodeSet set of YANG files info
+     */
+    public void updateFilePriority(Set<YangNode> yangNodeSet) {
+        for (YangNode yangNode : yangNodeSet) {
+            updateFilePriorityOfNode(yangNode);
+        }
+    }
+
+    /**
+     * Updates priority of the node.
+     *
+     * @param yangNode YANG node information
+     */
+    public void updateFilePriorityOfNode(YangNode yangNode) {
+        int curNodePriority = yangNode.getPriority();
+        if (yangNode instanceof YangReferenceResolver) {
+            List<YangImport> yangImportList = ((YangReferenceResolver) yangNode).getImportList();
+            if (yangImportList != null && !yangImportList.isEmpty()) {
+                Iterator<YangImport> importInfoIterator = yangImportList.iterator();
+                // Run through the imported list to update priority.
+                while (importInfoIterator.hasNext()) {
+                    YangImport yangImport = importInfoIterator.next();
+                    YangNode importedNode = yangImport.getImportedNode();
+                    if (curNodePriority >= importedNode.getPriority()) {
+                        importedNode.setPriority(curNodePriority + 1);
+                        updateFilePriorityOfNode(importedNode);
+                    }
+                }
+            }
+
+            List<YangInclude> yangIncludeList = ((YangReferenceResolver) yangNode).getIncludeList();
+            if (yangIncludeList != null && !yangIncludeList.isEmpty()) {
+                Iterator<YangInclude> includeInfoIterator = yangIncludeList.iterator();
+                // Run through the imported list to update priority.
+                while (includeInfoIterator.hasNext()) {
+                    YangInclude yangInclude = includeInfoIterator.next();
+                    YangNode includedNode = yangInclude.getIncludedNode();
+                    if (curNodePriority >= includedNode.getPriority()) {
+                        includedNode.setPriority(curNodePriority + 1);
+                        updateFilePriorityOfNode(includedNode);
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/utils/io/impl/YangPluginConfig.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/utils/io/impl/YangPluginConfig.java
index 8199a8e..963bb8d 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/utils/io/impl/YangPluginConfig.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/utils/io/impl/YangPluginConfig.java
@@ -59,7 +59,7 @@
     /**
      * Sets the string sbi or nbi for code generation.
      *
-     * @par code generation is for sbi
+     * @param codeGenerateForsbi generation is for sbi
      */
     public void setCodeGenerateForsbi(String codeGenerateForsbi) {
         this.codeGenerateForsbi = codeGenerateForsbi;
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileLinkingTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileLinkingTest.java
index b5fd40b..09641c1 100644
--- a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileLinkingTest.java
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterFileLinkingTest.java
@@ -984,4 +984,52 @@
         assertThat(leafref.getEffectiveDataType().getDataType(),
                 is(YangDataTypes.STRING));
     }
+
+    /**
+     * Checks priority of the file.
+     */
+    @Test
+    public void interFilePriority()
+            throws IOException, ParserException, MojoExecutionException {
+
+        String searchDir = "src/test/resources/interfilepriority";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.resolveDependenciesUsingLinker();
+
+        YangNode selfNode = null;
+        YangNode refNode1 = null;
+        YangNode refNode2 = null;
+
+        for (YangNode rootNode : utilManager.getYangNodeSet()) {
+            if (rootNode.getName().equals("module1")) {
+                selfNode = rootNode;
+            } else if (rootNode.getName().equals("module2")) {
+                refNode1 = rootNode;
+            } else {
+                refNode2 = rootNode;
+            }
+        }
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(selfNode instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(selfNode.getNodeType(), is(MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("module1"));
+        assertThat(yangNode.getPriority(), is(2));
+
+        // Check whether the data model tree returned is of type module.
+        assertThat(refNode1 instanceof YangModule, is(true));
+
+        // Check whether the node type is set properly to module.
+        assertThat(refNode1.getNodeType(), is(MODULE_NODE));
+
+        YangModule referredNode1 = (YangModule) refNode1;
+        assertThat(referredNode1.getName(), is("module2"));
+        assertThat(referredNode1.getPriority(), is(3));
+    }
 }
diff --git a/utils/yangutils/plugin/src/test/resources/interfilepriority/module1.yang b/utils/yangutils/plugin/src/test/resources/interfilepriority/module1.yang
new file mode 100644
index 0000000..9a21b03
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/resources/interfilepriority/module1.yang
@@ -0,0 +1,14 @@
+module module1 {
+    yang-version 1;
+    namespace "http://huawei.com";
+    prefix Ant;
+    import module2 {
+        prefix p;
+    }
+    leaf invalid-interval {
+        type p:hello;
+    }
+    typedef hello {
+        type string;
+    }
+}
diff --git a/utils/yangutils/plugin/src/test/resources/interfilepriority/module2.yang b/utils/yangutils/plugin/src/test/resources/interfilepriority/module2.yang
new file mode 100644
index 0000000..0a3bdad
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/resources/interfilepriority/module2.yang
@@ -0,0 +1,8 @@
+module module2 {
+    yang-version 1;
+    namespace "http://huawei.com";
+    prefix Ant2;
+    typedef hello {
+        type string;
+    }
+}
diff --git a/utils/yangutils/plugin/src/test/resources/interfilepriority/module3.yang b/utils/yangutils/plugin/src/test/resources/interfilepriority/module3.yang
new file mode 100644
index 0000000..948c797
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/resources/interfilepriority/module3.yang
@@ -0,0 +1,8 @@
+module module3 {
+    yang-version 1;
+    namespace "http://huawei.com";
+    prefix Ant;
+    import module1 {
+        prefix p;
+    }
+}
diff --git a/utils/yangutils/plugin/src/test/resources/interfilepriority/module4.yang b/utils/yangutils/plugin/src/test/resources/interfilepriority/module4.yang
new file mode 100644
index 0000000..df6f8b2
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/resources/interfilepriority/module4.yang
@@ -0,0 +1,8 @@
+module module4 {
+    yang-version 1;
+    namespace "http://huawei.com";
+    prefix Ant;
+    import module3 {
+        prefix p;
+    }
+}