[ONOS-3314] yang model translation into ONOS behaviour interface

Change-Id: Id86e7b696fe4362548d456253f77283c19faa710
diff --git a/tools/package/yangtools/pom.xml b/tools/package/yangtools/pom.xml
new file mode 100644
index 0000000..82422c0
--- /dev/null
+++ b/tools/package/yangtools/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.onosproject</groupId>
+    <artifactId>yangloader</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <dependencies>
+        <dependency>
+            <groupId>commons-configuration</groupId>
+            <artifactId>commons-configuration</artifactId>
+            <version>1.10</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>18.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-misc</artifactId>
+            <version>1.4.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-collections</groupId>
+            <artifactId>commons-collections</artifactId>
+            <version>3.2.1</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-jdk14</artifactId>
+            <version>1.7.12</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.3</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>2.3</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>org.onoproject.yangtool.YangLoaderMain</mainClass>
+                                </transformer>
+                            </transformers>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/tools/package/yangtools/src/main/java/org/onoproject/yangtool/YangLoader.java b/tools/package/yangtools/src/main/java/org/onoproject/yangtool/YangLoader.java
new file mode 100644
index 0000000..3712689
--- /dev/null
+++ b/tools/package/yangtools/src/main/java/org/onoproject/yangtool/YangLoader.java
@@ -0,0 +1,167 @@
+package org.onoproject.yangtool;
+
+import com.google.common.io.Files;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.onlab.util.Tools;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Class that takes in input two paths, one to the yang file and one where
+ * to generate the interface, and a yang container name, generates the sources
+ * through OpenDaylight code generator plugin from yang, and modifies
+ * them accordingly to the needs of the ONOS behavior system.
+ */
+public class YangLoader {
+    /**
+     * Public method to take a yang file from the input folder and generate classes
+     * to the output folder.
+     * @param inputFolder forlder with the yang files
+     * @param completeOuputFolder folder where to put the desired classes
+     * @throws IOException
+     * @throws ConfigurationException
+     * @throws InterruptedException
+     */
+    public void generateBehaviourInterface(String inputFolder,
+                                           String completeOuputFolder)
+            throws IOException, ConfigurationException, InterruptedException {
+        File projectDir = createTemporaryProject(inputFolder);
+        List<String> containerNames = findContainerName(
+                                new File(projectDir.getAbsolutePath() + "/src"));
+        System.out.println("Containers " + containerNames);
+        generateJava(projectDir);
+        //modifyClasses(containerName, projectDir, completeInterfaceOuputFolder);
+        copyFiles(new File(projectDir.getAbsolutePath() + "/dst"),
+                  new File(completeOuputFolder));
+        //System.out.println("Sources in " + completeOuputFolder);
+
+    }
+
+    private List<String> findContainerName(File scrDir) {
+        List<String> allContainers = new ArrayList<>();
+        Arrays.asList(scrDir.listFiles()).stream().forEach(f -> {
+            try {
+                FileUtils.readLines(f).stream()
+                        .filter(line -> line.matches("(.*)container(.*)\\{"))
+                        .collect(Collectors.toList()).forEach(s -> {
+                    s = s.replace("container", "");
+                    s = s.replace("{", "");
+                    allContainers.add(s.trim());
+                });
+
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        });
+        return allContainers;
+    }
+
+    private File createTemporaryProject(String inputFolder) throws IOException,
+            ConfigurationException {
+        File tempDir = Files.createTempDir();
+        File scrDir = new File(tempDir, "src");
+        scrDir.mkdir();
+        copyFiles(new File(inputFolder), scrDir);
+        createPomFile(tempDir, scrDir);
+        return tempDir;
+
+    }
+
+    private void copyFiles(File inputFolder, File scrDir) throws IOException {
+        Tools.copyDirectory(inputFolder, scrDir);
+    }
+
+    private void createPomFile(File tempDir, File scrDir) throws ConfigurationException {
+        File pom = new File(tempDir, "pom.xml");
+        File dstDir = new File(tempDir, "dst");
+        dstDir.mkdir();
+        XMLConfiguration cfg = new XMLConfiguration();
+        cfg.load(getClass().getResourceAsStream("/pom-template.xml"));
+        cfg.setProperty("build.plugins.plugin.executions.execution." +
+                                "configuration.yangFilesRootDir", scrDir.getPath());
+        cfg.setProperty("build.plugins.plugin.executions." +
+                                "execution.configuration.codeGenerators." +
+                                "generator.outputBaseDir", dstDir.getPath());
+        cfg.save(pom);
+    }
+
+    private void generateJava(File projectDir)
+            throws IOException, InterruptedException {
+        Runtime rt = Runtime.getRuntime();
+        Process pr = rt.exec("mvn generate-sources", null, projectDir);
+        String s = IOUtils.toString(pr.getInputStream(), "UTF-8");
+        if (pr.waitFor() == 0) {
+            if (s.contains("[WARNING]")) {
+                System.out.println("Sources not generated, warning log: \n" + s);
+            } else {
+                System.out.println("Sources generated");
+            }
+        } else {
+            System.out.println("Sources not generated. " + s +
+                                       " \nError " + pr.getInputStream().read());
+        }
+    }
+
+    //parsing classes part, for now is not used.
+    private void modifyClasses(String containerName, File projectDir,
+                               String pathToNewInterface) throws IOException {
+        String odlInterfacepath = getPathWithFileName(containerName, projectDir.getPath());
+        odlInterfacepath = odlInterfacepath + "/";
+        parseClass(odlInterfacepath, pathToNewInterface, containerName);
+        System.out.println("ONOS behaviour interface generated " +
+                                   "correctly at " + pathToNewInterface);
+    }
+
+    private String getPathWithFileName(String filename, String pathToGenerated) {
+        File[] directories = new File(pathToGenerated).listFiles(File::isDirectory);
+        while (directories.length != 0) {
+            pathToGenerated = pathToGenerated + "/" + directories[0].getName();
+            directories = new File(pathToGenerated).listFiles(File::isDirectory);
+        }
+        File dir = new File(pathToGenerated);
+        File behaviour = (File) Arrays.asList(dir.listFiles()).stream()
+                .filter(f -> f.getName().equals(filename)).toArray()[0];
+        return behaviour.getParentFile().getAbsolutePath();
+    }
+
+    private void parseClass(String filePath, String pathToNewInterface,
+                            String filename) throws IOException {
+        InputStream fis = null;
+        String newFile = "package org.onosproject.net.behaviour;\n" +
+                "import org.onosproject.net.driver.HandlerBehaviour;\n";
+        fis = new FileInputStream(filePath + filename);
+        InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8"));
+        BufferedReader br = new BufferedReader(isr);
+        String line;
+        while ((line = br.readLine()) != null) {
+            if (!line.contains("org.opendaylight.")) {
+                if (line.contains("ChildOf")) {
+                    newFile = newFile + "HandlerBehaviour\n";
+                } else {
+                    newFile = newFile + line + "\n";
+                }
+            }
+        }
+        PrintWriter out = new PrintWriter(pathToNewInterface +
+                                                  filename.replace(".java", "")
+                                                  + "Interface.java");
+        out.print(newFile);
+        out.flush();
+    }
+
+
+}
diff --git a/tools/package/yangtools/src/main/java/org/onoproject/yangtool/YangLoaderMain.java b/tools/package/yangtools/src/main/java/org/onoproject/yangtool/YangLoaderMain.java
new file mode 100644
index 0000000..7b13767
--- /dev/null
+++ b/tools/package/yangtools/src/main/java/org/onoproject/yangtool/YangLoaderMain.java
@@ -0,0 +1,16 @@
+package org.onoproject.yangtool;
+
+import org.apache.commons.configuration.ConfigurationException;
+
+import java.io.IOException;
+
+/**
+ * Main of the uangloader tool in order to be called through command line.
+ */
+public class YangLoaderMain {
+    public static void main (String args []) throws IOException,
+            ConfigurationException, InterruptedException {
+        YangLoader yl = new YangLoader();
+        yl.generateBehaviourInterface(args[0], args[1]);
+    }
+}
diff --git a/tools/package/yangtools/src/main/resources/pom-template.xml b/tools/package/yangtools/src/main/resources/pom-template.xml
new file mode 100644
index 0000000..5280e21
--- /dev/null
+++ b/tools/package/yangtools/src/main/resources/pom-template.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>groupId</groupId>
+    <artifactId>yangloader</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <pluginRepositories>
+        <pluginRepository>
+            <id>opendaylight-release</id>
+            <name>opendaylight-release</name>
+            <url>
+                http://nexus.opendaylight.org/content/repositories/opendaylight.release/
+            </url>
+        </pluginRepository>
+        <pluginRepository>
+            <id>opendaylight-snapshot</id>
+            <name>opendaylight-snapshot</name>
+            <url>
+                http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/
+            </url>
+        </pluginRepository>
+    </pluginRepositories>
+    <repositories>
+        <repository>
+            <id>opendaylight-release</id>
+            <name>opendaylight-release</name>
+            <url>
+                http://nexus.opendaylight.org/content/repositories/opendaylight.release/
+            </url>
+        </repository>
+        <repository>
+            <id>opendaylight-snapshot</id>
+            <name>opendaylight-snapshot</name>
+            <url>
+                http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/
+            </url>
+        </repository>
+    </repositories>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-binding</artifactId>
+            <version>0.7.2-Lithium-SR2</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+                <version>0.7.2-Lithium-SR2</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate-sources</goal>
+                        </goals>
+                        <configuration>
+                            <!-- directory containing yang files to parse and generate code -->
+                            <yangFilesRootDir>INPUTDIR</yangFilesRootDir>
+                            <codeGenerators>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <!-- directory into which generated files will be placed -->
+                                    <outputBaseDir>OUTPUTDIR</outputBaseDir>
+                                </generator>
+                            </codeGenerators>
+                            <inspectDependencies>false</inspectDependencies>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.opendaylight.yangtools</groupId>
+                        <artifactId>maven-sal-api-gen-plugin</artifactId>
+                        <version>0.7.2-Lithium-SR2</version>
+                        <type>jar</type>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.3</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>