From b6ec7e0959750ce6a42cf420ddf8d2cb85ca9a88 Mon Sep 17 00:00:00 2001 From: Martin Vitez Date: Fri, 29 Nov 2013 10:17:53 +0100 Subject: [PATCH] Added getDefaultInstance method to classes generated from typedef statement. Static method getDefaultInstance in typedef class expects one String parameter and will try to create and return an object of this type with given default value. Method is not generated for enumeration and instance-identifier types. Signed-off-by: Martin Vitez --- .../java/api/generator/ClassTemplate.xtend | 32 +++++++- .../generator/test/CompilationTestUtils.java | 8 +- .../test/TypedefCompilationTest.java | 82 ++++++++++++++++--- .../resources/compilation/typedef/foo.yang | 38 +++++++++ 4 files changed, 142 insertions(+), 18 deletions(-) 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 6c6fd13e6c..d26c3bb8bf 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 @@ -14,6 +14,7 @@ import com.google.common.collect.Range import java.util.regex.Pattern import com.google.common.io.BaseEncoding import java.beans.ConstructorProperties +import com.google.common.collect.Lists /** * Template for generating JAVA class. @@ -99,6 +100,8 @@ class ClassTemplate extends BaseTemplate { «generateFields» «constructors» + + «defaultInstance» «FOR field : properties SEPARATOR "\n"» «field.getterMethod» @@ -205,7 +208,7 @@ class ClassTemplate extends BaseTemplate { «ENDFOR» } ''' - + def protected parentConstructor() ''' /** * Creates a new instance from «genTO.superType.importedName» @@ -220,17 +223,42 @@ class ClassTemplate extends BaseTemplate { def protected defaultInstance() ''' «IF genTO.typedef && !allProperties.empty && !genTO.unionType» «val prop = allProperties.get(0)» + «IF !("org.opendaylight.yangtools.yang.binding.InstanceIdentifier".equals(prop.returnType.fullyQualifiedName))» public static «genTO.name» getDefaultInstance(String defaultValue) { «IF "byte[]".equals(prop.returnType.name)» «BaseEncoding.importedName» baseEncoding = «BaseEncoding.importedName».base64(); return new «genTO.name»(baseEncoding.decode(defaultValue)); + «ELSEIF "java.lang.String".equals(prop.returnType.fullyQualifiedName)» + return new «genTO.name»(defaultValue); + «ELSEIF allProperties.size > 1» + «bitsArgs» «ELSE» return new «genTO.name»(new «prop.returnType.importedName»(defaultValue)); «ENDIF» - } + } + «ENDIF» «ENDIF» ''' + def protected bitsArgs() ''' + «List.importedName»<«String.importedName»> properties = «Lists.importedName».newArrayList(«allProperties.propsAsArgs»); + if (!properties.contains(defaultValue)) { + throw new «IllegalArgumentException.importedName»("invalid default parameter"); + } + int i = 0; + return new «genTO.name»( + «FOR prop : allProperties SEPARATOR ","» + properties.get(i++).equals(defaultValue) ? new «Boolean.importedName»("true") : null + «ENDFOR» + ); + ''' + + def protected propsAsArgs(Iterable properties) ''' + «FOR prop : properties SEPARATOR ","» + "«prop.name»" + «ENDFOR» + ''' + /** * Template method which generates JAVA class declaration. * 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 a9f8526596..5da77c71e5 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 @@ -141,9 +141,9 @@ public class CompilationTestUtils { * @param args * array of argument classes */ - static void assertContainsConstructor(Class clazz, Class... args) { + static Constructor assertContainsConstructor(Class clazz, Class... args) { try { - clazz.getDeclaredConstructor(args); + return clazz.getDeclaredConstructor(args); } catch (NoSuchMethodException e) { throw new AssertionError("Constructor with args " + Arrays.toString(args) + " does not exists in class " + clazz.getSimpleName()); @@ -162,11 +162,13 @@ public class CompilationTestUtils { * method name * @param args * array of parameter type classes + * @return method with given name, return type and parameter types */ - static void assertContainsMethod(Class clazz, Class returnType, String name, Class... args) { + static Method assertContainsMethod(Class clazz, Class returnType, String name, Class... args) { try { Method m = clazz.getDeclaredMethod(name, args); assertEquals(returnType, m.getReturnType()); + return m; } catch (NoSuchMethodException e) { throw new AssertionError("Method " + name + " with args " + Arrays.toString(args) + " does not exists in class " + clazz.getSimpleName()); 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 5d3029f09e..071fa184c9 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 @@ -11,6 +11,8 @@ import static org.junit.Assert.*; import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.*; import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.math.BigDecimal; import java.net.URL; import java.net.URLClassLoader; @@ -30,6 +32,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; */ public class TypedefCompilationTest extends BaseCompilationTest { private static final String VAL = "_value"; + private static final String GET_VAL = "getValue"; private static final String UNITS = "_UNITS"; @Test @@ -47,6 +50,7 @@ public class TypedefCompilationTest extends BaseCompilationTest { generator.generateToFile(sourcesOutputDir); File parent = new File(sourcesOutputDir, NS_FOO); + File bitsExt = new File(parent, "BitsExt.java"); File int32Ext0 = new File(parent, "Int32Ext0.java"); File int32Ext1 = new File(parent, "Int32Ext1.java"); File int32Ext2 = new File(parent, "Int32Ext2.java"); @@ -58,6 +62,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(bitsExt.exists()); assertTrue(int32Ext0.exists()); assertTrue(int32Ext1.exists()); assertTrue(int32Ext2.exists()); @@ -69,13 +74,14 @@ public class TypedefCompilationTest extends BaseCompilationTest { assertTrue(unionExt2.exists()); assertTrue(unionExt3.exists()); assertTrue(unionExt4.exists()); - assertFilesCount(parent, 25); + assertFilesCount(parent, 27); // Test if sources are compilable testCompilation(sourcesOutputDir, compiledOutputDir); String pkg = BASE_PKG + ".urn.opendaylight.foo.rev131008"; ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() }); + Class bitsExtClass = Class.forName(pkg + ".BitsExt", true, loader); Class int32Ext1Class = Class.forName(pkg + ".Int32Ext1", true, loader); Class int32Ext2Class = Class.forName(pkg + ".Int32Ext2", true, loader); Class myDecimalTypeClass = Class.forName(pkg + ".MyDecimalType", true, loader); @@ -87,67 +93,117 @@ public class TypedefCompilationTest extends BaseCompilationTest { Class unionExt3Class = Class.forName(pkg + ".UnionExt3", true, loader); Class unionExt4Class = Class.forName(pkg + ".UnionExt4", true, loader); + // typedef bits-ext + assertFalse(bitsExtClass.isInterface()); + assertContainsField(bitsExtClass, "_pc", Boolean.class); + assertContainsField(bitsExtClass, "_bpc", Boolean.class); + assertContainsField(bitsExtClass, "_dpc", Boolean.class); + assertContainsField(bitsExtClass, "_lbpc", Boolean.class); + assertContainsField(bitsExtClass, "_spc", Boolean.class); + assertContainsField(bitsExtClass, "_sfmof", Boolean.class); + assertContainsField(bitsExtClass, "_sfapc", Boolean.class); + assertEquals(7, bitsExtClass.getDeclaredFields().length); + Constructor expectedConstructor = assertContainsConstructor(bitsExtClass, Boolean.class, Boolean.class, + Boolean.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class); + assertContainsConstructor(bitsExtClass, bitsExtClass); + assertEquals(2, bitsExtClass.getConstructors().length); + Method defInst = assertContainsMethod(bitsExtClass, bitsExtClass, "getDefaultInstance", String.class); + assertContainsDefaultMethods(bitsExtClass); + assertEquals(11, bitsExtClass.getDeclaredMethods().length); + + Object obj = expectedConstructor.newInstance(null, null, null, null, null, new Boolean("true"), null); + assertEquals(obj, defInst.invoke(null, "sfmof")); + // typedef int32-ext1 assertFalse(int32Ext1Class.isInterface()); assertContainsField(int32Ext1Class, VAL, Integer.class); assertEquals(1, int32Ext1Class.getDeclaredFields().length); - assertContainsConstructor(int32Ext1Class, Integer.class); + expectedConstructor = assertContainsConstructor(int32Ext1Class, Integer.class); assertContainsConstructor(int32Ext1Class, int32Ext1Class); assertEquals(2, int32Ext1Class.getConstructors().length); assertContainsDefaultMethods(int32Ext1Class); + assertContainsMethod(int32Ext1Class, Integer.class, GET_VAL); + defInst = assertContainsMethod(int32Ext1Class, int32Ext1Class, "getDefaultInstance", String.class); + assertEquals(5, int32Ext1Class.getDeclaredMethods().length); + + obj = expectedConstructor.newInstance(new Integer("159")); + assertEquals(obj, defInst.invoke(null, "159")); // typedef int32-ext2 assertFalse(int32Ext2Class.isInterface()); assertContainsFieldWithValue(int32Ext2Class, UNITS, String.class, "mile", Integer.class); assertEquals(1, int32Ext2Class.getDeclaredFields().length); - assertContainsConstructor(int32Ext2Class, Integer.class); + expectedConstructor = assertContainsConstructor(int32Ext2Class, Integer.class); assertContainsConstructor(int32Ext2Class, int32Ext2Class); assertContainsConstructor(int32Ext2Class, int32Ext1Class); assertEquals(3, int32Ext2Class.getDeclaredConstructors().length); assertContainsMethod(int32Ext2Class, String.class, "toString"); - assertEquals(1, int32Ext2Class.getDeclaredMethods().length); + defInst = assertContainsMethod(int32Ext2Class, int32Ext2Class, "getDefaultInstance", String.class); + assertEquals(2, int32Ext2Class.getDeclaredMethods().length); + + obj = expectedConstructor.newInstance(new Integer("159")); + assertEquals(obj, defInst.invoke(null, "159")); // typedef string-ext1 assertFalse(stringExt1Class.isInterface()); assertContainsField(stringExt1Class, VAL, String.class); assertContainsField(stringExt1Class, "patterns", List.class); assertContainsField(stringExt1Class, "PATTERN_CONSTANTS", List.class); - assertContainsMethod(stringExt1Class, String.class, "getValue"); assertEquals(3, stringExt1Class.getDeclaredFields().length); - assertContainsConstructor(stringExt1Class, String.class); + expectedConstructor = assertContainsConstructor(stringExt1Class, String.class); assertContainsConstructor(stringExt1Class, stringExt1Class); assertEquals(2, stringExt1Class.getDeclaredConstructors().length); - assertContainsGetLength(stringExt1Class); + assertContainsMethod(stringExt1Class, String.class, GET_VAL); + defInst = assertContainsMethod(stringExt1Class, stringExt1Class, "getDefaultInstance", String.class); assertContainsDefaultMethods(stringExt1Class); + assertContainsGetLength(stringExt1Class); + assertEquals(6, stringExt1Class.getDeclaredMethods().length); + + obj = expectedConstructor.newInstance("hello world"); + assertEquals(obj, defInst.invoke(null, "hello world")); // typedef string-ext2 assertFalse(stringExt2Class.isInterface()); assertEquals(0, stringExt2Class.getDeclaredFields().length); - assertContainsConstructor(stringExt2Class, String.class); + expectedConstructor = assertContainsConstructor(stringExt2Class, String.class); assertContainsConstructor(stringExt2Class, stringExt2Class); assertContainsConstructor(stringExt2Class, stringExt1Class); assertEquals(3, stringExt2Class.getDeclaredConstructors().length); assertContainsGetLength(stringExt2Class); - assertEquals(1, stringExt2Class.getDeclaredMethods().length); + defInst = assertContainsMethod(stringExt2Class, stringExt2Class, "getDefaultInstance", String.class); + assertEquals(2, stringExt2Class.getDeclaredMethods().length); + + obj = expectedConstructor.newInstance("helloWorld"); + assertEquals(obj, defInst.invoke(null, "helloWorld")); // typedef string-ext3 assertFalse(stringExt3Class.isInterface()); assertEquals(0, stringExt3Class.getDeclaredFields().length); - assertContainsConstructor(stringExt3Class, String.class); + expectedConstructor = assertContainsConstructor(stringExt3Class, String.class); assertContainsConstructor(stringExt3Class, stringExt3Class); assertContainsConstructor(stringExt3Class, stringExt2Class); assertEquals(3, stringExt3Class.getDeclaredConstructors().length); - assertEquals(0, stringExt3Class.getDeclaredMethods().length); + defInst = assertContainsMethod(stringExt3Class, stringExt3Class, "getDefaultInstance", String.class); + assertEquals(1, stringExt3Class.getDeclaredMethods().length); + + obj = expectedConstructor.newInstance("helloWorld"); + assertEquals(obj, defInst.invoke(null, "helloWorld")); // typedef my-decimal-type assertFalse(myDecimalTypeClass.isInterface()); assertContainsField(myDecimalTypeClass, VAL, BigDecimal.class); assertEquals(1, myDecimalTypeClass.getDeclaredFields().length); assertContainsMethod(myDecimalTypeClass, BigDecimal.class, "getValue"); - assertContainsConstructor(myDecimalTypeClass, BigDecimal.class); + expectedConstructor = assertContainsConstructor(myDecimalTypeClass, BigDecimal.class); assertContainsConstructor(myDecimalTypeClass, myDecimalTypeClass); assertEquals(2, myDecimalTypeClass.getDeclaredConstructors().length); + assertContainsMethod(myDecimalTypeClass, BigDecimal.class, GET_VAL); assertContainsDefaultMethods(myDecimalTypeClass); + defInst = assertContainsMethod(myDecimalTypeClass, myDecimalTypeClass, "getDefaultInstance", String.class); + assertEquals(5, myDecimalTypeClass.getDeclaredMethods().length); + + obj = expectedConstructor.newInstance(new BigDecimal("3.14")); + assertEquals(obj, defInst.invoke(null, "3.14")); // typedef union-ext1 assertFalse(unionExt1Class.isInterface()); @@ -205,7 +261,7 @@ public class TypedefCompilationTest extends BaseCompilationTest { assertEquals(5, unionExt4Class.getDeclaredConstructors().length); assertContainsDefaultMethods(unionExt4Class); - cleanUp(sourcesOutputDir, compiledOutputDir); + //cleanUp(sourcesOutputDir, compiledOutputDir); } } 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 1cbe5b9d7c..d2ed4581f5 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,6 +6,44 @@ module foo { revision "2013-10-08" { } + + typedef bits-ext { + type bits { + bit pc { + position 0; + } + bit bpc { + position 1; + } + bit dpc { + position 2; + } + bit lbpc { + position 3; + } + bit spc { + position 4; + } + bit sfmof { + position 5; + } + bit sfapc { + position 6; + } + } + } + + typedef myenum { + type enumeration { + enum zero; + enum one; + enum seven { + value 7; + } + } + default one; + } + typedef int32-ext0 { type int32; } -- 2.36.6