blob: 1c515f01bb7907cb906d0dbd0ca90b647733774c [file] [log] [blame]
package org.onosproject.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();
}
}