aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/tools/package/yangtools/src/main/java/org/onoproject/yangtool/YangLoader.java
blob: 371268904c6c81edde2df693b8a25c543899983a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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();
    }


}