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
17 * Template for generating JAVA class.
\r
19 class ClassTemplate extends BaseTemplate {
\r
21 protected val List<GeneratedProperty> properties
\r
22 protected val List<GeneratedProperty> finalProperties
\r
23 protected val List<GeneratedProperty> parentProperties
\r
24 protected val Iterable<GeneratedProperty> allProperties;
\r
25 protected val Restrictions restrictions
\r
28 * List of enumeration which are generated as JAVA enum type.
\r
30 protected val List<Enumeration> enums
\r
33 * List of constant instances which are generated as JAVA public static final attributes.
\r
35 protected val List<Constant> consts
\r
38 * List of generated types which are enclosed inside <code>genType</code>
\r
40 protected val List<GeneratedType> enclosedGeneratedTypes;
\r
43 protected val GeneratedTransferObject genTO;
\r
46 * Creates instance of this class with concrete <code>genType</code>.
\r
48 * @param genType generated transfer object which will be transformed to JAVA class source code
\r
50 new(GeneratedTransferObject genType) {
\r
52 this.genTO = genType
\r
53 this.properties = genType.properties
\r
54 this.finalProperties = GeneratorUtil.resolveReadOnlyPropertiesFromTO(genTO.properties)
\r
55 this.parentProperties = GeneratorUtil.getPropertiesOfAllParents(genTO)
\r
56 this.restrictions = genType.restrictions
\r
58 var List<GeneratedProperty> sorted = new ArrayList<GeneratedProperty>();
\r
59 sorted.addAll(properties);
\r
60 sorted.addAll(parentProperties);
\r
61 Collections.sort(sorted, new PropertyComparator());
\r
63 this.allProperties = sorted
\r
64 this.enums = genType.enumerations
\r
65 this.consts = genType.constantDefinitions
\r
66 this.enclosedGeneratedTypes = genType.enclosedTypes
\r
71 * Generates JAVA class source code (class body only).
\r
73 * @return string with JAVA class body source code
\r
75 def CharSequence generateAsInnerClass() {
\r
76 return generateBody(true)
\r
80 override protected body() {
\r
81 generateBody(false);
\r
85 * Template method which generates class body.
\r
87 * @param isInnerClass boolean value which specify if generated class is|isn't inner
\r
88 * @return string with class source code in JAVA format
\r
90 def protected generateBody(boolean isInnerClass) '''
\r
91 «type.comment.asJavadoc»
\r
92 «generateClassDeclaration(isInnerClass)» {
\r
94 «innerClassesDeclarations»
\r
96 «constantsDeclarations»
\r
99 «FOR field : properties SEPARATOR "\n"»
\r
100 «field.getterMethod»
\r
101 «IF !field.readOnly»
\r
102 «field.setterMethod»
\r
112 «generateGetLength»
\r
119 * Template method which generates inner classes inside this interface.
\r
121 * @return string with the source code for inner classes in JAVA format
\r
123 def protected innerClassesDeclarations() '''
\r
124 «IF !enclosedGeneratedTypes.empty»
\r
125 «FOR innerClass : enclosedGeneratedTypes SEPARATOR "\n"»
\r
126 «IF (innerClass instanceof GeneratedTransferObject)»
\r
127 «val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)»
\r
128 «classTemplate.generateAsInnerClass»
\r
136 def protected constructors() '''
\r
137 «IF genTO.unionType»
\r
138 «genUnionConstructor»
\r
140 «allValuesConstructor»
\r
142 «IF !allProperties.empty»
\r
145 «IF properties.empty && !parentProperties.empty »
\r
146 «parentConstructor»
\r
150 def protected allValuesConstructor() '''
\r
151 public «type.name»(«allProperties.asArgumentsDeclaration») {
\r
152 «IF false == parentProperties.empty»
\r
153 super(«parentProperties.asArguments»);
\r
155 «FOR p : allProperties»
\r
156 «generateRestrictions(type, p.fieldName.toString, p.returnType)»
\r
158 «FOR p : properties»
\r
159 this.«p.fieldName» = «p.fieldName»;
\r
164 def protected genUnionConstructor() '''
\r
165 «FOR p : allProperties»
\r
166 «val List<GeneratedProperty> other = new ArrayList(properties)»
\r
167 «val added = other.remove(p)»
\r
168 «genConstructor(p, other)»
\r
173 def protected genConstructor(GeneratedProperty property, GeneratedProperty... other) '''
\r
174 public «type.name»(«property.returnType.importedName + " " + property.name») {
\r
175 «IF false == parentProperties.empty»
\r
176 super(«parentProperties.asArguments»);
\r
178 «generateRestrictions(type, property.fieldName.toString, property.returnType)»
\r
179 this.«property.fieldName» = «property.name»;
\r
181 this.«p.fieldName» = null;
\r
186 def protected copyConstructor() '''
\r
188 * Creates a copy from Source Object.
\r
190 * @param source Source object
\r
192 public «type.name»(«type.name» source) {
\r
193 «IF false == parentProperties.empty»
\r
196 «FOR p : properties»
\r
197 this.«p.fieldName» = source.«p.fieldName»;
\r
202 def protected parentConstructor() '''
\r
204 * Creates a new instance from «genTO.superType.importedName»
\r
206 * @param source Source object
\r
208 public «type.name»(«genTO.superType.importedName» source) {
\r
216 * Template method which generates JAVA class declaration.
\r
218 * @param isInnerClass boolean value which specify if generated class is|isn't inner
\r
219 * @return string with class declaration in JAVA format
\r
221 def protected generateClassDeclaration(boolean isInnerClass) '''
\r
223 IF (isInnerClass)»«
\r
225 ELSEIF (type.abstract)»«
\r
229 ENDIF»class «type.name»«
\r
230 IF (genTO.superType != null)»«
\r
231 " extends "»«genTO.superType.importedName»«
\r
233 «IF (!type.implements.empty)»«
\r
235 FOR type : type.implements SEPARATOR ", "»«
\r
236 type.importedName»«
\r
242 * Template method which generates JAVA enum type.
\r
244 * @return string with inner enum source code in JAVA format
\r
246 def protected enumDeclarations() '''
\r
248 «FOR e : enums SEPARATOR "\n"»
\r
249 «val enumTemplate = new EnumTemplate(e)»
\r
250 «enumTemplate.generateAsInnerClass»
\r
255 def protected suidDeclaration() '''
\r
256 «IF genTO.SUID != null»
\r
257 private static final long serialVersionUID = «genTO.SUID.value»L;
\r
262 * Template method wich generates JAVA constants.
\r
264 * @return string with constants in JAVA format
\r
266 def protected constantsDeclarations() '''
\r
269 «IF c.name == TypeConstants.PATTERN_CONSTANT_NAME»
\r
270 «val cValue = c.value»
\r
271 «IF cValue instanceof List<?>»
\r
272 «val cValues = cValue as List<?>»
\r
273 private static final «List.importedName»<«Pattern.importedName»> «Constants.MEMBER_PATTERN_LIST» = new «ArrayList.importedName»<«Pattern.importedName»>();
\r
274 public static final «List.importedName»<String> «TypeConstants.PATTERN_CONSTANT_NAME» = «Arrays.importedName».asList(«
\r
275 FOR v : cValues SEPARATOR ", "»«
\r
276 IF v instanceof String»"«
\r
281 «generateStaticInicializationBlock»
\r
284 public static final «c.type.importedName» «c.name» = «c.value»;
\r
291 * Template method which generates JAVA static initialization block.
\r
293 * @return string with static initialization block in JAVA format
\r
295 def protected generateStaticInicializationBlock() '''
\r
297 for (String regEx : «TypeConstants.PATTERN_CONSTANT_NAME») {
\r
298 «Constants.MEMBER_PATTERN_LIST».add(Pattern.compile(regEx));
\r
304 * Template method which generates JAVA class attributes.
\r
306 * @return string with the class attributes in JAVA format
\r
308 def protected generateFields() '''
\r
309 «IF !properties.empty»
\r
310 «FOR f : properties»
\r
311 «IF f.readOnly»final«ENDIF» private «f.returnType.importedName» «f.fieldName»;
\r
318 * Template method which generates the method <code>hashCode()</code>.
\r
320 * @return string with the <code>hashCode()</code> method definition in JAVA format
\r
322 def protected generateHashCode() '''
\r
323 «IF !genTO.hashCodeIdentifiers.empty»
\r
325 public int hashCode() {
\r
326 final int prime = 31;
\r
328 «FOR property : genTO.hashCodeIdentifiers»
\r
329 «IF property.returnType.name.contains("[")»
\r
330 result = prime * result + ((«property.fieldName» == null) ? 0 : «Arrays.importedName».hashCode(«property.fieldName»));
\r
332 result = prime * result + ((«property.fieldName» == null) ? 0 : «property.fieldName».hashCode());
\r
341 * Template method which generates the method <code>equals()</code>.
\r
343 * @return string with the <code>equals()</code> method definition in JAVA format
\r
345 def protected generateEquals() '''
\r
346 «IF !genTO.equalsIdentifiers.empty»
\r
348 public boolean equals(java.lang.Object obj) {
\r
355 if (getClass() != obj.getClass()) {
\r
358 «type.name» other = («type.name») obj;
\r
359 «FOR property : genTO.equalsIdentifiers»
\r
360 «val fieldName = property.fieldName»
\r
361 if («fieldName» == null) {
\r
362 if (other.«fieldName» != null) {
\r
365 «IF property.returnType.name.contains("[")»
\r
366 } else if(!«Arrays.importedName».equals(«fieldName», other.«fieldName»)) {
\r
368 } else if(!«fieldName».equals(other.«fieldName»)) {
\r
379 * Template method which generates the method <code>toString()</code>.
\r
381 * @return string with the <code>toString()</code> method definition in JAVA format
\r
383 def protected generateToString() '''
\r
384 «IF !genTO.toStringIdentifiers.empty»
\r
386 public String toString() {
\r
387 StringBuilder builder = new StringBuilder();
\r
388 «val properties = genTO.toStringIdentifiers»
\r
389 builder.append("«type.name» [«properties.get(0).fieldName»=");
\r
390 «IF properties.get(0).returnType.name.contains("[")»
\r
391 builder.append(«Arrays.importedName».toString(«properties.get(0).fieldName»));
\r
393 builder.append(«properties.get(0).fieldName»);
\r
395 «FOR i : 1..<genTO.toStringIdentifiers.size»
\r
396 builder.append(", «properties.get(i).fieldName»=");
\r
397 «IF properties.get(i).returnType.name.contains("[")»
\r
398 builder.append(«Arrays.importedName».toString(«properties.get(i).fieldName»));
\r
400 builder.append(«properties.get(i).fieldName»);
\r
403 builder.append("]");
\r
404 return builder.toString();
\r
409 def private generateGetLength() '''
\r
410 «IF restrictions != null && !(restrictions.lengthConstraints.empty)»
\r
411 public static «List.importedName»<«Range.importedName»<Integer>> getLength() {
\r
412 final «List.importedName»<«Range.importedName»<Integer>> result = new «ArrayList.importedName»<>();
\r
413 «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.importedName»<>();
\r
414 «FOR r : restrictions.lengthConstraints»
\r
415 result.add(«Range.importedName».closed(«r.min», «r.max»));
\r