Added serialVersionUID field to classes generated from list key.
[yangtools.git] / code-generator / binding-java-api-generator / src / main / java / org / opendaylight / yangtools / sal / java / api / generator / ClassTemplate.xtend
index 6f1c3c95380427458a42f24ff87697228c1f9224..458b8114e0cba8a59eb790fd8129f1a2147a21a8 100644 (file)
@@ -1,17 +1,17 @@
 package org.opendaylight.yangtools.sal.java.api.generator\r
 \r
 import java.util.List\r
-import java.util.Map\r
 import org.opendaylight.yangtools.binding.generator.util.TypeConstants\r
 import org.opendaylight.yangtools.sal.binding.model.api.Constant\r
 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration\r
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty\r
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject\r
-import org.opendaylight.yangtools.sal.binding.model.api.Type\r
-import org.opendaylight.yangtools.binding.generator.util.Types\r
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType\r
-\r
-\r
+import java.util.ArrayList\r
+import java.util.Collections\rimport java.util.Arrays
+import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
+import com.google.common.collect.Range
+
 /**\r
  * Template for generating JAVA class. \r
  */\r
@@ -21,6 +21,7 @@ class ClassTemplate extends BaseTemplate {
     protected val List<GeneratedProperty> finalProperties\r
     protected val List<GeneratedProperty> parentProperties\r
     protected val Iterable<GeneratedProperty> allProperties;\r
+    protected val Restrictions restrictions\r
     \r
     /**\r
      * List of enumeration which are generated as JAVA enum type.\r
@@ -39,7 +40,7 @@ class ClassTemplate extends BaseTemplate {
     \r
     \r
     protected val GeneratedTransferObject genTO;\r
-    \r
+\r
     /**\r
      * Creates instance of this class with concrete <code>genType</code>.\r
      * \r
@@ -51,27 +52,30 @@ class ClassTemplate extends BaseTemplate {
         this.properties = genType.properties\r
         this.finalProperties = GeneratorUtil.resolveReadOnlyPropertiesFromTO(genTO.properties)\r
         this.parentProperties = GeneratorUtil.getPropertiesOfAllParents(genTO)\r
-        this.allProperties = properties + parentProperties\r
+        this.restrictions = genType.restrictions\r
+\r
+        var List<GeneratedProperty> sorted = new ArrayList<GeneratedProperty>();\r
+        sorted.addAll(properties);\r
+        sorted.addAll(parentProperties);\r
+        Collections.sort(sorted, new PropertyComparator());\r
+\r
+        this.allProperties = sorted\r
         this.enums = genType.enumerations\r
         this.consts = genType.constantDefinitions\r
         this.enclosedGeneratedTypes = genType.enclosedTypes\r
     }\r
-    \r
 \r
-    \r
-    \r
-    \r
+\r
     /**\r
      * Generates JAVA class source code (class body only).\r
      * \r
      * @return string with JAVA class body source code\r
      */\r
-    def generateAsInnerClass() {\r
+    def CharSequence generateAsInnerClass() {\r
         return generateBody(true)\r
     }\r
-    \r
 \r
-    \r
+\r
     override protected body() {\r
         generateBody(false);\r
     }\r
@@ -83,9 +87,10 @@ class ClassTemplate extends BaseTemplate {
      * @return string with class source code in JAVA format\r
      */\r
     def protected generateBody(boolean isInnerClass) '''\r
-        «type.comment.generateComment»\r
+        «type.comment.asJavadoc»\r
         «generateClassDeclaration(isInnerClass)» {\r
-               «innerClassesDeclarations»\r
+            «suidDeclaration»\r
+            «innerClassesDeclarations»\r
             «enumDeclarations»\r
             «constantsDeclarations»\r
             «generateFields»\r
@@ -96,14 +101,19 @@ class ClassTemplate extends BaseTemplate {
                     «field.setterMethod»\r
                 «ENDIF»\r
             «ENDFOR»\r
+\r
             «generateHashCode»\r
+\r
             «generateEquals»\r
+\r
             «generateToString»\r
-        \r
+\r
+            «generateGetLength»\r
+\r
         }\r
     '''\r
-    \r
-    \r
+\r
+\r
     /**\r
      * Template method which generates inner classes inside this interface.\r
      * \r
@@ -123,13 +133,17 @@ class ClassTemplate extends BaseTemplate {
     \r
     \r
     def protected constructors() '''\r
-    «allValuesConstructor»\r
-    «IF !allProperties.empty»\r
-    «copyConstructor»\r
-    «ENDIF»\r
-    «IF properties.empty && !parentProperties.empty »\r
-        «parentConstructor»\r
-    «ENDIF»\r
+        «IF genTO.unionType»\r
+            «genUnionConstructor»\r
+        «ELSE»\r
+            «allValuesConstructor»\r
+        «ENDIF»\r
+        «IF !allProperties.empty»\r
+            «copyConstructor»\r
+        «ENDIF»\r
+        «IF properties.empty && !parentProperties.empty »\r
+            «parentConstructor»\r
+        «ENDIF»\r
     '''\r
     \r
     def protected allValuesConstructor() '''\r
@@ -137,13 +151,37 @@ class ClassTemplate extends BaseTemplate {
         «IF false == parentProperties.empty»\r
             super(«parentProperties.asArguments»);\r
         «ENDIF»\r
+        «FOR p : allProperties» \r
+            «generateLengthRestrictions(type, p.fieldName.toString, p.returnType)»\r
+        «ENDFOR»\r
         «FOR p : properties» \r
             this.«p.fieldName» = «p.fieldName»;\r
         «ENDFOR»\r
     }\r
     '''\r
-    \r
-    \r
+\r
+    def protected genUnionConstructor() '''\r
+    «FOR p : allProperties»\r
+        «val List<GeneratedProperty> other = new ArrayList(properties)»\r
+        «val added = other.remove(p)»\r
+        «genConstructor(p, other)»\r
+    «ENDFOR»\r
+\r
+    '''\r
+\r
+    def protected genConstructor(GeneratedProperty property, GeneratedProperty... other) '''\r
+    public «type.name»(«property.returnType.importedName + " " + property.name») {\r
+        «IF false == parentProperties.empty»\r
+            super(«parentProperties.asArguments»);\r
+        «ENDIF»\r
+            «generateLengthRestrictions(type, property.fieldName.toString, property.returnType)»\r
+            this.«property.fieldName» = «property.name»;\r
+            «FOR p : other»\r
+            this.«p.fieldName» = null;\r
+            «ENDFOR»\r
+    }\r
+    '''\r
+\r
     def protected copyConstructor() '''\r
     /**\r
      * Creates a copy from Source Object.\r
@@ -171,19 +209,7 @@ class ClassTemplate extends BaseTemplate {
     }\r
     '''\r
     \r
-    /**\r
-     * Template method which generates JAVA comments.\r
-     * \r
-     * @param string with the comment for whole JAVA class\r
-     * @return string with comment in JAVA format\r
-     */\r
-    def protected generateComment(String comment) '''\r
-        «IF comment != null && !comment.empty»\r
-            /**\r
-            «comment»\r
-            **/\r
-        «ENDIF»\r
-    '''\r
+\r
     \r
     /**\r
      * Template method which generates JAVA class declaration.\r
@@ -202,8 +228,8 @@ class ClassTemplate extends BaseTemplate {
         ENDIF»class «type.name»«\r
         IF (genTO.superType != null)»«\r
             " extends "»«genTO.superType.importedName»«\r
-        ENDIF»«\r
-        IF (!type.implements.empty)»«\r
+        ENDIF»\r
+        «IF (!type.implements.empty)»«\r
             " implements "»«\r
             FOR type : type.implements SEPARATOR ", "»«\r
                 type.importedName»«\r
@@ -224,7 +250,13 @@ class ClassTemplate extends BaseTemplate {
             «ENDFOR»\r
         «ENDIF»\r
     '''\r
-    \r
+\r
+    def protected suidDeclaration() '''\r
+        «IF genTO.SUID != null»\r
+            private static final long serialVersionUID = «genTO.SUID.value»L; \r
+        «ENDIF»\r
+    '''\r
+\r
     /**\r
      * Template method wich generates JAVA constants.\r
      * \r
@@ -238,13 +270,13 @@ class ClassTemplate extends BaseTemplate {
                     «IF cValue instanceof List<?>»\r
                         «val cValues = cValue as List<?>»\r
                         private static final List<Pattern> «Constants.MEMBER_PATTERN_LIST» = new ArrayList<Pattern>();\r
-                        public static final List<String> «TypeConstants.PATTERN_CONSTANT_NAME» = Arrays.asList(«\r
+                        public static final List<String> «TypeConstants.PATTERN_CONSTANT_NAME» = «Arrays.importedName».asList(«\r
                         FOR v : cValues SEPARATOR ", "»«\r
                             IF v instanceof String»"«\r
                                 v as String»"«\r
                             ENDIF»«\r
                         ENDFOR»);\r
-                        \r
+\r
                         «generateStaticInicializationBlock»\r
                     «ENDIF»\r
                 «ELSE»\r
@@ -253,10 +285,10 @@ class ClassTemplate extends BaseTemplate {
             «ENDFOR»\r
         «ENDIF»\r
     '''\r
-    \r
+\r
     /**\r
      * Template method which generates JAVA static initialization block.\r
-     * \r
+     *\r
      * @return string with static initialization block in JAVA format\r
      */\r
     def protected generateStaticInicializationBlock() '''\r
@@ -266,10 +298,10 @@ class ClassTemplate extends BaseTemplate {
             }\r
         }\r
     '''\r
-    \r
+\r
     /**\r
      * Template method which generates JAVA class attributes.\r
-     * \r
+     *\r
      * @return string with the class attributes in JAVA format\r
      */\r
     def protected generateFields() '''\r
@@ -279,11 +311,11 @@ class ClassTemplate extends BaseTemplate {
             «ENDFOR»\r
         «ENDIF»\r
     '''\r
-    \r
+\r
 \r
     /**\r
      * Template method which generates the method <code>hashCode()</code>.\r
-     * \r
+     *\r
      * @return string with the <code>hashCode()</code> method definition in JAVA format\r
      */\r
     def protected generateHashCode() '''\r
@@ -293,17 +325,21 @@ class ClassTemplate extends BaseTemplate {
                 final int prime = 31;\r
                 int result = 1;\r
                 «FOR property : genTO.hashCodeIdentifiers»\r
+                    «IF property.returnType.name.contains("[")»\r
+                    result = prime * result + ((«property.fieldName» == null) ? 0 : «Arrays.importedName».hashCode(«property.fieldName»));\r
+                    «ELSE»\r
                     result = prime * result + ((«property.fieldName» == null) ? 0 : «property.fieldName».hashCode());\r
+                    «ENDIF»\r
                 «ENDFOR»\r
                 return result;\r
             }\r
         «ENDIF»\r
     '''\r
-    \r
+\r
     /**\r
      * Template method which generates the method <code>equals()</code>.\r
-     * \r
-     * @return string with the <code>equals()</code> method definition in JAVA format     \r
+     *\r
+     * @return string with the <code>equals()</code> method definition in JAVA format\r
      */\r
     def protected generateEquals() '''\r
         «IF !genTO.equalsIdentifiers.empty»\r
@@ -325,7 +361,11 @@ class ClassTemplate extends BaseTemplate {
                         if (other.«fieldName» != null) {\r
                             return false;\r
                         }\r
+                    «IF property.returnType.name.contains("[")»\r
+                    } else if(!«Arrays.importedName».equals(«fieldName», other.«fieldName»)) {\r
+                    «ELSE»\r
                     } else if(!«fieldName».equals(other.«fieldName»)) {\r
+                    «ENDIF»\r
                         return false;\r
                     }\r
                 «ENDFOR»\r
@@ -333,11 +373,11 @@ class ClassTemplate extends BaseTemplate {
             }\r
         «ENDIF»\r
     '''\r
-    \r
+\r
     /**\r
      * Template method which generates the method <code>toString()</code>.\r
-     * \r
-     * @return string with the <code>toString()</code> method definition in JAVA format     \r
+     *\r
+     * @return string with the <code>toString()</code> method definition in JAVA format\r
      */\r
     def protected generateToString() '''\r
         «IF !genTO.toStringIdentifiers.empty»\r
@@ -346,15 +386,36 @@ class ClassTemplate extends BaseTemplate {
                 StringBuilder builder = new StringBuilder();\r
                 «val properties = genTO.toStringIdentifiers»\r
                 builder.append("«type.name» [«properties.get(0).fieldName»=");\r
-                builder.append(«properties.get(0).fieldName»);\r
+                «IF properties.get(0).returnType.name.contains("[")»\r
+                    builder.append(«Arrays.importedName».toString(«properties.get(0).fieldName»));\r
+                «ELSE»\r
+                    builder.append(«properties.get(0).fieldName»);\r
+                «ENDIF»\r
                 «FOR i : 1..<genTO.toStringIdentifiers.size»\r
                     builder.append(", «properties.get(i).fieldName»=");\r
-                    builder.append(«properties.get(i).fieldName»);\r
+                    «IF properties.get(i).returnType.name.contains("[")»\r
+                        builder.append(«Arrays.importedName».toString(«properties.get(i).fieldName»));\r
+                    «ELSE»\r
+                        builder.append(«properties.get(i).fieldName»);\r
+                    «ENDIF»\r
                 «ENDFOR»\r
                 builder.append("]");\r
                 return builder.toString();\r
             }\r
         «ENDIF»\r
     '''\r
-    \r
+\r
+    def private generateGetLength() '''\r
+        «IF restrictions != null && !(restrictions.lengthConstraints.empty)»\r
+            public static «List.importedName»<«Range.importedName»<Integer>> getLength() {\r
+                final «List.importedName»<«Range.importedName»<Integer>> result = new «ArrayList.importedName»<>();\r
+                «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.importedName»<>(); \r
+                «FOR r : restrictions.lengthConstraints»\r
+                    result.add(«Range.importedName».closed(«r.min», «r.max»));\r
+                «ENDFOR»\r
+                return result;\r
+            }\r
+        «ENDIF»\r
+    '''\r
+\r
 }\r