blob: 1c515f01bb7907cb906d0dbd0ca90b647733774c [file] [log] [blame]
Jian Lidc94fc92016-01-29 17:38:11 -08001package org.onosproject.yangtool;
andreaa9d838e2015-11-10 18:18:10 -08002
3import com.google.common.io.Files;
4import org.apache.commons.configuration.ConfigurationException;
5import org.apache.commons.configuration.XMLConfiguration;
6import org.apache.commons.io.FileUtils;
7import org.apache.commons.io.IOUtils;
8import org.onlab.util.Tools;
9
10import java.io.BufferedReader;
11import java.io.File;
12import java.io.FileInputStream;
13import java.io.IOException;
14import java.io.InputStream;
15import java.io.InputStreamReader;
16import java.io.PrintWriter;
17import java.nio.charset.Charset;
18import java.util.ArrayList;
19import java.util.Arrays;
20import java.util.List;
21import java.util.stream.Collectors;
22
23/**
24 * Class that takes in input two paths, one to the yang file and one where
25 * to generate the interface, and a yang container name, generates the sources
26 * through OpenDaylight code generator plugin from yang, and modifies
27 * them accordingly to the needs of the ONOS behavior system.
28 */
29public class YangLoader {
30 /**
31 * Public method to take a yang file from the input folder and generate classes
32 * to the output folder.
33 * @param inputFolder forlder with the yang files
34 * @param completeOuputFolder folder where to put the desired classes
35 * @throws IOException
36 * @throws ConfigurationException
37 * @throws InterruptedException
38 */
39 public void generateBehaviourInterface(String inputFolder,
40 String completeOuputFolder)
41 throws IOException, ConfigurationException, InterruptedException {
42 File projectDir = createTemporaryProject(inputFolder);
43 List<String> containerNames = findContainerName(
44 new File(projectDir.getAbsolutePath() + "/src"));
45 System.out.println("Containers " + containerNames);
46 generateJava(projectDir);
47 //modifyClasses(containerName, projectDir, completeInterfaceOuputFolder);
48 copyFiles(new File(projectDir.getAbsolutePath() + "/dst"),
49 new File(completeOuputFolder));
50 //System.out.println("Sources in " + completeOuputFolder);
51
52 }
53
54 private List<String> findContainerName(File scrDir) {
55 List<String> allContainers = new ArrayList<>();
56 Arrays.asList(scrDir.listFiles()).stream().forEach(f -> {
57 try {
58 FileUtils.readLines(f).stream()
59 .filter(line -> line.matches("(.*)container(.*)\\{"))
60 .collect(Collectors.toList()).forEach(s -> {
61 s = s.replace("container", "");
62 s = s.replace("{", "");
63 allContainers.add(s.trim());
64 });
65
66 } catch (IOException e) {
67 throw new RuntimeException(e);
68 }
69 });
70 return allContainers;
71 }
72
73 private File createTemporaryProject(String inputFolder) throws IOException,
74 ConfigurationException {
75 File tempDir = Files.createTempDir();
76 File scrDir = new File(tempDir, "src");
77 scrDir.mkdir();
78 copyFiles(new File(inputFolder), scrDir);
79 createPomFile(tempDir, scrDir);
80 return tempDir;
81
82 }
83
84 private void copyFiles(File inputFolder, File scrDir) throws IOException {
85 Tools.copyDirectory(inputFolder, scrDir);
86 }
87
88 private void createPomFile(File tempDir, File scrDir) throws ConfigurationException {
89 File pom = new File(tempDir, "pom.xml");
90 File dstDir = new File(tempDir, "dst");
91 dstDir.mkdir();
92 XMLConfiguration cfg = new XMLConfiguration();
93 cfg.load(getClass().getResourceAsStream("/pom-template.xml"));
94 cfg.setProperty("build.plugins.plugin.executions.execution." +
95 "configuration.yangFilesRootDir", scrDir.getPath());
96 cfg.setProperty("build.plugins.plugin.executions." +
97 "execution.configuration.codeGenerators." +
98 "generator.outputBaseDir", dstDir.getPath());
99 cfg.save(pom);
100 }
101
102 private void generateJava(File projectDir)
103 throws IOException, InterruptedException {
104 Runtime rt = Runtime.getRuntime();
105 Process pr = rt.exec("mvn generate-sources", null, projectDir);
106 String s = IOUtils.toString(pr.getInputStream(), "UTF-8");
107 if (pr.waitFor() == 0) {
108 if (s.contains("[WARNING]")) {
109 System.out.println("Sources not generated, warning log: \n" + s);
110 } else {
111 System.out.println("Sources generated");
112 }
113 } else {
114 System.out.println("Sources not generated. " + s +
115 " \nError " + pr.getInputStream().read());
116 }
117 }
118
119 //parsing classes part, for now is not used.
120 private void modifyClasses(String containerName, File projectDir,
121 String pathToNewInterface) throws IOException {
122 String odlInterfacepath = getPathWithFileName(containerName, projectDir.getPath());
123 odlInterfacepath = odlInterfacepath + "/";
124 parseClass(odlInterfacepath, pathToNewInterface, containerName);
125 System.out.println("ONOS behaviour interface generated " +
126 "correctly at " + pathToNewInterface);
127 }
128
129 private String getPathWithFileName(String filename, String pathToGenerated) {
130 File[] directories = new File(pathToGenerated).listFiles(File::isDirectory);
131 while (directories.length != 0) {
132 pathToGenerated = pathToGenerated + "/" + directories[0].getName();
133 directories = new File(pathToGenerated).listFiles(File::isDirectory);
134 }
135 File dir = new File(pathToGenerated);
136 File behaviour = (File) Arrays.asList(dir.listFiles()).stream()
137 .filter(f -> f.getName().equals(filename)).toArray()[0];
138 return behaviour.getParentFile().getAbsolutePath();
139 }
140
141 private void parseClass(String filePath, String pathToNewInterface,
142 String filename) throws IOException {
143 InputStream fis = null;
144 String newFile = "package org.onosproject.net.behaviour;\n" +
145 "import org.onosproject.net.driver.HandlerBehaviour;\n";
146 fis = new FileInputStream(filePath + filename);
147 InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8"));
148 BufferedReader br = new BufferedReader(isr);
149 String line;
150 while ((line = br.readLine()) != null) {
151 if (!line.contains("org.opendaylight.")) {
152 if (line.contains("ChildOf")) {
153 newFile = newFile + "HandlerBehaviour\n";
154 } else {
155 newFile = newFile + line + "\n";
156 }
157 }
158 }
159 PrintWriter out = new PrintWriter(pathToNewInterface +
160 filename.replace(".java", "")
161 + "Interface.java");
162 out.print(newFile);
163 out.flush();
164 }
165
166
167}