BUG-1485: convert BuilderTemplate to use LengthGenerator 14/21514/4
authorRobert Varga <rovarga@cisco.com>
Sun, 31 May 2015 17:51:43 +0000 (19:51 +0200)
committerRobert Varga <nite@hq.sk>
Mon, 8 Jun 2015 16:33:14 +0000 (16:33 +0000)
This converts BuilderTemplate to use the LengthGenerator class as
appropriate, speeding operations up. Also removes caching fields.

Change-Id: I1a0bfc56df8ab36880ae8e14c111cb9aca68c626
Signed-off-by: Robert Varga <rovarga@cisco.com>
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java

index ef40bb1c0cccbce81c056c431f753da903a33812..790acce3ee892748565a93639d8f9041bd8899d6 100644 (file)
@@ -47,10 +47,6 @@ abstract class BaseTemplate {
 
     def packageDefinition() '''package «type.packageName»;'''
 
-    protected def getFullyQualifiedName() {
-        return type.fullyQualifiedName
-    }
-
     final public def generate() {
         val _body = body()
         '''
@@ -326,14 +322,6 @@ abstract class BaseTemplate {
         return sb.toString
     }
 
-    /**
-     * Print length constraint.
-     * This should always be a BigInteger (only string and binary can have length restriction)
-     */
-    def printLengthConstraint(Type returnType, Class<? extends Number> clazz, String paramName, boolean isNestedType, boolean isArray) '''
-        «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName»«IF isNestedType».getValue()«ENDIF».length«IF !isArray»()«ENDIF»);
-    '''
-
     def protected generateToString(Collection<GeneratedProperty> properties) '''
         «IF !properties.empty»
             @Override
@@ -371,19 +359,6 @@ abstract class BaseTemplate {
         return restrictions
     }
 
-    def boolean isArrayType(GeneratedTransferObject type) {
-        var isArray = false
-        val GeneratedProperty value = findProperty(type, "value")
-        if (value != null && value.returnType.name.contains("[")) {
-            isArray = true
-        }
-        return isArray
-    }
-
-    def String toQuote(Object obj) {
-        return "\"" + obj.toString + "\"";
-    }
-
     /**
      * Template method which generates method parameters with their types from <code>parameters</code>.
      *
@@ -399,6 +374,7 @@ abstract class BaseTemplate {
         ENDIF
     »'''
 
+    @Deprecated
     def protected String importedNumber(Class<? extends Number> clazz) {
         if (clazz.equals(typeof(BigDecimal))) {
             return BigDecimal.importedName
@@ -406,6 +382,7 @@ abstract class BaseTemplate {
         return BigInteger.importedName
     }
 
+    @Deprecated
     def protected String importedNumber(Type clazz) {
         if (clazz.fullyQualifiedName.equals(BigDecimal.canonicalName)) {
             return BigDecimal.importedName
@@ -413,6 +390,7 @@ abstract class BaseTemplate {
         return BigInteger.importedName
     }
 
+    @Deprecated
     def protected String numericValue(Class<? extends Number> clazz, Object numberValue) {
         val number = clazz.importedName;
         val value = numberValue.toString
index 097a3a5742d6495e9aa90ebc4d84971ba76dd7e0..38a6219bad4e70639570c67ca984274683f96b99 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.yangtools.sal.java.api.generator
 
-import com.google.common.collect.ImmutableList
 import com.google.common.collect.ImmutableSortedSet
 import com.google.common.collect.Range
 import java.math.BigDecimal
@@ -34,9 +33,9 @@ import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
 import org.opendaylight.yangtools.sal.binding.model.api.Type
 import org.opendaylight.yangtools.yang.binding.Augmentable
+import org.opendaylight.yangtools.yang.binding.AugmentationHolder
 import org.opendaylight.yangtools.yang.binding.DataObject
 import org.opendaylight.yangtools.yang.binding.Identifiable
-import org.opendaylight.yangtools.yang.binding.AugmentationHolder
 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint
 
 /**
@@ -420,10 +419,8 @@ class BuilderTemplate extends BaseTemplate {
             «FOR f : properties»
                 private«IF _final» final«ENDIF» «f.returnType.importedName» «f.fieldName»;
                 «val restrictions = f.returnType.restrictions»
-                «IF !_final && restrictions != null»
-                    «IF !(restrictions.lengthConstraints.empty)»
-                        private static «List.importedName»<«Range.importedName»<«f.returnType.importedNumber»>> «f.fieldName»_length;
-                    «ENDIF»
+                «IF !_final && restrictions != null && !(restrictions.lengthConstraints.empty)»
+                    «LengthGenerator.generateLengthChecker(f.fieldName.toString, f.returnType, restrictions.lengthConstraints)»
                 «ENDIF»
             «ENDFOR»
         «ENDIF»
@@ -442,7 +439,6 @@ class BuilderTemplate extends BaseTemplate {
      */
     def private generateSetters() '''
         «FOR field : properties SEPARATOR '\n'»
-            «val length = field.fieldName + "_length"»
             «val restrictions = field.returnType.restrictions»
             «IF restrictions != null»
                 «IF !restrictions.rangeConstraints.nullOrEmpty»
@@ -462,11 +458,11 @@ class BuilderTemplate extends BaseTemplate {
                     «ENDIF»
                 }
                 «ENDIF»
-                «generateRestrictions(field, "value", length
+                «generateRestrictions(field, "value")»
                 this.«field.fieldName» = value;
                 return this;
             }
-            «generateLengthMethod(length, field.returnType, type.name+BUILDER, length
+            «generateLengthMethod(field.fieldName + "_length", field.returnType
             «val range = field.fieldName + "_range"»
             «generateRangeMethod(range, restrictions, field.returnType)»
         «ENDFOR»
@@ -494,43 +490,20 @@ class BuilderTemplate extends BaseTemplate {
         «ENDIF»
     '''
 
-    def private generateRestrictions(GeneratedProperty field, String paramName, String lengthGetter) '''
+    def private generateRestrictions(GeneratedProperty field, String paramName) '''
         «val Type type = field.returnType»
-        «IF type instanceof ConcreteType»
-            «createRestrictions(type, paramName, type.name.contains("["), lengthGetter)»
-        «ELSEIF type instanceof GeneratedTransferObject»
-            «createRestrictions(type, paramName, isArrayType(type as GeneratedTransferObject), lengthGetter)»
-        «ENDIF»
-    '''
-
-    def private createRestrictions(Type type, String paramName, boolean isArray, String lengthGetter) '''
         «val restrictions = type.getRestrictions»
-        «IF restrictions !== null»
-            «val boolean isNestedType = !(type instanceof ConcreteType)»
-            «IF !restrictions.lengthConstraints.empty»
-                «generateLengthRestriction(type, paramName, lengthGetter, isNestedType, isArray)»
+        «IF restrictions !== null && !restrictions.lengthConstraints.empty»
+            «IF type instanceof ConcreteType»
+                «LengthGenerator.generateLengthCheckerCall(field.fieldName.toString, paramName)»
+            «ELSE»
+                «LengthGenerator.generateLengthCheckerCall(field.fieldName.toString, paramName + ".getValue()")»
             «ENDIF»
         «ENDIF»
     '''
 
-    def private generateLengthRestriction(Type type, String paramName, String getterName, boolean isNestedType, boolean isArray) '''
-        «val restrictions = type.getRestrictions»
-        if («paramName» != null) {
-            «val clazz = restrictions.lengthConstraints.iterator.next.min.class»
-            «printLengthConstraint(type, clazz, paramName, isNestedType, isArray)»
-            boolean isValidLength = false;
-            for («Range.importedName»<«clazz.importedNumber»> r : «getterName»()) {
-                if (r.contains(_constraint)) {
-                    isValidLength = true;
-                }
-            }
-            if (!isValidLength) {
-                throw new IllegalArgumentException(String.format("Invalid length: %s, expected: %s.", «paramName», «getterName»));
-            }
-        }
-    '''
-
-    def private generateLengthMethod(String methodName, Type type, String className, String varName) '''
+    @Deprecated
+    def private generateLengthMethod(String methodName, Type type) '''
         «val Restrictions restrictions = type.restrictions»
         «IF restrictions != null && !(restrictions.lengthConstraints.empty)»
             «val numberClass = restrictions.lengthConstraints.iterator.next.min.class»
@@ -540,29 +513,24 @@ class BuilderTemplate extends BaseTemplate {
             @Deprecated
             public static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> «methodName»() {
                 «IF numberClass.equals(typeof(BigDecimal))»
-                    «lengthBody(restrictions, numberClass, className, varName
+                    «lengthBody(restrictions, numberClass)»
                 «ELSE»
-                    «lengthBody(restrictions, typeof(BigInteger), className, varName
+                    «lengthBody(restrictions, typeof(BigInteger))»
                 «ENDIF»
             }
         «ENDIF»
     '''
 
-    def private lengthBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
-        if («varName» == null) {
-            synchronized («className».class) {
-                if («varName» == null) {
-                    «ImmutableList.importedName».Builder<«Range.importedName»<«numberClass.importedName»>> builder = «ImmutableList.importedName».builder();
-                    «FOR r : restrictions.lengthConstraints»
-                        builder.add(«Range.importedName».closed(«numericValue(numberClass, r.min)», «numericValue(numberClass, r.max)»));
-                    «ENDFOR»
-                    «varName» = builder.build();
-                }
-            }
-        }
-        return «varName»;
+    @Deprecated
+    def private lengthBody(Restrictions restrictions, Class<? extends Number> numberClass) '''
+        «List.importedName»<«Range.importedName»<«numberClass.importedName»>> ret = new «ArrayList.importedName»<>(«restrictions.lengthConstraints.size»);
+        «FOR r : restrictions.lengthConstraints»
+            ret.add(«Range.importedName».closed(«numericValue(numberClass, r.min)», «numericValue(numberClass, r.max)»));
+        «ENDFOR»
+        return ret;
     '''
 
+    @Deprecated
     def private generateRangeMethod(String methodName, Restrictions restrictions, Type returnType) '''
         «IF restrictions != null && !(restrictions.rangeConstraints.empty)»
             «val number = returnType.importedNumber»
@@ -580,6 +548,7 @@ class BuilderTemplate extends BaseTemplate {
         «ENDIF»
     '''
 
+    @Deprecated
     def private rangeBody(List<RangeConstraint> restrictions, Class<? extends Number> numberClass) '''
          final «List.importedName»<«Range.importedName»<«numberClass.importedName»>> ret = new java.util.ArrayList<>(«restrictions.size»);
          «FOR r : restrictions»
@@ -834,10 +803,6 @@ class BuilderTemplate extends BaseTemplate {
         «ENDIF»
     '''
 
-    override protected getFullyQualifiedName() {
-        '''«type.fullyQualifiedName»Builder'''.toString
-    }
-
     def implementedInterfaceGetter() '''
     public «Class.importedName»<«type.importedName»> getImplementedInterface() {
         return «type.importedName».class;
index 5c342643c3e0335c798209713a3a78f81e823b39..7d45f8f3e44855df84b677a700604123cbdff82d 100644 (file)
@@ -443,16 +443,16 @@ public class CompilationTest extends BaseCompilationTest {
         Method m = assertContainsMethod(builderClass, builderClass, "setIdBinary", b.getClass());
         final List<Range<Integer>> lengthConstraints = new ArrayList<>();
         lengthConstraints.add(Range.closed(1, 10));
-        Object arg = new byte[] {};
-        String expectedMsg = String.format("Invalid length: %s, expected: %s.", arg, lengthConstraints);
+        byte[] arg = new byte[] {};
+        String expectedMsg = String.format("Invalid length: %s, expected: %s.", Arrays.toString(arg), lengthConstraints);
         assertContainsRestrictionCheck(builderObj, m, expectedMsg, arg);
 
         m = assertContainsMethod(builderClass, builderClass, "setIdDecimal64", BigDecimal.class);
         final List<Range<BigDecimal>> rangeConstraints = new ArrayList<>();
         rangeConstraints.add(Range.closed(new BigDecimal("1.5"), new BigDecimal("5.5")));
-        arg = new BigDecimal("1.4");
-        expectedMsg = String.format("Invalid range: %s, expected: %s.", arg, rangeConstraints);
-        assertContainsRestrictionCheck(builderObj, m, expectedMsg, arg);
+        Object arg1 = new BigDecimal("1.4");
+        expectedMsg = String.format("Invalid range: %s, expected: %s.", arg1, rangeConstraints);
+        assertContainsRestrictionCheck(builderObj, m, expectedMsg, arg1);
 
         cleanUp(sourcesOutputDir, compiledOutputDir);
     }