1 package org.opendaylight.yangtools.sal.java.api.generator
5 import org.opendaylight.yangtools.binding.generator.util.TypeConstants
6 import org.opendaylight.yangtools.sal.binding.model.api.Constant
7 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
8 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
9 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
10 import org.opendaylight.yangtools.sal.binding.model.api.Type
11 import org.opendaylight.yangtools.binding.generator.util.Types
14 * Template for generating JAVA class.
19 * Generated transfer object for which class JAVA file is generated
21 val GeneratedTransferObject genTO
24 * Map of imports for this <code>genTO</code>.
26 val Map<String, String> imports
29 * List of generated property instances which represents class attributes.
31 val List<GeneratedProperty> fields
34 * List of enumeration which are generated as JAVA enum type.
36 val List<Enumeration> enums
39 * List of constant instances which are generated as JAVA public static final attributes.
41 val List<Constant> consts
44 * Creates instance of this class with concrete <code>genTO</code>.
46 * @param genTO generated transfer object which will be transformed to JAVA class source code
48 new(GeneratedTransferObject genTO) {
50 throw new IllegalArgumentException("Generated transfer object reference cannot be NULL!")
54 this.imports = GeneratorUtil.createImports(genTO)
55 this.fields = genTO.properties
56 this.enums = genTO.enumerations
57 this.consts = genTO.constantDefinitions
61 * Generates JAVA class source code (package name + class body).
63 * @return string with JAVA class source code
65 def String generate() {
66 val body = generateBody(false)
67 val pkgAndImports = generatePkgAndImports
68 return pkgAndImports.toString + body.toString
72 * Generates JAVA class source code (class body only).
74 * @return string with JAVA class body source code
76 def generateAsInnerClass() {
77 return generateBody(true)
81 * Template method which generates class body.
83 * @param isInnerClass boolean value which specify if generated class is|isn't inner
84 * @return string with class source code in JAVA format
86 def private generateBody(boolean isInnerClass) '''
87 «genTO.comment.generateComment»
88 «generateClassDeclaration(isInnerClass)» {
98 «FOR field : fields SEPARATOR "\n"»
99 «field.generateGetter»
102 «field.generateSetter»
116 * Template method which generates JAVA comments.
118 * @param string with the comment for whole JAVA class
119 * @return string with comment in JAVA format
121 def private generateComment(String comment) '''
122 «IF comment != null && !comment.empty»
130 * Template method which generates JAVA class declaration.
132 * @param isInnerClass boolean value which specify if generated class is|isn't inner
133 * @return string with class declaration in JAVA format
135 def private generateClassDeclaration(boolean isInnerClass) '''
139 ELSEIF (genTO.abstract)»«
143 ENDIF»class «genTO.name»«
144 IF (genTO.extends != null)»«
145 " extends "»«genTO.extends.resolveName»«
147 IF (!genTO.implements.empty)»«
149 FOR type : genTO.implements SEPARATOR ", "»«
156 * Template method which generates JAVA enum type.
158 * @return string with inner enum source code in JAVA format
160 def private generateEnums() '''
162 «FOR e : enums SEPARATOR "\n"»
163 «val enumTemplate = new EnumTemplate(e)»
164 «enumTemplate.generateAsInnerClass»
170 * Template method wich generates JAVA constants.
172 * @return string with constants in JAVA format
174 def private generateConstants() '''
177 «IF c.name == TypeConstants.PATTERN_CONSTANT_NAME»
178 «val cValue = c.value»
179 «IF cValue instanceof List<?>»
180 «val cValues = cValue as List<?>»
181 private static final List<Pattern> «Constants.MEMBER_PATTERN_LIST» = new ArrayList<Pattern>();
182 public static final List<String> «TypeConstants.PATTERN_CONSTANT_NAME» = Arrays.asList(«
183 FOR v : cValues SEPARATOR ", "»«
184 IF v instanceof String»"«
189 «generateStaticInicializationBlock»
192 public static final «c.type.resolveName» «c.name» = «c.value»;
199 * Template method which generates JAVA static initialization block.
201 * @return string with static initialization block in JAVA format
203 def private generateStaticInicializationBlock() '''
205 for (String regEx : «TypeConstants.PATTERN_CONSTANT_NAME») {
206 «Constants.MEMBER_PATTERN_LIST».add(Pattern.compile(regEx));
212 * Template method which generates JAVA class attributes.
214 * @return string with the class attributes in JAVA format
216 def private generateFields() '''
219 private «f.returnType.resolveName» «f.fieldName»;
225 * Template method which generates JAVA constructor(s).
227 * @return string with the class constructor(s) in JAVA format
229 def private generateConstructor() '''
230 «val genTOTopParent = GeneratorUtil.getTopParrentTransportObject(genTO)»
231 «val properties = GeneratorUtil.resolveReadOnlyPropertiesFromTO(genTO.properties)»
232 «val propertiesAllParents = GeneratorUtil.getPropertiesOfAllParents(genTO)»
233 «IF !genTO.unionType»
234 ««« create constructor for every parent property
235 «IF genTOTopParent != genTO && genTOTopParent.unionType»
236 «FOR parentProperty : propertiesAllParents SEPARATOR "\n"»
237 «val parentPropertyAndProperties = properties + #[parentProperty]»
238 «if (genTO.abstract) "protected" else "public"» «genTO.name»(«parentPropertyAndProperties.generateParameters») {
239 super(«#[parentProperty].generateParameterNames»);
240 «FOR property : properties»
241 this.«property.fieldName» = «property.name»;
245 ««« create one constructor
247 «val propertiesAll = propertiesAllParents + properties»
248 «if (genTO.abstract) "protected" else "public"» «genTO.name»(«propertiesAll.generateParameters») {
249 super(«propertiesAllParents.generateParameterNames()»);
250 «FOR property : properties»
251 this.«property.fieldName» = «property.fieldName»;
255 ««« create constructor for every property
257 «FOR property : properties SEPARATOR "\n"»
258 «val propertyAndTopParentProperties = propertiesAllParents + #[property]»
259 «if (genTO.abstract) "protected" else "public"» «genTO.name»(«propertyAndTopParentProperties.generateParameters») {
260 super(«propertiesAllParents.generateParameterNames()»);
261 this.«property.fieldName» = «property.fieldName»;
268 * Template method which generates the getter method for <code>field</code>
271 * generated property with data about field which is generated as the getter method
272 * @return string with the getter method source code in JAVA format
274 def private generateGetter(GeneratedProperty field) {
275 val prefix = if(field.returnType.equals(Types.typeForClass(Boolean))) "is" else "get"
277 public «field.returnType.resolveName» «prefix»«field.name.toFirstUpper»() {
278 return «field.fieldName»;
284 * Template method which generates the setter method for <code>field</code>
287 * generated property with data about field which is generated as the setter method
288 * @return string with the setter method source code in JAVA format
290 def private generateSetter(GeneratedProperty field) '''
291 «val type = field.returnType.resolveName»
292 public void set«field.name.toFirstUpper»(«type» «field.fieldName») {
293 this.«field.fieldName» = «field.fieldName»;
298 * Template method which generates method parameters with their types from <code>parameters</code>.
301 * group of generated property instances which are transformed to the method parameters
302 * @return string with the list of the method parameters with their types in JAVA format
304 def private generateParameters(Iterable<GeneratedProperty> parameters) '''«
305 IF !parameters.empty»«
306 FOR parameter : parameters SEPARATOR ", "»«
307 parameter.returnType.resolveName» «parameter.fieldName»«
313 * Template method which generates sequence of the names of the class attributes from <code>parameters</code>.
316 * group of generated property instances which are transformed to the sequence of parameter names
317 * @return string with the list of the parameter names of the <code>parameters</code>
319 def private generateParameterNames(Iterable<GeneratedProperty> parameters) '''«
320 IF !parameters.empty»«
321 FOR parameter : parameters SEPARATOR ", "»«
322 parameter.fieldName»«
328 * Template method which generates the method <code>hashCode()</code>.
330 * @return string with the <code>hashCode()</code> method definition in JAVA format
332 def private generateHashCode() '''
333 «IF !genTO.hashCodeIdentifiers.empty»
335 public int hashCode() {
336 final int prime = 31;
338 «FOR property : genTO.hashCodeIdentifiers»
339 result = prime * result + ((«property.fieldName» == null) ? 0 : «property.fieldName».hashCode());
347 * Template method which generates the method <code>equals()</code>.
349 * @return string with the <code>equals()</code> method definition in JAVA format
351 def private generateEquals() '''
352 «IF !genTO.equalsIdentifiers.empty»
354 public boolean equals(java.lang.Object obj) {
361 if (getClass() != obj.getClass()) {
364 «genTO.name» other = («genTO.name») obj;
365 «FOR property : genTO.equalsIdentifiers»
366 «val fieldName = property.fieldName»
367 if («fieldName» == null) {
368 if (other.«fieldName» != null) {
371 } else if(!«fieldName».equals(other.«fieldName»)) {
381 * Template method which generates the method <code>toString()</code>.
383 * @return string with the <code>toString()</code> method definition in JAVA format
385 def private generateToString() '''
386 «IF !genTO.toStringIdentifiers.empty»
388 public String toString() {
389 StringBuilder builder = new StringBuilder();
390 «val properties = genTO.toStringIdentifiers»
391 builder.append("«genTO.name» [«properties.get(0).fieldName»=");
392 builder.append(«properties.get(0).fieldName»);
393 «FOR i : 1..<genTO.toStringIdentifiers.size»
394 builder.append(", «properties.get(i).fieldName»=");
395 builder.append(«properties.get(i).fieldName»);
398 return builder.toString();
404 * Template method which generate package name line and import lines.
406 * @result string with package and import lines in JAVA format
408 def private generatePkgAndImports() '''
409 package «genTO.packageName»;
413 «FOR entry : imports.entrySet»
414 import «entry.value».«entry.key»;
421 * Adds package to imports if it is necessary and returns necessary type name (with or without package name)
423 * @param type JAVA <code>Type</code>
424 * @return string with the type name (with or without package name)
426 def private resolveName(Type type) {
427 GeneratorUtil.putTypeIntoImports(genTO, type, imports);
428 GeneratorUtil.getExplicitType(genTO, type, imports)
431 def private fieldName(GeneratedProperty property) {
432 '''_«property.name»'''