[ONOS-5633][ONOS-5702] ONOS YANG tools to support multi-threaded execution + defect fix

Change-Id: I20733f0350ea7e4e6558bd895a3c7c18477af6cf
diff --git a/generator/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGeneratorUtil.java b/generator/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGeneratorUtil.java
index 724c9cf..bde310d 100644
--- a/generator/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGeneratorUtil.java
+++ b/generator/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGeneratorUtil.java
@@ -39,40 +39,12 @@
 public final class JavaCodeGeneratorUtil {
 
     /**
-     * Current YANG node.
-     */
-    private static YangNode curNode;
-
-    /**
-     * Root node.
-     */
-    private static YangNode rootNode;
-
-    /**
      * Creates a java code generator utility object.
      */
     private JavaCodeGeneratorUtil() {
     }
 
     /**
-     * Returns current YANG node.
-     *
-     * @return current YANG node
-     */
-    public static YangNode getCurNode() {
-        return curNode;
-    }
-
-    /**
-     * Sets current YANG node.
-     *
-     * @param node current YANG node
-     */
-    public static void setCurNode(YangNode node) {
-        curNode = node;
-    }
-
-    /**
      * Generates Java code files corresponding to the YANG schema.
      *
      * @param rootNode   root node of the data model tree
@@ -84,7 +56,6 @@
             throws TranslatorException, IOException {
 
         YangNode codeGenNode = rootNode;
-        setRootNode(rootNode);
         TraversalType curTraversal = ROOT;
 
         while (codeGenNode != null) {
@@ -94,9 +65,8 @@
                             codeGenNode.getName() + " in " + codeGenNode.getLineNumber() + " at "
                             + codeGenNode.getCharPosition() + " in " + codeGenNode.getFileName());
                 }
-                setCurNode(codeGenNode);
                 try {
-                    generateCodeEntry(codeGenNode, yangPlugin);
+                    generateCodeEntry(codeGenNode, yangPlugin, rootNode);
                     codeGenNode.setNameSpaceAndAddToParentSchemaMap();
                 } catch (InvalidNodeForTranslatorException e) {
                     if (codeGenNode.getNextSibling() != null) {
@@ -109,7 +79,7 @@
                     continue;
                 } catch (Exception e) {
                     e.printStackTrace();
-                    close(codeGenNode, yangPlugin);
+                    close(codeGenNode, yangPlugin, rootNode);
                     throw new TranslatorException(e.getMessage());
                 }
 
@@ -119,20 +89,20 @@
                 codeGenNode = codeGenNode.getChild();
             } else if (codeGenNode.getNextSibling() != null) {
                 try {
-                    generateCodeExit(codeGenNode, yangPlugin);
+                    generateCodeExit(codeGenNode, yangPlugin, rootNode);
                 } catch (Exception e) {
                     e.printStackTrace();
-                    close(codeGenNode, yangPlugin);
+                    close(codeGenNode, yangPlugin, rootNode);
                     throw new TranslatorException(e.getMessage());
                 }
                 curTraversal = SIBILING;
                 codeGenNode = codeGenNode.getNextSibling();
             } else {
                 try {
-                    generateCodeExit(codeGenNode, yangPlugin);
+                    generateCodeExit(codeGenNode, yangPlugin, rootNode);
                 } catch (Exception e) {
                     e.printStackTrace();
-                    close(codeGenNode, yangPlugin);
+                    close(codeGenNode, yangPlugin, rootNode);
                     throw new TranslatorException(e.getMessage());
                 }
                 curTraversal = PARENT;
@@ -146,16 +116,19 @@
      *
      * @param codeGenNode current data model node for which the code needs to be generated
      * @param yangPlugin  YANG plugin config
+     * @param rootNode    YANG root node
      * @throws TranslatorException when fails to generate java code file the current node
      * @throws IOException         when fails to do IO operations
      */
-    private static void generateCodeEntry(YangNode codeGenNode, YangPluginConfig yangPlugin)
+    private static void generateCodeEntry(YangNode codeGenNode,
+                                          YangPluginConfig yangPlugin,
+                                          YangNode rootNode)
             throws TranslatorException, IOException {
 
         if (codeGenNode instanceof JavaCodeGenerator) {
             ((JavaCodeGenerator) codeGenNode).generateCodeEntry(yangPlugin);
         } else {
-            close(codeGenNode, yangPlugin);
+            close(codeGenNode, yangPlugin, rootNode);
             throw new TranslatorException(
                     "Generated data model node cannot be translated to target language code for " +
                             codeGenNode.getName() + " in " + codeGenNode.getLineNumber()
@@ -168,16 +141,19 @@
      *
      * @param codeGenNode  current data model node for which the code needs to be generated
      * @param pluginConfig plugin configurations
+     * @param rootNode     YANG root node
      * @throws TranslatorException when fails to generate java code file the current node
      * @throws IOException         when fails to do IO operations
      */
-    private static void generateCodeExit(YangNode codeGenNode, YangPluginConfig pluginConfig)
+    private static void generateCodeExit(YangNode codeGenNode,
+                                         YangPluginConfig pluginConfig,
+                                         YangNode rootNode)
             throws TranslatorException, IOException {
 
         if (codeGenNode instanceof JavaCodeGenerator) {
             ((JavaCodeGenerator) codeGenNode).generateCodeExit();
         } else {
-            close(codeGenNode, pluginConfig);
+            close(codeGenNode, pluginConfig, rootNode);
             throw new TranslatorException(
                     "Generated data model node cannot be translated to target language code for " +
                             codeGenNode.getName() + " in " + codeGenNode.getLineNumber()
@@ -187,11 +163,12 @@
 
     /**
      * Free other YANG nodes of data-model tree when error occurs while file generation of current node.
+     *
+     * @param freedNode current data model node
      */
-    private static void freeRestResources() {
+    private static void freeRestResources(YangNode freedNode) {
 
-        YangNode freedNode = getCurNode();
-        if (getCurNode() != null) {
+        if (freedNode != null) {
             YangNode tempNode = freedNode;
             TraversalType curTraversal = ROOT;
 
@@ -246,18 +223,16 @@
             throws IOException {
 
         if (rootNode != null) {
-            //Free other resources where translator has failed.
-            freeRestResources();
 
             // Start removing all open files.
             YangNode tempNode = rootNode;
-            setCurNode(tempNode.getChild());
+            YangNode curNode = tempNode.getChild();
             TraversalType curTraversal = ROOT;
 
             while (tempNode != null) {
 
                 if (curTraversal != PARENT) {
-                    close(tempNode, yangPluginConfig);
+                    close(tempNode, yangPluginConfig, rootNode);
                 }
                 if (curTraversal != PARENT && tempNode.getChild() != null) {
                     curTraversal = CHILD;
@@ -271,7 +246,7 @@
                 }
             }
 
-            freeRestResources();
+            freeRestResources(curNode);
         }
     }
 
@@ -280,19 +255,21 @@
      *
      * @param node       current YANG node
      * @param yangPlugin plugin configurations
+     * @param rootNode   YANG root node
      * @throws IOException when fails to do IO operations
      */
-    private static void close(YangNode node, YangPluginConfig yangPlugin)
+    private static void close(YangNode node, YangPluginConfig yangPlugin,
+                              YangNode rootNode)
             throws IOException {
         if (node instanceof JavaCodeGenerator && ((TempJavaCodeFragmentFilesContainer) node)
                 .getTempJavaCodeFragmentFiles() != null) {
             ((TempJavaCodeFragmentFilesContainer) node).getTempJavaCodeFragmentFiles().freeTemporaryResources(true);
         }
-        if (getRootNode() != null) {
-            JavaFileInfoTranslator javaFileInfo = ((JavaFileInfoContainer) getRootNode()).getJavaFileInfo();
+        if (rootNode != null) {
+            JavaFileInfoTranslator javaFileInfo = ((JavaFileInfoContainer) rootNode).getJavaFileInfo();
             if (javaFileInfo.getPackage() != null) {
                 searchAndDeleteTempDir(javaFileInfo.getBaseCodeGenPath() +
-                        javaFileInfo.getPackageFilePath());
+                                               javaFileInfo.getPackageFilePath());
             } else {
                 searchAndDeleteTempDir(yangPlugin.getCodeGenDir());
             }
@@ -301,24 +278,6 @@
     }
 
     /**
-     * Returns root node.
-     *
-     * @return root node
-     */
-    private static YangNode getRootNode() {
-        return rootNode;
-    }
-
-    /**
-     * Sets root node.
-     *
-     * @param rootNode root node
-     */
-    private static void setRootNode(YangNode rootNode) {
-        JavaCodeGeneratorUtil.rootNode = rootNode;
-    }
-
-    /**
      * Searches child node in data model tree.
      *
      * @param parentNode parent node
diff --git a/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java b/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java
index fe6a40b..221f414 100644
--- a/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java
+++ b/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java
@@ -562,7 +562,7 @@
                                              List<String> importsList)
             throws IOException {
 
-        insertDataIntoJavaFile(file, CopyrightHeader.getCopyrightHeader());
+        insertDataIntoJavaFile(file, CopyrightHeader.parseCopyrightHeader());
         insertDataIntoJavaFile(file, pkg);
 
         /*
diff --git a/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/SubtreeFilteringMethodsGenerator.java b/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/SubtreeFilteringMethodsGenerator.java
index 3e60817..d4904ae 100644
--- a/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/SubtreeFilteringMethodsGenerator.java
+++ b/generator/src/main/java/org/onosproject/yangutils/translator/tojava/utils/SubtreeFilteringMethodsGenerator.java
@@ -1204,21 +1204,38 @@
         return "                    Class<?>[] classArray = " + call + "" +
                 ".getClass()" +
                 ".getInterfaces();\n" +
-                "                    Class<?> caseClass = classArray[0];\n" +
+                "                    Class<?> caseIntf = classArray[0];\n" +
                 "                    try {\n" +
-                "                        Object obj1 = caseClass.newInstance();\n" +
+                "                        ClassLoader classLoader = this" +
+                ".getClass().getClassLoader();\n" +
+                "                        String className = \"Default\" + " +
+                "caseIntf.getSimpleName();\n" +
+                "                        className = caseIntf.getPackage()" +
+                ".getName() + \".\" + className;\n" +
+                "                        Class<?> caseClass = classLoader" +
+                ".loadClass(className);\n" +
+                "                        java.lang.reflect.Constructor<?> " +
+                "constructor = caseClass.getDeclaredConstructor();\n" +
+                "                        constructor.setAccessible(true);\n" +
+                "                        Object obj1 = constructor" +
+                ".newInstance();\n" +
                 "                        java.lang.reflect.Method method =" +
-                " caseClass.getMethod(\"builder\", caseClass);\n" +
-                "                        Object obj = method.invoke(obj1," +
-                " (Object) null);\n" +
-                "                        method = caseClass.getMethod(\"build\", caseClass);\n" +
-                "                        Object obj2 = method.invoke(obj, " +
-                "(Object) null);\n" +
-                "                        method = caseClass.getMethod(\"processSubtreeFiltering\", caseClass);\n" +
+                " caseClass.getMethod(\"builder\");\n" +
+                "                        Object obj = method.invoke(obj1);\n" +
+                "                        Class<?> builderClass = obj.getClass();\n" +
+                "                        method = builderClass.getMethod(\"build\");\n" +
+                "                        Object obj2 = method.invoke(obj);\n" +
+                "                        Class<?> input = this.getClass()" +
+                ".getMethod(" + "\"" + name + "\").getReturnType();\n" +
+                "                        method = caseClass.getMethod" +
+                "(\"processSubtreeFiltering\", input,\n" +
+                "                                     boolean.class);\n" +
                 "                        result = (" + returnType + ") method.invoke" +
                 "(obj2, " + call + ", true);\n" +
                 "                    } catch (NoSuchMethodException | InstantiationException |\n" +
-                "                            IllegalAccessException | InvocationTargetException e) {\n" +
+                "                            IllegalAccessException | " +
+                "InvocationTargetException |\n" +
+                "                            ClassNotFoundException e) {\n" +
                 "                        e.printStackTrace();\n" +
                 "                    }\n";
     }
diff --git a/generator/src/main/java/org/onosproject/yangutils/utils/io/impl/CopyrightHeader.java b/generator/src/main/java/org/onosproject/yangutils/utils/io/impl/CopyrightHeader.java
index 5833de2..8b55768 100644
--- a/generator/src/main/java/org/onosproject/yangutils/utils/io/impl/CopyrightHeader.java
+++ b/generator/src/main/java/org/onosproject/yangutils/utils/io/impl/CopyrightHeader.java
@@ -37,9 +37,6 @@
     private static final String COPYRIGHTS_FIRST_LINE = "/*\n * Copyright " + Calendar.getInstance().get(Calendar.YEAR)
             + "-present Open Networking Laboratory\n";
     private static final String TEMP_FILE = "temp.txt";
-    private static ClassLoader classLoader = CopyrightHeader.class.getClassLoader();
-
-    private static String copyrightHeader;
 
     /**
      * Creates an instance of copyright header.
@@ -48,40 +45,18 @@
     }
 
     /**
-     * Returns copyright file header.
-     *
-     * @return copyright file header
-     * @throws IOException when fails to parse copyright header
-     */
-    public static String getCopyrightHeader() throws IOException {
-
-        if (copyrightHeader == null) {
-            parseCopyrightHeader();
-        }
-        return copyrightHeader;
-    }
-
-    /**
-     * Sets the copyright header.
-     *
-     * @param header copyright header
-     */
-    private static void setCopyrightHeader(String header) {
-
-        copyrightHeader = header;
-    }
-
-    /**
      * parses Copyright to the temporary file.
      *
+     * @return string of file.
      * @throws IOException when fails to get the copyright header
      */
-    private static void parseCopyrightHeader() throws IOException {
+    public static String parseCopyrightHeader() throws IOException {
 
         File temp = new File(TEMP_FILE);
 
         try {
-            InputStream stream = classLoader.getResourceAsStream(COPYRIGHT_HEADER_FILE);
+            InputStream stream = CopyrightHeader.class.getClassLoader()
+                    .getResourceAsStream(COPYRIGHT_HEADER_FILE);
             OutputStream out = new FileOutputStream(temp);
 
             int index;
@@ -91,8 +66,7 @@
             }
             out.close();
             stream.close();
-            getStringFileContent(temp);
-            setCopyrightHeader(getStringFileContent(temp));
+            return getStringFileContent(temp);
         } catch (IOException e) {
             throw new IOException("failed to parse the Copyright header");
         } finally {
diff --git a/generator/src/main/java/org/onosproject/yangutils/utils/io/impl/YangIoUtils.java b/generator/src/main/java/org/onosproject/yangutils/utils/io/impl/YangIoUtils.java
index a03ebb4..15051cb 100644
--- a/generator/src/main/java/org/onosproject/yangutils/utils/io/impl/YangIoUtils.java
+++ b/generator/src/main/java/org/onosproject/yangutils/utils/io/impl/YangIoUtils.java
@@ -68,7 +68,7 @@
 import static org.onosproject.yangutils.utils.UtilConstants.UNDER_SCORE;
 import static org.onosproject.yangutils.utils.UtilConstants.UNUSED;
 import static org.onosproject.yangutils.utils.UtilConstants.YANG_AUTO_PREFIX;
-import static org.onosproject.yangutils.utils.io.impl.CopyrightHeader.getCopyrightHeader;
+import static org.onosproject.yangutils.utils.io.impl.CopyrightHeader.parseCopyrightHeader;
 import static org.onosproject.yangutils.utils.io.impl.FileSystemUtil.appendFileContents;
 import static org.onosproject.yangutils.utils.io.impl.FileSystemUtil.updateFileHandle;
 import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.PACKAGE_INFO;
@@ -134,7 +134,7 @@
             FileWriter fileWriter = new FileWriter(packageInfo);
             BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
 
-            bufferedWriter.write(getCopyrightHeader());
+            bufferedWriter.write(parseCopyrightHeader());
             //TODO: get the compiler annotations and pass the info
             bufferedWriter.write(getJavaDoc(PACKAGE_INFO, classInfo, isChildNode,
                                             null));
@@ -688,7 +688,8 @@
      * @param conflictResolver object of YANG to java naming conflict util
      * @return camel case rule checked string
      */
-    private static String applyCamelCaseRule(String[] stringArray, YangToJavaNamingConflictUtil conflictResolver) {
+    private static String applyCamelCaseRule(String[] stringArray,
+                                             YangToJavaNamingConflictUtil conflictResolver) {
 
         String ruleChecker = stringArray[0].toLowerCase();
         int i;