--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.sal.java.api.generator.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl;
+import org.opendaylight.yangtools.sal.binding.model.api.Type;
+import org.opendaylight.yangtools.sal.java.api.generator.GeneratorJavaFile;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+/**
+ * Test correct code generation.
+ *
+ */
+public class CompilationTest {
+ private static final String FS = File.separator;
+ private static final String TEST_PATH = "target" + FS + "test";
+ private static final File TEST_DIR = new File(TEST_PATH);
+
+ private static final String GENERATOR_OUTPUT_PATH = TEST_PATH + FS + "src";
+ private static final File GENERATOR_OUTPUT_DIR = new File(GENERATOR_OUTPUT_PATH);
+ private static final String COMPILER_OUTPUT_PATH = TEST_PATH + FS + "bin";
+ private static final File COMPILER_OUTPUT_DIR = new File(COMPILER_OUTPUT_PATH);
+
+ private YangParserImpl parser;
+ private BindingGenerator bindingGenerator;
+
+ @BeforeClass
+ public static void createTestDirs() {
+ if (TEST_DIR.exists()) {
+ deleteTestDir(TEST_DIR);
+ }
+ assertTrue(GENERATOR_OUTPUT_DIR.mkdirs());
+ assertTrue(COMPILER_OUTPUT_DIR.mkdirs());
+ }
+
+ @Before
+ public void init() {
+ parser = new YangParserImpl();
+ bindingGenerator = new BindingGeneratorImpl();
+ }
+
+ /**
+ * Method to clean resources. It is manually called at the end of each test
+ * instead of marking it with @After annotation to prevent removing
+ * generated code if test fails.
+ */
+ public void cleanUp(File... resourceDirs) {
+ for (File resourceDir : resourceDirs) {
+ if (resourceDir.exists()) {
+ deleteTestDir(resourceDir);
+ }
+ }
+ }
+
+ @Test
+ public void testListGeneration() throws Exception {
+ final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "list-gen");
+ assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
+ final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "list-gen");
+ assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
+
+ final List<File> sourceFiles = getSourceFiles("/compilation/list-gen");
+ final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
+ final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
+ final List<Type> types = bindingGenerator.generateTypes(context);
+ final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+ generator.generateToFile(sourcesOutputDir);
+
+ File parent = new File(sourcesOutputDir, "org" + FS + "opendaylight" + FS + "yang" + FS + "gen" + FS + "v1"
+ + FS + "urn" + FS + "opendaylight" + FS + "test" + FS + "rev131008");
+ File linksKeyFile = new File(parent, "LinksKey.java");
+ assertTrue(new File(parent, "KeyArgs.java").exists());
+ assertTrue(new File(parent, "Links.java").exists());
+ assertTrue(new File(parent, "LinksBuilder.java").exists());
+ assertTrue(linksKeyFile.exists());
+ assertTrue(new File(parent, "TestData.java").exists());
+ assertTrue(new File(parent, "links" + FS + "Level.java").exists());
+ assertTrue(new File(parent, "links" + FS + "LinkGroup.java").exists());
+ assertTrue(new File(parent, "links" + FS + "Node.java").exists());
+ assertTrue(new File(parent, "links" + FS + "NodeBuilder.java").exists());
+ assertTrue(new File(parent, "links" + FS + "NodeList.java").exists());
+ assertTrue(new File(parent, "links" + FS + "NodeListBuilder.java").exists());
+ assertTrue(linksKeyFile.exists());
+
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+
+ List<File> filesList = getJavaFiles(sourcesOutputDir);
+ Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
+ Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
+ boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
+ assertTrue(compiled);
+
+ ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
+ Class<?> linksKeyClass = Class.forName("org.opendaylight.yang.gen.v1.urn.opendaylight.test.rev131008.LinksKey",
+ true, loader);
+
+ // test list key constructor arguments ordering
+ try {
+ linksKeyClass.getConstructor(Byte.class, String.class, Integer.class);
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError("Parameters of list key constructor are not properly ordered");
+ }
+
+ cleanUp(sourcesOutputDir, compiledOutputDir);
+ }
+
+ @Test
+ public void testAugmentUnderUsesGeneration() throws Exception {
+ final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "augment-under-uses");
+ assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
+ final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "augment-under-uses");
+ assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
+
+ final List<File> sourceFiles = getSourceFiles("/compilation/augment-under-uses");
+ final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
+ final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
+ final List<Type> types = bindingGenerator.generateTypes(context);
+ final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+ generator.generateToFile(sourcesOutputDir);
+
+ File parent = new File(sourcesOutputDir + FS + "org" + FS + "opendaylight" + FS + "yang" + FS + "gen" + FS
+ + "v1" + FS + "urn" + FS + "opendaylight" + FS + "test" + FS + "rev131008");
+ assertTrue(new File(parent, "Object.java").exists());
+ assertTrue(new File(parent, "OpenObject.java").exists());
+ assertTrue(new File(parent, "object" + FS + "Nodes.java").exists());
+ assertTrue(new File(parent, "object" + FS + "NodesBuilder.java").exists());
+ assertTrue(new File(parent, "open" + FS + "object" + FS + "Nodes1.java").exists());
+ assertTrue(new File(parent, "open" + FS + "object" + FS + "Nodes1Builder.java").exists());
+ assertTrue(new File(parent, "open" + FS + "object" + FS + "nodes" + FS + "Links.java").exists());
+ assertTrue(new File(parent, "open" + FS + "object" + FS + "nodes" + FS + "LinksBuilder.java").exists());
+
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+
+ List<File> filesList = getJavaFiles(sourcesOutputDir);
+ Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
+ Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
+ boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
+ assertTrue(compiled);
+
+ cleanUp(sourcesOutputDir, compiledOutputDir);
+ }
+
+ @Test
+ public void compilationTest() throws Exception {
+ final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "yang");
+ assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
+ final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "yang");
+ assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
+
+ final List<File> sourceFiles = getSourceFiles("/yang");
+ final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
+ final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
+ final List<Type> types = bindingGenerator.generateTypes(context);
+ final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+ generator.generateToFile(sourcesOutputDir);
+
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+
+ List<File> filesList = getJavaFiles(sourcesOutputDir);
+ Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
+ Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
+ boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
+ assertTrue(compiled);
+ }
+
+ private List<File> getSourceFiles(String path) {
+ final String resPath = getClass().getResource(path).getPath();
+ final File sourcesDir = new File(resPath);
+ final List<File> sourceFiles = new ArrayList<>();
+ final File[] fileArray = sourcesDir.listFiles();
+ sourceFiles.addAll(Arrays.asList(fileArray));
+ return sourceFiles;
+ }
+
+ private static void deleteTestDir(File file) {
+ if (file.isDirectory()) {
+ for (File f : file.listFiles()) {
+ deleteTestDir(f);
+ }
+ }
+ if (!file.delete()) {
+ throw new RuntimeException("Failed to clean up after test");
+ }
+ }
+
+ /**
+ * Search recursively given directory for *.java files.
+ *
+ * @param directory
+ * directory to search
+ * @return List of java files found
+ */
+ private List<File> getJavaFiles(File directory) {
+ List<File> result = new ArrayList<File>();
+ for (File file : directory.listFiles()) {
+ if (file.isDirectory()) {
+ result.addAll(getJavaFiles(file));
+ } else {
+ String absPath = file.getAbsolutePath();
+ if (absPath.endsWith(".java")) {
+ result.add(file);
+ }
+ }
+ }
+ return result;
+ }
+}
public class GeneratorJavaFileTest {
private static final String FS = File.separator;
private static final String PATH = "target/test/test-dir";
- private final File testDir = new File(PATH);
-
- private static final String GENERATOR_OUTPUT_PATH = "target/test/src";
- private static final File GENERATOR_OUTPUT = new File(GENERATOR_OUTPUT_PATH);
- private static final String COMPILER_OUTPUT_PATH = "target/test/bin";
- private static final File COMPILER_OUTPUT = new File(COMPILER_OUTPUT_PATH);
-
- @Before
- public void init() {
- assertTrue(testDir.mkdirs());
- assertTrue(COMPILER_OUTPUT.mkdirs());
- assertTrue(GENERATOR_OUTPUT.mkdirs());
- }
-
- @After
- public void cleanUp() {
- if (testDir.exists()) {
- deleteTestDir(testDir);
- }
- if (COMPILER_OUTPUT.exists()) {
- deleteTestDir(COMPILER_OUTPUT);
- }
- if (GENERATOR_OUTPUT.exists()) {
- deleteTestDir(GENERATOR_OUTPUT);
- }
- }
@Test
public void test() throws IOException {
assertTrue(filesList.contains("Type4Builder.java"));
}
- @Test
- public void compilationTest() throws Exception {
- final YangParserImpl parser = new YangParserImpl();
- final BindingGenerator bindingGenerator = new BindingGeneratorImpl();
-
- final String resPath = getClass().getResource("/yang").getPath();
- final File sourcesDir = new File(resPath);
- final List<File> sourceFiles = new ArrayList<File>();
- final File[] fileArray = sourcesDir.listFiles();
-
- for (int i = 0; i < fileArray.length; ++i) {
- sourceFiles.add(fileArray[i]);
- }
-
- final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
-
- final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
- final List<Type> types = bindingGenerator.generateTypes(context);
- final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
- generator.generateToFile(new File(GENERATOR_OUTPUT_PATH));
-
- JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
-
- List<File> filesList = getJavaFiles(new File(GENERATOR_OUTPUT_PATH));
- Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
- Iterable<String> options = Arrays.asList(new String[] { "-d", COMPILER_OUTPUT_PATH });
- boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
- assertTrue(compiled);
- }
-
private GeneratedType createGeneratedType(String pkgName, String name) {
GeneratedTypeBuilder builder = new GeneratedTypeBuilderImpl(pkgName, name);
builder.addImplementsType(BindingTypes.DATA_OBJECT);
return builder.toInstance();
}
- private void deleteTestDir(File file) {
- if (file.isDirectory()) {
- for (File f : file.listFiles()) {
- deleteTestDir(f);
- }
- }
- if (!file.delete()) {
- throw new RuntimeException("Failed to clean up after test");
- }
- }
-
- /**
- * Search recursively given directory for *.java files.
- *
- * @param directory
- * directory to search
- * @return List of java files found
- */
- private List<File> getJavaFiles(File directory) {
- List<File> result = new ArrayList<File>();
- for (File file : directory.listFiles()) {
- if (file.isDirectory()) {
- result.addAll(getJavaFiles(file));
- } else {
- String absPath = file.getAbsolutePath();
- if (absPath.endsWith(".java")) {
- result.add(file);
- }
- }
- }
- return result;
- }
}
package org.opendaylight.yangtools.sal.binding.yang.types;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
/**
* Sorts set <code>groupingDefinitions</code> according to the mutual
* dependencies.<br />
- *
+ *
* Elements of <code>groupingDefinitions</code> are firstly transformed to
* {@link org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node
* Node} interfaces and then are sorted by
* {@link org.opendaylight.yangtools.yang.parser.util.TopologicalSort#sort(Set)
* sort()} method of <code>TopologicalSort</code>.<br />
* <br />
- *
- *
+ *
+ *
* <i>Definition of dependency relation:<br />
* The first <code>GroupingDefinition</code> object (in this context)
* depends on second <code>GroupingDefinition</code> object if the first one
* contains in its set of <code>UsesNode</code> (obtained through
* {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer#getUses()
* getUses} method) reference to the second one.</i>
- *
+ *
* @param groupingDefinitions
* set of grouping definition which should be sorted according to
* mutual dependencies
* dependencies
* @throws IllegalArgumentException
* if <code>groupingDefinitions</code>
- *
+ *
*/
- public List<GroupingDefinition> sort(final Set<GroupingDefinition> groupingDefinitions) {
+ public List<GroupingDefinition> sort(final Collection<GroupingDefinition> groupingDefinitions) {
if (groupingDefinitions == null) {
throw new IllegalArgumentException("Set of Type Definitions " + "cannot be NULL!");
}
/**
* Wraps every grouping definition to node type and adds to every node
* information about dependencies.
- *
+ *
* The map with mapping from schema path (represents grouping definition) to
* node is created. For every created node (next <i>nodeFrom</i>) is for its
* wrapped grouping definition passed the set of its <i>uses nodes</i>
* <i>nodeTo</i>). This dependency relationship between nodeFrom and all
* found nodesTo is modeled with creating of one edge from nodeFrom to
* nodeTo.
- *
- *
+ *
+ *
* @param groupingDefinitions
* set of goruping definition which will be wrapped to nodes
- *
+ *
* @return set of nodes where every one contains wrapped grouping definition
*/
- private Set<Node> groupingDefinitionsToNodes(final Set<GroupingDefinition> groupingDefinitions) {
+ private Set<Node> groupingDefinitionsToNodes(final Collection<GroupingDefinition> groupingDefinitions) {
final Map<SchemaPath, Node> nodeMap = Maps.newHashMap();
final Set<Node> resultNodes = Sets.newHashSet();
* <code>container</code>, from uses in groupings inside
* <code>container</code> and from uses inside child nodes of the
* <code>container</code>.
- *
+ *
* @param container
* data node container which can contain some uses of grouping
* @return set of uses nodes which were find in <code>container</code>.