Added getDefaultInstance method to classes generated from typedef statement.
authorMartin Vitez <mvitez@cisco.com>
Fri, 29 Nov 2013 09:17:53 +0000 (10:17 +0100)
committerMartin Vitez <mvitez@cisco.com>
Fri, 29 Nov 2013 14:28:25 +0000 (15:28 +0100)
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 <mvitez@cisco.com>
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java
code-generator/binding-java-api-generator/src/test/resources/compilation/typedef/foo.yang

index 6c6fd13e6c85aefb48e23732caf845091b32b764..d26c3bb8bfeaf92a9131c2306b7d9e3a39e1cb55 100644 (file)
@@ -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
 
 /**\r
  * Template for generating JAVA class. \r
@@ -99,6 +100,8 @@ class ClassTemplate extends BaseTemplate {
             «generateFields»\r
 \r
             «constructors»\r
+            \r
+            «defaultInstance»\r
 \r
             «FOR field : properties SEPARATOR "\n"»\r
                 «field.getterMethod»\r
@@ -205,7 +208,7 @@ class ClassTemplate extends BaseTemplate {
         «ENDFOR»\r
     }\r
     '''\r
-    \r
+\r
     def protected parentConstructor() '''\r
     /**\r
      * Creates a new instance from «genTO.superType.importedName»\r
@@ -220,17 +223,42 @@ class ClassTemplate extends BaseTemplate {
     def protected defaultInstance() '''\r
         «IF genTO.typedef && !allProperties.empty && !genTO.unionType»\r
             «val prop = allProperties.get(0)»\r
+            «IF !("org.opendaylight.yangtools.yang.binding.InstanceIdentifier".equals(prop.returnType.fullyQualifiedName))»\r
             public static «genTO.name» getDefaultInstance(String defaultValue) {\r
                 «IF "byte[]".equals(prop.returnType.name)»\r
                     «BaseEncoding.importedName» baseEncoding = «BaseEncoding.importedName».base64(); \r
                     return new «genTO.name»(baseEncoding.decode(defaultValue));\r
+                «ELSEIF "java.lang.String".equals(prop.returnType.fullyQualifiedName)»\r
+                    return new «genTO.name»(defaultValue);\r
+                «ELSEIF allProperties.size > 1»\r
+                    «bitsArgs»\r
                 «ELSE»\r
                     return new «genTO.name»(new «prop.returnType.importedName»(defaultValue));\r
                 «ENDIF»\r
-            } \r
+            }\r
+            «ENDIF»\r
         «ENDIF»\r
     '''\r
 \r
+    def protected bitsArgs() '''\r
+        «List.importedName»<«String.importedName»> properties = «Lists.importedName».newArrayList(«allProperties.propsAsArgs»);\r
+        if (!properties.contains(defaultValue)) {\r
+            throw new «IllegalArgumentException.importedName»("invalid default parameter");\r
+        }\r
+        int i = 0;\r
+        return new «genTO.name»(\r
+        «FOR prop : allProperties SEPARATOR ","»\r
+            properties.get(i++).equals(defaultValue) ? new «Boolean.importedName»("true") : null\r
+        «ENDFOR»\r
+        );\r
+    '''\r
+\r
+    def protected propsAsArgs(Iterable<GeneratedProperty> properties) '''\r
+        «FOR prop : properties SEPARATOR ","»\r
+            "«prop.name»"\r
+        «ENDFOR»\r
+    '''\r
+\r
     /**\r
      * Template method which generates JAVA class declaration.\r
      * \r
index a9f85265964bfa3148e2ac3de7667930ad8bc66c..5da77c71e5a5fe590c49d6069f15a4ba5dc8d783 100644 (file)
@@ -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());
index 5d3029f09e3364e2cc6caad0d4674f13a6ede0c3..071fa184c9f75249d5c36d97737ce81be6bdd697 100644 (file)
@@ -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);
     }
 
 }
index 1cbe5b9d7cf8376574f328edfe667b8b91108df6..d2ed4581f5f1fb0c7649099b6cc3309c27f20e2f 100644 (file)
@@ -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;
     }