Merge "OF plugin classes must have a strict dependency on Connection Service"
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-java-api-generator / src / main / java / org / opendaylight / controller / sal / java / api / generator / ClassTemplate.xtend
1 package org.opendaylight.controller.sal.java.api.generator
2
3 import java.util.List
4 import java.util.Map
5 import org.opendaylight.controller.binding.generator.util.TypeConstants
6 import org.opendaylight.controller.sal.binding.model.api.Constant
7 import org.opendaylight.controller.sal.binding.model.api.Enumeration
8 import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty
9 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject
10 import org.opendaylight.controller.sal.binding.model.api.Type
11
12 class ClassTemplate {
13     
14     val GeneratedTransferObject genTO
15     val Map<String, String> imports
16     val List<GeneratedProperty> fields
17     val List<Enumeration> enums
18     val List<Constant> consts
19     
20     new(GeneratedTransferObject genTO) {
21         if (genTO == null) {
22             throw new IllegalArgumentException("Generated transfer object reference cannot be NULL!")
23         }
24         
25         this.genTO = genTO
26         this.imports = GeneratorUtil.createImports(genTO)
27         this.fields = genTO.properties
28         this.enums = genTO.enumerations
29         this.consts = genTO.constantDefinitions
30     }
31     
32     def generate() {
33         val body = generateBody(false)
34         val pkgAndImports = generatePkgAndImports
35         return pkgAndImports.toString + body.toString
36     }
37     
38     def generateAsInnerClass() {
39         return generateBody(true)
40     }
41     
42     def private generateBody(boolean isInnerClass) '''
43         «genTO.comment.generateComment»
44         «generateClassDeclaration(isInnerClass)» {
45
46             «generateEnums»
47         
48             «generateConstants»
49         
50             «generateFields»
51         
52             «generateConstructor»
53         
54             «FOR field : fields SEPARATOR "\n"»
55                 «field.generateGetter»
56                 «IF !field.readOnly»
57                 
58                     «field.generateSetter»
59                 «ENDIF»
60             «ENDFOR»
61         
62             «generateHashCode»
63         
64             «generateEquals»
65         
66             «generateToString»
67         
68         }
69     '''
70     
71     def private generateComment(String comment) '''
72         «IF comment != null && !comment.empty»
73             /*
74             «comment»
75             */
76         «ENDIF»
77     '''
78     
79     def private generateClassDeclaration(boolean isInnerClass) '''
80         public«
81         IF (isInnerClass)»«
82             " static final "»«
83         ELSEIF (genTO.abstract)»«
84             " abstract "»«
85         ELSE»«
86             " "»«
87         ENDIF»class «genTO.name»«
88         IF (genTO.extends != null)»«
89             " extends "»«genTO.extends.resolveName»«
90         ENDIF»«
91         IF (!genTO.implements.empty)»«
92             " implements "»«
93             FOR type : genTO.implements SEPARATOR ", "»«
94                 type.resolveName»«
95             ENDFOR»«
96         ENDIF
97     »'''
98     
99     def private generateEnums() '''
100         «IF !enums.empty»
101             «FOR e : enums SEPARATOR "\n"»
102                 «val enumTemplate = new EnumTemplate(e)»
103                 «enumTemplate.generateAsInnerClass»
104             «ENDFOR»
105         «ENDIF»
106     '''
107     
108     def private generateConstants() '''
109         «IF !consts.empty»
110             «FOR c : consts»
111                 «IF c.name == TypeConstants.PATTERN_CONSTANT_NAME»
112                     «val cValue = c.value»
113                     «IF cValue instanceof List<?>»
114                         «val cValues = cValue as List<?>»
115                         private static final List<Pattern> «Constants.MEMBER_PATTERN_LIST» = new ArrayList<Pattern>();
116                         public static final List<String> «TypeConstants.PATTERN_CONSTANT_NAME» = Arrays.asList(«
117                         FOR v : cValues SEPARATOR ", "»«
118                             IF v instanceof String»"«
119                                 v as String»"«
120                             ENDIF»«
121                         ENDFOR»);
122                         
123                         «generateStaticInicializationBlock»
124                     «ENDIF»
125                 «ELSE»
126                     public static final «c.type.resolveName» «c.name» = «c.value»;
127                 «ENDIF»
128             «ENDFOR»
129         «ENDIF»
130     '''
131     
132     def private generateStaticInicializationBlock() '''
133         static {
134             for (String regEx : «TypeConstants.PATTERN_CONSTANT_NAME») {
135                 «Constants.MEMBER_PATTERN_LIST».add(Pattern.compile(regEx));
136             }
137         }
138     '''
139     def private generateFields() '''
140         «IF !fields.empty»
141             «FOR f : fields»
142                 private «f.returnType.resolveName» «f.name»;
143             «ENDFOR»
144         «ENDIF»
145     '''
146     
147     def private generateConstructor() '''
148         «val genTOTopParent = GeneratorUtil.getTopParrentTransportObject(genTO)»
149         «val properties = GeneratorUtil.resolveReadOnlyPropertiesFromTO(genTO.properties)»
150         «val propertiesAllParents = GeneratorUtil.getPropertiesOfAllParents(genTO)»
151         «IF !genTO.unionType»
152 «««            create constructor for every parent property
153             «IF genTOTopParent != genTO && genTOTopParent.unionType»
154                 «FOR parentProperty : propertiesAllParents SEPARATOR "\n"»
155                     «val parentPropertyAndProperties = properties + #[parentProperty]»
156                     «if (genTO.abstract) "protected" else "public"» «genTO.name»(«parentPropertyAndProperties.generateParameters») {
157                         super(«#[parentProperty].generateParameterNames»);
158                         «FOR property : properties»
159                             this.«property.name» = «property.name»;
160                         «ENDFOR»
161                     }
162                 «ENDFOR»
163 «««            create one constructor
164             «ELSE»
165                 «val propertiesAll = propertiesAllParents + properties»
166                 «if (genTO.abstract) "protected" else "public"» «genTO.name»(«propertiesAll.generateParameters») {
167                     super(«propertiesAllParents.generateParameterNames()»);
168                     «FOR property : properties»
169                         this.«property.name» = «property.name»;
170                     «ENDFOR»
171                 }
172             «ENDIF»
173 «««        create constructor for every property
174         «ELSE»
175             «FOR property : properties SEPARATOR "\n"»
176                 «val propertyAndTopParentProperties = propertiesAllParents + #[property]»
177                 «if (genTO.abstract) "protected" else "public"» «genTO.name»(«propertyAndTopParentProperties.generateParameters») {
178                     super(«propertiesAllParents.generateParameterNames()»);
179                     this.«property.name» = «property.name»;
180                 }
181             «ENDFOR»
182         «ENDIF»
183     '''
184     
185     def private generateGetter(GeneratedProperty field) '''
186         public «field.returnType.resolveName» get«field.name.toFirstUpper»() {
187             return «field.name»;
188         }
189     '''
190     
191     def private generateSetter(GeneratedProperty field) '''
192         «val type = field.returnType.resolveName»
193         public void set«field.name.toFirstUpper»(«type» «field.name») {
194             this.«field.name» = «field.name»;
195         }
196     '''
197     
198     def private generateParameters(Iterable<GeneratedProperty> parameters) '''«
199         IF !parameters.empty»«
200             FOR parameter : parameters SEPARATOR ", "»«
201                 parameter.returnType.resolveName» «parameter.name»«
202             ENDFOR»«
203         ENDIF
204     »'''
205     
206     def private generateParameterNames(Iterable<GeneratedProperty> parameters) '''«
207         IF !parameters.empty»«
208             FOR parameter : parameters SEPARATOR ", "»«
209                 parameter.name»«
210             ENDFOR»«
211         ENDIF
212     »'''
213     
214     def private generateHashCode() '''
215         «IF !genTO.hashCodeIdentifiers.empty»
216             @Override
217             public int hashCode() {
218                 final int prime = 31;
219                 int result = 1;
220                 «FOR property : genTO.hashCodeIdentifiers»
221                     result = prime * result + ((«property.name» == null) ? 0 : «property.name».hashCode());
222                 «ENDFOR»
223                 return result;
224             }
225         «ENDIF»
226     '''
227     def private generateEquals() '''
228         «IF !genTO.equalsIdentifiers.empty»
229             @Override
230             public boolean equals(Object obj) {
231                 if (this == obj) {
232                     return true;
233                 }
234                 if (obj == null) {
235                     return false;
236                 }
237                 if (getClass() != obj.getClass()) {
238                     return false;
239                 }
240                 «genTO.name» other = («genTO.name») obj;
241                 «FOR property : genTO.equalsIdentifiers»
242                     «val fieldName = property.name»
243                     if («fieldName» == null) {
244                         if (other.«fieldName» != null) {
245                             return false;
246                         }
247                     } else if(!«fieldName».equals(other.«fieldName»)) {
248                         return false;
249                     }
250                 «ENDFOR»
251                 return true;
252             }
253         «ENDIF»
254     '''
255     
256     def private generateToString() '''
257         «IF !genTO.toStringIdentifiers.empty»
258             @Override
259             public String toString() {
260                 StringBuilder builder = new StringBuilder();
261                 «val properties = genTO.toStringIdentifiers»
262                 builder.append("«genTO.name» [«properties.get(0).name»=");
263                 builder.append(«properties.get(0).name»);
264                 «FOR i : 1..<genTO.toStringIdentifiers.size»
265                     builder.append(", «properties.get(i).name»=");
266                     builder.append(«properties.get(i).name»);
267                 «ENDFOR»
268                 builder.append("]");
269                 return builder.toString();
270             }
271         «ENDIF»
272     '''
273     
274     def private generatePkgAndImports() '''
275         package «genTO.packageName»;
276         
277         
278         «IF !imports.empty»
279             «FOR entry : imports.entrySet»
280                 import «entry.value».«entry.key»;
281             «ENDFOR»
282         «ENDIF»
283         
284     '''
285     
286     def private resolveName(Type type) {
287         GeneratorUtil.putTypeIntoImports(genTO, type, imports);
288         GeneratorUtil.getExplicitType(genTO, type, imports)
289     }
290     
291 }