Updated code generation
[yangtools.git] / code-generator / binding-java-api-generator / src / main / java / org / opendaylight / yangtools / sal / java / api / generator / ClassTemplate.xtend
1 package org.opendaylight.yangtools.sal.java.api.generator\r
2 \r
3 import java.util.List\r
4 import java.util.Map\r
5 import org.opendaylight.yangtools.binding.generator.util.TypeConstants\r
6 import org.opendaylight.yangtools.sal.binding.model.api.Constant\r
7 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration\r
8 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty\r
9 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject\r
10 import org.opendaylight.yangtools.sal.binding.model.api.Type\r
11 import org.opendaylight.yangtools.binding.generator.util.Types\r
12 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType\r
13 \r
14 \r
15 /**\r
16  * Template for generating JAVA class. \r
17  */\r
18 class ClassTemplate extends BaseTemplate {\r
19 \r
20     protected val List<GeneratedProperty> properties\r
21     protected val List<GeneratedProperty> finalProperties\r
22     protected val List<GeneratedProperty> parentProperties\r
23     protected val Iterable<GeneratedProperty> allProperties;\r
24     \r
25     /**\r
26      * List of enumeration which are generated as JAVA enum type.\r
27      */\r
28     protected val List<Enumeration> enums\r
29     \r
30     /**\r
31      * List of constant instances which are generated as JAVA public static final attributes.\r
32      */\r
33     protected val List<Constant> consts\r
34     \r
35     /**\r
36      * List of generated types which are enclosed inside <code>genType</code>\r
37      */\r
38     protected val List<GeneratedType> enclosedGeneratedTypes;\r
39     \r
40     \r
41     protected val GeneratedTransferObject genTO;\r
42     \r
43     /**\r
44      * Creates instance of this class with concrete <code>genType</code>.\r
45      * \r
46      * @param genType generated transfer object which will be transformed to JAVA class source code\r
47      */\r
48     new(GeneratedTransferObject genType) {\r
49         super(genType)\r
50         this.genTO = genType\r
51         this.properties = genType.properties\r
52         this.finalProperties = GeneratorUtil.resolveReadOnlyPropertiesFromTO(genTO.properties)\r
53         this.parentProperties = GeneratorUtil.getPropertiesOfAllParents(genTO)\r
54         this.allProperties = properties + parentProperties\r
55         this.enums = genType.enumerations\r
56         this.consts = genType.constantDefinitions\r
57         this.enclosedGeneratedTypes = genType.enclosedTypes\r
58     }\r
59     \r
60 \r
61     \r
62     \r
63     \r
64     /**\r
65      * Generates JAVA class source code (class body only).\r
66      * \r
67      * @return string with JAVA class body source code\r
68      */\r
69     def generateAsInnerClass() {\r
70         return generateBody(true)\r
71     }\r
72     \r
73 \r
74     \r
75     override protected body() {\r
76         generateBody(false);\r
77     }\r
78 \r
79     /**\r
80      * Template method which generates class body.\r
81      * \r
82      * @param isInnerClass boolean value which specify if generated class is|isn't inner\r
83      * @return string with class source code in JAVA format\r
84      */\r
85     def protected generateBody(boolean isInnerClass) '''\r
86         «type.comment.generateComment»\r
87         «generateClassDeclaration(isInnerClass)» {\r
88                 «innerClassesDeclarations»\r
89 \r
90             «enumDeclarations»\r
91         \r
92             «constantsDeclarations»\r
93         \r
94             «generateFields»\r
95         \r
96             «constructors»\r
97         \r
98             «FOR field : properties SEPARATOR "\n"»\r
99                 «field.getterMethod»\r
100                 «IF !field.readOnly»\r
101                 \r
102                     «field.setterMethod»\r
103                 «ENDIF»\r
104             «ENDFOR»\r
105         \r
106             «generateHashCode»\r
107         \r
108             «generateEquals»\r
109         \r
110             «generateToString»\r
111         \r
112         }\r
113     '''\r
114     \r
115     \r
116     /**\r
117      * Template method which generates inner classes inside this interface.\r
118      * \r
119      * @return string with the source code for inner classes in JAVA format\r
120      */\r
121     def protected innerClassesDeclarations() '''\r
122         «IF !enclosedGeneratedTypes.empty»\r
123             «FOR innerClass : enclosedGeneratedTypes SEPARATOR "\n"»\r
124                 «IF (innerClass instanceof GeneratedTransferObject)»\r
125                     «val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)»\r
126                     «classTemplate.generateAsInnerClass»\r
127                     \r
128                 «ENDIF»\r
129             «ENDFOR»\r
130         «ENDIF»\r
131     '''\r
132     \r
133     \r
134     def protected constructors() '''\r
135     «allValuesConstructor»\r
136     «IF !allProperties.empty»\r
137     «copyConstructor»\r
138     «ENDIF»\r
139     «IF properties.empty && !parentProperties.empty »\r
140         «parentConstructor»\r
141     «ENDIF»\r
142     '''\r
143     \r
144     def protected allValuesConstructor() '''\r
145     public «type.name»(«allProperties.asArgumentsDeclaration») {\r
146         «IF false == parentProperties.empty»\r
147             super(«parentProperties.asArguments»);\r
148         «ENDIF»\r
149         «FOR p : properties» \r
150             this.«p.fieldName» = «p.fieldName»;\r
151         «ENDFOR»\r
152     }\r
153     '''\r
154     \r
155     \r
156     def protected copyConstructor() '''\r
157     /**\r
158      * Creates a copy from Source Object.\r
159      *\r
160      * @param source Source object\r
161      */\r
162     public «type.name»(«type.name» source) {\r
163         «IF false == parentProperties.empty»\r
164             super(source);\r
165         «ENDIF»\r
166         «FOR p : properties» \r
167             this.«p.fieldName» = source.«p.fieldName»;\r
168         «ENDFOR»\r
169     }\r
170     '''\r
171     \r
172     def protected parentConstructor() '''\r
173     /**\r
174      * Creates a new instance from «genTO.extends.importedName»\r
175      *\r
176      * @param source Source object\r
177      */\r
178     public «type.name»(«genTO.extends.importedName» source) {\r
179             super(source);\r
180     }\r
181     '''\r
182     \r
183     /**\r
184      * Template method which generates JAVA comments.\r
185      * \r
186      * @param string with the comment for whole JAVA class\r
187      * @return string with comment in JAVA format\r
188      */\r
189     def protected generateComment(String comment) '''\r
190         «IF comment != null && !comment.empty»\r
191             /**\r
192             «comment»\r
193             **/\r
194         «ENDIF»\r
195     '''\r
196     \r
197     /**\r
198      * Template method which generates JAVA class declaration.\r
199      * \r
200      * @param isInnerClass boolean value which specify if generated class is|isn't inner\r
201      * @return string with class declaration in JAVA format\r
202      */\r
203     def protected generateClassDeclaration(boolean isInnerClass) '''\r
204         public«\r
205         IF (isInnerClass)»«\r
206             " static final "»«\r
207         ELSEIF (type.abstract)»«\r
208             " abstract "»«\r
209         ELSE»«\r
210             " "»«\r
211         ENDIF»class «type.name»«\r
212         IF (genTO.extends != null)»«\r
213             " extends "»«genTO.extends.importedName»«\r
214         ENDIF»«\r
215         IF (!type.implements.empty)»«\r
216             " implements "»«\r
217             FOR type : type.implements SEPARATOR ", "»«\r
218                 type.importedName»«\r
219             ENDFOR»«\r
220         ENDIF\r
221     »'''\r
222     \r
223     /**\r
224      * Template method which generates JAVA enum type.\r
225      * \r
226      * @return string with inner enum source code in JAVA format\r
227      */\r
228     def protected enumDeclarations() '''\r
229         «IF !enums.empty»\r
230             «FOR e : enums SEPARATOR "\n"»\r
231                 «val enumTemplate = new EnumTemplate(e)»\r
232                 «enumTemplate.generateAsInnerClass»\r
233             «ENDFOR»\r
234         «ENDIF»\r
235     '''\r
236     \r
237     /**\r
238      * Template method wich generates JAVA constants.\r
239      * \r
240      * @return string with constants in JAVA format \r
241      */\r
242     def protected constantsDeclarations() '''\r
243         «IF !consts.empty»\r
244             «FOR c : consts»\r
245                 «IF c.name == TypeConstants.PATTERN_CONSTANT_NAME»\r
246                     «val cValue = c.value»\r
247                     «IF cValue instanceof List<?>»\r
248                         «val cValues = cValue as List<?>»\r
249                         private static final List<Pattern> «Constants.MEMBER_PATTERN_LIST» = new ArrayList<Pattern>();\r
250                         public static final List<String> «TypeConstants.PATTERN_CONSTANT_NAME» = Arrays.asList(«\r
251                         FOR v : cValues SEPARATOR ", "»«\r
252                             IF v instanceof String»"«\r
253                                 v as String»"«\r
254                             ENDIF»«\r
255                         ENDFOR»);\r
256                         \r
257                         «generateStaticInicializationBlock»\r
258                     «ENDIF»\r
259                 «ELSE»\r
260                     public static final «c.type.importedName» «c.name» = «c.value»;\r
261                 «ENDIF»\r
262             «ENDFOR»\r
263         «ENDIF»\r
264     '''\r
265     \r
266     /**\r
267      * Template method which generates JAVA static initialization block.\r
268      * \r
269      * @return string with static initialization block in JAVA format\r
270      */\r
271     def protected generateStaticInicializationBlock() '''\r
272         static {\r
273             for (String regEx : «TypeConstants.PATTERN_CONSTANT_NAME») {\r
274                 «Constants.MEMBER_PATTERN_LIST».add(Pattern.compile(regEx));\r
275             }\r
276         }\r
277     '''\r
278     \r
279     /**\r
280      * Template method which generates JAVA class attributes.\r
281      * \r
282      * @return string with the class attributes in JAVA format\r
283      */\r
284     def protected generateFields() '''\r
285         «IF !properties.empty»\r
286             «FOR f : properties»\r
287                 «IF f.readOnly»final«ENDIF» private «f.returnType.importedName» «f.fieldName»;\r
288             «ENDFOR»\r
289         «ENDIF»\r
290     '''\r
291     \r
292 \r
293     /**\r
294      * Template method which generates the method <code>hashCode()</code>.\r
295      * \r
296      * @return string with the <code>hashCode()</code> method definition in JAVA format\r
297      */\r
298     def protected generateHashCode() '''\r
299         «IF !genTO.hashCodeIdentifiers.empty»\r
300             @Override\r
301             public int hashCode() {\r
302                 final int prime = 31;\r
303                 int result = 1;\r
304                 «FOR property : genTO.hashCodeIdentifiers»\r
305                     result = prime * result + ((«property.fieldName» == null) ? 0 : «property.fieldName».hashCode());\r
306                 «ENDFOR»\r
307                 return result;\r
308             }\r
309         «ENDIF»\r
310     '''\r
311     \r
312     /**\r
313      * Template method which generates the method <code>equals()</code>.\r
314      * \r
315      * @return string with the <code>equals()</code> method definition in JAVA format     \r
316      */\r
317     def protected generateEquals() '''\r
318         «IF !genTO.equalsIdentifiers.empty»\r
319             @Override\r
320             public boolean equals(java.lang.Object obj) {\r
321                 if (this == obj) {\r
322                     return true;\r
323                 }\r
324                 if (obj == null) {\r
325                     return false;\r
326                 }\r
327                 if (getClass() != obj.getClass()) {\r
328                     return false;\r
329                 }\r
330                 «type.name» other = («type.name») obj;\r
331                 «FOR property : genTO.equalsIdentifiers»\r
332                     «val fieldName = property.fieldName»\r
333                     if («fieldName» == null) {\r
334                         if (other.«fieldName» != null) {\r
335                             return false;\r
336                         }\r
337                     } else if(!«fieldName».equals(other.«fieldName»)) {\r
338                         return false;\r
339                     }\r
340                 «ENDFOR»\r
341                 return true;\r
342             }\r
343         «ENDIF»\r
344     '''\r
345     \r
346     /**\r
347      * Template method which generates the method <code>toString()</code>.\r
348      * \r
349      * @return string with the <code>toString()</code> method definition in JAVA format     \r
350      */\r
351     def protected generateToString() '''\r
352         «IF !genTO.toStringIdentifiers.empty»\r
353             @Override\r
354             public String toString() {\r
355                 StringBuilder builder = new StringBuilder();\r
356                 «val properties = genTO.toStringIdentifiers»\r
357                 builder.append("«type.name» [«properties.get(0).fieldName»=");\r
358                 builder.append(«properties.get(0).fieldName»);\r
359                 «FOR i : 1..<genTO.toStringIdentifiers.size»\r
360                     builder.append(", «properties.get(i).fieldName»=");\r
361                     builder.append(«properties.get(i).fieldName»);\r
362                 «ENDFOR»\r
363                 builder.append("]");\r
364                 return builder.toString();\r
365             }\r
366         «ENDIF»\r
367     '''\r
368     \r
369 }\r