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 b97e9b01cf279ab2bdf23e238b97a257aae1383f..458b8114e0cba8a59eb790fd8129f1a2147a21a8 100644 (file)
@@ -7,8 +7,11 @@ import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
 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.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
@@ -18,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
@@ -36,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
@@ -48,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
@@ -82,7 +89,8 @@ class ClassTemplate extends BaseTemplate {
     def protected generateBody(boolean isInnerClass) '''\r
         «type.comment.asJavadoc»\r
         «generateClassDeclaration(isInnerClass)» {\r
-               «innerClassesDeclarations»\r
+            «suidDeclaration»\r
+            «innerClassesDeclarations»\r
             «enumDeclarations»\r
             «constantsDeclarations»\r
             «generateFields»\r
@@ -93,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
@@ -120,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
@@ -134,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
@@ -209,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
@@ -223,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
@@ -238,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
@@ -251,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
@@ -264,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
@@ -278,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
@@ -310,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
@@ -318,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
@@ -332,15 +387,14 @@ class ClassTemplate extends BaseTemplate {
                 «val properties = genTO.toStringIdentifiers»\r
                 builder.append("«type.name» [«properties.get(0).fieldName»=");\r
                 «IF properties.get(0).returnType.name.contains("[")»\r
-                    builder.append(java.util.Arrays.toString(«properties.get(0).fieldName»));\r
+                    builder.append(«Arrays.importedName».toString(«properties.get(0).fieldName»));\r
                 «ELSE»\r
                     builder.append(«properties.get(0).fieldName»);\r
                 «ENDIF»\r
-                builder.append(«properties.get(0).fieldName»);\r
                 «FOR i : 1..<genTO.toStringIdentifiers.size»\r
                     builder.append(", «properties.get(i).fieldName»=");\r
                     «IF properties.get(i).returnType.name.contains("[")»\r
-                        builder.append(java.util.Arrays.toString(«properties.get(i).fieldName»));\r
+                        builder.append(«Arrays.importedName».toString(«properties.get(i).fieldName»));\r
                     «ELSE»\r
                         builder.append(«properties.get(i).fieldName»);\r
                     «ENDIF»\r
@@ -350,5 +404,18 @@ class ClassTemplate extends BaseTemplate {
             }\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