[ONOS-6941] addition of derived identities search

Change-Id: Ibefb62de9c00fdc57cf67d6433b850ddecccfb7a
diff --git a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/javamodel/YangJavaIdentityTranslator.java b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/javamodel/YangJavaIdentityTranslator.java
index 096a1ce..265107e 100644
--- a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/javamodel/YangJavaIdentityTranslator.java
+++ b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/javamodel/YangJavaIdentityTranslator.java
@@ -15,6 +15,11 @@
  */
 package org.onosproject.yang.compiler.translator.tojava.javamodel;
 
+import org.onosproject.yang.compiler.datamodel.YangIdentity;
+import org.onosproject.yang.compiler.datamodel.YangModule;
+import org.onosproject.yang.compiler.datamodel.YangNode;
+import org.onosproject.yang.compiler.datamodel.YangRevision;
+import org.onosproject.yang.compiler.datamodel.YangSubModule;
 import org.onosproject.yang.compiler.datamodel.javadatamodel.YangJavaIdentity;
 import org.onosproject.yang.compiler.translator.exception.TranslatorException;
 import org.onosproject.yang.compiler.translator.tojava.JavaCodeGenerator;
@@ -35,6 +40,7 @@
 import static org.onosproject.yang.compiler.translator.tojava.utils.JavaFileGeneratorUtils.getFileObject;
 import static org.onosproject.yang.compiler.translator.tojava.utils.JavaFileGeneratorUtils.initiateJavaFileGeneration;
 import static org.onosproject.yang.compiler.translator.tojava.utils.JavaIdentifierSyntax.createPackage;
+import static org.onosproject.yang.compiler.translator.tojava.utils.JavaIdentifierSyntax.getRootPackage;
 import static org.onosproject.yang.compiler.translator.tojava.utils.MethodsGenerator.getFromStringMethodForIdentity;
 import static org.onosproject.yang.compiler.translator.tojava.utils.MethodsGenerator.getToStringMethodForIdentity;
 import static org.onosproject.yang.compiler.translator.tojava.utils.TranslatorErrorType.FAIL_AT_ENTRY;
@@ -43,8 +49,10 @@
 import static org.onosproject.yang.compiler.utils.UtilConstants.CLOSE_CURLY_BRACKET;
 import static org.onosproject.yang.compiler.utils.UtilConstants.EMPTY_STRING;
 import static org.onosproject.yang.compiler.utils.UtilConstants.JAVA_FILE_EXTENSION;
+import static org.onosproject.yang.compiler.utils.UtilConstants.PERIOD;
 import static org.onosproject.yang.compiler.utils.io.impl.FileSystemUtil.closeFile;
 import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.formatFile;
+import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.getCamelCase;
 import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.getCapitalCase;
 import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.insertDataIntoJavaFile;
 
@@ -137,7 +145,7 @@
             createPackage(this);
             List<String> imports = null;
             boolean isQualified;
-
+            List<YangIdentity> idList = getExtendList();
             if (getBaseNode() != null && getBaseNode().getReferredIdentity() != null) {
                 if (!(getBaseNode().getReferredIdentity() instanceof YangJavaIdentityTranslator)) {
                     throw new TranslatorException(getErrorMsg(FAIL_AT_ENTRY, this,
@@ -156,12 +164,13 @@
                     imports = importData.getImports(true);
                 }
             }
+            imports = getImportOfDerId(idList, imports, className);
 
             File file = getFileObject(path, className, JAVA_FILE_EXTENSION, itsInfo);
 
             initiateJavaFileGeneration(file, GENERATE_IDENTITY_CLASS, imports, this, className);
             //Add to string and from string method to class
-            addStringMethodsToClass(file, name);
+            addStringMethodsToClass(file, name, idList);
             insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET);
             formatFile(file);
             closeFile(file, false);
@@ -171,10 +180,77 @@
         }
     }
 
-    private void addStringMethodsToClass(File file, String className) throws IOException {
+    /**
+     * Gets the import statements of derived identities.
+     *
+     * @param idList    derived identities list.
+     * @param imports   import statements.
+     * @param className base type class name.
+     * @return list of import statements.
+     */
+    private List<String> getImportOfDerId(List<YangIdentity> idList,
+                                          List<String> imports, String className) {
+        if (idList != null) {
+            for (YangIdentity id : idList) {
+                String derClassName = getCapitalCase(
+                        getCamelCase(id.getName(), null));
+                JavaFileInfoTranslator info = ((
+                        YangJavaIdentityTranslator) id).getJavaFileInfo();
+                String derPkg = info.getPackage();
+                if (derPkg == null) {
+                    derPkg = getDerivedPackage(id);
+                }
+                JavaQualifiedTypeInfoTranslator derPkgInfo =
+                        new JavaQualifiedTypeInfoTranslator();
+                derPkgInfo.setClassInfo(derClassName);
+                derPkgInfo.setPkgInfo(derPkg);
+                importData.addImportInfo(derPkgInfo, className,
+                                         javaFileInfo.getPackage());
+            }
+            imports = importData.getImports(true);
+        }
+        return imports;
+    }
+
+    /**
+     * Gets the derived package of YangIdentity.
+     *
+     * @param id YANG Identity.
+     * @return package of identity.
+     */
+    private String getDerivedPackage(YangIdentity id) {
+        String derPkg = null;
+        byte version;
+        String moduleName;
+        YangRevision revision;
+        String nodeName;
+
+        YangNode node = id.getParent();
+        if (node instanceof YangModule) {
+            YangModule module = (YangModule) node;
+            version = module.getVersion();
+            moduleName = module.getModuleName();
+            revision = module.getRevision();
+            nodeName = module.getName();
+        } else {
+            YangSubModule subModule = (YangSubModule) node;
+            version = subModule.getVersion();
+            moduleName = subModule.getModuleName();
+            revision = subModule.getRevision();
+            nodeName = subModule.getName();
+        }
+        String modulePkg = getRootPackage(version, moduleName, revision, null);
+        String modJava = getCamelCase(nodeName, null);
+        derPkg = modulePkg + PERIOD + modJava.toLowerCase();
+        return derPkg;
+    }
+
+    private void addStringMethodsToClass(File file, String className,
+                                         List<YangIdentity> idList)
+            throws IOException {
         insertDataIntoJavaFile(file, getToStringMethodForIdentity(getName()));
         insertDataIntoJavaFile(file, getFromStringMethodForIdentity(
-                className, getName()));
+                className, getName(), idList));
     }
 
     /**
diff --git a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/MethodsGenerator.java b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/MethodsGenerator.java
index 5f3b6cb..c7630fa 100644
--- a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/MethodsGenerator.java
+++ b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/MethodsGenerator.java
@@ -62,6 +62,7 @@
 import static org.onosproject.yang.compiler.translator.tojava.utils.StringGenerator.getBitSetAttr;
 import static org.onosproject.yang.compiler.translator.tojava.utils.StringGenerator.getCatchSubString;
 import static org.onosproject.yang.compiler.translator.tojava.utils.StringGenerator.getCompareToString;
+import static org.onosproject.yang.compiler.translator.tojava.utils.StringGenerator.getElseIfConditionBegin;
 import static org.onosproject.yang.compiler.translator.tojava.utils.StringGenerator.getExceptionThrowString;
 import static org.onosproject.yang.compiler.translator.tojava.utils.StringGenerator.getForLoopString;
 import static org.onosproject.yang.compiler.translator.tojava.utils.StringGenerator.getGreaterThanCondition;
@@ -1535,7 +1536,6 @@
                 .append(signatureClose())
                 .append(methodClose(FOUR_SPACE));
         return builder.toString();
-
     }
 
     // Returns if condition for add to list method.
@@ -1860,10 +1860,12 @@
      *
      * @param name       name of identity
      * @param schemaName schema name
+     * @param idList     list of derived identities
      * @return from string method
      */
     public static String getFromStringMethodForIdentity(String name,
-                                                        String schemaName) {
+                                                        String schemaName,
+                                                        List<YangIdentity> idList) {
         StringBuilder builder = new StringBuilder(NEW_LINE);
         builder.append(getJavaDoc(FROM_METHOD, name, false, null));
         String caps = getCapitalCase(name);
@@ -1876,7 +1878,21 @@
                                        STRING_DATA_TYPE, CLASS_TYPE))
                 .append(getIfConditionBegin(EIGHT_SPACE_INDENTATION, cond))
                 .append(getReturnString(returnVal, TWELVE_SPACE_INDENTATION))
-                .append(signatureClose()).append(methodClose(EIGHT_SPACE))
+                .append(signatureClose());
+        if (idList != null) {
+            for (YangIdentity id : idList) {
+                cond = getTwoParaEqualsString(FROM_STRING_PARAM_NAME,
+                                              getQuotedString(id.getName()));
+                name = getCamelCase(id.getName(), null);
+                caps = getCapitalCase(name);
+                returnVal = caps + PERIOD + CLASS;
+                builder.append(getElseIfConditionBegin(
+                        EIGHT_SPACE_INDENTATION, cond))
+                        .append(getReturnString(returnVal, TWELVE_SPACE_INDENTATION))
+                        .append(signatureClose());
+            }
+        }
+        builder.append(methodClose(EIGHT_SPACE))
                 .append(getExceptionThrowString(EIGHT_SPACE_INDENTATION))
                 .append(methodClose(FOUR_SPACE));
         return builder.toString();
diff --git a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java
index 97e2a86..01a47f9 100644
--- a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java
+++ b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java
@@ -193,6 +193,38 @@
     }
 
     /**
+     * Checks the derived identities with referred base types in inter modules.
+     *
+     * @throws IOException            if any error occurs during IO on files
+     * @throws ParserException        if any error occurs during parsing
+     * @throws MojoExecutionException if any mojo operation fails
+     */
+    @Test
+    public void processIdentityRefTranslator() throws IOException,
+            ParserException,
+            MojoExecutionException {
+
+        deleteDirectory(DIR);
+        String searchDir = "src/test/resources/DerivedIdentity";
+
+        Set<Path> paths = new HashSet<>();
+        for (String file : getYangFiles(searchDir)) {
+            paths.add(Paths.get(file));
+        }
+
+        utilManager.createYangFileInfoSet(paths);
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+        utilManager.resolveDependenciesUsingLinker();
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(DIR);
+        utilManager.translateToJava(yangPluginConfig);
+        YangPluginConfig.compileCode(COMP);
+        deleteDirectory(DIR);
+    }
+
+    /**
      * Checks collision detection of an augment linked to a target having
      * same node in the same level.
      *
diff --git a/compiler/plugin/maven/src/test/resources/DerivedIdentity/DerivedIdentities.yang b/compiler/plugin/maven/src/test/resources/DerivedIdentity/DerivedIdentities.yang
new file mode 100644
index 0000000..379f832
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/DerivedIdentity/DerivedIdentities.yang
@@ -0,0 +1,31 @@
+module IdentityTypedef {
+    yang-version 1;
+    namespace http://huawei.com;
+    prefix IdentityTypedef;
+
+    identity ref-address-family {
+
+    }
+
+    identity ipv4-address-family {
+        base ref-address-family;
+    }
+
+    identity ipv6-address-family {
+        base ref-address-family;
+    }
+
+    leaf tunnel {
+        type type15;
+    }
+
+    leaf-list network-ref {
+        type type15;
+    }
+
+    typedef type15 {
+        type identityref {
+            base ref-address-family;
+        }
+    }
+}
\ No newline at end of file
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobSimpleDataTypeTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobSimpleDataTypeTest.java
index 65d4c4f..46779de 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobSimpleDataTypeTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobSimpleDataTypeTest.java
@@ -221,6 +221,10 @@
         dBlr = addDataNode(dBlr, "identityref1", DATA_TYPE_NAME_SPACE, value, null);
         dBlr = exitDataNode(dBlr);
 
+        value = "pro";
+        dBlr = addDataNode(dBlr, "identityref2", null, value, null);
+        dBlr = exitDataNode(dBlr);
+
         value = "successful exit";
         dBlr = addDataNode(dBlr, "lfenum1", DATA_TYPE_NAME_SPACE, value, null);
         dBlr = exitDataNode(dBlr);
@@ -679,6 +683,7 @@
         assertThat(cont.lfunion13().toString(), is("b2 "));
         assertThat(cont.lfunion14().toString(), is("one"));
         assertThat(cont.identityref1().getSimpleName(), is("Iden"));
+        assertThat(cont.identityref2().getSimpleName(), is("Pro"));
         assertThat(cont.lfenum1().enumeration(), is(SUCCESSFUL_EXIT));
         assertThat(cont.instIden(), is("/cont"));
         value = 8;
diff --git a/runtime/src/test/resources/yobTestYangFiles/simple-data-types.yang b/runtime/src/test/resources/yobTestYangFiles/simple-data-types.yang
index 1267a0a..d401a9c 100644
--- a/runtime/src/test/resources/yobTestYangFiles/simple-data-types.yang
+++ b/runtime/src/test/resources/yobTestYangFiles/simple-data-types.yang
@@ -295,6 +295,12 @@
             }
         }
 
+        leaf identityref2 {
+            type identityref {
+                base iden;
+            }
+        }
+
         leaf lfenum1 {
             type tpdfun0;
         }