From: Martin Vitez Date: Thu, 10 Jul 2014 13:51:32 +0000 (+0200) Subject: BUG-1347: fixed bug in generation constraints for decimal64 type. X-Git-Tag: release/helium~344^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=611f520db42615f3085f4938ba3f8c0fd4a6cc81;hp=ac8aab5cefd508cce3a1227d81da8e0664d4fd3a;p=yangtools.git BUG-1347: fixed bug in generation constraints for decimal64 type. Added test. Change-Id: I52a539ea7c5ff6b36b9bc362660188f9627bff7d Signed-off-by: Martin Vitez --- 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 672d4b648e..c1b1074d5d 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 @@ -178,7 +178,7 @@ abstract class BaseTemplate { «generateLengthRestriction(returnType, restrictions, paramName, isNestedType)» «ENDIF» «IF !restrictions.rangeConstraints.empty» - «generateRangeRestriction(returnType, restrictions, paramName, isNestedType)» + «generateRangeRestriction(returnType, paramName, isNestedType)» «ENDIF» «ENDIF» ''' @@ -199,12 +199,11 @@ abstract class BaseTemplate { } ''' - def private generateRangeRestriction(Type returnType, Restrictions restrictions, String paramName, boolean isNestedType) ''' - «val clazz = restrictions.rangeConstraints.iterator.next.min.class» + def private generateRangeRestriction(Type returnType, String paramName, boolean isNestedType) ''' if («paramName» != null) { - «printRangeConstraint(returnType, clazz, paramName, isNestedType)» + «printRangeConstraint(returnType, paramName, isNestedType)» boolean isValidRange = false; - for («Range.importedName»<«clazz.importedNumber»> r : «IF isNestedType»«returnType.importedName».«ENDIF»range()) { + for («Range.importedName»<«returnType.importedNumber»> r : «IF isNestedType»«returnType.importedName».«ENDIF»range()) { if (r.contains(_constraint)) { isValidRange = true; } @@ -223,22 +222,22 @@ abstract class BaseTemplate { «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName»«IF isNestedType».getValue()«ENDIF».length«IF !isArray»()«ENDIF»); ''' - def printRangeConstraint(Type returnType, Class clazz, String paramName, boolean isNestedType) ''' - «IF clazz.canonicalName.equals(BigDecimal.canonicalName)» - «clazz.importedNumber» _constraint = new «clazz.importedNumber»(«paramName»«IF isNestedType».getValue()«ENDIF».toString()); + def printRangeConstraint(Type returnType, String paramName, boolean isNestedType) ''' + «IF BigDecimal.canonicalName.equals(returnType.fullyQualifiedName)» + «BigDecimal.importedName» _constraint = new «BigDecimal.importedName»(«paramName»«IF isNestedType».getValue()«ENDIF».toString()); «ELSE» «IF isNestedType» «val propReturnType = findProperty(returnType as GeneratedTransferObject, "value").returnType» «IF propReturnType.fullyQualifiedName.equals(BigInteger.canonicalName)» - «clazz.importedNumber» _constraint = «paramName».getValue(); + «BigInteger.importedName» _constraint = «paramName».getValue(); «ELSE» - «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName».getValue()); + «BigInteger.importedName» _constraint = «BigInteger.importedName».valueOf(«paramName».getValue()); «ENDIF» «ELSE» «IF returnType.fullyQualifiedName.equals(BigInteger.canonicalName)» - «clazz.importedNumber» _constraint = «paramName»; + «BigInteger.importedName» _constraint = «paramName»; «ELSE» - «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName»); + «BigInteger.importedName» _constraint = «BigInteger.importedName».valueOf(«paramName»); «ENDIF» «ENDIF» «ENDIF» @@ -271,15 +270,6 @@ abstract class BaseTemplate { «ENDIF» ''' - def GeneratedProperty getPropByName(GeneratedType gt, String name) { - for (GeneratedProperty prop : gt.properties) { - if (prop.name.equals(name)) { - return prop; - } - } - return null; - } - def getRestrictions(Type type) { var Restrictions restrictions = null if (type instanceof ConcreteType) { @@ -347,15 +337,27 @@ abstract class BaseTemplate { return «varName»; ''' - def protected generateRangeMethod(String methodName, Type type, String className, String varName) ''' - «val Restrictions restrictions = type.restrictions» + def protected generateRangeMethod(String methodName, Restrictions restrictions, Type returnType, String className, String varName) ''' «IF restrictions != null && !(restrictions.rangeConstraints.empty)» - «val numberClass = restrictions.rangeConstraints.iterator.next.min.class» - public static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> «methodName»() { - «IF numberClass.equals(typeof(BigDecimal))» - «rangeMethodBody(restrictions, numberClass, className, varName)» + «val number = returnType.importedNumber» + public static «List.importedName»<«Range.importedName»<«number»>> «methodName»() { + «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)» + «rangeMethodBody(restrictions, BigDecimal, className, varName)» + «ELSE» + «rangeMethodBody(restrictions, BigInteger, className, varName)» + «ENDIF» + } + «ENDIF» + ''' + + def protected generateRangeMethod(String methodName, Restrictions restrictions, String className, String varName, Iterable properties) ''' + «IF restrictions != null && !(restrictions.rangeConstraints.empty)» + «val returnType = properties.iterator.next.returnType» + public static «List.importedName»<«Range.importedName»<«returnType.importedNumber»>> «methodName»() { + «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)» + «rangeMethodBody(restrictions, BigDecimal, className, varName)» «ELSE» - «rangeMethodBody(restrictions, typeof(BigInteger), className, varName)» + «rangeMethodBody(restrictions, BigInteger, className, varName)» «ENDIF» } «ENDIF» @@ -383,6 +385,13 @@ abstract class BaseTemplate { return BigInteger.importedName } + def protected String importedNumber(Type clazz) { + if (clazz.fullyQualifiedName.equals(BigDecimal.canonicalName)) { + return BigDecimal.importedName + } + return BigInteger.importedName + } + def private String numericValue(Class clazz, Object numberValue) { val number = clazz.importedName; val value = numberValue.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 fbd198054a..c97838ed02 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 @@ -405,12 +405,10 @@ class BuilderTemplate extends BaseTemplate { «val restrictions = f.returnType.restrictions» «IF !_final && restrictions != null» «IF !(restrictions.lengthConstraints.empty)» - «val clazz = restrictions.lengthConstraints.iterator.next.min.class» - private static «List.importedName»<«Range.importedName»<«clazz.importedNumber»>> «f.fieldName»_length; + private static «List.importedName»<«Range.importedName»<«f.returnType.importedNumber»>> «f.fieldName»_length; «ENDIF» «IF !(restrictions.rangeConstraints.empty)» - «val clazz = restrictions.rangeConstraints.iterator.next.min.class» - private static «List.importedName»<«Range.importedName»<«clazz.importedNumber»>> «f.fieldName»_range; + private static «List.importedName»<«Range.importedName»<«f.returnType.importedNumber»>> «f.fieldName»_range; «ENDIF» «ENDIF» «ENDFOR» @@ -438,7 +436,7 @@ class BuilderTemplate extends BaseTemplate { return this; } «generateLengthMethod(length, field.returnType, type.name+BUILDER, length)» - «generateRangeMethod(range, field.returnType, type.name+BUILDER, range)» + «generateRangeMethod(range, field.returnType.restrictions, field.returnType, type.name+BUILDER, range)» «ENDFOR» «IF augmentField != null» @@ -466,7 +464,7 @@ class BuilderTemplate extends BaseTemplate { «generateLengthRestriction(type, paramName, lengthGetter, isNestedType, isArray)» «ENDIF» «IF !restrictions.rangeConstraints.empty» - «generateRangeRestriction(type, paramName, rangeGetter, isNestedType, isArray)» + «generateRangeRestriction(type, paramName, rangeGetter, isNestedType)» «ENDIF» «ENDIF» ''' @@ -488,13 +486,11 @@ class BuilderTemplate extends BaseTemplate { } ''' - def private generateRangeRestriction(Type type, String paramName, String getterName, boolean isNestedType, boolean isArray) ''' - «val restrictions = type.getRestrictions» + def private generateRangeRestriction(Type type, String paramName, String getterName, boolean isNestedType) ''' if («paramName» != null) { - «val clazz = restrictions.rangeConstraints.iterator.next.min.class» - «printRangeConstraint(type, clazz, paramName, isNestedType)» + «printRangeConstraint(type, paramName, isNestedType)» boolean isValidRange = false; - for («Range.importedName»<«clazz.importedNumber»> r : «getterName»()) { + for («Range.importedName»<«type.importedNumber»> r : «getterName»()) { if (r.contains(_constraint)) { isValidRange = true; } 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 85b2df5d62..fed70f50ea 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 @@ -127,7 +127,7 @@ class ClassTemplate extends BaseTemplate { «generateLengthMethod("length", genTO, genTO.importedName, "_length")» - «generateRangeMethod("range", genTO, genTO.importedName, "_range")» + «generateRangeMethod("range", genTO.restrictions, genTO.importedName, "_range", allProperties)» } ''' @@ -366,13 +366,15 @@ class ClassTemplate extends BaseTemplate { */ def protected generateFields() ''' «IF restrictions != null» - «IF !(restrictions.lengthConstraints.empty)» - «val numberClass = restrictions.lengthConstraints.iterator.next.min.class» - private static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> _length; - «ENDIF» - «IF !(restrictions.rangeConstraints.empty)» - «val numberClass = restrictions.rangeConstraints.iterator.next.min.class» - private static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> _range; + «val prop = getPropByName("value")» + «IF prop != null» + «val numberClass = prop.returnType.importedNumber» + «IF !(restrictions.lengthConstraints.empty)» + private static «List.importedName»<«Range.importedName»<«numberClass»>> _length; + «ENDIF» + «IF !(restrictions.rangeConstraints.empty)» + private static «List.importedName»<«Range.importedName»<«numberClass»>> _range; + «ENDIF» «ENDIF» «ENDIF» «IF !properties.empty» @@ -444,4 +446,13 @@ class ClassTemplate extends BaseTemplate { «ENDIF» ''' + def GeneratedProperty getPropByName(String name) { + for (GeneratedProperty prop : allProperties) { + if (prop.name.equals(name)) { + return prop; + } + } + return null; + } + } 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 f8b2eda1a6..a80133d173 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 @@ -91,7 +91,7 @@ public class TypedefCompilationTest extends BaseCompilationTest { assertTrue(unionExt2.exists()); assertTrue(unionExt3.exists()); assertTrue(unionExt4.exists()); - assertFilesCount(parent, 30); + assertFilesCount(parent, 31); // Test if sources are compilable testCompilation(sourcesOutputDir, compiledOutputDir); @@ -102,6 +102,7 @@ public class TypedefCompilationTest extends BaseCompilationTest { Class int32Ext1Class = Class.forName(pkg + ".Int32Ext1", true, loader); Class int32Ext2Class = Class.forName(pkg + ".Int32Ext2", true, loader); Class myDecimalTypeClass = Class.forName(pkg + ".MyDecimalType", true, loader); + Class myDecimalType2Class = Class.forName(pkg + ".MyDecimalType2", true, loader); Class stringExt1Class = Class.forName(pkg + ".StringExt1", true, loader); Class stringExt2Class = Class.forName(pkg + ".StringExt2", true, loader); Class stringExt3Class = Class.forName(pkg + ".StringExt3", true, loader); @@ -264,6 +265,30 @@ public class TypedefCompilationTest extends BaseCompilationTest { obj = expectedConstructor.newInstance(new BigDecimal("3.14")); assertEquals(obj, defInst.invoke(null, "3.14")); + // typedef my-decimal-type2 + assertFalse(myDecimalType2Class.isInterface()); + assertContainsField(myDecimalType2Class, VAL, BigDecimal.class); + assertContainsField(myDecimalType2Class, RANGE, List.class); + assertContainsFieldWithValue(myDecimalType2Class, "serialVersionUID", Long.TYPE, -672265764962082714L, BigDecimal.class); + assertEquals(3, myDecimalType2Class.getDeclaredFields().length); + assertContainsMethod(myDecimalType2Class, BigDecimal.class, "getValue"); + expectedConstructor = assertContainsConstructor(myDecimalType2Class, BigDecimal.class); + assertContainsConstructor(myDecimalType2Class, myDecimalType2Class); + assertEquals(2, myDecimalType2Class.getDeclaredConstructors().length); + assertContainsMethod(myDecimalType2Class, BigDecimal.class, GET_VAL); + assertContainsDefaultMethods(myDecimalType2Class); + defInst = assertContainsMethod(myDecimalType2Class, myDecimalType2Class, "getDefaultInstance", String.class); + assertContainsGetLengthOrRange(myDecimalType2Class, false); + assertEquals(6, myDecimalType2Class.getDeclaredMethods().length); + + List> decimal2RangeConstraints = new ArrayList<>(); + decimal2RangeConstraints.add(Range.closed(new BigDecimal("0"), new BigDecimal("1"))); + arg = new BigDecimal("1.4"); + expectedMsg = String.format("Invalid range: %s, expected: %s.", arg, decimal2RangeConstraints); + assertContainsRestrictionCheck(expectedConstructor, expectedMsg, arg); + obj = expectedConstructor.newInstance(new BigDecimal("0.14")); + assertEquals(obj, defInst.invoke(null, "0.14")); + // typedef union-ext1 assertFalse(unionExt1Class.isInterface()); assertContainsField(unionExt1Class, "_int16", Short.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 19d2eb1d5e..911096606e 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 @@ -95,6 +95,13 @@ module foo { } } + typedef my-decimal-type2 { + type decimal64 { + fraction-digits 18; + range "0..1"; + } + } + typedef union-ext1 { type union { type int16 {