[ONOS-4712] inter jar file linker unit test case.

Change-Id: I566b9ce59cb37e664914f99263c597ead7ce5e11
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/plugin/manager/YangPluginUtils.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/plugin/manager/YangPluginUtils.java
index ef218d5..ccb43e3 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/plugin/manager/YangPluginUtils.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/plugin/manager/YangPluginUtils.java
@@ -32,6 +32,7 @@
 import java.util.Set;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
+
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Resource;
@@ -192,8 +193,9 @@
 
         StringBuilder path = new StringBuilder();
         List<String> jarPaths = new ArrayList<>();
-        for (Dependency dependency : project.getDependencies()) {
+        for (Object obj : project.getDependencies()) {
 
+            Dependency dependency = (Dependency) obj;
             path.append(localRepository.getBasedir());
             path.append(SLASH);
             path.append(getPackageDirPathFromJavaJPackage(dependency.getGroupId()));
diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterJarLinkerTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterJarLinkerTest.java
new file mode 100644
index 0000000..5efc477
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterJarLinkerTest.java
@@ -0,0 +1,353 @@
+/*
+ * 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.plugin.manager;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangContainer;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
+import org.onosproject.yangutils.datamodel.YangGrouping;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.utils.io.impl.YangFileScanner;
+import org.onosproject.yangutils.utils.io.impl.YangPluginConfig;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.STRING;
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
+import static org.onosproject.yangutils.plugin.manager.YangPluginUtils.deSerializeDataModel;
+import static org.onosproject.yangutils.plugin.manager.YangPluginUtils.parseJarFile;
+import static org.onosproject.yangutils.plugin.manager.YangPluginUtils.serializeDataModel;
+import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
+import static org.onosproject.yangutils.utils.UtilConstants.TEMP;
+import static org.onosproject.yangutils.utils.UtilConstants.YANG_RESOURCES;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
+
+/**
+ * Unit test case for inter jar linker.
+ */
+public class InterJarLinkerTest {
+
+    private final YangUtilManager utilManager = new YangUtilManager();
+
+    private static final String TARGET = "target/interJarFileLinking/";
+    private static final String YANG_FILES_DIR = "src/test/resources/interJarFileLinking/yangFiles/";
+    private static final String TARGET_RESOURCE_PATH = SLASH + TEMP + SLASH + YANG_RESOURCES + SLASH;
+    private static final String JAR_FILE_NAME = "onlab-test-1.7.0-SNAPSHOT.jar";
+    private static final String SER_FILE_NAME = "portPair.ser";
+
+    private static final String FLOW_CLASSIFIER_FOLDER = "target/interJarFileLinking/org/onosproject"
+            + "/yang/gen/v1/sfc/flowclassifier/rev20160524";
+    private static final String PORT_PAIR_FOLDER = "target/interJarFileLinking/org/onosproject"
+            + "/yang/gen/v1/sfc/portpair/rev20160524";
+    private static final String FLOW_CLASSIFIER_MANAGER = FLOW_CLASSIFIER_FOLDER + SLASH + "FlowClassifierManager.java";
+
+    /**
+     * Unit test case for a single jar dependency.
+     *
+     * @throws IOException when fails to do IO operations
+     * @throws MojoExecutionException when fails to do mojo operations
+     */
+    @Test
+    public void processSingleJarLinking()
+            throws IOException, MojoExecutionException {
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(YANG_FILES_DIR));
+
+        int size1 = utilManager.getYangFileInfoSet().size();
+        utilManager.parseYangFileInfoSet();
+
+        provideTestJarFile();
+        utilManager.setYangFileInfoSet(removeFileInfoFromSet(utilManager.getYangFileInfoSet()));
+
+        for (String file : getListOfTestJar(TARGET)) {
+            addInterJarRootNodes(file);
+        }
+
+        utilManager.resolveDependenciesUsingLinker();
+
+        int size2 = utilManager.getYangFileInfoSet().size();
+        assertThat(true, is(size1 != size2));
+        assertThat(true, is(parseFileInfoSet(utilManager.getYangFileInfoSet().iterator())));
+
+        deleteDirectory(TARGET);
+        deleteTestSerFile();
+    }
+
+    /**
+     * Unit test case for a multiple jar dependency.
+     *
+     * @throws IOException when fails to do IO operations
+     * @throws MojoExecutionException when fails to do mojo operations
+     */
+    @Test
+    public void processMultipleJarLinking()
+            throws IOException, MojoExecutionException {
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(YANG_FILES_DIR));
+
+        int size1 = utilManager.getYangFileInfoSet().size();
+        utilManager.parseYangFileInfoSet();
+
+        provideTestJarFile();
+        utilManager.setYangFileInfoSet(removeFileInfoFromSet(utilManager.getYangFileInfoSet()));
+        for (String file : getListOfTestJar(TARGET)) {
+            addInterJarRootNodes(file);
+        }
+
+        utilManager.resolveDependenciesUsingLinker();
+        int size2 = utilManager.getYangFileInfoSet().size();
+        assertThat(true, is(size1 != size2));
+        assertThat(true, is(parseFileInfoSet(utilManager.getYangFileInfoSet().iterator())));
+        assertThat(true, is(parseFileInfoSet(utilManager.getYangFileInfoSet().iterator())));
+
+        /*
+         * grouping flow-classifier {
+         *      container flow-classifier {
+         *           leaf id {
+         *                type flow-classifier-id;
+         *           }
+         *
+         *           leaf tenant-id {
+         *                type port-pair:tenant-id;
+         *           }
+         *           .
+         *           .
+         *           .
+         *
+         */
+
+        Iterator<YangFileInfo> yangFileInfoIterator = utilManager.getYangFileInfoSet().iterator();
+
+        YangFileInfo yangFileInfo = yangFileInfoIterator.next();
+
+        while (yangFileInfoIterator.hasNext()) {
+            if (yangFileInfo.getRootNode().getName().equals("flow-classifier")) {
+                break;
+            }
+            yangFileInfo = yangFileInfoIterator.next();
+        }
+
+        YangNode node = yangFileInfo.getRootNode();
+        node = node.getChild();
+        while (node != null) {
+            if (node instanceof YangGrouping) {
+                break;
+            }
+            node = node.getNextSibling();
+        }
+
+        node = node.getChild();
+        ListIterator<YangLeaf> leafIterator = ((YangContainer) node).getListOfLeaf().listIterator();
+        YangLeaf leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("id"));
+        assertThat(leafInfo.getDataType().getDataTypeName(), is("flow-classifier-id"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        leafInfo = leafIterator.next();
+
+        assertThat(leafInfo.getName(), is("tenant-id"));
+        assertThat(leafInfo.getDataType().getDataType(), is(DERIVED));
+
+        assertThat(true, is(((YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef()
+                .getName().equals("tenant-id")));
+
+        assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED));
+
+        YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) leafInfo.getDataType().getDataTypeExtendedInfo();
+
+        // Check for the effective built-in type.
+        assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING));
+
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir(TARGET);
+
+        utilManager.translateToJava(utilManager.getYangFileInfoSet(), yangPluginConfig);
+
+        testIfFlowClassifierFilesExists();
+        testIfPortPairFileDoesNotExist();
+        deleteDirectory(TARGET);
+        deleteTestSerFile();
+    }
+
+    /**
+     * Test if flow classifier code is generated.
+     */
+    private void testIfFlowClassifierFilesExists() {
+        File folder = new File(System.getProperty("user.dir") + SLASH + FLOW_CLASSIFIER_FOLDER);
+        File file = new File(System.getProperty("user.dir") + SLASH + FLOW_CLASSIFIER_MANAGER);
+        assertThat(true, is(folder.exists()));
+        assertThat(true, is(file.exists()));
+    }
+
+    /**
+     * Tests if port pair code is not generated.
+     */
+    private void testIfPortPairFileDoesNotExist() {
+        File folder = new File(System.getProperty("user.dir") + SLASH + PORT_PAIR_FOLDER);
+        assertThat(false, is(folder.exists()));
+    }
+
+    /**
+     * Need to remove port-pair YANG file info from the set so , serialized file info can be
+     * tested.
+     *
+     * @param fileInfoSet YANG file info set
+     * @return updated file info set
+     */
+    private Set<YangFileInfo> removeFileInfoFromSet(Set<YangFileInfo> fileInfoSet) {
+        String portPairFile = System.getProperty("user.dir") + SLASH + YANG_FILES_DIR + "portpair.yang";
+        for (YangFileInfo fileInfo : fileInfoSet) {
+            if (fileInfo.getYangFileName().equals(portPairFile)) {
+                fileInfoSet.remove(fileInfo);
+                return fileInfoSet;
+            }
+        }
+        return fileInfoSet;
+    }
+
+    /**
+     * Provides test jar files for linker.
+     *
+     * @throws IOException when fails to do IO operations
+     */
+    private void provideTestJarFile() throws IOException {
+
+        MavenProject project = new MavenProject();
+        serializeDataModel(TARGET, utilManager.getYangFileInfoSet(), project, false);
+        createTestJar();
+    }
+
+    /**
+     * Deletes serialized file.
+     */
+    private void deleteTestSerFile() {
+        File ser = new File(System.getProperty("user.dir") + SLASH + YANG_FILES_DIR + SER_FILE_NAME);
+        ser.delete();
+    }
+
+    /**
+     * Parses file info list and returns true if file info list contains the serialized file info.
+     *
+     * @param yangFileInfoIterator file info list iterator
+     * @return true if present
+     */
+    private boolean parseFileInfoSet(Iterator<YangFileInfo> yangFileInfoIterator) {
+        YangFileInfo yangFileInfo = yangFileInfoIterator.next();
+        while (yangFileInfoIterator.hasNext()) {
+            if (yangFileInfo.getRootNode().getName().equals("port-pair")) {
+                return true;
+            } else if (yangFileInfo.getRootNode().getName().equals("flow-classifier")) {
+                return true;
+            }
+            yangFileInfo = yangFileInfoIterator.next();
+        }
+        return false;
+
+    }
+
+    /**
+     * Returns list of test jar files.
+     *
+     * @param searchdir search directory
+     * @return list of test jar files
+     */
+    private List<String> getListOfTestJar(String searchdir) {
+        List<String> jarFiles = new ArrayList<>();
+
+        File directory = new File(searchdir + "/");
+        File[] files = directory.listFiles();
+
+        for (File file : files) {
+            if (!file.isDirectory()) {
+                jarFiles.add(file.toString());
+            }
+        }
+
+        return jarFiles;
+    }
+
+    /**
+     * Adds data model nodes of jar to file info set.
+     *
+     * @param jarFile jar file name
+     * @throws IOException when fails to do IO operations
+     */
+    private void addInterJarRootNodes(String jarFile) throws IOException {
+        try {
+            List<YangNode> interJarResolvedNodes = deSerializeDataModel(parseJarFile(jarFile, TARGET));
+
+            for (YangNode node : interJarResolvedNodes) {
+                YangFileInfo dependentFileInfo = new YangFileInfo();
+                dependentFileInfo.setRootNode(node);
+                dependentFileInfo.setForTranslator(false);
+                dependentFileInfo.setYangFileName(node.getName());
+                utilManager.getYangFileInfoSet().add(dependentFileInfo);
+            }
+        } catch (IOException e) {
+            throw new IOException("failed to resolve in interjar scenario.");
+        }
+    }
+
+    /**
+     * Creates a temporary test jar files.
+     */
+    private void createTestJar() {
+
+        File file = new File(TARGET + TARGET_RESOURCE_PATH);
+        File[] files = file.listFiles();
+
+        String[] source = new String[files.length];
+
+        for (int i = 0; i < files.length; i++) {
+            source[i] = files[i].toString();
+        }
+        byte[] buf = new byte[1024];
+
+        try {
+            String target = TARGET + JAR_FILE_NAME;
+            JarOutputStream out = new JarOutputStream(new FileOutputStream(target));
+            for (String element : source) {
+                FileInputStream in = new FileInputStream(element);
+                out.putNextEntry(new JarEntry(element));
+                int len;
+                while ((len = in.read(buf)) > 0) {
+                    out.write(buf, 0, len);
+                }
+                out.closeEntry();
+                in.close();
+            }
+            out.close();
+        } catch (IOException e) {
+        }
+    }
+
+}
diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test1-1.7.0-SNAPSHOT.jar b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test1-1.7.0-SNAPSHOT.jar
deleted file mode 100644
index 7e8459b..0000000
--- a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test1-1.7.0-SNAPSHOT.jar
+++ /dev/null
Binary files differ
diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test2-1.7.0-SNAPSHOT.jar b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test2-1.7.0-SNAPSHOT.jar
deleted file mode 100644
index 22cbdb9..0000000
--- a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test2-1.7.0-SNAPSHOT.jar
+++ /dev/null
Binary files differ
diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/single/onlab-test1-1.7.0-SNAPSHOT.jar b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/single/onlab-test1-1.7.0-SNAPSHOT.jar
deleted file mode 100644
index 7e8459b..0000000
--- a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/single/onlab-test1-1.7.0-SNAPSHOT.jar
+++ /dev/null
Binary files differ
diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/flowclassifier.yang b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/flowclassifier.yang
new file mode 100644
index 0000000..0fa3ba1
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/flowclassifier.yang
@@ -0,0 +1,175 @@
+module flow-classifier {
+
+    yang-version 1;
+
+    namespace "sfc.flowclassifier";
+
+    prefix "flow-classifier";
+
+    import "port-pair" {
+        prefix "port-pair";
+    } 
+    
+    organization "ON-LAB";
+
+    description "This submodule defines for flow classifier.";
+
+    revision "2016-05-24" {
+        description "Initial revision.";
+    }
+
+    typedef flow-classifier-id {
+        type port-pair:uuid;
+    }
+
+    typedef IpPrefix {
+        type string;
+    }
+
+    typedef VirtualPortId {
+        type string;
+    }
+ 
+    grouping flow-classifier {
+        container flow-classifier {
+        	leaf id {
+                    type flow-classifier-id;
+        	}
+
+        	leaf tenant-id {
+        	    type port-pair:tenant-id;
+        	}
+
+        	leaf name {
+           	    type string;
+          	}
+ 
+        	leaf description {
+            	    type string;
+        	}
+    
+        	leaf etherType {
+            	    type string;
+        	}
+
+        	leaf protocol {
+            	    type string;
+        	}
+
+        	leaf priority {
+            	    type int32;
+        	}
+
+        	leaf minSrcPortRange {
+           	    type int32;
+        	}
+
+        	leaf maxSrcPortRange {
+            	    type int32;
+        	}
+
+       		leaf minDstPortRange {
+            	    type int32;
+        	}  
+
+        	leaf maxDstPortRange {
+            	    type int32;
+        	}
+
+        	leaf srcIpPrefix {
+            	    type IpPrefix;
+        	}
+
+        	leaf dstIpPrefix {
+            	    type IpPrefix;
+        	}
+
+        	leaf srcPort {
+	   	    type VirtualPortId;
+        	}
+
+        	leaf dstPort {
+	    	    type VirtualPortId;
+        	}
+    	}
+    }
+   rpc exists {
+      input {
+         leaf id {
+            type flow-classifier-id;
+          }
+      }
+      output {
+          leaf is-present {
+              type boolean;
+          }
+      }
+    }
+
+   rpc get-flow-classifier-count {
+      
+      output {
+          leaf count {
+              type int32;
+          }
+      }
+    }
+   
+   rpc get-flow-classifier {
+      input {
+         leaf id {
+            type flow-classifier-id;
+          }
+      }
+      output {
+          uses flow-classifier;
+      }
+    }
+
+   rpc create-flow-classifier {
+      input {
+          uses flow-classifier;
+      }
+      output {
+          leaf is-created {
+              type boolean;
+          }
+      }
+    }
+
+   rpc update-flow-classifier {
+      input {
+          uses flow-classifier;
+      }
+      output {
+          leaf is-updated {
+              type boolean;
+          }
+      }
+    }
+
+   rpc remove-flow-classifier {
+      input {
+         leaf id {
+            type flow-classifier-id;
+          }
+      }
+      output {
+          leaf is-removed {
+              type boolean;
+          }
+      }
+    }
+ 
+    notification Flow-Classifier-Put {
+       uses flow-classifier;
+    }
+    
+    notification Flow-Classifier-Delete {
+       uses flow-classifier;
+    }
+
+    notification Flow-Classifier-Update {
+        uses flow-classifier;
+    }
+}
diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/portpair.yang b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/portpair.yang
new file mode 100644
index 0000000..ee67c62
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/portpair.yang
@@ -0,0 +1,137 @@
+module port-pair {
+
+    yang-version 1;
+
+    namespace "sfc.portpair";
+
+    prefix "port-pair";
+   
+    organization "Huawei india pvt. ltd..";
+
+    description "This submodule defines for port pair.";
+
+    revision "2016-05-24" {
+        description "Initial revision.";
+    }
+
+    typedef uuid {
+    	type string;
+    }
+
+    typedef port-pair-id {
+        type uuid;
+    }
+
+    typedef tenant-id {
+        type uuid;
+    }
+    
+     grouping port-pair {
+        container  port-pair {
+
+        	leaf name {
+           	    type string;
+        	}
+
+        	leaf id {
+           	    type port-pair-id;
+        	}
+
+        	leaf tenantIdentifier {
+           	    type tenant-id;
+        	}
+
+        	leaf description {
+            	    type string;
+        	}
+
+        	leaf ingress {
+            	    type uuid;
+        	}
+
+        	leaf egress {
+           	    type uuid;
+        	}  
+   	}
+    }
+   rpc exists {
+      input {
+         leaf id {
+            type port-pair-id;
+          }
+      }
+      output {
+          leaf is-present {
+              type boolean;
+          }
+      }
+    }
+
+   rpc get-port-pair-count {
+      
+      output {
+          leaf count {
+              type int32;
+          }
+      }
+    }
+   
+   rpc get-port-pair {
+      input {
+         leaf id {
+            type port-pair-id;
+          }
+      }
+      output {
+          uses port-pair;
+      }
+    }
+
+   rpc create-port-pair {
+      input {
+          uses port-pair;
+      }
+      output {
+          leaf is-created {
+              type boolean;
+          }
+      }
+    }
+
+   rpc update-port-pair {
+      input {
+          uses port-pair;
+      }
+      output {
+          leaf is-updated {
+              type boolean;
+          }
+      }
+    }
+
+   rpc remove-port-pair {
+      input {
+         leaf id {
+            type port-pair-id;
+          }
+      }
+      output {
+          leaf is-removed {
+              type boolean;
+          }
+      }
+    }
+     
+ 
+    notification port-pair-put {
+        uses port-pair;
+    }
+    
+    notification port-pair-Delete {
+        uses port-pair;
+    }
+
+    notification port-pair-Update {
+        uses port-pair;
+    }   
+}
diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/test.yang b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/test.yang
new file mode 100644
index 0000000..4e7275c
--- /dev/null
+++ b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/test.yang
@@ -0,0 +1,29 @@
+module Test {
+    yang-version 1;
+    namespace http://huawei.com;
+    prefix Ant;
+    container valid {
+        leaf invalid-interval {
+            type "uint16";
+            units "seconds";
+            status current;
+            reference "RFC 6020";
+        }
+    }
+    container invalid {
+        leaf invalid-interval {
+            type "uint16";
+            units "seconds";
+            status current;
+            reference "RFC 6020";
+        }
+    }
+    container valid2 {
+        leaf invalid-interval {
+            type "uint16";
+            units "seconds";
+            status current;
+            reference "RFC 6020";
+        }
+    }
+}