[ONOS-4350] Inter file linking implementation and inter-jar linking framework

Change-Id: I71a26ba3e0b9d17261e78a9313fe7f047195932e
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
new file mode 100644
index 0000000..0fc3d99
--- /dev/null
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
@@ -0,0 +1,120 @@
+/*
+ * 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.linker.impl;
+
+import java.util.Set;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.linker.YangLinker;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.plugin.manager.YangFileInfo;
+
+import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;
+
+/**
+ * Representation of entity which provides linking service of YANG files.
+ */
+public class YangLinkerManager implements YangLinker {
+    @Override
+    public void resolveDependencies(Set<YangFileInfo> yangFileInfoSet) {
+
+        // Carry out linking of sub module with module.
+        linkSubModulesToParentModule(yangFileInfoSet);
+
+        // Add references to import list.
+        addRefToYangFilesImportList(yangFileInfoSet);
+
+        // Add reference to include list.
+        addRefToYangFilesIncludeList(yangFileInfoSet);
+
+        // TODO check for circular import/include.
+
+        // Carry out inter-file linking.
+        processInterFileLinking(yangFileInfoSet);
+    }
+
+    /**
+     * Resolves sub-module linking by linking sub module with parent module.
+     *
+     * @param yangFileInfoSet set of YANG files info
+     * @throws LinkerException fails to link sub-module to parent module
+     */
+    public void linkSubModulesToParentModule(Set<YangFileInfo> yangFileInfoSet) throws LinkerException {
+        for (YangFileInfo yangFileInfo : yangFileInfoSet) {
+            YangNode yangNode = yangFileInfo.getRootNode();
+            if (yangNode instanceof YangSubModule) {
+                try {
+                    ((YangSubModule) yangNode).linkWithModule(yangFileInfoSet);
+                } catch (DataModelException e) {
+                    String errorInfo = "YANG file error: " + yangFileInfo.getYangFileName() + " at line: "
+                            + e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE
+                            + e.getMessage();
+                    throw new LinkerException(errorInfo);
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds imported node information to the import list.
+     *
+     * @param yangFileInfoSet set of YANG files info
+     * @throws LinkerException fails to find imported module
+     */
+    public void addRefToYangFilesImportList(Set<YangFileInfo> yangFileInfoSet) throws LinkerException {
+        for (YangFileInfo yangFileInfo : yangFileInfoSet) {
+            YangNode yangNode = yangFileInfo.getRootNode();
+            if (yangNode instanceof YangReferenceResolver) {
+                ((YangReferenceResolver) yangNode).addReferencesToImportList(yangFileInfoSet);
+            }
+        }
+    }
+
+    /**
+     * Adds included node information to the include list.
+     *
+     * @param yangFileInfoSet set of YANG files info
+     * @throws LinkerException fails to find included sub-module
+     */
+    public void addRefToYangFilesIncludeList(Set<YangFileInfo> yangFileInfoSet) throws LinkerException {
+        for (YangFileInfo yangFileInfo : yangFileInfoSet) {
+            YangNode yangNode = yangFileInfo.getRootNode();
+            if (yangNode instanceof YangReferenceResolver) {
+                ((YangReferenceResolver) yangNode).addReferencesToIncludeList(yangFileInfoSet);
+            }
+        }
+    }
+
+    /**
+     * Processes inter file linking for type and uses.
+     *
+     * @param yangFileInfoSet set of YANG files info
+     * @throws LinkerException a violation in linker execution
+     */
+    public void processInterFileLinking(Set<YangFileInfo> yangFileInfoSet) throws LinkerException {
+        for (YangFileInfo yangFileInfo : yangFileInfoSet) {
+            try {
+                ((YangReferenceResolver) yangFileInfo.getRootNode()).resolveInterFileLinking();
+            } catch (DataModelException e) {
+                String errorInfo = "Error in file: " + yangFileInfo.getYangFileName() + " at line: "
+                        + e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE + e.getMessage();
+                throw new LinkerException(errorInfo);
+            }
+        }
+    }
+}