[ONOS-4799],[ONOS-4351] Augment inter file linker and Generated Code refactored.

Change-Id: Id1f3ac9c90a632373f51cc75d499c3110216be17
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java
index 4a2b6f5..c6fd897 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java
@@ -20,6 +20,7 @@
 import java.io.IOException;
 import java.util.List;
 
+import org.onosproject.yangutils.datamodel.YangAugment;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.translator.tojava.JavaFileInfo;
@@ -39,13 +40,14 @@
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_EVENT_CLASS;
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_EVENT_LISTENER_INTERFACE;
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_EVENT_SUBJECT_CLASS;
+import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_IDENTITY_CLASS;
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_SERVICE_AND_MANAGER;
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_TYPEDEF_CLASS;
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_UNION_CLASS;
-import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_IDENTITY_CLASS;
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.IMPL_CLASS_MASK;
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.INTERFACE_MASK;
 import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.ATTRIBUTES_MASK;
+import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.AUGMENTE_CLASS_CONSTRUCTOR_MASK;
 import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.CONSTRUCTOR_FOR_TYPE_MASK;
 import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.CONSTRUCTOR_IMPL_MASK;
 import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.ENUM_IMPL_MASK;
@@ -66,26 +68,16 @@
 import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.SETTER_FOR_INTERFACE_MASK;
 import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.TO_STRING_IMPL_MASK;
 import static org.onosproject.yangutils.translator.tojava.utils.ClassDefinitionGenerator.generateClassDefinition;
-import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getJavaPackageFromPackagePath;
-import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getSmallCase;
-import static org.onosproject.yangutils.utils.UtilConstants.CLOSE_PARENTHESIS;
+import static org.onosproject.yangutils.utils.UtilConstants.BUILDER;
 import static org.onosproject.yangutils.utils.UtilConstants.CLOSE_CURLY_BRACKET;
-import static org.onosproject.yangutils.utils.UtilConstants.COMPONENT_ANNOTATION;
-import static org.onosproject.yangutils.utils.UtilConstants.EQUAL;
-import static org.onosproject.yangutils.utils.UtilConstants.FOUR_SPACE_INDENTATION;
-import static org.onosproject.yangutils.utils.UtilConstants.IMMEDIATE;
-import static org.onosproject.yangutils.utils.UtilConstants.INT;
+import static org.onosproject.yangutils.utils.UtilConstants.DEFAULT;
 import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;
-import static org.onosproject.yangutils.utils.UtilConstants.OPEN_PARENTHESIS;
 import static org.onosproject.yangutils.utils.UtilConstants.PACKAGE;
 import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
-import static org.onosproject.yangutils.utils.UtilConstants.PRIVATE;
 import static org.onosproject.yangutils.utils.UtilConstants.REGEX_FOR_ANY_STRING_ENDING_WITH_SERVICE;
 import static org.onosproject.yangutils.utils.UtilConstants.SEMI_COLAN;
-import static org.onosproject.yangutils.utils.UtilConstants.SERVICE_ANNOTATION;
 import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
 import static org.onosproject.yangutils.utils.UtilConstants.SPACE;
-import static org.onosproject.yangutils.utils.UtilConstants.TRUE;
 import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.BUILDER_CLASS;
 import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.BUILDER_INTERFACE;
 import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.ENUM_CLASS;
@@ -97,6 +89,9 @@
 import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.RPC_INTERFACE;
 import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.RPC_MANAGER;
 import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.getJavaDoc;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCamelCase;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getJavaPackageFromPackagePath;
 import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.insertDataIntoJavaFile;
 import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.parsePkg;
 
@@ -130,11 +125,12 @@
      *
      * @param generatedTempFiles    temporary file types
      * @param tempJavaFragmentFiles temp java fragment files
+     * @param absolutePath          absolute path
      * @return data stored in temporary files
      * @throws IOException when failed to get the data from temporary file handle
      */
     public static String getDataFromTempFileHandle(int generatedTempFiles,
-            TempJavaFragmentFiles tempJavaFragmentFiles)
+                                                   TempJavaFragmentFiles tempJavaFragmentFiles, String absolutePath)
             throws IOException {
 
         TempJavaTypeFragmentFiles typeFragmentFiles = null;
@@ -156,49 +152,64 @@
 
         if ((generatedTempFiles & ATTRIBUTES_MASK) != 0) {
             return tempJavaFragmentFiles
-                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getAttributesTempFileHandle());
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getAttributesTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & GETTER_FOR_INTERFACE_MASK) != 0) {
             return tempJavaFragmentFiles
-                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getGetterInterfaceTempFileHandle());
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getGetterInterfaceTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & SETTER_FOR_INTERFACE_MASK) != 0) {
             return tempJavaFragmentFiles
-                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getSetterInterfaceTempFileHandle());
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getSetterInterfaceTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & GETTER_FOR_CLASS_MASK) != 0) {
             return tempJavaFragmentFiles
-                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getGetterImplTempFileHandle());
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getGetterImplTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & SETTER_FOR_CLASS_MASK) != 0) {
             return tempJavaFragmentFiles
-                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getSetterImplTempFileHandle());
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getSetterImplTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & CONSTRUCTOR_IMPL_MASK) != 0) {
             if (beanFragmentFiles == null) {
                 throw new TranslatorException("Required constructor info is missing.");
             }
             return beanFragmentFiles
-                    .getTemporaryDataFromFileHandle(beanFragmentFiles.getConstructorImplTempFileHandle());
+                    .getTemporaryDataFromFileHandle(beanFragmentFiles.getConstructorImplTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & HASH_CODE_IMPL_MASK) != 0) {
             return tempJavaFragmentFiles
-                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getHashCodeImplTempFileHandle());
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getHashCodeImplTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & EQUALS_IMPL_MASK) != 0) {
             return tempJavaFragmentFiles
-                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getEqualsImplTempFileHandle());
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getEqualsImplTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & TO_STRING_IMPL_MASK) != 0) {
             return tempJavaFragmentFiles
-                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getToStringImplTempFileHandle());
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getToStringImplTempFileHandle(),
+                            absolutePath);
+        } else if ((generatedTempFiles & AUGMENTE_CLASS_CONSTRUCTOR_MASK) != 0) {
+            return tempJavaFragmentFiles
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getAugmentConstructorImplTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & OF_STRING_IMPL_MASK) != 0) {
             if (typeFragmentFiles == null) {
                 throw new TranslatorException("Required of string implementation info is missing.");
             }
             return typeFragmentFiles
-                    .getTemporaryDataFromFileHandle(typeFragmentFiles.getOfStringImplTempFileHandle());
+                    .getTemporaryDataFromFileHandle(typeFragmentFiles.getOfStringImplTempFileHandle(), absolutePath);
         } else if ((generatedTempFiles & CONSTRUCTOR_FOR_TYPE_MASK) != 0) {
             if (typeFragmentFiles == null) {
                 throw new TranslatorException("Required constructor implementation info is missing.");
             }
             return typeFragmentFiles
-                    .getTemporaryDataFromFileHandle(typeFragmentFiles.getConstructorForTypeTempFileHandle());
+                    .getTemporaryDataFromFileHandle(typeFragmentFiles.getConstructorForTypeTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & FROM_STRING_IMPL_MASK) != 0) {
             return tempJavaFragmentFiles
-                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getFromStringImplTempFileHandle());
+                    .getTemporaryDataFromFileHandle(tempJavaFragmentFiles.getFromStringImplTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & ENUM_IMPL_MASK) != 0) {
             if (!(tempJavaFragmentFiles instanceof TempJavaEnumerationFragmentFiles)) {
                 throw new TranslatorException("Required enum info is missing.");
@@ -206,49 +217,56 @@
             TempJavaEnumerationFragmentFiles enumFragmentFiles =
                     (TempJavaEnumerationFragmentFiles) tempJavaFragmentFiles;
             return enumFragmentFiles
-                    .getTemporaryDataFromFileHandle(enumFragmentFiles.getEnumClassTempFileHandle());
+                    .getTemporaryDataFromFileHandle(enumFragmentFiles.getEnumClassTempFileHandle(), absolutePath);
         } else if ((generatedTempFiles & RPC_INTERFACE_MASK) != 0) {
             if (serviceFragmentFiles == null) {
                 throw new TranslatorException("Required rpc interface info is missing.");
             }
             return serviceFragmentFiles
-                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getRpcInterfaceTempFileHandle());
+                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getRpcInterfaceTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & RPC_IMPL_MASK) != 0) {
             if (serviceFragmentFiles == null) {
                 throw new TranslatorException("Required rpc implementation info is missing.");
             }
             return serviceFragmentFiles
-                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getRpcImplTempFileHandle());
+                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getRpcImplTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & EVENT_ENUM_MASK) != 0) {
             if (serviceFragmentFiles == null) {
                 throw new TranslatorException("Required rpc implementation info is missing.");
             }
             return serviceFragmentFiles
-                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventEnumTempFileHandle());
+                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventEnumTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & EVENT_METHOD_MASK) != 0) {
             if (serviceFragmentFiles == null) {
                 throw new TranslatorException("Required rpc implementation info is missing.");
             }
             return serviceFragmentFiles
-                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventMethodTempFileHandle());
+                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventMethodTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & EVENT_SUBJECT_GETTER_MASK) != 0) {
             if (serviceFragmentFiles == null) {
                 throw new TranslatorException("Required rpc implementation info is missing.");
             }
             return serviceFragmentFiles
-                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventSubjectGetterTempFileHandle());
+                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventSubjectGetterTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & EVENT_SUBJECT_SETTER_MASK) != 0) {
             if (serviceFragmentFiles == null) {
                 throw new TranslatorException("Required rpc implementation info is missing.");
             }
             return serviceFragmentFiles
-                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventSubjectSetterTempFileHandle());
+                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventSubjectSetterTempFileHandle(),
+                            absolutePath);
         } else if ((generatedTempFiles & EVENT_SUBJECT_ATTRIBUTE_MASK) != 0) {
             if (serviceFragmentFiles == null) {
                 throw new TranslatorException("Required rpc implementation info is missing.");
             }
             return serviceFragmentFiles
-                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventSubjectAttributeTempFileHandle());
+                    .getTemporaryDataFromFileHandle(serviceFragmentFiles.getEventSubjectAttributeTempFileHandle(),
+                            absolutePath);
         }
         return null;
     }
@@ -265,7 +283,7 @@
      * @throws IOException when fails to generate a file
      */
     public static void initiateJavaFileGeneration(File file, String className, int genType, List<String> imports,
-            String pkg, YangPluginConfig pluginConfig)
+                                                  String pkg, YangPluginConfig pluginConfig)
             throws IOException {
 
         try {
@@ -287,16 +305,11 @@
      * @throws IOException when fails to generate a file
      */
     public static void initiateJavaFileGeneration(File file, int genType, List<String> imports,
-            YangNode curNode, String className)
+                                                  YangNode curNode, String className)
             throws IOException {
 
         try {
-            if (file.exists()) {
-                throw new IOException(file.getName() + " is reused due to YANG naming");
-            }
-
             file.createNewFile();
-
             appendContents(file, genType, imports, curNode, className);
         } catch (IOException e) {
             throw new IOException("Failed to create " + file.getName() + " class file.");
@@ -314,7 +327,7 @@
      * @throws IOException
      */
     private static void appendContents(File file, int genType, List<String> importsList, YangNode curNode,
-            String className)
+                                       String className)
             throws IOException {
 
         JavaFileInfo javaFileInfo = ((JavaFileInfoContainer) curNode).getJavaFileInfo();
@@ -322,6 +335,10 @@
         String name = javaFileInfo.getJavaName();
         String path = javaFileInfo.getBaseCodeGenPath() + javaFileInfo.getPackageFilePath();
 
+        YangNode augmentedNode = null;
+        if (curNode instanceof YangAugment) {
+            augmentedNode = ((YangAugment) curNode).getAugmentedNode();
+        }
         String pkgString = null;
         if (genType == GENERATE_EVENT_CLASS
                 || genType == GENERATE_EVENT_LISTENER_INTERFACE
@@ -332,9 +349,23 @@
         }
         switch (genType) {
             case INTERFACE_MASK:
-                appendHeaderContents(file, pkgString, importsList);
+                if (augmentedNode != null) {
+                    appendHeaderContents(file, pkgString, importsList, augmentedNode);
+                } else {
+                    appendHeaderContents(file, pkgString, importsList);
+                }
                 write(file, genType, INTERFACE, curNode, className);
                 break;
+            case IMPL_CLASS_MASK:
+                appendHeaderContents(file, pkgString, importsList);
+                write(file, genType, IMPL_CLASS, curNode, className);
+                break;
+            case BUILDER_CLASS_MASK:
+                write(file, genType, BUILDER_CLASS, curNode, className);
+                break;
+            case BUILDER_INTERFACE_MASK:
+                write(file, genType, BUILDER_INTERFACE, curNode, className);
+                break;
             case GENERATE_SERVICE_AND_MANAGER:
                 appendHeaderContents(file, pkgString, importsList);
                 write(file, genType, RPC_INTERFACE, curNode, className);
@@ -373,26 +404,16 @@
      * @throws IOException when fails to append contents
      */
     private static void appendContents(File file, String fileName, int genType, List<String> importsList, String pkg,
-            YangPluginConfig pluginConfig)
+                                       YangPluginConfig pluginConfig)
             throws IOException {
 
         String pkgString = parsePackageString(pkg, importsList);
 
         switch (genType) {
-            case IMPL_CLASS_MASK:
-                write(file, fileName, genType, IMPL_CLASS, pluginConfig);
-                break;
-            case BUILDER_INTERFACE_MASK:
-                write(file, fileName, genType, BUILDER_INTERFACE, pluginConfig);
-                break;
             case GENERATE_TYPEDEF_CLASS:
                 appendHeaderContents(file, pkgString, importsList);
                 write(file, fileName, genType, IMPL_CLASS, pluginConfig);
                 break;
-            case BUILDER_CLASS_MASK:
-                appendHeaderContents(file, pkgString, importsList);
-                write(file, fileName, genType, BUILDER_CLASS, pluginConfig);
-                break;
             case GENERATE_UNION_CLASS:
                 appendHeaderContents(file, pkgString, importsList);
                 write(file, fileName, genType, IMPL_CLASS, pluginConfig);
@@ -428,7 +449,7 @@
     }
 
     /**
-     * Appends other contents to interface, builder and typedef classes.
+     * Appends other contents to interface, impl and typedef classes.
      * for example : ONOS copyright, imports and package.
      *
      * @param file        generated file
@@ -456,6 +477,39 @@
     }
 
     /**
+     * Appends other contents to interface and impl classes when augmented node is not null.
+     * for example : ONOS copyright, imports and package.
+     *
+     * @param file          generated file
+     * @param pkg           generated package
+     * @param augmentedNode augmented node
+     * @param importsList   list of imports
+     * @throws IOException when fails to append contents
+     */
+    private static void appendHeaderContents(File file, String pkg, List<String> importsList, YangNode augmentedNode)
+            throws IOException {
+
+        insertDataIntoJavaFile(file, CopyrightHeader.getCopyrightHeader());
+        insertDataIntoJavaFile(file, pkg);
+
+        /*
+         * TODO: add the file header using
+         * JavaCodeSnippetGen.getFileHeaderComment
+         */
+
+        if (importsList != null) {
+            insertDataIntoJavaFile(file, NEW_LINE);
+            for (String imports : importsList) {
+                if (!imports.contains(getCapitalCase(DEFAULT) + getCapitalCase(getCamelCase(augmentedNode.getName(),
+                        null)))
+                        && !imports.contains(getCapitalCase(getCamelCase(augmentedNode.getName(), null)) + BUILDER)) {
+                    insertDataIntoJavaFile(file, imports);
+                }
+            }
+        }
+    }
+
+    /**
      * Writes data to the specific generated file.
      *
      * @param file        generated file
@@ -472,7 +526,7 @@
         if ((genType & GENERATE_SERVICE_AND_MANAGER) != 0) {
             if (!fileName.matches(REGEX_FOR_ANY_STRING_ENDING_WITH_SERVICE)) {
                 insertDataIntoJavaFile(file, getJavaDoc(RPC_MANAGER, fileName, false, pluginConfig));
-                insertDataIntoJavaFile(file, addComponentString());
+                insertDataIntoJavaFile(file, JavaCodeSnippetGen.addComponentString());
             } else {
                 insertDataIntoJavaFile(file, getJavaDoc(javaDocType, fileName, false, pluginConfig));
             }
@@ -493,30 +547,10 @@
      * @throws IOException when fails to write into a file
      */
     private static void write(File file, String fileName, int genType, JavaDocType javaDocType,
-            YangPluginConfig pluginConfig)
+                              YangPluginConfig pluginConfig)
             throws IOException {
         insertDataIntoJavaFile(file, getJavaDoc(javaDocType, fileName, false, pluginConfig));
         insertDataIntoJavaFile(file, generateClassDefinition(genType, fileName));
     }
 
-    /**
-     * Returns integer attribute for enum's class to get the values.
-     *
-     * @param className enum's class name
-     * @return enum's attribute
-     */
-    public static String getEnumsValueAttribute(String className) {
-        return NEW_LINE + FOUR_SPACE_INDENTATION + PRIVATE + SPACE + INT + SPACE + getSmallCase(className)
-                + SEMI_COLAN + NEW_LINE;
-    }
-
-    /**
-     * Returns component string.
-     *
-     * @return component string
-     */
-    public static String addComponentString() {
-        return NEW_LINE + COMPONENT_ANNOTATION + SPACE + OPEN_PARENTHESIS + IMMEDIATE + SPACE
-                + EQUAL + SPACE + TRUE + CLOSE_PARENTHESIS + NEW_LINE + SERVICE_ANNOTATION;
-    }
 }