verifyCorrectLog(v);
}
+ @Test
+ public void testFindResourceOnCp() throws VerificationException {
+ Verifier v1 = new Verifier(new File("src/test/resources/GenerateTest1/").getAbsolutePath());
+ v1.executeGoal("package");
+ v1.assertFilePresent("target/external-resources/testfile1.yang");
+ v1.assertFilePresent("target/external-resources/testfile2.yang");
+ v1.assertFilePresent("target/external-resources/testfile3.yang");
+
+ Verifier v2 = YangToSourcesPluginTest.setUp("GenerateTest2/",
+ false);
+ v2.executeGoal("package");
+ }
+
}
--- /dev/null
+<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.opendaylight.controller</groupId>
+ <artifactId>generator-test1</artifactId>
+ <version>0.5-SNAPSHOT</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <version>0.5-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <yangFilesRootDir>src/main/resources</yangFilesRootDir>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl
+ </codeGeneratorClass>
+ </generator>
+ </codeGenerators>
+ <resourceProviders>
+ <provider>
+ <resourceProviderClass>
+ org.opendaylight.controller.yang2sources.spi.ResourceProviderTestImpl
+ </resourceProviderClass>
+ </provider>
+ </resourceProviders>
+ </configuration>
+ </execution>
+ </executions>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-maven-plugin-spi</artifactId>
+ <version>0.5-SNAPSHOT</version>
+ <type>test-jar</type>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+module types1 {
+ yang-version 1;
+ namespace "urn:simple.container.demo";
+ prefix "t1";
+
+ import types2 {
+ prefix "data";
+ revision-date 2013-02-27;
+ }
+
+ import types3 {
+ prefix "t3";
+ revision-date 2013-02-27;
+ }
+
+ organization "opendaylight";
+ contact "http://www.opendaylight.org/";
+
+ revision "2013-02-27" {
+ reference " WILL BE DEFINED LATER";
+ }
+
+ leaf testleaf {
+ type data:my-type1 {
+ range "min..max";
+ }
+ }
+
+ leaf test-string-leaf {
+ type data:my-string-type-ext;
+ }
+
+ leaf leaf-with-length {
+ type data:my-string-type {
+ length "7..max";
+ }
+ }
+
+ leaf test-int-leaf {
+ type data:my-int-type-ext;
+ }
+
+ leaf test-decimal-leaf {
+ type data:my-decimal-type {
+ fraction-digits 4;
+ }
+ }
+
+ leaf test-decimal-leaf2 {
+ type data:my-decimal-type-ext;
+ }
+
+ container ext {
+ data:c-define "MY_INTERFACES";
+ }
+
+ leaf union-leaf {
+ type data:my-union-ext;
+ }
+
+ deviation /data:system/data:user {
+ deviate add {
+ default "admin"; // new users are 'admin' by default
+ config "true";
+ }
+ }
+
+ leaf nested-union-leaf {
+ type data:nested-union1;
+ }
+
+ leaf custom-union-leaf {
+ type t3:union1;
+ }
+
+ container transfer {
+ choice how {
+ default interval;
+ case interval {
+ leaf interval {
+ type uint16;
+ default 30;
+ units minutes;
+ }
+ }
+ case daily {
+ leaf daily {
+ type empty;
+ }
+ leaf time-of-day {
+ type string;
+ units 24-hour-clock;
+ default 1am;
+ }
+ }
+ case manual {
+ leaf manual {
+ type empty;
+ }
+ }
+ }
+ }
+
+ anyxml data {
+ description
+ "Copy of the source datastore subset that matched
+ the filter criteria (if any). An empty data container
+ indicates that the request did not produce any results.";
+ }
+
+ augment "/data:interfaces/data:ifEntry/t3:augment-holder" {
+ when "if:ifType='ds0'";
+ leaf ds0ChannelNumber {
+ type string;
+ }
+ }
+
+}
--- /dev/null
+module types2 {
+ yang-version 1;
+ namespace "urn:simple.types.data.demo";
+ prefix "t2";
+
+ organization "opendaylight";
+ contact "http://www.opendaylight.org/";
+
+ description "This is types-data test description";
+
+ revision "2013-02-27" {
+ reference " WILL BE DEFINED LATER";
+ }
+
+ typedef my-base-int32-type {
+ type int32 {
+ range "2..20";
+ }
+ }
+
+ typedef my-type1 {
+ type my-base-int32-type {
+ range "11..max";
+ }
+ units "mile";
+ default "11";
+ }
+
+ typedef my-custom-string {
+ type string {
+ pattern "[a-k]*";
+ length "5..11";
+ }
+ }
+
+ typedef my-string-type {
+ type my-custom-string {
+ length "5..10";
+ }
+ }
+
+ typedef my-string-type2 {
+ type my-string-type {
+ pattern "[b-u]*";
+ }
+ }
+
+ typedef my-string-type-ext {
+ type my-string-type2 {
+ pattern "[e-z]*";
+ }
+ }
+
+ typedef my-int-type {
+ type int32 {
+ range "10..20";
+ }
+ }
+
+ typedef my-int-type2 {
+ type my-int-type {
+ range "12..18";
+ }
+ }
+
+ typedef my-int-type-ext {
+ type my-int-type2 {
+ range "14..16";
+ }
+ }
+
+ typedef my-decimal-type {
+ type decimal64 {
+ fraction-digits 6;
+ }
+ }
+
+ typedef my-decimal-type-ext {
+ type decimal64 {
+ fraction-digits 5;
+ }
+ }
+
+ typedef my-union {
+ type union {
+ type int16 {
+ range "1..100";
+ }
+ type int32;
+ }
+ }
+
+ typedef my-union-ext {
+ type my-union;
+ }
+
+ typedef nested-union1 {
+ type nested-union2;
+ }
+
+ typedef nested-union2 {
+ type union {
+ type my-union-ext;
+ type string;
+ }
+ }
+
+ leaf if-name {
+ type leafref {
+ path "/interface/name";
+ }
+ }
+
+ leaf name {
+ type string;
+ }
+
+ leaf nested-type-leaf {
+ type my-type1;
+ }
+
+ extension c-define {
+ description
+ "Takes as argument a name string.
+ Makes the code generator use the given name in the
+ #define.";
+ argument "name" {
+ yin-element "true";
+ }
+ }
+
+ container system {
+ leaf user {
+ type string;
+ }
+ }
+
+ grouping target {
+ leaf address {
+ type string;
+ description "Target IP address";
+ }
+ container port {
+ description "Target port container";
+ }
+ }
+
+ container peer {
+ container destination {
+ uses target {
+ refine address {
+ default "1.2.3.4";
+ }
+ refine port {
+ must "must-condition" {
+ error-message "An error message test";
+ error-app-tag "An error app tag test";
+ }
+ }
+ }
+ }
+ }
+
+ container interfaces {
+ list ifEntry {
+ key "ifIndex";
+
+ leaf ifIndex {
+ type uint32;
+ units minutes;
+ }
+
+ leaf ifMtu {
+ type int32;
+ }
+ }
+ }
+
+}
--- /dev/null
+module types3 {
+ yang-version 1;
+ namespace "urn:simple.container.demo.test";
+ prefix "t3";
+
+ import types2 {
+ prefix "data";
+ revision-date 2013-02-27;
+ }
+
+ organization "opendaylight";
+ contact "http://www.opendaylight.org/";
+
+ revision "2013-02-27" {
+ reference " WILL BE DEFINED LATER";
+ }
+
+ typedef union1 {
+ type union2;
+ }
+
+ typedef union2 {
+ type union {
+ type int32;
+ type data:nested-union2;
+ }
+ }
+
+ augment "/data:interfaces/data:ifEntry" {
+ when "if:ifType='ds0'";
+ container augment-holder {
+ description "Description for augment holder";
+ }
+ }
+
+ augment "/data:interfaces/data:ifEntry" {
+ when "if:ifType='ds2'";
+ container augment-holder2 {
+ description "Description for augment holder";
+ }
+ }
+
+ container network {
+ mnt:mountpoint point {
+ mnt:target-ref target;
+ }
+
+ description "network-description";
+ reference "network-reference";
+ status obsolete;
+ config true;
+ presence "some presence text";
+ }
+
+ feature local-storage {
+ description
+ "This feature means the device supports local
+ storage (memory, flash or disk) that can be used to
+ store syslog messages.";
+ }
+
+ extension c-define {
+ description
+ "Takes as argument a name string.
+ Makes the code generator use the given name in the
+ #define.";
+ argument "name";
+ }
+
+ notification event {
+ leaf event-class {
+ type string;
+ }
+ anyxml reporting-entity;
+ leaf severity {
+ type string;
+ }
+ }
+
+ rpc get-config {
+ description
+ "Retrieve all or part of a specified configuration.";
+
+ reference "RFC 6241, Section 7.1";
+
+ input {
+ container source {
+ description
+ "Particular configuration to retrieve.";
+
+ choice config-source {
+ mandatory true;
+ description
+ "The configuration to retrieve.";
+ case a {
+ leaf candidate {
+ if-feature candidate;
+ type empty;
+ description
+ "The candidate configuration is the config source.";
+ }
+ }
+ case b {
+ leaf running {
+ type empty;
+ description
+ "The running configuration is the config source.";
+ }
+ }
+ case c {
+ leaf startup {
+ if-feature startup;
+ type empty;
+ description
+ "The startup configuration is the config source.
+ This is optional-to-implement on the server because
+ not all servers will support filtering for this
+ datastore.";
+ }
+ }
+ }
+ }
+
+ anyxml filter {
+ description
+ "Subtree or XPath filter to use.";
+ nc:get-filter-element-attributes;
+ }
+ }
+
+ output {
+ anyxml data {
+ description
+ "Copy of the source datastore subset that matched
+ the filter criteria (if any). An empty data container
+ indicates that the request did not produce any results.";
+ }
+ }
+ }
+
+}
--- /dev/null
+<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.opendaylight.controller</groupId>
+ <artifactId>generator-test2</artifactId>
+ <version>0.5-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>generator-test1</artifactId>
+ <version>0.5-SNAPSHOT</version>
+ <scope>system</scope>
+ <systemPath>${project.basedir}/../GenerateTest1/target/generator-test1-0.5-SNAPSHOT.jar</systemPath>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <version>0.5-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <yangFilesRootDir>${project.basedir}</yangFilesRootDir>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ outDir/
+ </outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <resourceProviders>
+ <provider>
+ <resourceProviderClass>
+ org.opendaylight.controller.yang2sources.spi.ResourceProviderTestImpl
+ </resourceProviderClass>
+ <outputBaseDir>
+ outDir/
+ </outputBaseDir>
+ </provider>
+ </resourceProviders>
+ </configuration>
+ </execution>
+ </executions>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-maven-plugin-spi</artifactId>
+ <version>0.5-SNAPSHOT</version>
+ <type>test-jar</type>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
File file = new File(rootDir);
if(!file.exists()) {
- throw new FileNotFoundException();
+ throw new FileNotFoundException(rootDir);
}
Collection<File> yangFiles = FileUtils.listFiles(new File(rootDir),
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.io.Files;
/**
* Generate sources from yang files using user provided set of
@Mojo(name = "generate-sources", defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresDependencyResolution = ResolutionScope.COMPILE, requiresProject = true)
public final class YangToSourcesMojo extends AbstractMojo {
private static final String LOG_PREFIX = "yang-to-sources:";
- private static final String INPUT_RESOURCE_DIR = "META-INF/yangs/";
+ private static final String INPUT_RESOURCE_DIR = "META-INF/yang/";
private static final String OUTPUT_RESOURCE_DIR = "/target/external-resources/";
/**
if (yangFiles.isEmpty()) {
getLog().warn(
- Util.message("No %s file found in %s", LOG_PREFIX,
- Util.YANG_SUFFIX, yangFilesRootDir));
+ Util.message(
+ "No %s file found in %s or in dependencies",
+ LOG_PREFIX, Util.YANG_SUFFIX, yangFilesRootDir));
return null;
}
yangFiles.addAll(getFilesFromYangRoot());
// load files from dependencies
- yangFiles.addAll(getFilesFromDependencies());
-
+ Collection<File> filesFromDependencies = getFilesFromDependencies();
+ yangFiles.addAll(filesFromDependencies);
for (ResourceProviderArg resourceProvider : resourceProviders) {
try {
File rootDir = new File(yangFilesRootDir);
try {
- if(!rootDir.isAbsolute()) {
- yangFilesLoaded = Util.listFiles(project.getBasedir().getAbsolutePath() + yangFilesRootDir);
- } else {
+ if (rootDir.isAbsolute()) {
yangFilesLoaded = Util.listFiles(yangFilesRootDir);
+ } else {
+ String path = project.getBasedir().getAbsolutePath()
+ + File.separator + yangFilesRootDir;
+ yangFilesLoaded = Util.listFiles(path);
}
-
- } catch(FileNotFoundException e) {
- getLog().warn("Directory '" + yangFilesRootDir + "' does not exists.");
+ } catch (FileNotFoundException e) {
+ getLog().warn(
+ "yangFilesRootDir[" + rootDir.getAbsolutePath()
+ + "] does not exists.");
yangFilesLoaded = new ArrayList<File>();
}
+
Collection<File> yangFiles = new ArrayList<File>(yangFilesLoaded);
try {
- for(File yangFile : yangFilesLoaded) {
+ for (File yangFile : yangFilesLoaded) {
InputStream is = new FileInputStream(yangFile);
- yangFiles.add(createFileFromStream(is, project.getBasedir().getAbsolutePath() + OUTPUT_RESOURCE_DIR + yangFile.getName()));
+ yangFiles.add(createFileFromStream(is,
+ project.getBasedir().getAbsolutePath()
+ + OUTPUT_RESOURCE_DIR + yangFile.getName()));
resources.add(is);
}
- } catch(IOException e) {
+ } catch (IOException e) {
getLog().warn("Exception while loading yang files.", e);
}
return yangFiles;
continue;
}
InputStream entryStream = zip.getInputStream(entry);
- String newEntryName = entryName.substring(INPUT_RESOURCE_DIR.length());
- File f = createFileFromStream(entryStream, project.getBasedir().getAbsolutePath() + OUTPUT_RESOURCE_DIR + newEntryName);
+ String newEntryName = entryName
+ .substring(INPUT_RESOURCE_DIR.length());
+ File tmp = Files.createTempDir();
+ File f = createFileFromStream(entryStream,
+ tmp.getAbsolutePath() + newEntryName);
yangFiles.add(f);
resources.add(entryStream);
return yangFiles;
}
- private File createFileFromStream(InputStream is, String absoluteName) throws IOException {
+ private File createFileFromStream(InputStream is, String absoluteName)
+ throws IOException {
File f = new File(absoluteName);
- if(!f.exists()) {
+ if (!f.exists()) {
f.getParentFile().mkdirs();
}
f.createNewFile();
ZipEntry entry = entries.nextElement();
String entryName = entry.getName();
- if(entryName.startsWith(INPUT_RESOURCE_DIR)) {
- if(entry.isDirectory()) {
+ if (entryName.startsWith(INPUT_RESOURCE_DIR)) {
+ if (entry.isDirectory()) {
continue;
}
if (!Util.acceptedFilter(entryName, filter)) {
try {
resource.close();
} catch (IOException e) {
- getLog().warn("Failed to close resources: "+ resource, e);
+ getLog().warn("Failed to close resources: " + resource, e);
}
}
}
*/
public class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
TypeDefinitionBuilder, Builder {
+ private final static String CLASS_NAME = UnionTypeBuilder.class
+ .getSimpleName();
+
private final int line;
private final List<TypeDefinition<?>> types;
private final List<TypeDefinitionBuilder> typedefs;
private final UnionType instance;
+ private boolean built;
private final List<String> actualPath;
private final URI namespace;
@Override
public UnionType build() {
- for (TypeDefinitionBuilder tdb : typedefs) {
- types.add(tdb.build());
+ if (built) {
+ return instance;
+ } else {
+ for (TypeDefinitionBuilder tdb : typedefs) {
+ types.add(tdb.build());
+ }
+ built = true;
+ return instance;
}
- return instance;
}
@Override
public void setPath(final SchemaPath schemaPath) {
- throw new IllegalStateException("Can not set path to "
- + UnionTypeBuilder.class.getSimpleName());
+ throw new IllegalStateException("Can not set path to " + CLASS_NAME);
}
@Override
public void setDescription(final String description) {
throw new IllegalStateException("Can not set description to "
- + UnionTypeBuilder.class.getSimpleName());
+ + CLASS_NAME);
}
@Override
public void setReference(final String reference) {
throw new IllegalStateException("Can not set reference to "
- + UnionTypeBuilder.class.getSimpleName());
+ + CLASS_NAME);
}
@Override
public void setStatus(final Status status) {
- throw new IllegalStateException("Can not set status to "
- + UnionTypeBuilder.class.getSimpleName());
+ throw new IllegalStateException("Can not set status to " + CLASS_NAME);
}
@Override
public void addUnknownSchemaNode(final UnknownSchemaNodeBuilder unknownNode) {
throw new IllegalStateException("Can not add unknown node to "
- + UnionTypeBuilder.class.getSimpleName());
+ + CLASS_NAME);
}
@Override
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(
final List<InputStream> yangFileStreams) {
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = new HashMap<String, TreeMap<Date, ModuleBuilder>>();
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = new LinkedHashMap<String, TreeMap<Date, ModuleBuilder>>();
final ParseTreeWalker walker = new ParseTreeWalker();
final List<ParseTree> trees = parseStreams(yangFileStreams);
final ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
// module dependency graph sorted
List<ModuleSimple> sorted = new ModuleDependencySort(builders).sort();
- for (ModuleBuilder builder : builders) {
+ // TODO FIX THIS ASAP!
+ // FIXME this is just temp workaround the ModuleDependencySort MUST
+ // RETURN ordered List
+ // of SORTED and DEPENDECNY RESOLVED MODULE BUILDERS!!!!!!
+ final List<ModuleBuilder> orderedBuilders = new ArrayList<ModuleBuilder>();
+ for (final ModuleSimple ms : sorted) {
+ for (int i = 0; i < builders.length; ++i) {
+ if (ms.getName().equals(builders[i].getName())
+ && ms.getRevision().equals(builders[i].getRevision())) {
+ orderedBuilders.add(builders[i]);
+ }
+ }
+ }
+ // FIXME END OF WORKAROUND
+
+ for (ModuleBuilder builder : orderedBuilders) {
final String builderName = builder.getName();
Date builderRevision = builder.getRevision();
if (builderRevision == null) {
resolveAugments(modules);
// build
- final Set<Module> result = new HashSet<Module>();
+ final Set<Module> result = new LinkedHashSet<Module>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
.entrySet()) {
final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
List<PatternConstraint> patterns = Collections.emptyList();
Integer fractionDigits = null;
if (referencedType == null) {
- final TypeDefinitionBuilder tdb = (TypeDefinitionBuilder) nodeToResolve;
+ final TypeDefinitionBuilder tdb = nodeToResolve.getTypedef();
ranges = tdb.getRanges();
constraints.addRanges(ranges);
lengths = tdb.getLengths();
for (AugmentationSchemaBuilder augmentBuilder : module
.getAddedAugments()) {
- if(!augmentBuilder.isResolved()) {
+ if (!augmentBuilder.isResolved()) {
final SchemaPath augmentTargetSchemaPath = augmentBuilder
.getTargetPath();
final List<QName> path = augmentTargetSchemaPath.getPath();
for (DataSchemaNodeBuilder child : dependentModule
.getChildNodes()) {
final QName childQName = child.getQName();
- if (childQName.getLocalName().equals(qname.getLocalName())) {
+ if (childQName.getLocalName().equals(
+ qname.getLocalName())) {
currentParent = child;
i++;
break;
}
final QName currentQName = currentParent.getQName();
- final QName lastAugmentPathElement = path.get(path.size() - 1);
+ final QName lastAugmentPathElement = path
+ .get(path.size() - 1);
if (currentQName.getLocalName().equals(
lastAugmentPathElement.getLocalName())) {
ParserUtils.fillAugmentTarget(augmentBuilder,
((AugmentationTargetBuilder) currentParent)
.addAugmentation(augmentBuilder);
SchemaPath oldPath = currentParent.getPath();
- augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
+ augmentBuilder.setTargetPath(new SchemaPath(oldPath
+ .getPath(), oldPath.isAbsolute()));
augmentBuilder.setResolved(true);
module.augmentResolved();
}
}
-
}
}
}
@Override
public Module findModuleByName(final String name, final Date revision) {
- if ((name != null) && (revision != null)) {
+ if (name != null) {
for (final Module module : modules) {
- if (module.getName().equals(name)
+ if (revision == null) {
+ if (module.getName().equals(name)) {
+ return module;
+ }
+ } else if (module.getName().equals(name)
&& module.getRevision().equals(revision)) {
return module;
}