1 package org.opendaylight.yangtools.sal.java.api.generator
\r
3 import java.util.List
\r
4 import org.opendaylight.yangtools.binding.generator.util.TypeConstants
\r
5 import org.opendaylight.yangtools.sal.binding.model.api.Constant
\r
6 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
\r
7 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
\r
8 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
\r
9 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
\r
10 import java.util.ArrayList
\r
11 import java.util.Collections
\rimport java.util.Arrays
12 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
13 import com.google.common.collect.Range
14 import java.util.regex.Pattern
15 import com.google.common.io.BaseEncoding
16 import java.beans.ConstructorProperties
17 import com.google.common.collect.Lists
20 * Template for generating JAVA class.
\r
22 class ClassTemplate extends BaseTemplate {
\r
24 protected val List<GeneratedProperty> properties
\r
25 protected val List<GeneratedProperty> finalProperties
\r
26 protected val List<GeneratedProperty> parentProperties
\r
27 protected val Iterable<GeneratedProperty> allProperties;
\r
28 protected val Restrictions restrictions
\r
31 * List of enumeration which are generated as JAVA enum type.
\r
33 protected val List<Enumeration> enums
\r
36 * List of constant instances which are generated as JAVA public static final attributes.
\r
38 protected val List<Constant> consts
\r
41 * List of generated types which are enclosed inside <code>genType</code>
\r
43 protected val List<GeneratedType> enclosedGeneratedTypes;
\r
46 protected val GeneratedTransferObject genTO;
\r
49 * Creates instance of this class with concrete <code>genType</code>.
\r
51 * @param genType generated transfer object which will be transformed to JAVA class source code
\r
53 new(GeneratedTransferObject genType) {
\r
55 this.genTO = genType
\r
56 this.properties = genType.properties
\r
57 this.finalProperties = GeneratorUtil.resolveReadOnlyPropertiesFromTO(genTO.properties)
\r
58 this.parentProperties = GeneratorUtil.getPropertiesOfAllParents(genTO)
\r
59 this.restrictions = genType.restrictions
\r
61 var List<GeneratedProperty> sorted = new ArrayList<GeneratedProperty>();
\r
62 sorted.addAll(properties);
\r
63 sorted.addAll(parentProperties);
\r
64 Collections.sort(sorted, new PropertyComparator());
\r
66 this.allProperties = sorted
\r
67 this.enums = genType.enumerations
\r
68 this.consts = genType.constantDefinitions
\r
69 this.enclosedGeneratedTypes = genType.enclosedTypes
\r
74 * Generates JAVA class source code (class body only).
\r
76 * @return string with JAVA class body source code
\r
78 def CharSequence generateAsInnerClass() {
\r
79 return generateBody(true)
\r
83 override protected body() {
\r
84 generateBody(false);
\r
88 * Template method which generates class body.
\r
90 * @param isInnerClass boolean value which specify if generated class is|isn't inner
\r
91 * @return string with class source code in JAVA format
\r
93 def protected generateBody(boolean isInnerClass) '''
\r
94 «type.comment.asJavadoc»
\r
95 «generateClassDeclaration(isInnerClass)» {
\r
97 «innerClassesDeclarations»
\r
99 «constantsDeclarations»
\r
106 «FOR field : properties SEPARATOR "\n"»
\r
107 «field.getterMethod»
\r
108 «IF !field.readOnly»
\r
109 «field.setterMethod»
\r
117 «generateToString(genTO.toStringIdentifiers)»
\r
119 «generateGetLength»
\r
126 * Template method which generates inner classes inside this interface.
\r
128 * @return string with the source code for inner classes in JAVA format
\r
130 def protected innerClassesDeclarations() '''
\r
131 «IF !enclosedGeneratedTypes.empty»
\r
132 «FOR innerClass : enclosedGeneratedTypes SEPARATOR "\n"»
\r
133 «IF (innerClass instanceof GeneratedTransferObject)»
\r
134 «val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)»
\r
135 «classTemplate.generateAsInnerClass»
\r
143 def protected constructors() '''
\r
144 «IF genTO.unionType»
\r
145 «genUnionConstructor»
\r
147 «allValuesConstructor»
\r
149 «IF !allProperties.empty»
\r
152 «IF properties.empty && !parentProperties.empty »
\r
153 «parentConstructor»
\r
157 def protected allValuesConstructor() '''
\r
158 «IF genTO.typedef && !allProperties.empty && allProperties.size == 1 && allProperties.get(0).name.equals("value")»
\r
159 @«ConstructorProperties.importedName»("value")
\r
161 public «type.name»(«allProperties.asArgumentsDeclaration») {
\r
162 «IF false == parentProperties.empty»
\r
163 super(«parentProperties.asArguments»);
\r
165 «FOR p : allProperties»
\r
166 «generateRestrictions(type, p.fieldName.toString, p.returnType)»
\r
168 «FOR p : properties»
\r
169 this.«p.fieldName» = «p.fieldName»;
\r
174 def protected genUnionConstructor() '''
\r
175 «FOR p : allProperties»
\r
176 «val List<GeneratedProperty> other = new ArrayList(properties)»
\r
177 «val added = other.remove(p)»
\r
178 «genConstructor(p, other)»
\r
183 def protected genConstructor(GeneratedProperty property, GeneratedProperty... other) '''
\r
184 public «type.name»(«property.returnType.importedName + " " + property.name») {
\r
185 «IF false == parentProperties.empty»
\r
186 super(«parentProperties.asArguments»);
\r
188 «generateRestrictions(type, property.fieldName.toString, property.returnType)»
\r
189 this.«property.fieldName» = «property.name»;
\r
191 this.«p.fieldName» = null;
\r
196 def protected copyConstructor() '''
\r
198 * Creates a copy from Source Object.
\r
200 * @param source Source object
\r
202 public «type.name»(«type.name» source) {
\r
203 «IF false == parentProperties.empty»
\r
206 «FOR p : properties»
\r
207 this.«p.fieldName» = source.«p.fieldName»;
\r
212 def protected parentConstructor() '''
\r
214 * Creates a new instance from «genTO.superType.importedName»
\r
216 * @param source Source object
\r
218 public «type.name»(«genTO.superType.importedName» source) {
\r
223 def protected defaultInstance() '''
\r
224 «IF genTO.typedef && !allProperties.empty && !genTO.unionType»
\r
225 «val prop = allProperties.get(0)»
\r
226 «IF !("org.opendaylight.yangtools.yang.binding.InstanceIdentifier".equals(prop.returnType.fullyQualifiedName))»
\r
227 public static «genTO.name» getDefaultInstance(String defaultValue) {
\r
228 «IF "byte[]".equals(prop.returnType.name)»
\r
229 «BaseEncoding.importedName» baseEncoding = «BaseEncoding.importedName».base64();
\r
230 return new «genTO.name»(baseEncoding.decode(defaultValue));
\r
231 «ELSEIF "java.lang.String".equals(prop.returnType.fullyQualifiedName)»
\r
232 return new «genTO.name»(defaultValue);
\r
233 «ELSEIF allProperties.size > 1»
\r
236 return new «genTO.name»(new «prop.returnType.importedName»(defaultValue));
\r
243 def protected bitsArgs() '''
\r
244 «List.importedName»<«String.importedName»> properties = «Lists.importedName».newArrayList(«allProperties.propsAsArgs»);
\r
245 if (!properties.contains(defaultValue)) {
\r
246 throw new «IllegalArgumentException.importedName»("invalid default parameter");
\r
249 return new «genTO.name»(
\r
250 «FOR prop : allProperties SEPARATOR ","»
\r
251 properties.get(i++).equals(defaultValue) ? new «Boolean.importedName»("true") : null
\r
256 def protected propsAsArgs(Iterable<GeneratedProperty> properties) '''
\r
257 «FOR prop : properties SEPARATOR ","»
\r
263 * Template method which generates JAVA class declaration.
\r
265 * @param isInnerClass boolean value which specify if generated class is|isn't inner
\r
266 * @return string with class declaration in JAVA format
\r
268 def protected generateClassDeclaration(boolean isInnerClass) '''
\r
270 IF (isInnerClass)»«
\r
272 ELSEIF (type.abstract)»«
\r
276 ENDIF»class «type.name»«
\r
277 IF (genTO.superType != null)»«
\r
278 " extends "»«genTO.superType.importedName»«
\r
280 «IF (!type.implements.empty)»«
\r
282 FOR type : type.implements SEPARATOR ", "»«
\r
283 type.importedName»«
\r
289 * Template method which generates JAVA enum type.
\r
291 * @return string with inner enum source code in JAVA format
\r
293 def protected enumDeclarations() '''
\r
295 «FOR e : enums SEPARATOR "\n"»
\r
296 «val enumTemplate = new EnumTemplate(e)»
\r
297 «enumTemplate.generateAsInnerClass»
\r
302 def protected suidDeclaration() '''
\r
303 «IF genTO.SUID != null»
\r
304 private static final long serialVersionUID = «genTO.SUID.value»L;
\r
309 * Template method wich generates JAVA constants.
\r
311 * @return string with constants in JAVA format
\r
313 def protected constantsDeclarations() '''
\r
316 «IF c.name == TypeConstants.PATTERN_CONSTANT_NAME»
\r
317 «val cValue = c.value»
\r
318 «IF cValue instanceof List<?>»
\r
319 «val cValues = cValue as List<?>»
\r
320 private static final «List.importedName»<«Pattern.importedName»> «Constants.MEMBER_PATTERN_LIST» = new «ArrayList.importedName»<«Pattern.importedName»>();
\r
321 public static final «List.importedName»<String> «TypeConstants.PATTERN_CONSTANT_NAME» = «Arrays.importedName».asList(«
\r
322 FOR v : cValues SEPARATOR ", "»«
\r
323 IF v instanceof String»"«
\r
328 «generateStaticInicializationBlock»
\r
331 public static final «c.type.importedName» «c.name» = «c.value»;
\r
338 * Template method which generates JAVA static initialization block.
\r
340 * @return string with static initialization block in JAVA format
\r
342 def protected generateStaticInicializationBlock() '''
\r
344 for (String regEx : «TypeConstants.PATTERN_CONSTANT_NAME») {
\r
345 «Constants.MEMBER_PATTERN_LIST».add(Pattern.compile(regEx));
\r
351 * Template method which generates JAVA class attributes.
\r
353 * @return string with the class attributes in JAVA format
\r
355 def protected generateFields() '''
\r
356 «IF !properties.empty»
\r
357 «FOR f : properties»
\r
358 «IF f.readOnly»final«ENDIF» private «f.returnType.importedName» «f.fieldName»;
\r
365 * Template method which generates the method <code>hashCode()</code>.
\r
367 * @return string with the <code>hashCode()</code> method definition in JAVA format
\r
369 def protected generateHashCode() '''
\r
370 «IF !genTO.hashCodeIdentifiers.empty»
\r
372 public int hashCode() {
\r
373 final int prime = 31;
\r
375 «FOR property : genTO.hashCodeIdentifiers»
\r
376 «IF property.returnType.name.contains("[")»
\r
377 result = prime * result + ((«property.fieldName» == null) ? 0 : «Arrays.importedName».hashCode(«property.fieldName»));
\r
379 result = prime * result + ((«property.fieldName» == null) ? 0 : «property.fieldName».hashCode());
\r
388 * Template method which generates the method <code>equals()</code>.
\r
390 * @return string with the <code>equals()</code> method definition in JAVA format
\r
392 def protected generateEquals() '''
\r
393 «IF !genTO.equalsIdentifiers.empty»
\r
395 public boolean equals(java.lang.Object obj) {
\r
402 if (getClass() != obj.getClass()) {
\r
405 «type.name» other = («type.name») obj;
\r
406 «FOR property : genTO.equalsIdentifiers»
\r
407 «val fieldName = property.fieldName»
\r
408 if («fieldName» == null) {
\r
409 if (other.«fieldName» != null) {
\r
412 «IF property.returnType.name.contains("[")»
\r
413 } else if(!«Arrays.importedName».equals(«fieldName», other.«fieldName»)) {
\r
415 } else if(!«fieldName».equals(other.«fieldName»)) {
\r
425 def private generateGetLength() '''
\r
426 «IF restrictions != null && !(restrictions.lengthConstraints.empty)»
\r
427 public static «List.importedName»<«Range.importedName»<Integer>> getLength() {
\r
428 final «List.importedName»<«Range.importedName»<Integer>> result = new «ArrayList.importedName»<>();
\r
429 «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.importedName»<>();
\r
430 «FOR r : restrictions.lengthConstraints»
\r
431 result.add(«Range.importedName».closed(«r.min», «r.max»));
\r
438 def private generateGetRange() '''
\r
439 «IF restrictions != null && !(restrictions.lengthConstraints.empty)»
\r
440 public static «List.importedName»<«Range.importedName»<Integer>> getLength() {
\r
441 final «List.importedName»<«Range.importedName»<Integer>> result = new «ArrayList.importedName»<>();
\r
442 «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.importedName»<>();
\r
443 «FOR r : restrictions.lengthConstraints»
\r
444 result.add(«Range.importedName».closed(«r.min», «r.max»));
\r