[ONOS-4991][ONOS-4994] Leafref and translator issue fixes
Change-Id: I583ff24e987a680706025f43979469edeb523b50
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaAttributeInfo.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaAttributeInfo.java
index 0f64e2f..1ffbc6e 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaAttributeInfo.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaAttributeInfo.java
@@ -19,6 +19,9 @@
 import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 
+import static org.onosproject.yangutils.translator.tojava.utils.JavaFileGeneratorUtils.isTypeLeafref;
+import static org.onosproject.yangutils.translator.tojava.utils.JavaFileGeneratorUtils.isTypeNameLeafref;
+
 /**
  * Represents the attribute info corresponding to class/interface generated.
  */
@@ -235,6 +238,10 @@
                                                                YangType<?> attributeType, boolean isQualifiedAccess,
                                                                boolean isListAttribute) {
 
+        if (attributeType != null) {
+            attributeType = isTypeLeafref(attributeType);
+        }
+        attributeName = isTypeNameLeafref(attributeName, attributeType);
         JavaAttributeInfo newAttr = new JavaAttributeInfo();
         newAttr.setImportInfo(importInfo);
         newAttr.setAttributeName(attributeName);
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGeneratorUtil.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGeneratorUtil.java
index 2534756..afcb61a 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGeneratorUtil.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGeneratorUtil.java
@@ -17,16 +17,16 @@
 package org.onosproject.yangutils.translator.tojava;
 
 import java.io.IOException;
-
 import org.onosproject.yangutils.datamodel.TraversalType;
 import org.onosproject.yangutils.datamodel.YangInput;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangNodeType;
 import org.onosproject.yangutils.datamodel.YangOutput;
+import org.onosproject.yangutils.datamodel.javadatamodel.JavaFileInfo;
+import org.onosproject.yangutils.datamodel.javadatamodel.YangPluginConfig;
 import org.onosproject.yangutils.translator.exception.InvalidNodeForTranslatorException;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
-import org.onosproject.yangutils.datamodel.javadatamodel.YangPluginConfig;
-import org.onosproject.yangutils.datamodel.javadatamodel.JavaFileInfo;
+
 import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
 import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
 import static org.onosproject.yangutils.datamodel.TraversalType.ROOT;
@@ -279,14 +279,15 @@
             ((TempJavaCodeFragmentFilesContainer) node).getTempJavaCodeFragmentFiles().freeTemporaryResources(true);
         } else {
 
-            JavaFileInfo javaFileInfo = ((JavaFileInfoContainer) getRootNode()).getJavaFileInfo();
-            if (javaFileInfo != null) {
-                searchAndDeleteTempDir(javaFileInfo.getBaseCodeGenPath() +
-                        javaFileInfo.getPackageFilePath());
-            } else {
-                searchAndDeleteTempDir(yangPlugin.getManagerCodeGenDir());
+            if (getRootNode() != null) {
+                JavaFileInfo javaFileInfo = ((JavaFileInfoContainer) getRootNode()).getJavaFileInfo();
+                if (javaFileInfo != null) {
+                    searchAndDeleteTempDir(javaFileInfo.getBaseCodeGenPath() +
+                            javaFileInfo.getPackageFilePath());
+                } else {
+                    searchAndDeleteTempDir(yangPlugin.getManagerCodeGenDir());
+                }
             }
-
         }
     }
 
@@ -320,7 +321,7 @@
         YangNode child = parentNode.getChild();
         TraversalType curTraversal = ROOT;
         if (child == null) {
-            throw new IllegalArgumentException("given parent node does not contain any child nodes");
+            throw new IllegalArgumentException("Given parent node does not contain any child nodes");
         }
 
         while (child != null) {
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/TempJavaEventFragmentFiles.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/TempJavaEventFragmentFiles.java
index 9ca6b4e..cf8e73e 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/TempJavaEventFragmentFiles.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/TempJavaEventFragmentFiles.java
@@ -20,12 +20,10 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.javadatamodel.JavaFileInfo;
-import org.onosproject.yangutils.translator.tojava.javamodel.YangJavaGroupingTranslator;
-import org.onosproject.yangutils.translator.tojava.utils.JavaExtendsListHolder;
 import org.onosproject.yangutils.datamodel.javadatamodel.YangPluginConfig;
+import org.onosproject.yangutils.translator.tojava.utils.JavaExtendsListHolder;
 
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_EVENT_SUBJECT_CLASS;
 import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.EVENT_ENUM_MASK;
@@ -490,15 +488,8 @@
             throws IOException {
 
         JavaFileInfo parentInfo = ((JavaFileInfoContainer) curNode).getJavaFileInfo();
-        YangNode childNode = curNode.getChild();
-
-        // Skip grouping, as it wont have the package name.
-        while (childNode instanceof YangJavaGroupingTranslator) {
-            childNode = childNode.getNextSibling();
-        }
-        JavaFileInfo childInfo = ((JavaFileInfoContainer) childNode).getJavaFileInfo();
         return getFileObject(getDirPath(parentInfo), name, JAVA_FILE_EXTENSION,
-                childInfo.getBaseCodeGenPath());
+                parentInfo.getPluginConfig().getCodeGenDir());
     }
 
     /**
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaTypeDefTranslator.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaTypeDefTranslator.java
index 7cec2df..998cc0f 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaTypeDefTranslator.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaTypeDefTranslator.java
@@ -16,10 +16,13 @@
 package org.onosproject.yangutils.translator.tojava.javamodel;
 
 import java.io.IOException;
-
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
+import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.javadatamodel.JavaFileInfo;
 import org.onosproject.yangutils.datamodel.javadatamodel.YangJavaTypeDef;
 import org.onosproject.yangutils.datamodel.javadatamodel.YangPluginConfig;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
+import org.onosproject.yangutils.translator.exception.InvalidNodeForTranslatorException;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGenerator;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
@@ -105,6 +108,15 @@
      */
     @Override
     public void generateCodeEntry(YangPluginConfig yangPlugin) throws TranslatorException {
+        YangType typeInTypeDef = this.getTypeDefBaseType();
+        if (typeInTypeDef.getDataType() == YangDataTypes.DERIVED) {
+            YangDerivedInfo derivedInfo = (YangDerivedInfo) typeInTypeDef.getDataTypeExtendedInfo();
+            if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.LEAFREF) {
+                throw new InvalidNodeForTranslatorException();
+            }
+        } else if (typeInTypeDef.getDataType() == YangDataTypes.LEAFREF) {
+            throw new InvalidNodeForTranslatorException();
+        }
         try {
             generateCodeOfNode(this, yangPlugin);
         } catch (IOException e) {
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 55c64e4..2c00cc2 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,13 +20,15 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-
 import org.onosproject.yangutils.datamodel.YangAtomicPath;
 import org.onosproject.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
+import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.javadatamodel.JavaFileInfo;
 import org.onosproject.yangutils.datamodel.javadatamodel.YangPluginConfig;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
 import org.onosproject.yangutils.translator.tojava.JavaFileInfoContainer;
@@ -80,6 +82,7 @@
 import static org.onosproject.yangutils.translator.tojava.YangJavaModelUtils.getAugmentedNodesPackage;
 import static org.onosproject.yangutils.translator.tojava.utils.ClassDefinitionGenerator.generateClassDefinition;
 import static org.onosproject.yangutils.utils.UtilConstants.CLOSE_CURLY_BRACKET;
+import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
 import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;
 import static org.onosproject.yangutils.utils.UtilConstants.PACKAGE;
 import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
@@ -705,4 +708,31 @@
 
     }
 
+    /**
+     * Checks if the type name is leafref and returns the effective type name.
+     *
+     * @param attributeName name of the current type
+     * @param attributeType effective type
+     * @return name of the effective type
+     */
+    public static String isTypeNameLeafref(String attributeName, YangType<?> attributeType) {
+        if (attributeName.equalsIgnoreCase(LEAFREF)) {
+            return attributeType.getDataTypeName();
+        }
+        return attributeName;
+    }
+
+    /**
+     * Checks if the type is leafref and returns the effective type.
+     *
+     * @param attributeType current type
+     * @return effective type
+     */
+    public static YangType isTypeLeafref(YangType<?> attributeType) {
+        if (attributeType.getDataType() == YangDataTypes.LEAFREF) {
+            YangLeafRef leafRef = (YangLeafRef) attributeType.getDataTypeExtendedInfo();
+            return leafRef.getEffectiveDataType();
+        }
+        return attributeType;
+    }
 }
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java
index 0d76d7b..2312ba7 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java
@@ -1022,11 +1022,11 @@
      * List of keywords in java, this is used for checking if the input does not contain these keywords.
      */
     public static final List<String> JAVA_KEY_WORDS = Arrays.asList(
-            "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue",
-            "default", "do", "double", "else", "extends", "false", "final", "finally", "float", "for", "goto", "if",
-            "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package",
-            "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch",
-            "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while");
+            "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized",
+            "boolean", "do", "if", "private", "this", "break", "double", "implements", "protected", "throw", "byte",
+            "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", "catch",
+            "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally",
+            "long", "strictfp", "volatile", "const", "float", "native", "super", "while");
 
     /**
      * Static attribute for regex for all the special characters.
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java
index 3b50365..82ad492 100644
--- a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java
@@ -1918,4 +1918,69 @@
         assertThat(leafref.getEffectiveDataType().getDataType(),
                 is(YangDataTypes.DERIVED));
     }
+
+    /**
+     * Checks self resolution when leafref under typedef refers to the node where it is used.
+     */
+    @Test
+    public void processSelfResolutionWhenLeafrefInTypedefIsUsedInSameReferredNode()
+            throws IOException, ParserException {
+
+        String searchDir = "src/test/resources/leafreflinker/intrafile/leafrefintypedefwithsamereferpath";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+        YangNode selfNode = null;
+
+        // Create YANG node set
+        yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
+
+        // Add references to import list.
+        yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
+
+        updateFilePriority(utilManager.getYangNodeSet());
+
+        // Carry out inter-file linking.
+        yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
+
+        Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
+
+        YangNode rootNode = yangNodeIterator.next();
+
+        if (rootNode.getName().equals("typedef")) {
+            selfNode = 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(YangNodeType.MODULE_NODE));
+
+        // Check whether the module name is set correctly.
+        YangModule yangNode = (YangModule) selfNode;
+        assertThat(yangNode.getName(), is("typedef"));
+
+        ListIterator<YangLeaf> leafIterator;
+        YangLeaf leafInfo;
+
+        YangContainer yangContainer = (YangContainer) yangNode.getChild().getNextSibling();
+
+        leafIterator = yangContainer.getListOfLeaf().listIterator();
+        leafInfo = leafIterator.next();
+
+        // Check whether the information in the leaf is correct.
+        assertThat(leafInfo.getName(), is("reference"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
+        assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
+        YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
+
+        // Check whether leafref type got resolved.
+        assertThat(leafref.getResolvableStatus(),
+                is(ResolvableStatus.RESOLVED));
+
+        // Check the effective type for the leaf.
+        assertThat(leafref.getEffectiveDataType().getDataType(),
+                is(YangDataTypes.UINT8));
+    }
 }
diff --git a/utils/yangutils/plugin/src/test/resources/leafreflinker/intrafile/leafrefintypedefwithsamereferpath/SelfResolutionWhenLeafrefInTypedefIsUsedInSameReferredNode.yang b/utils/yangutils/plugin/src/test/resources/leafreflinker/intrafile/leafrefintypedefwithsamereferpath/SelfResolutionWhenLeafrefInTypedefIsUsedInSameReferredNode.yang
new file mode 100644
index 0000000..7506be9
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/resources/leafreflinker/intrafile/leafrefintypedefwithsamereferpath/SelfResolutionWhenLeafrefInTypedefIsUsedInSameReferredNode.yang
@@ -0,0 +1,34 @@
+module typedef {
+    yang-version "1";
+    namespace "http://rob.sh/yang/test/list";
+    prefix "foo";
+    organization "BugReports Inc";
+    contact "Bug reporter";
+
+    description
+        "A test module";
+    revision 2014-01-01 {
+        description "april-fools";
+        reference "fooled-you";
+    }
+
+    typedef referenced-leaf {
+        type leafref {
+            path "/container/target";
+            require-instance false;
+        }
+    }
+
+    container container {
+        description
+            "A container";
+        leaf-list target {
+            type uint8;
+            description
+                "A target leaf for leafref checks";
+        }
+        leaf reference {
+            type referenced-leaf;
+        }
+    }
+}