From: Tony Tkacik Date: Tue, 19 Nov 2013 13:56:40 +0000 (+0000) Subject: Merge "Added export of augmentation schemas to Binding Context" X-Git-Tag: yangtools-0.6.0~177 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=077e763b51089a5c43be3c715a85ad7cd905ddde;hp=bd6fee58322b627f82f3f8ad3913774f23b45c94;p=yangtools.git Merge "Added export of augmentation schemas to Binding Context" --- diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java index 57e319f590..344d29829d 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java @@ -26,9 +26,11 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition; import org.opendaylight.yangtools.yang.model.util.ExtendedType; /** @@ -404,9 +406,17 @@ public final class BindingGeneratorUtil { if (type instanceof ExtendedType) { ExtendedType ext = (ExtendedType)type; + TypeDefinition base = ext.getBaseType(); length.addAll(ext.getLengthConstraints()); pattern.addAll(ext.getPatternConstraints()); range.addAll(ext.getRangeConstraints()); + + if (base instanceof IntegerTypeDefinition && range.isEmpty()) { + range.addAll(((IntegerTypeDefinition)base).getRangeConstraints()); + } else if (base instanceof UnsignedIntegerTypeDefinition && range.isEmpty()) { + range.addAll(((UnsignedIntegerTypeDefinition)base).getRangeConstraints()); + } + } return new Restrictions() { diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java index ffcbf175b6..b658d2f2fa 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java @@ -30,6 +30,7 @@ public final class Types { public static final ConcreteType BOOLEAN = typeForClass(Boolean.class); public static final ConcreteType FUTURE = typeForClass(Future.class); + public static final ConcreteType STRING = typeForClass(String.class); public static final ConcreteType VOID = typeForClass(Void.class); /** diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend index 532850f37b..f603932210 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend @@ -16,36 +16,36 @@ import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject import java.util.Collection abstract class BaseTemplate { - - + protected val GeneratedType type; - protected val Map importMap; + protected val Map importMap; static val paragraphSplitter = Splitter.on("\n\n").omitEmptyStrings(); + new(GeneratedType _type) { - if (_type== null) { + if (_type == null) { throw new IllegalArgumentException("Generated type reference cannot be NULL!") } this.type = _type; this.importMap = GeneratorUtil.createImports(type) } - - def packageDefinition () '''package «type.packageName»;''' + def packageDefinition() '''package «type.packageName»;''' protected def getFullyQualifiedName() { return type.fullyQualifiedName } - - final public def generate() { - val _body = body() - ''' - «packageDefinition» - «imports» - «_body» - '''.toString + final public def generate() { + val _body = body() + ''' + «packageDefinition» + «imports» + + «_body» + '''.toString } - protected def imports() ''' + + protected def imports() ''' «IF !importMap.empty» «FOR entry : importMap.entrySet» «IF entry.value != fullyQualifiedName» @@ -53,16 +53,14 @@ abstract class BaseTemplate { «ENDIF» «ENDFOR» «ENDIF» - + ''' protected abstract def CharSequence body(); // Helper patterns - final protected def fieldName(GeneratedProperty property) '''_«property.name»''' - final protected def propertyNameFromGetter(MethodSignature getter) { var int prefix; if (getter.name.startsWith("is")) { @@ -83,18 +81,18 @@ abstract class BaseTemplate { * @return string with the getter method source code in JAVA format */ final protected def getterMethod(GeneratedProperty field) { - ''' - public «field.returnType.importedName» «field.getterMethodName»() { - return «field.fieldName»; - } - ''' + ''' + public «field.returnType.importedName» «field.getterMethodName»() { + return «field.fieldName»; + } + ''' } final protected def getterMethodName(GeneratedProperty field) { val prefix = if(field.returnType.equals(Types.BOOLEAN)) "is" else "get" return '''«prefix»«field.name.toFirstUpper»''' } - + /** * Template method which generates the setter method for field * @@ -109,16 +107,16 @@ abstract class BaseTemplate { return this; } ''' - + final protected def importedName(Type intype) { GeneratorUtil.putTypeIntoImports(type, intype, importMap); GeneratorUtil.getExplicitType(type, intype, importMap) } - + final protected def importedName(Class cls) { importedName(Types.typeForClass(cls)) } - + /** * Template method which generates method parameters with their types from parameters. * @@ -126,9 +124,9 @@ abstract class BaseTemplate { * group of generated property instances which are transformed to the method parameters * @return string with the list of the method parameters with their types in JAVA format */ - def final protected asArgumentsDeclaration(Iterable parameters) - '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.returnType.importedName» «parameter.fieldName»«ENDFOR»«ENDIF»''' - + def final protected asArgumentsDeclaration(Iterable parameters) '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter. + returnType.importedName» «parameter.fieldName»«ENDFOR»«ENDIF»''' + /** * Template method which generates sequence of the names of the class attributes from parameters. * @@ -136,67 +134,64 @@ abstract class BaseTemplate { * group of generated property instances which are transformed to the sequence of parameter names * @return string with the list of the parameter names of the parameters */ - def final protected asArguments(Iterable parameters) - '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.fieldName»«ENDFOR»«ENDIF»''' - - - /** + def final protected asArguments(Iterable parameters) '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter. + fieldName»«ENDFOR»«ENDIF»''' + + /** * Template method which generates JAVA comments. * * @param comment string with the comment for whole JAVA class * @return string with comment in JAVA format */ def protected CharSequence asJavadoc(String comment) { - if (comment==null) return ''; + if(comment == null) return ''; val paragraphs = paragraphSplitter.split(comment) - + return ''' /** «FOR p : paragraphs SEPARATOR "

"» - «p» + «p» «ENDFOR» **/ - ''' + ''' } - def generateLengthRestrictions(Type type, String paramName, Type returnType) ''' + def generateRestrictions(Type type, String paramName, Type returnType) ''' «val boolean isArray = returnType.name.contains("[")» - «IF type instanceof ConcreteType» - «val restrictions = (type as ConcreteType).restrictions» - «IF restrictions !== null && !restrictions.lengthConstraints.empty» - «generateLengthRestriction(type, restrictions, paramName, isArray, !(returnType instanceof ConcreteType))» - «ENDIF» - «ENDIF» - «IF type instanceof GeneratedTransferObject» - «val restrictions = (type as GeneratedTransferObject).restrictions» - «IF restrictions !== null && !restrictions.lengthConstraints.empty» - «generateLengthRestriction(type, restrictions, paramName, isArray, !(returnType instanceof ConcreteType))» - «ENDIF» - «ENDIF» + «processRestrictions(type, paramName, returnType, isArray)» ''' - def generateLengthRestrictions(GeneratedProperty field, String paramName) ''' + def generateRestrictions(GeneratedProperty field, String paramName) ''' «val Type type = field.returnType» «IF type instanceof ConcreteType» - «val boolean isArray = type.name.contains("[")» - «val restrictions = (type as ConcreteType).restrictions» - «IF restrictions !== null && !restrictions.lengthConstraints.empty» - «generateLengthRestriction(type, restrictions, paramName, isArray, false)» - «ENDIF» + «processRestrictions(type, paramName, field.returnType, type.name.contains("["))» + «ELSEIF type instanceof GeneratedTransferObject» + «processRestrictions(type, paramName, field.returnType, isArrayType(type as GeneratedTransferObject))» «ENDIF» - «IF type instanceof GeneratedTransferObject» - «var isArray = isArrayType(type as GeneratedTransferObject)» - «val restrictions = (type as GeneratedTransferObject).restrictions» - «IF restrictions !== null && !restrictions.lengthConstraints.empty» - «generateLengthRestriction(type, restrictions, paramName, isArray, true)» + ''' + + + private def processRestrictions(Type type, String paramName, Type returnType, boolean isArray) ''' + «val restrictions = type.getRestrictions» + «IF restrictions !== null» + «IF !restrictions.lengthConstraints.empty» + «generateLengthRestriction(type, restrictions, paramName, isArray, + !(returnType instanceof ConcreteType))» + «ENDIF» + «IF !restrictions.rangeConstraints.empty && + ("java.lang".equals(returnType.packageName) || "java.math".equals(returnType.packageName))» + «generateRangeRestriction(type, returnType, restrictions, paramName, + !(returnType instanceof ConcreteType))» «ENDIF» «ENDIF» ''' - def generateLengthRestriction(Type type, Restrictions restrictions, String paramName, boolean isArray, boolean isNestedType) ''' + def generateLengthRestriction(Type type, Restrictions restrictions, String paramName, boolean isArray, + boolean isNestedType) ''' if («paramName» != null) { boolean isValidLength = false; - «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.importedName»<>(); + «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList. + importedName»<>(); «FOR r : restrictions.lengthConstraints» lengthConstraints.add(«Range.importedName».closed(«r.min», «r.max»)); «ENDFOR» @@ -214,7 +209,7 @@ abstract class BaseTemplate { if (r.contains(«paramName».length())) { «ENDIF» «ENDIF» - isValidLength = true; + isValidLength = true; } } if (!isValidLength) { @@ -223,6 +218,32 @@ abstract class BaseTemplate { } ''' + def generateRangeRestriction(Type type, Type returnType, Restrictions restrictions, String paramName, + boolean isNestedType) ''' + «val javaType = Class.forName(returnType.fullyQualifiedName)» + if («paramName» != null) { + boolean isValidRange = false; + «List.importedName»<«Range.importedName»<«javaType.importedName»>> rangeConstraints = new «ArrayList. + importedName»<>(); + «FOR r : restrictions.rangeConstraints» + rangeConstraints.add(«Range.importedName».closed(new «javaType.importedName»(«r.min.toQuote»), new «javaType. + importedName»(«r.max.toQuote»))); + «ENDFOR» + for («Range.importedName»<«javaType.importedName»> r : rangeConstraints) { + «IF isNestedType» + if (r.contains(«paramName».getValue())) { + «ELSE» + if (r.contains(«paramName»)) { + «ENDIF» + isValidRange = true; + } + } + if (!isValidRange) { + throw new IllegalArgumentException("illegal length"); + } + } + ''' + def GeneratedProperty getPropByName(GeneratedType gt, String name) { for (GeneratedProperty prop : gt.properties) { if (prop.name.equals(name)) { @@ -241,6 +262,16 @@ abstract class BaseTemplate { return null; } + def getRestrictions(Type type) { + var Restrictions restrictions = null + if (type instanceof ConcreteType) { + restrictions = (type as ConcreteType).restrictions + } else if (type instanceof GeneratedTransferObject) { + restrictions = (type as GeneratedTransferObject).restrictions + } + return restrictions + } + def boolean isArrayType(GeneratedTransferObject type) { var isArray = false val GeneratedTransferObject superType = type.findSuperType @@ -261,4 +292,8 @@ abstract class BaseTemplate { return base; } + def String toQuote(Object obj) { + return "\"" + obj.toString + "\""; + } + } diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend index 9608aeaa21..fbe9886d00 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend @@ -399,7 +399,7 @@ class BuilderTemplate extends BaseTemplate { def private generateSetters() ''' «FOR field : properties SEPARATOR '\n'» public «type.name»«BUILDER» set«field.name.toFirstUpper»(«field.returnType.importedName» value) { - «generateLengthRestrictions(field, "value")» + «generateRestrictions(field, "value")» this.«field.fieldName» = value; return this; @@ -442,7 +442,6 @@ class BuilderTemplate extends BaseTemplate { «ENDFOR» ); «FOR field : keyProps» - «val genProp = getPropByName(allProps, field.name)» this.«field.fieldName» = builder.«field.getterMethodName»(); «ENDFOR» } else { diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend index 458b8114e0..de3ceb454d 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend @@ -11,6 +11,7 @@ import java.util.ArrayList import java.util.Collections import java.util.Arrays import org.opendaylight.yangtools.sal.binding.model.api.Restrictions import com.google.common.collect.Range +import java.util.regex.Pattern /** * Template for generating JAVA class. @@ -152,7 +153,7 @@ class ClassTemplate extends BaseTemplate { super(«parentProperties.asArguments»); «ENDIF» «FOR p : allProperties» - «generateLengthRestrictions(type, p.fieldName.toString, p.returnType)» + «generateRestrictions(type, p.fieldName.toString, p.returnType)» «ENDFOR» «FOR p : properties» this.«p.fieldName» = «p.fieldName»; @@ -174,7 +175,7 @@ class ClassTemplate extends BaseTemplate { «IF false == parentProperties.empty» super(«parentProperties.asArguments»); «ENDIF» - «generateLengthRestrictions(type, property.fieldName.toString, property.returnType)» + «generateRestrictions(type, property.fieldName.toString, property.returnType)» this.«property.fieldName» = «property.name»; «FOR p : other» this.«p.fieldName» = null; @@ -269,8 +270,8 @@ class ClassTemplate extends BaseTemplate { «val cValue = c.value» «IF cValue instanceof List» «val cValues = cValue as List» - private static final List «Constants.MEMBER_PATTERN_LIST» = new ArrayList(); - public static final List «TypeConstants.PATTERN_CONSTANT_NAME» = «Arrays.importedName».asList(« + private static final «List.importedName»<«Pattern.importedName»> «Constants.MEMBER_PATTERN_LIST» = new «ArrayList.importedName»<«Pattern.importedName»>(); + public static final «List.importedName» «TypeConstants.PATTERN_CONSTANT_NAME» = «Arrays.importedName».asList(« FOR v : cValues SEPARATOR ", "»« IF v instanceof String»"« v as String»"« diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorUtil.java b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorUtil.java index 9db1ce8540..da285e37be 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorUtil.java +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorUtil.java @@ -60,17 +60,6 @@ public final class GeneratorUtil { } } - final List constants = genType.getConstantDefinitions(); - final List methods = genType.getMethodDefinitions(); - - // CONSTANTS - if (constants != null) { - for (final Constant constant : constants) { - final Type constantType = constant.getType(); - putTypeIntoImports(genType, constantType, imports); - } - } - // REGULAR EXPRESSION if (genType instanceof GeneratedTransferObject && isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) { @@ -79,6 +68,7 @@ public final class GeneratorUtil { putTypeIntoImports(genType, Types.typeForClass(java.util.ArrayList.class), imports); } + final List methods = genType.getMethodDefinitions(); // METHODS if (methods != null) { for (final MethodSignature method : methods) { diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java index 6f0aaae29e..833fcab854 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java @@ -41,14 +41,14 @@ public class AugmentToUsesInAugmentCompilationTest extends BaseCompilationTest { // Test if all sources are generated from 'module foo' File fooParent = new File(sourcesOutputDir, NS_FOO); - testFilesCount(fooParent, 4); + assertFilesCount(fooParent, 4); assertTrue(new File(fooParent, "IgpLinkAttributes.java").exists()); assertTrue(new File(fooParent, "Link1.java").exists()); assertTrue(new File(fooParent, "Link1Builder.java").exists()); // Test if all sources are generated from 'module bar' File barParent = new File(sourcesOutputDir, NS_BAR); - testFilesCount(barParent, 7); + assertFilesCount(barParent, 7); assertTrue(new File(barParent, "BarData.java").exists()); assertTrue(new File(barParent, "NetworkTopology.java").exists()); assertTrue(new File(barParent, "NetworkTopologyBuilder.java").exists()); @@ -56,22 +56,22 @@ public class AugmentToUsesInAugmentCompilationTest extends BaseCompilationTest { assertTrue(new File(barParent, "LinkAttributes.java").exists()); File networkParent = new File(barParent, "network"); - testFilesCount(networkParent, 1); + assertFilesCount(networkParent, 1); File topologyParent = new File(networkParent, "topology"); - testFilesCount(topologyParent, 3); + assertFilesCount(topologyParent, 3); assertTrue(new File(topologyParent, "Topology.java").exists()); assertTrue(new File(topologyParent, "TopologyBuilder.java").exists()); assertTrue(new File(topologyParent, "TopologyKey.java").exists()); File linkParent = new File(barParent, "link"); - testFilesCount(linkParent, 3); + assertFilesCount(linkParent, 3); assertTrue(new File(linkParent, "Link.java").exists()); assertTrue(new File(linkParent, "LinkBuilder.java").exists()); assertTrue(new File(linkParent, "LinkKey.java").exists()); // Test if all sources are generated from 'module baz' File bazParent = new File(sourcesOutputDir, NS_BAZ); - testFilesCount(bazParent, 4); + assertFilesCount(bazParent, 4); assertTrue(new File(bazParent, "IgpLinkAttributes1.java").exists()); assertTrue(new File(bazParent, "IgpLinkAttributes1Builder.java").exists()); assertTrue(new File(bazParent, "LinkAttributes.java").exists()); @@ -88,7 +88,7 @@ public class AugmentToUsesInAugmentCompilationTest extends BaseCompilationTest { Class igpLinkAttributesClass = Class.forName(BASE_PKG + ".urn.opendaylight.foo.rev131008.IgpLinkAttributes", true, loader); - testImplementsIfc(link1Class, igpLinkAttributesClass); + assertImplementsIfc(link1Class, igpLinkAttributesClass); } catch (ClassNotFoundException e) { throw new AssertionError("Class for augment wasn't generated"); } @@ -101,7 +101,7 @@ public class AugmentToUsesInAugmentCompilationTest extends BaseCompilationTest { Class linkAttributesClass = Class.forName(BASE_PKG + ".urn.opendaylight.baz.rev131008.LinkAttributes", true, loader); - testImplementsIfc(igpLinkAttributes1Class, linkAttributesClass); + assertImplementsIfc(igpLinkAttributes1Class, linkAttributesClass); } catch (ClassNotFoundException e) { throw new AssertionError("Class for augment wasn't generated"); } diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java index 06ac678afe..a4f42fe860 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java @@ -43,7 +43,7 @@ public class CascadeUsesCompilationTest extends BaseCompilationTest { // Test if all sources are generated from module foo File parent = new File(sourcesOutputDir, NS_FOO); - testFilesCount(parent, 5); + assertFilesCount(parent, 5); File fooData = new File(parent, "FooData.java"); File foo_gr1 = new File(parent, "FooGr1.java"); File nodes = new File(parent, "Nodes.java"); @@ -55,7 +55,7 @@ public class CascadeUsesCompilationTest extends BaseCompilationTest { // Test if all sources are generated from module bar parent = new File(sourcesOutputDir, NS_BAR); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); File barGr1 = new File(parent, "BarGr1.java"); File barGr2 = new File(parent, "BarGr2.java"); assertTrue(barGr1.exists()); @@ -63,7 +63,7 @@ public class CascadeUsesCompilationTest extends BaseCompilationTest { // Test if all sources are generated from module baz parent = new File(sourcesOutputDir, NS_BAZ); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); File bazGr1 = new File(parent, "BazGr1.java"); assertTrue(bazGr1.exists()); @@ -81,8 +81,8 @@ public class CascadeUsesCompilationTest extends BaseCompilationTest { Class bazGr1Class = Class.forName(BASE_PKG + ".urn.opendaylight.baz.rev131008.BazGr1", true, loader); // test generated interface from 'container nodes' - testImplementsIfc(nodesClass, fooGr1Class); - testImplementsIfc(nodesClass, barGr2Class); + assertImplementsIfc(nodesClass, fooGr1Class); + assertImplementsIfc(nodesClass, barGr2Class); // test generated builder for 'container nodes' assertFalse(nodesBuilderClass.isInterface()); diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java index 1fe839cef9..3d9ece434e 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java @@ -64,7 +64,7 @@ public class CompilationTest extends BaseCompilationTest { assertTrue(linksBuilder.exists()); assertTrue(linksKey.exists()); assertTrue(testData.exists()); - testFilesCount(parent, 6); + assertFilesCount(parent, 6); parent = new File(sourcesOutputDir, NS_TEST + FS + "links"); File level = new File(parent, "Level.java"); @@ -81,7 +81,7 @@ public class CompilationTest extends BaseCompilationTest { assertTrue(nodeList.exists()); assertTrue(nodeListBuilder.exists()); assertTrue(nodesType.exists()); - testFilesCount(parent, 7); + assertFilesCount(parent, 7); // Test if sources are compilable testCompilation(sourcesOutputDir, compiledOutputDir); @@ -101,7 +101,7 @@ public class CompilationTest extends BaseCompilationTest { assertTrue(linksClass.isInterface()); // TODO: anyxml assertEquals(6, linksClass.getDeclaredMethods().length); - testImplementsIfc(linksClass, keyArgsClass); + assertImplementsIfc(linksClass, keyArgsClass); // Test list key constructor arguments ordering assertContainsConstructor(linksKeyClass, Byte.class, String.class, Integer.class); @@ -133,77 +133,77 @@ public class CompilationTest extends BaseCompilationTest { assertTrue(new File(parent, "OpenObject.java").exists()); assertTrue(new File(parent, "ExplicitRouteObject.java").exists()); assertTrue(new File(parent, "PathKeySubobject.java").exists()); - testFilesCount(parent, 7); + assertFilesCount(parent, 7); parent = new File(parent, "object"); assertTrue(new File(parent, "Nodes.java").exists()); assertTrue(new File(parent, "NodesBuilder.java").exists()); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); parent = new File(sourcesOutputDir, NS_FOO + FS + "open"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "object"); assertTrue(new File(parent, "Nodes1.java").exists()); assertTrue(new File(parent, "Nodes1Builder.java").exists()); - testFilesCount(parent, 3); + assertFilesCount(parent, 3); parent = new File(parent, "nodes"); assertTrue(new File(parent, "Links.java").exists()); assertTrue(new File(parent, "LinksBuilder.java").exists()); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); parent = new File(sourcesOutputDir, NS_FOO + FS + "explicit"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "route"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "object"); assertTrue(new File(parent, "Subobjects.java").exists()); assertTrue(new File(parent, "SubobjectsBuilder.java").exists()); - testFilesCount(parent, 3); + assertFilesCount(parent, 3); parent = new File(parent, "subobjects"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "subobject"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "type"); assertTrue(new File(parent, "PathKey.java").exists()); assertTrue(new File(parent, "PathKeyBuilder.java").exists()); - testFilesCount(parent, 3); + assertFilesCount(parent, 3); parent = new File(parent, "path"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "key"); assertTrue(new File(parent, "PathKey.java").exists()); assertTrue(new File(parent, "PathKeyBuilder.java").exists()); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); // Test if all sources were generated from 'module bar' parent = new File(sourcesOutputDir, NS_BAR); assertTrue(new File(parent, "BasicExplicitRouteSubobjects.java").exists()); assertTrue(new File(parent, "ExplicitRouteSubobjects.java").exists()); - testFilesCount(parent, 3); + assertFilesCount(parent, 3); parent = new File(parent, "basic"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "explicit"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "route"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "subobjects"); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); assertTrue(new File(parent, "SubobjectType.java").exists()); parent = new File(parent, "subobject"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "type"); assertTrue(new File(parent, "IpPrefix.java").exists()); assertTrue(new File(parent, "IpPrefixBuilder.java").exists()); assertTrue(new File(parent, "Label.java").exists()); assertTrue(new File(parent, "LabelBuilder.java").exists()); - testFilesCount(parent, 4); + assertFilesCount(parent, 4); // Test if sources are compilable testCompilation(sourcesOutputDir, compiledOutputDir); @@ -235,19 +235,19 @@ public class CompilationTest extends BaseCompilationTest { assertTrue(pathAttributes.exists()); assertTrue(update.exists()); assertTrue(updateBuilder.exists()); - testFilesCount(parent, 6); + assertFilesCount(parent, 6); parent = new File(sourcesOutputDir, NS_FOO + FS + "path"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "attributes"); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); File origin = new File(parent, "Origin.java"); File originBuilder = new File(parent, "OriginBuilder.java"); assertTrue(origin.exists()); assertTrue(originBuilder.exists()); parent = new File(sourcesOutputDir, NS_FOO + FS + "update"); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); pathAttributes = new File(parent, "PathAttributes.java"); File pathAttributesBuilder = new File(parent, "PathAttributesBuilder.java"); assertTrue(pathAttributes.exists()); @@ -261,94 +261,94 @@ public class CompilationTest extends BaseCompilationTest { assertTrue(destination.exists()); assertTrue(pathAttributes1.exists()); assertTrue(pathAttributes1Builder.exists()); - testFilesCount(parent, 5); + assertFilesCount(parent, 5); parent = new File(sourcesOutputDir, NS_BAR + FS + "destination"); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); File destinationType = new File(parent, "DestinationType.java"); assertTrue(destinationType.exists()); parent = new File(parent, "destination"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "type"); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); File destinationIpv4 = new File(parent, "DestinationIp.java"); File destinationIpv4Builder = new File(parent, "DestinationIpBuilder.java"); assertTrue(destinationIpv4.exists()); assertTrue(destinationIpv4Builder.exists()); parent = new File(sourcesOutputDir, NS_BAR + FS + "update"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "path"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "attributes"); File mpUnreachNlri = new File(parent, "MpUnreachNlri.java"); File mpUnreachNlriBuilder = new File(parent, "MpUnreachNlriBuilder.java"); assertTrue(mpUnreachNlri.exists()); assertTrue(mpUnreachNlriBuilder.exists()); - testFilesCount(parent, 3); + assertFilesCount(parent, 3); parent = new File(parent, "mp"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "unreach"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "nlri"); File withdrawnRoutes = new File(parent, "WithdrawnRoutes.java"); File withdrawnRoutesBuilder = new File(parent, "WithdrawnRoutesBuilder.java"); assertTrue(withdrawnRoutes.exists()); assertTrue(withdrawnRoutesBuilder.exists()); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); // Test if all sources were generated from 'module baz' parent = new File(sourcesOutputDir, NS_BAZ); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); File linkstateDestination = new File(parent, "LinkstateDestination.java"); assertTrue(linkstateDestination.exists()); parent = new File(sourcesOutputDir, NS_BAZ + FS + "update"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "path"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "attributes"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "mp"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "unreach"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "nlri"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "withdrawn"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "routes"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "destination"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "type"); File destinationLinkstate = new File(parent, "DestinationLinkstate.java"); File destinationLinkstateBuilder = new File(parent, "DestinationLinkstateBuilder.java"); assertTrue(destinationLinkstate.exists()); assertTrue(destinationLinkstateBuilder.exists()); - testFilesCount(parent, 3); + assertFilesCount(parent, 3); parent = new File(parent, "destination"); - testFilesCount(parent, 1); + assertFilesCount(parent, 1); parent = new File(parent, "linkstate"); File links = new File(parent, "Links.java"); File linksBuilder = new File(parent, "LinksBuilder.java"); assertTrue(links.exists()); assertTrue(linksBuilder.exists()); - testFilesCount(parent, 3); + assertFilesCount(parent, 3); parent = new File(parent, "links"); File source = new File(parent, "Source.java"); File sourceBuilder = new File(parent, "SourceBuilder.java"); assertTrue(source.exists()); assertTrue(sourceBuilder.exists()); - testFilesCount(parent, 3); + assertFilesCount(parent, 3); parent = new File(parent, "source"); File address = new File(parent, "Address.java"); File addressBuilder = new File(parent, "AddressBuilder.java"); assertTrue(address.exists()); assertTrue(addressBuilder.exists()); - testFilesCount(parent, 2); + assertFilesCount(parent, 2); // Test if sources are compilable testCompilation(sourcesOutputDir, compiledOutputDir); @@ -371,7 +371,7 @@ public class CompilationTest extends BaseCompilationTest { generator.generateToFile(sourcesOutputDir); File parent = new File(sourcesOutputDir, NS_TEST); - testFilesCount(parent, 4); + assertFilesCount(parent, 4); assertTrue(new File(parent, "TestData.java").exists()); assertTrue(new File(parent, "Nodes.java").exists()); assertTrue(new File(parent, "NodesBuilder.java").exists()); @@ -425,13 +425,13 @@ public class CompilationTest extends BaseCompilationTest { // Test if all sources are generated File fooParent = new File(sourcesOutputDir, NS_FOO); - testFilesCount(fooParent, 3); + assertFilesCount(fooParent, 3); assertTrue(new File(fooParent, "FooData.java").exists()); assertTrue(new File(fooParent, "Nodes.java").exists()); assertTrue(new File(fooParent, "NodesBuilder.java").exists()); File barParent = new File(sourcesOutputDir, NS_BAR); - testFilesCount(barParent, 1); + assertFilesCount(barParent, 1); assertTrue(new File(barParent, "IdentityClass.java").exists()); // Test if sources are compilable diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java index c20a52dbb0..a9f8526596 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java @@ -11,6 +11,7 @@ import static org.junit.Assert.*; import java.io.File; import java.io.FileNotFoundException; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; @@ -54,6 +55,17 @@ public class CompilationTestUtils { } } + /** + * Asserts that class contains field with fiven name and type. + * + * @param clazz + * class to test + * @param name + * field name + * @param type + * field type + * @return field with given name if present in class + */ static Field assertContainsField(Class clazz, String name, Class type) { try { Field f = clazz.getDeclaredField(name); @@ -64,6 +76,71 @@ public class CompilationTestUtils { } } + /** + * Asserts that class contains field with given name and value. Method tries + * to create new instance of class and get value of field. If class + * constructor contains any arguments, class is instantiated with null + * values. + * + * @param clazz + * class to test + * @param name + * name of field + * @param returnType + * return type of field + * @param expectedValue + * expected value of field + * @param constructorArgs + * constructor arguments of class to test + */ + static void assertContainsFieldWithValue(Class clazz, String name, Class returnType, Object expectedValue, + Class... constructorArgs) { + Object[] initargs = null; + if (constructorArgs != null && constructorArgs.length > 0) { + initargs = new Object[constructorArgs.length]; + for (int i = 0; i < constructorArgs.length; i++) { + initargs[i] = null; + } + } + assertContainsFieldWithValue(clazz, name, returnType, expectedValue, constructorArgs, initargs); + } + + /** + * Asserts that class contains field with given name, return type and value. + * + * @param clazz + * class to test + * @param name + * name of field + * @param returnType + * return type of field + * @param expectedValue + * expected value of field + * @param constructorArgs + * array of constructor arguments classes + * @param initargs + * array of constructor values + */ + static void assertContainsFieldWithValue(Class clazz, String name, Class returnType, Object expectedValue, + Class[] constructorArgs, Object... initargs) { + Field f = assertContainsField(clazz, name, returnType); + try { + Constructor c = clazz.getDeclaredConstructor(constructorArgs); + Object o = c.newInstance(initargs); + assertEquals(expectedValue, f.get(o)); + } catch (Exception e) { + throw new AssertionError("Failed to perform " + name + " field test", e); + } + } + + /** + * Asserts that class contains constructor with parameter types. + * + * @param clazz + * class to test + * @param args + * array of argument classes + */ static void assertContainsConstructor(Class clazz, Class... args) { try { clazz.getDeclaredConstructor(args); @@ -73,6 +150,19 @@ public class CompilationTestUtils { } } + /** + * Asserts that class contains method with given name, return type and + * parameter types. + * + * @param clazz + * class to test + * @param returnType + * method return type + * @param name + * method name + * @param args + * array of parameter type classes + */ static void assertContainsMethod(Class clazz, Class returnType, String name, Class... args) { try { Method m = clazz.getDeclaredMethod(name, args); @@ -83,8 +173,19 @@ public class CompilationTestUtils { } } - static void assertContainsMethod(Class clazz, String returnTypeStr, String name, ClassLoader loader) - throws Exception { + /** + * Asserts that class contains method with given name and return type. + * + * @param clazz + * class to test + * @param returnTypeStr + * name of method return type + * @param name + * method name + * @param loader + * current class loader + */ + static void assertContainsMethod(Class clazz, String returnTypeStr, String name, ClassLoader loader) { Class returnType; try { returnType = Class.forName(returnTypeStr, true, loader); @@ -92,14 +193,16 @@ public class CompilationTestUtils { assertEquals(returnType, method.getReturnType()); } catch (ClassNotFoundException e) { throw new AssertionError("Return type of method '" + name + "' not found"); + } catch (NoSuchMethodException e) { + throw new AssertionError("Method " + name + " does not exists in class " + clazz.getSimpleName()); } } /** - * Check for presence of hashCode, equals and toString methods. + * Asserts that class containes hashCode, equals and toString methods. * * @param clazz - * class to check + * class to test */ static void assertContainsDefaultMethods(Class clazz) { assertContainsMethod(clazz, Integer.TYPE, "hashCode"); @@ -108,12 +211,12 @@ public class CompilationTestUtils { } /** - * Check for presence of 'public static + * Asserts that class contains 'public static * java.util.List> * getLength()' method. * * @param clazz - * class to check + * class to test */ static void assertContainsGetLength(Class clazz) { try { @@ -141,18 +244,18 @@ public class CompilationTestUtils { } /** - * Test if generated source implements interface. + * Asserts that class implements given interface. * - * @param classToTest + * @param clazz * source to test - * @param ifcClass - * expected interface type + * @param ifc + * expected interface */ - static void testImplementsIfc(Class classToTest, Class ifcClass) { - Class[] interfaces = classToTest.getInterfaces(); + static void assertImplementsIfc(Class clazz, Class ifc) { + Class[] interfaces = clazz.getInterfaces(); List> ifcsList = Arrays.asList(interfaces); - if (!ifcsList.contains(ifcClass)) { - throw new AssertionError(classToTest + " should implement " + ifcClass); + if (!ifcsList.contains(ifc)) { + throw new AssertionError(clazz + " should implement " + ifc); } } @@ -160,31 +263,42 @@ public class CompilationTestUtils { * Test if interface generated from augment extends Augmentation interface * with correct generic type. * - * @param classToTest + * @param clazz * interface generated from augment - * @param genericType + * @param genericTypeName * fully qualified name of expected parameter type */ - static void testAugmentation(Class classToTest, String genericType) { - final String ifcToImplement = "interface org.opendaylight.yangtools.yang.binding.Augmentation"; - testImplementParameterizedIfc(classToTest, ifcToImplement, genericType); + static void testAugmentation(Class clazz, String genericTypeName) { + final String ifcName = "interface org.opendaylight.yangtools.yang.binding.Augmentation"; + assertImplementsParameterizedIfc(clazz, ifcName, genericTypeName); } - static void testImplementParameterizedIfc(Class classToTest, String ifcToImplement, String genericType) { - ParameterizedType augmentation = null; - for (java.lang.reflect.Type ifc : classToTest.getGenericInterfaces()) { + /** + * Asserts that class implements interface with given name and generic type + * parameter. + * + * @param clazz + * class to test + * @param ifcName + * name of interface + * @param genericTypeName + * name of generic type + */ + static void assertImplementsParameterizedIfc(Class clazz, String ifcName, String genericTypeName) { + ParameterizedType ifcType = null; + for (java.lang.reflect.Type ifc : clazz.getGenericInterfaces()) { if (ifc instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) ifc; - if (ifcToImplement.equals(pt.getRawType().toString())) { - augmentation = pt; + if (ifcName.equals(pt.getRawType().toString())) { + ifcType = pt; } } } - assertNotNull(augmentation); + assertNotNull(ifcType); - java.lang.reflect.Type[] typeArguments = augmentation.getActualTypeArguments(); + java.lang.reflect.Type[] typeArguments = ifcType.getActualTypeArguments(); assertEquals(1, typeArguments.length); - assertEquals("interface " + genericType, typeArguments[0].toString()); + assertEquals("interface " + genericTypeName, typeArguments[0].toString()); } /** @@ -205,7 +319,15 @@ public class CompilationTestUtils { assertTrue(compiled); } - static void testFilesCount(File dir, int count) { + /** + * Asserts that directory contains exactly given count of files. + * + * @param dir + * directory to test + * @param count + * expected count of files in directory + */ + static void assertFilesCount(File dir, int count) { File[] dirContent = dir.listFiles(); if (dirContent == null) { throw new AssertionError("File " + dir + " doesn't exists or it's not a directory"); diff --git a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java index d335633792..5d3029f09e 100644 --- a/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java +++ b/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java @@ -30,6 +30,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; */ public class TypedefCompilationTest extends BaseCompilationTest { private static final String VAL = "_value"; + private static final String UNITS = "_UNITS"; @Test public void test() throws Exception { @@ -46,6 +47,7 @@ public class TypedefCompilationTest extends BaseCompilationTest { generator.generateToFile(sourcesOutputDir); File parent = new File(sourcesOutputDir, NS_FOO); + File int32Ext0 = new File(parent, "Int32Ext0.java"); File int32Ext1 = new File(parent, "Int32Ext1.java"); File int32Ext2 = new File(parent, "Int32Ext2.java"); File myDecimalType = new File(parent, "MyDecimalType.java"); @@ -56,6 +58,7 @@ public class TypedefCompilationTest extends BaseCompilationTest { File unionExt2 = new File(parent, "UnionExt2.java"); File unionExt3 = new File(parent, "UnionExt3.java"); File unionExt4 = new File(parent, "UnionExt4.java"); + assertTrue(int32Ext0.exists()); assertTrue(int32Ext1.exists()); assertTrue(int32Ext2.exists()); assertTrue(myDecimalType.exists()); @@ -66,7 +69,7 @@ public class TypedefCompilationTest extends BaseCompilationTest { assertTrue(unionExt2.exists()); assertTrue(unionExt3.exists()); assertTrue(unionExt4.exists()); - testFilesCount(parent, 16); + assertFilesCount(parent, 25); // Test if sources are compilable testCompilation(sourcesOutputDir, compiledOutputDir); @@ -95,12 +98,14 @@ public class TypedefCompilationTest extends BaseCompilationTest { // typedef int32-ext2 assertFalse(int32Ext2Class.isInterface()); - assertEquals(0, int32Ext2Class.getDeclaredFields().length); + assertContainsFieldWithValue(int32Ext2Class, UNITS, String.class, "mile", Integer.class); + assertEquals(1, int32Ext2Class.getDeclaredFields().length); assertContainsConstructor(int32Ext2Class, Integer.class); assertContainsConstructor(int32Ext2Class, int32Ext2Class); assertContainsConstructor(int32Ext2Class, int32Ext1Class); assertEquals(3, int32Ext2Class.getDeclaredConstructors().length); - assertEquals(0, int32Ext2Class.getDeclaredMethods().length); + assertContainsMethod(int32Ext2Class, String.class, "toString"); + assertEquals(1, int32Ext2Class.getDeclaredMethods().length); // typedef string-ext1 assertFalse(stringExt1Class.isInterface()); @@ -171,7 +176,8 @@ public class TypedefCompilationTest extends BaseCompilationTest { assertFalse(unionExt3Class.isInterface()); assertContainsField(unionExt3Class, "_string", String.class); assertContainsField(unionExt3Class, "_unionExt2", unionExt2Class); - assertEquals(2, unionExt3Class.getDeclaredFields().length); + assertContainsFieldWithValue(unionExt3Class, UNITS, String.class, "object id", String.class); + assertEquals(3, unionExt3Class.getDeclaredFields().length); assertContainsMethod(unionExt3Class, String.class, "getString"); assertContainsMethod(unionExt3Class, unionExt2Class, "getUnionExt2"); assertContainsConstructor(unionExt3Class, String.class); diff --git a/code-generator/binding-java-api-generator/src/test/resources/compilation/typedef/foo.yang b/code-generator/binding-java-api-generator/src/test/resources/compilation/typedef/foo.yang index 7a43a64458..1cbe5b9d7c 100644 --- a/code-generator/binding-java-api-generator/src/test/resources/compilation/typedef/foo.yang +++ b/code-generator/binding-java-api-generator/src/test/resources/compilation/typedef/foo.yang @@ -6,9 +6,13 @@ module foo { revision "2013-10-08" { } + typedef int32-ext0 { + type int32; + } + typedef int32-ext1 { type int32 { - range "2..20"; + range "2..2147483647"; } } @@ -63,6 +67,7 @@ module foo { type union-ext2; type string; } + units "object id"; } typedef union-ext4 { @@ -94,4 +99,39 @@ module foo { } } + + typedef a { + type int8; + } + + typedef b { + type int16; + } + + typedef c { + type int32; + } + + typedef d { + type int64 { + range 0..max; + } + } + + typedef e { + type uint8; + } + + typedef f { + type uint16; + } + + typedef g { + type uint32; + } + + typedef h { + type uint64; + } + } diff --git a/code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java b/code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java index 712d079c32..5ca744e909 100644 --- a/code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java +++ b/code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java @@ -25,6 +25,7 @@ import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil; import org.opendaylight.yangtools.binding.generator.util.TypeConstants; import org.opendaylight.yangtools.binding.generator.util.Types; import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.EnumerationBuilderImpl; +import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl; import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider; import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType; @@ -617,15 +618,17 @@ public final class TypeProviderImpl implements TypeProvider { final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName, (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef); genTOBuilder.setIsUnion(true); + addUnitsToGenTO(genTOBuilder, typedef.getUnits()); returnType = genTOBuilder.toInstance(); } else if (innerTypeDefinition instanceof EnumTypeDefinition) { final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition; + // TODO units for typedef enum returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef); - } else if (innerTypeDefinition instanceof BitsTypeDefinition) { final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition; final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForBitsTypeDefinition( basePackageName, bitsTypeDefinition, typedefName); + addUnitsToGenTO(genTOBuilder, typedef.getUnits()); returnType = genTOBuilder.toInstance(); } else { final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType( @@ -657,23 +660,22 @@ public final class TypeProviderImpl implements TypeProvider { */ private GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition typedef, final Type javaType) { - if (javaType != null) { - final String propertyName = "value"; - - final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef); - genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef)); - final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName); - genPropBuilder.setReturnType(javaType); - genTOBuilder.addEqualsIdentity(genPropBuilder); - genTOBuilder.addHashIdentity(genPropBuilder); - genTOBuilder.addToStringProperty(genPropBuilder); - if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef instanceof ExtendedType) { - final List regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef); - addStringRegExAsConstant(genTOBuilder, regExps); - } - return genTOBuilder.toInstance(); + Preconditions.checkNotNull(javaType, "javaType cannot be null"); + final String propertyName = "value"; + + final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef); + genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef)); + final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName); + genPropBuilder.setReturnType(javaType); + genTOBuilder.addEqualsIdentity(genPropBuilder); + genTOBuilder.addHashIdentity(genPropBuilder); + genTOBuilder.addToStringProperty(genPropBuilder); + if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef instanceof ExtendedType) { + final List regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef); + addStringRegExAsConstant(genTOBuilder, regExps); } - return null; + addUnitsToGenTO(genTOBuilder, typedef.getUnits()); + return genTOBuilder.toInstance(); } /** @@ -1105,6 +1107,7 @@ public final class TypeProviderImpl implements TypeProvider { genTOBuilder.setExtendsType((GeneratedTransferObject) type); } } + addUnitsToGenTO(genTOBuilder, typedef.getUnits()); return genTOBuilder.toInstance(); } @@ -1199,4 +1202,13 @@ public final class TypeProviderImpl implements TypeProvider { } } + private void addUnitsToGenTO(GeneratedTOBuilder to, String units) { + if (units != null && !units.isEmpty()) { + to.addConstant(Types.STRING, "_UNITS", "\"" + units + "\""); + GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS"); + prop.setReturnType(Types.STRING); + to.addToStringProperty(prop); + } + } + } diff --git a/code-generator/maven-sal-api-gen-plugin/pom.xml b/code-generator/maven-sal-api-gen-plugin/pom.xml index 0fa6057860..97fe5d2734 100644 --- a/code-generator/maven-sal-api-gen-plugin/pom.xml +++ b/code-generator/maven-sal-api-gen-plugin/pom.xml @@ -30,6 +30,11 @@ org.opendaylight.yangtools binding-java-api-generator + + junit + junit + test + @@ -52,6 +57,13 @@ + + org.eclipse.xtend + xtend-maven-plugin + + + maven-clean-plugin + diff --git a/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/GeneratorImpl.xtend b/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/GeneratorImpl.xtend new file mode 100644 index 0000000000..78eeaf3383 --- /dev/null +++ b/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/GeneratorImpl.xtend @@ -0,0 +1,533 @@ +package org.opendaylight.yangtools.yang.unified.doc.generator + +import org.opendaylight.yangtools.yang.model.api.SchemaContext +import java.io.File +import java.util.Set +import org.opendaylight.yangtools.yang.model.api.Module +import java.io.IOException +import java.util.HashSet +import java.io.FileWriter +import java.io.BufferedWriter +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode +import org.opendaylight.yangtools.yang.model.api.TypeDefinition +import org.opendaylight.yangtools.yang.model.api.SchemaNode +import org.opendaylight.yangtools.yang.model.util.ExtendedType +import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition +import java.text.SimpleDateFormat +import java.util.Collection +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint +import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition +import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint +import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition +import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition +import org.opendaylight.yangtools.yang.model.api.NotificationDefinition +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer +import org.slf4j.LoggerFactory +import org.slf4j.Logger +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema +import java.util.List +import org.opendaylight.yangtools.yang.common.QName +import org.opendaylight.yangtools.yang.model.api.RpcDefinition +import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition + +class GeneratorImpl { + + File path + static val REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd") + static val Logger LOG = LoggerFactory.getLogger(GeneratorImpl) + + + def generate(SchemaContext context, File targetPath, Set modulesToGen) throws IOException { + path = targetPath; + path.mkdirs(); + val it = new HashSet; + for (module : modulesToGen) { + add(module.generateDocumentation()); + } + return it; + } + + def generateDocumentation(Module module) { + val destination = new File(path, '''«module.name».html''') + try { + val fw = new FileWriter(destination) + destination.createNewFile(); + val bw = new BufferedWriter(fw) + + bw.append(module.generate); + bw.close(); + fw.close(); + } catch (IOException e) { + LOG.error(e.getMessage()); + } + return destination; + } + + def generate(Module module) ''' + + + + «module.name» + + + «module.body» + + + ''' + + def body(Module module) ''' + «header(module)» + + «typeDefinitions(module)» + + «identities(module)» + + «groupings(module)» + + «dataStore(module)» + + «notifications(module)» + + «augmentations(module)» + + «rpcs(module)» + + «extensions(module)» + + «features(module)» + + ''' + + + def typeDefinitions(Module module) { + val Set> typedefs = module.typeDefinitions + if (typedefs.empty) { + return ''; + } + return ''' +

Type Definitions

+
    + «FOR typedef : typedefs» +
  • + «strong("typedef " + typedef.QName.localName)» +
      + «typedef.descAndRef» + «typedef.restrictions» +
    +
  • + «ENDFOR» +
+ ''' + } + + private def identities(Module module) { + if (module.identities.empty) { + return ''; + } + return ''' +

Identities

+
    + «FOR identity : module.identities» +
  • + «strong("identity " + identity.QName.localName)» +
      + «identity.descAndRef» + «IF identity.baseIdentity != null» + «listItem("base", identity.baseIdentity.QName.localName)» + «ENDIF» +
    +
  • + «ENDFOR» +
+ ''' + } + + private def groupings(Module module) { + if (module.groupings.empty) { + return ''; + } + return ''' +

Groupings

+
    + «FOR grouping : module.groupings» +
  • + «strong("grouping " + grouping.QName.localName)» +
      + «grouping.descAndRef» +
    +
  • + «ENDFOR» +
+ ''' + } + + def dataStore(Module module) { + if (module.childNodes.empty) { + return ''; + } + return ''' +

Datastore Structure

+ «tree(module)» + ''' + } + + def augmentations(Module module) { + if (module.augmentations.empty) { + return ''; + } + return ''' +

Augmentations

+ +
    + «FOR augment : module.augmentations» +
  • + augment + «augment.tree» +
  • + «ENDFOR» +
+ ''' + } + + def notifications(Module module) { + val Set notificationdefs = module.notifications + if (notificationdefs.empty) { + return ''; + } + return ''' +

Notifications

+ +
    + «FOR notificationdef : notificationdefs» +
  • + «notificationdef.nodeName» + «notificationdef.tree» +
  • + «ENDFOR» +
+ ''' + } + + def rpcs(Module module) { + if (module.rpcs.empty) { + return ''; + } + return ''' +

RPC Definitions

+ +
    + «FOR rpc : module.rpcs» +
  • + «rpc.nodeName» + «rpc.tree» +
  • + «ENDFOR» +
+ ''' + } + + def extensions(Module module) { + if (module.extensionSchemaNodes.empty) { + return ''; + } + return ''' +

Extensions

+ +
    + «FOR ext : module.extensionSchemaNodes» +
  • + «ext.nodeName» + «ext.tree» +
  • + «ENDFOR» +
+ ''' + } + + def features(Module module) { + if (module.features.empty) { + return ''; + } + return ''' +

Features

+ +
    + «FOR feature : module.features» +
  • + «strong("feature " + feature.QName.localName)» +
      + «feature.descAndRef» +
    +
  • + «ENDFOR» +
+ ''' + } + + def header(Module module) ''' +

«module.name»

+ +

Base Information

+
+
Prefix
+
«pre(module.prefix)»
+
Namespace
+
«pre(module.namespace.toString)»
+
Revision
+
«pre(REVISION_FORMAT.format(module.revision))»
+ + «FOR imp : module.imports BEFORE "
Imports
" » +
«pre(imp.prefix)» = «pre(imp.moduleName)»
+ «ENDFOR» +
+ ''' + + def process(Module module) { + throw new UnsupportedOperationException("TODO: auto-generated method stub") + } + + + + /* #################### TREE STRUCTURE #################### */ + def dispatch CharSequence tree(Module module) ''' + «strong("module " + module.name)» + «module.childNodes.tree» + ''' + + def dispatch CharSequence tree(DataNodeContainer node) ''' + «IF node instanceof SchemaNode» + «(node as SchemaNode).nodeName» + «ENDIF» + «node.childNodes.tree» + ''' + + def dispatch CharSequence tree(DataSchemaNode node) ''' + «node.nodeName» + ''' + + def dispatch CharSequence tree(ListSchemaNode node) ''' + «node.nodeName» + «node.childNodes.tree» + ''' + + def dispatch CharSequence tree(Collection childNodes) ''' + «IF childNodes !== null && !childNodes.empty» +
    + «FOR child : childNodes» +
  • + «child.tree» +
  • + «ENDFOR» +
+ «ENDIF» + ''' + + def listKeys(ListSchemaNode node) ''' + [«FOR key : node.keyDefinition SEPARATOR " "»«key.localName»«ENDFOR»] + ''' + + def dispatch CharSequence tree(AugmentationSchema augment) ''' +
    + «listItem(augment.description)» + «listItem("Reference", augment.reference)» + «IF augment.whenCondition !== null» + «listItem("When", augment.whenCondition.toString)» + «ENDIF» +
  • + Path «augment.targetPath.path.pathToTree» +
  • +
  • + Child nodes + «augment.childNodes.tree» +
  • +
+ ''' + + def dispatch CharSequence tree(NotificationDefinition notification) ''' +
    + «notification.descAndRef» +
  • + Child nodes + «notification.childNodes.tree» +
  • +
+ ''' + + def dispatch CharSequence tree(RpcDefinition rpc) ''' +
    + «rpc.descAndRef» +
  • + «rpc.input.tree» +
  • +
  • + «rpc.output.tree» +
  • +
+ ''' + + def dispatch CharSequence tree(ExtensionDefinition ext) ''' +
    + «ext.descAndRef» + «listItem("Argument", ext.argument)» +
+ ''' + + + + /* #################### RESTRICTIONS #################### */ + private def restrictions(TypeDefinition type) ''' + «type.toLength» + «type.toRange» + ''' + + def dispatch toLength(TypeDefinition type) { + } + + def dispatch toLength(BinaryTypeDefinition type) ''' + «type.lengthConstraints.toLengthStmt» + ''' + + def dispatch toLength(StringTypeDefinition type) ''' + «type.lengthConstraints.toLengthStmt» + ''' + + def dispatch toLength(ExtendedType type) ''' + «type.lengthConstraints.toLengthStmt» + ''' + + def dispatch toRange(TypeDefinition type) { + } + + def dispatch toRange(DecimalTypeDefinition type) ''' + «type.rangeConstraints.toRangeStmt» + ''' + + def dispatch toRange(IntegerTypeDefinition type) ''' + «type.rangeConstraints.toRangeStmt» + ''' + + def dispatch toRange(UnsignedIntegerTypeDefinition type) ''' + «type.rangeConstraints.toRangeStmt» + ''' + + def dispatch toRange(ExtendedType type) ''' + «type.rangeConstraints.toRangeStmt» + ''' + + def toLengthStmt(Collection lengths) ''' + «IF lengths != null && !lengths.empty» + «listItem("Length restrictions")» +
    + «FOR length : lengths» +
  • + «IF length.min == length.max» + «length.min» + «ELSE» + <«length.min», «length.max»> + «ENDIF» +
  • + «ENDFOR» +
+ «ENDIF» + ''' + + def toRangeStmt(Collection ranges) ''' + «IF ranges != null && !ranges.empty» + «listItem("Range restrictions")» +
    + «FOR range : ranges» +
  • + «IF range.min == range.max» + «range.min» + «ELSE» + <«range.min», «range.max»> + «ENDIF» +
  • + «ENDFOR» +
+ «ENDIF» + ''' + + + + /* #################### UTILITY #################### */ + private def strong(String str) '''«str»''' + private def italic(String str) '''«str»''' + private def pre(String str) '''
«str»
''' + + def CharSequence descAndRef(SchemaNode node) ''' + «listItem(node.description)» + «listItem("Reference", node.reference)» + ''' + + private def listItem(String value) ''' + «IF value !== null && !value.empty» +
  • + «value» +
  • + «ENDIF» + ''' + + private def listItem(String name, String value) ''' + «IF value !== null && !value.empty» +
  • + «name» +
      +
    • + «value» +
    • +
    +
  • + «ENDIF» + ''' + + private def CharSequence pathToTree(List path) ''' + «IF path !== null && !path.empty» +
      + «FOR pathElement : path» +
    • + «pathElement.namespace» «pathElement.localName» +
    • + «ENDFOR» +
    + «ENDIF» + ''' + + def dispatch addedByInfo(SchemaNode node) ''' + ''' + + def dispatch addedByInfo(DataSchemaNode node) ''' + «IF node.augmenting»(A)«ENDIF»«IF node.addedByUses»(U)«ENDIF» + ''' + + def dispatch isAddedBy(SchemaNode node) { + return false; + } + + def dispatch isAddedBy(DataSchemaNode node) { + if (node.augmenting || node.addedByUses) { + return true + } else { + return false; + } + } + + def dispatch nodeName(SchemaNode node) ''' + «IF node.isAddedBy» + «italic(node.QName.localName)»«node.addedByInfo» + «ELSE» + «strong(node.QName.localName)»«node.addedByInfo» + «ENDIF» + ''' + + def dispatch nodeName(ListSchemaNode node) ''' + «IF node.isAddedBy» + «italic(node.QName.localName)» «IF node.keyDefinition !== null && !node.keyDefinition.empty»«node.listKeys»«ENDIF»«node.addedByInfo» + «ELSE» + «strong(node.QName.localName)» «IF node.keyDefinition !== null && !node.keyDefinition.empty»«node.listKeys»«ENDIF» + «ENDIF» + ''' + +} diff --git a/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocumentationGeneratorImpl.java b/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocumentationGeneratorImpl.java new file mode 100644 index 0000000000..39a1d0bea1 --- /dev/null +++ b/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocumentationGeneratorImpl.java @@ -0,0 +1,46 @@ +package org.opendaylight.yangtools.yang.unified.doc.generator.maven; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.unified.doc.generator.GeneratorImpl; +import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator; + +public class DocumentationGeneratorImpl extends GeneratorImpl implements CodeGenerator { + + @Override + public Collection generateSources(SchemaContext arg0, File arg1, Set arg2) throws IOException { + // TODO Auto-generated method stub + generate(arg0, arg1, arg2); + return Collections.emptySet(); + } + + @Override + public void setLog(Log log) { + // use maven logging if necessary + + } + + @Override + public void setAdditionalConfig(Map additionalConfiguration) { + // no additional config utilized + } + + @Override + public void setResourceBaseDir(File resourceBaseDir) { + // no resource processing necessary + } + + @Override + public void setMavenProject(MavenProject project) { + // no additional information needed + } +} diff --git a/code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocGenTest.java b/code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocGenTest.java new file mode 100644 index 0000000000..7bf8f3ea6c --- /dev/null +++ b/code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocGenTest.java @@ -0,0 +1,81 @@ +package org.opendaylight.yangtools.yang.unified.doc.generator.maven; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator; + +public class DocGenTest { + public static final String FS = File.separator; + private static final String TEST_PATH = "target" + FS + "test" + FS + "site"; + private static final File GENERATOR_OUTPUT_DIR = new File(TEST_PATH); + private YangParserImpl parser; + + @Before + public void init() { + if (GENERATOR_OUTPUT_DIR.exists()) { + deleteTestDir(GENERATOR_OUTPUT_DIR); + } + assertTrue(GENERATOR_OUTPUT_DIR.mkdirs()); + parser = new YangParserImpl(); + } + + @After + public void cleanUp() { + if (GENERATOR_OUTPUT_DIR.exists()) { + deleteTestDir(GENERATOR_OUTPUT_DIR); + } + } + + @Test + public void testListGeneration() throws Exception { + final List sourceFiles = getSourceFiles("/doc-gen"); + final Set modulesToBuild = parser.parseYangModels(sourceFiles); + final SchemaContext context = parser.resolveSchemaContext(modulesToBuild); + final CodeGenerator generator = new DocumentationGeneratorImpl(); + generator.generateSources(context, GENERATOR_OUTPUT_DIR, modulesToBuild); + } + + private static List getSourceFiles(String path) throws FileNotFoundException { + final String resPath = DocGenTest.class.getResource(path).getPath(); + final File sourcesDir = new File(resPath); + if (sourcesDir.exists()) { + final List sourceFiles = new ArrayList<>(); + final File[] fileArray = sourcesDir.listFiles(); + if (fileArray == null) { + throw new IllegalArgumentException("Unable to locate files in " + sourcesDir); + } + sourceFiles.addAll(Arrays.asList(fileArray)); + return sourceFiles; + } else { + throw new FileNotFoundException("Testing files were not found(" + sourcesDir.getName() + ")"); + } + } + + private static void deleteTestDir(File file) { + if (file.isDirectory()) { + File[] filesToDelete = file.listFiles(); + if (filesToDelete != null) { + for (File f : filesToDelete) { + deleteTestDir(f); + } + } + } + if (!file.delete()) { + throw new RuntimeException("Failed to clean up after test"); + } + } + +} diff --git a/code-generator/maven-sal-api-gen-plugin/src/test/resources/doc-gen/network-topology@2013-07-12.yang b/code-generator/maven-sal-api-gen-plugin/src/test/resources/doc-gen/network-topology@2013-07-12.yang new file mode 100644 index 0000000000..fb18be46bc --- /dev/null +++ b/code-generator/maven-sal-api-gen-plugin/src/test/resources/doc-gen/network-topology@2013-07-12.yang @@ -0,0 +1,432 @@ +module network-topology { + yang-version 1; + namespace "urn:TBD:params:xml:ns:yang:network-topology"; + // replace with IANA namespace when assigned + prefix "nt"; + + organization "TBD"; + + contact "WILL-BE-DEFINED-LATER"; +/* + description + "This module defines a model for the topology of a network. + Key design decisions are as follows: + A topology consists of a set of nodes and links. + Links are point-to-point and unidirectional. + Bidirectional connections need to be represented through + two separate links. + Multipoint connections, broadcast domains etc can be represented + through a hierarchy of nodes, then connecting nodes at + upper layers of the hierarchy."; +*/ + revision 2013-07-12 { + description + "Initial revision."; + } + + typedef topology-id { + type string; + description + "An identifier for a topology."; + } + + typedef node-id { + type string; + description + "An identifier for a node in a topology. + The identifier may be opaque. + The identifier SHOULD be chosen such that the same node in a + real network topology will always be identified through the + same identifier, even if the model is instantiated in separate + datastores. An implementation MAY choose to capture semantics + in the identifier, for example to indicate the type of node + and/or the type of topology that the node is a part of."; + } + + typedef link-id { + type string; + description + "An identifier for a link in a topology. + The identifier may be opaque. + The identifier SHOULD be chosen such that the same link in a + real network topology will always be identified through the + same identifier, even if the model is instantiated in separate + datastores. An implementation MAY choose to capture semantics + in the identifier, for example to indicate the type of link + and/or the type of topology that the link is a part of."; + } + + typedef tp-id { + type string; + description + "An identifier for termination points on a node. + The identifier may be opaque. + The identifier SHOULD be chosen such that the same TP in a + real network topology will always be identified through the + same identifier, even if the model is instantiated in separate + datastores. An implementation MAY choose to capture semantics + in the identifier, for example to indicate the type of TP + and/or the type of node and topology that the TP is a part of."; + } + + typedef tp-ref { + type leafref { + path "/network-topology/topology/node/termination-point/tp-id"; + } + description + "A type for an absolute reference to a termination point. + (This type should not be used for relative references. + In such a case, a relative path should be used instead.)"; + } + typedef topology-ref { + type leafref { + path "/network-topology/topology/topology-id"; + } + description + "A type for an absolute reference a topology instance."; + } + + typedef node-ref { + type leafref { + path "/network-topology/topology/node/node-id"; + } + description + "A type for an absolute reference to a node instance. + (This type should not be used for relative references. + In such a case, a relative path should be used instead.)"; + } + + typedef link-ref { + type leafref { + path "/network-topology/topology/link/link-id"; + } + description + "A type for an absolute reference a link instance. + (This type should not be used for relative references. + In such a case, a relative path should be used instead.)"; + } + + typedef x { + type binary { + length 5..10|15..20|25..30; + } + description "x type description"; + reference "x type reference"; + } + + typedef y { + type int32 { + range 5..555; + } + } + + identity crypto-alg { + description "Base identity from which all crypto algorithms are derived."; + } + + identity des { + base "crypto-alg"; + description "DES crypto algorithm"; + } + + identity des3 { + base "crypto-alg"; + description "Triple DES crypto algorithm"; + } + + grouping tp-attributes { + description + "The data objects needed to define a termination point. + (This only includes a single leaf at this point, used + to identify the termination point.) + Provided in a grouping so that in addition to the datastore, + the data can also be included in notifications."; + leaf tp-id { + type tp-id; + } + leaf-list tp-ref { + type tp-ref; + config false; + description + "The leaf list identifies any termination points that the + termination point is dependent on, or maps onto. + Those termination points will themselves be contained + in a supporting node. + This dependency information can be inferred from + the dependencies between links. For this reason, + this item is not separately configurable. Hence no + corresponding constraint needs to be articulated. + The corresponding information is simply provided by the + implementing system."; + } + } + + grouping node-attributes { + description + "The data objects needed to define a node. + The objects are provided in a grouping so that in addition to + the datastore, the data can also be included in notifications + as needed."; + leaf node-id { + type node-id; + description + "The identifier of a node in the topology. + A node is specific to a topology to which it belongs."; + } + list supporting-node { + description + "This list defines vertical layering information for nodes. + It allows to capture for any given node, which node (or nodes) + in the corresponding underlay topology it maps onto. + A node can map to zero, one, or more nodes below it; + accordingly there can be zero, one, or more elements in the list. + If there are specific layering requirements, for example + specific to a particular type of topology that only allows + for certain layering relationships, the choice + below can be augmented with additional cases. + A list has been chosen rather than a leaf-list in order + to provide room for augmentations, e.g. for + statistics or priorization information associated with + supporting nodes."; + key "node-ref"; + leaf node-ref { + type node-ref; + } + } + } + + grouping link-attributes { + // This is a grouping, not defined inline with the link definition itself, + // so it can be included in a notification, if needed + leaf link-id { + type link-id; + description + "The identifier of a link in the topology. + A link is specific to a topology to which it belongs."; + } + container source { + description "XYZ"; + leaf source-node { + mandatory true; + type node-ref; + description + "Source node identifier, must be in same topology."; + } + leaf source-tp { + type tp-ref; + description + "Termination point within source node that terminates the link."; + } + } + container destination { + leaf dest-node { + mandatory true; + type node-ref; + description + "Destination node identifier, must be in same topology."; + } + leaf dest-tp { + type tp-ref; + description + "Termination point within destination node that terminates the link."; + } + } + list supporting-link { + key "link-ref"; + leaf link-ref { + type link-ref; + } + } + } + + + container network-topology { + list topology { + description " + This is the model of an abstract topology. + A topology contins nodes and links. + Each topology MUST be identified by + unique topology-id for reason that a network could contain many + topologies. + "; + key "topology-id"; + leaf topology-id { + type topology-id; + description " + It is presumed that a datastore will contain many topologies. To + distinguish between topologies it is vital to have UNIQUE + topology identifiers. + "; + } + container topology-types { + description + "This container is used to identify the type, or types + (as a topology can support several types simultaneously), + of the topology. + Topology types are the subject of several integrity constraints + that an implementing server can validate in order to + maintain integrity of the datastore. + Topology types are indicated through separate data nodes; + the set of topology types is expected to increase over time. + To add support for a new topology, an augmenting module + needs to augment this container with a new empty optional + container to indicate the new topology type. + The use of a container allows to indicate a subcategorization + of topology types. + The container SHALL NOT be augmented with any data nodes + that serve a purpose other than identifying a particular + topology type. + "; + } + list underlay-topology { + key "topology-ref"; + leaf topology-ref { + type topology-ref; + } + // a list, not a leaf-list, to allow for potential augmentation + // with properties specific to the underlay topology, + // such as statistics, preferences, or cost. + description + "Identifies the topology, or topologies, that this topology + is dependent on."; + } + + list node { + description "The list of network nodes defined for the topology."; + key "node-id"; + uses node-attributes; + must "boolean(../underlay-topology[*]/node[./supporting-nodes/node-ref])"; + // This constraint is meant to ensure that a referenced node is in fact + // a node in an underlay topology. + list termination-point { + description + "A termination point can terminate a link. + Depending on the type of topology, a termination point could, + for example, refer to a port or an interface."; + key "tp-id"; + uses tp-attributes; + } + } + + list link { + description " + A Network Link connects a by Local (Source) node and + a Remote (Destination) Network Nodes via a set of the + nodes' termination points. + As it is possible to have several links between the same + source and destination nodes, and as a link could potentially + be re-homed between termination points, to ensure that we + would always know to distinguish between links, every link + is identified by a dedicated link identifier. + Note that a link models a point-to-point link, not a multipoint + link. + Layering dependencies on links in underlay topologies are + not represented as the layering information of nodes and of + termination points is sufficient. + "; + key "link-id"; + uses link-attributes; + must "boolean(../underlay-topology/link[./supporting-link]"; + // Constraint: any supporting link must be part of an underlay topology + must "boolean(../node[./source/source-node])"; + // Constraint: A link must have as source a node of the same topology + must "boolean(../node[./destination/dest-node])"; + // Constraint: A link must have as source a destination of the same topology + must "boolean(../node/termination-point[./source/source-tp])"; + // Constraint: The source termination point must be contained in the source node + must "boolean(../node/termination-point[./destination/dest-tp])"; + // Constraint: The destination termination point must be contained + // in the destination node + } + } + } + + notification n1 { + description "This example defines a notification 1."; + leaf event-class { + type string; + } + anyxml reporting-entity; + container severity { + list links { + container endpoints { + leaf start { + type x; + } + leaf end { + type y; + } + } + leaf id { + type string; + } + } + } + } + + notification n2 { + description "This example defines a notification 2."; + leaf event-class { + type string; + } + anyxml reporting-entity; + leaf severity { + type string; + } + } + + augment "/network-topology" { + anyxml any-a; + anyxml any-b; + } + + augment "/network-topology/topology" { + description "description of augment 2"; + reference "reference of augment 2"; + list list-a {} + list list-b { + leaf leaf-c { + type string; + } + } + } + + augment "/network-topology/topology/topology-types" { + container container-c { + leaf id { + type binary; + } + } + } + + rpc rock-the-house { + description "This statement is used to define a NETCONF RPC operation."; + reference "http://tools.ietf.org/html/rfc6020#section-7.13"; + input { + leaf zip-code { + type string; + } + } + output { + leaf number { + type int32; + } + } + } + + extension c-define { + description + "Takes as argument a name string. + Makes the code generator use the given name in the + #define."; + argument "name"; + } + + feature local-storage { + description + "This feature means the device supports local + storage (memory, flash or disk) that can be used to + store syslog messages."; + } + +} diff --git a/model/ietf/ietf-topology/pom.xml b/model/ietf/ietf-topology/pom.xml index 27b0559f4b..828aa89c82 100644 --- a/model/ietf/ietf-topology/pom.xml +++ b/model/ietf/ietf-topology/pom.xml @@ -1,4 +1,5 @@ - + model-ietf @@ -27,6 +28,40 @@ + + org.opendaylight.yangtools + yang-maven-plugin + 0.5.9-SNAPSHOT + + + + generate-sources + + + src/main/yang + + + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + target/generated-sources/sal + + + org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl + target/generated-sources/site + + + true + + + + + + org.opendaylight.yangtools + maven-sal-api-gen-plugin + 0.6.0-SNAPSHOT + jar + + + maven-jar-plugin diff --git a/pom.xml b/pom.xml index 1dc89df7ea..3faec7b031 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 yangtools @@ -9,7 +10,7 @@ UTF-8 http://nexus.opendaylight.org/content - + 1.7 1.7 @@ -19,7 +20,7 @@ 2.4 2.9.1 2.2.1 - 2.16 + 2.16 3.1 @@ -159,7 +160,8 @@ ${maven.jar.version} - + ${project.build.outputDirectory}/META-INF/MANIFEST.MF @@ -238,6 +240,28 @@ + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.version} + + stylesheet.css + + + + attach-javadocs + + jar + + + + + aggregate + + site + + + @@ -265,24 +289,6 @@ org.apache.maven.plugins maven-javadoc-plugin - ${maven.javadoc.version} - - maven - - - - attach-javadocs - - jar - - - - - aggregate - - site - - diff --git a/src/main/resources/stylesheet.css b/src/main/resources/stylesheet.css new file mode 100644 index 0000000000..76de82bfe1 --- /dev/null +++ b/src/main/resources/stylesheet.css @@ -0,0 +1,475 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} + diff --git a/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java b/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java index 4bf91e32ea..66c745e29a 100644 --- a/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java +++ b/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java @@ -159,9 +159,16 @@ public final class InstanceIdentifier implements Path extends Builder> { - + /** + * @deprecated use {@link child(Class)} or {@link augmentation(Class)} instead. + */ + @Deprecated InstanceIdentifierBuilder node(Class container); + /** + * @deprecated use {@link child(Class,Identifier)} or {@link augmentation(Class,Identifier)} instead. + */ + @Deprecated & DataObject, K extends Identifier> InstanceIdentifierBuilder node( Class listItem, K listKey); @@ -170,14 +177,28 @@ public final class InstanceIdentifier implements Path & ChildOf, K extends Identifier> InstanceIdentifierBuilder child( Class listItem, K listKey); + > InstanceIdentifierBuilder augmentation(Class container); + } + /** + * @deprecated use {@link builder(Class)} or {@link builder(Class,Identifier)} instead. + */ + @Deprecated @SuppressWarnings("rawtypes") public static InstanceIdentifierBuilder builder() { return new BuilderImpl(); } - @SuppressWarnings({ "rawtypes", "unchecked" }) + public static > InstanceIdentifierBuilder builder(Class container) { + return new BuilderImpl().addNode(container); + } + + public static & DataObject, K extends Identifier> InstanceIdentifierBuilder builder( + Class listItem, K listKey) { + return new BuilderImpl().addNode(listItem, listKey); + } + public static InstanceIdentifierBuilder builder(InstanceIdentifier basePath) { return new BuilderImpl(basePath.path,basePath.targetType); } @@ -191,12 +212,26 @@ public final class InstanceIdentifier implements Path(); } - public BuilderImpl(List prefix,Class target) { this.path = new ArrayList<>(prefix); this.target = target; } + @SuppressWarnings("unchecked") + private InstanceIdentifierBuilder addNode(Class container) { + target = container; + path.add(new Item(container)); + return (InstanceIdentifierBuilder) this; + } + + @SuppressWarnings("unchecked") + private , K extends Identifier> InstanceIdentifierBuilder addNode( + Class listItem, K listKey) { + target = listItem; + path.add(new IdentifiableItem(listItem, listKey)); + return (InstanceIdentifierBuilder) this; + } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public InstanceIdentifier toInstance() { @@ -205,31 +240,31 @@ public final class InstanceIdentifier implements Path InstanceIdentifierBuilder node(Class container) { - target = container; - path.add(new Item(container)); - return (InstanceIdentifierBuilder) this; + return addNode(container); } @Override - @SuppressWarnings("unchecked") public , K extends Identifier> InstanceIdentifierBuilder node( Class listItem, K listKey) { - target = listItem; - path.add(new IdentifiableItem(listItem, listKey)); - return (InstanceIdentifierBuilder) this; + return addNode(listItem, listKey); } - + @Override public > InstanceIdentifierBuilder child(Class container) { - return node(container); + return addNode(container); } @Override public & ChildOf, K extends Identifier> InstanceIdentifierBuilder child( Class listItem, K listKey) { - return node(listItem,listKey); + return addNode(listItem,listKey); + } + + @Override + public > InstanceIdentifierBuilder augmentation( + Class container) { + return addNode(container); } } diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/Int64.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/Int64.java index 5f42022547..892a1436ee 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/Int64.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/Int64.java @@ -22,7 +22,7 @@ public final class Int64 extends AbstractSignedInteger { private static final String DESCRIPTION = "int64 represents integer values between -9223372036854775808 and 9223372036854775807, inclusively."; private Int64() { - super(NAME, DESCRIPTION, Integer.MIN_VALUE, Integer.MAX_VALUE, ""); + super(NAME, DESCRIPTION, Long.MIN_VALUE, Long.MAX_VALUE, ""); } public static Int64 getInstance() { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserListenerUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserListenerUtils.java index 917a001c6b..3f4166bd08 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserListenerUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserListenerUtils.java @@ -132,12 +132,16 @@ public final class ParserListenerUtils { * @return first string value from given tree */ public static String stringFromNode(final ParseTree treeNode) { - final String result = ""; + String result = ""; for (int i = 0; i < treeNode.getChildCount(); ++i) { if (treeNode.getChild(i) instanceof StringContext) { final StringContext context = (StringContext) treeNode.getChild(i); if (context != null) { - return context.getChild(0).getText().replace("\"", ""); + result = context.getChild(0).getText(); + if (!(result.startsWith("\"")) && result.endsWith("\"")) { + LOG.error("Syntax error at line " + context.getStart().getLine() + ": missing '\"'."); + } + return result.replace("\"", ""); } } }