1 package org.opendaylight.yangtools.sal.java.api.generator
3 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
4 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
6 import org.opendaylight.yangtools.sal.binding.model.api.Type
7 import org.opendaylight.yangtools.binding.generator.util.Types
8 import com.google.common.base.Splitter
9 import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
10 import com.google.common.collect.Range
11 import java.util.ArrayList
13 import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType
14 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
15 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
16 import java.util.Collection
18 abstract class BaseTemplate {
20 protected val GeneratedType type;
21 protected val Map<String, String> importMap;
22 static val paragraphSplitter = Splitter.on("\n\n").omitEmptyStrings();
24 new(GeneratedType _type) {
26 throw new IllegalArgumentException("Generated type reference cannot be NULL!")
29 this.importMap = GeneratorUtil.createImports(type)
32 def packageDefinition() '''package «type.packageName»;'''
34 protected def getFullyQualifiedName() {
35 return type.fullyQualifiedName
38 final public def generate() {
48 protected def imports() '''
50 «FOR entry : importMap.entrySet»
51 «IF entry.value != fullyQualifiedName»
52 import «entry.value».«entry.key»;
59 protected abstract def CharSequence body();
62 final protected def fieldName(GeneratedProperty property) '''_«property.name»'''
64 final protected def propertyNameFromGetter(MethodSignature getter) {
66 if (getter.name.startsWith("is")) {
68 } else if (getter.name.startsWith("get")) {
71 throw new IllegalArgumentException("Not a getter")
73 return getter.name.substring(prefix).toFirstLower;
77 * Template method which generates the getter method for <code>field</code>
80 * generated property with data about field which is generated as the getter method
81 * @return string with the getter method source code in JAVA format
83 final protected def getterMethod(GeneratedProperty field) {
85 public «field.returnType.importedName» «field.getterMethodName»() {
86 return «field.fieldName»;
91 final protected def getterMethodName(GeneratedProperty field) {
92 val prefix = if(field.returnType.equals(Types.BOOLEAN)) "is" else "get"
93 return '''«prefix»«field.name.toFirstUpper»'''
97 * Template method which generates the setter method for <code>field</code>
100 * generated property with data about field which is generated as the setter method
101 * @return string with the setter method source code in JAVA format
103 final protected def setterMethod(GeneratedProperty field) '''
104 «val returnType = field.returnType.importedName»
105 public «type.name» set«field.name.toFirstUpper»(«returnType» value) {
106 this.«field.fieldName» = value;
111 final protected def importedName(Type intype) {
112 GeneratorUtil.putTypeIntoImports(type, intype, importMap);
113 GeneratorUtil.getExplicitType(type, intype, importMap)
116 final protected def importedName(Class<?> cls) {
117 importedName(Types.typeForClass(cls))
121 * Template method which generates method parameters with their types from <code>parameters</code>.
124 * group of generated property instances which are transformed to the method parameters
125 * @return string with the list of the method parameters with their types in JAVA format
127 def final protected asArgumentsDeclaration(Iterable<GeneratedProperty> parameters) '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.
128 returnType.importedName» «parameter.fieldName»«ENDFOR»«ENDIF»'''
131 * Template method which generates sequence of the names of the class attributes from <code>parameters</code>.
134 * group of generated property instances which are transformed to the sequence of parameter names
135 * @return string with the list of the parameter names of the <code>parameters</code>
137 def final protected asArguments(Iterable<GeneratedProperty> parameters) '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.
138 fieldName»«ENDFOR»«ENDIF»'''
141 * Template method which generates JAVA comments.
143 * @param comment string with the comment for whole JAVA class
144 * @return string with comment in JAVA format
146 def protected CharSequence asJavadoc(String comment) {
147 if(comment == null) return '';
148 val paragraphs = paragraphSplitter.split(comment)
152 «FOR p : paragraphs SEPARATOR "<p>"»
159 def generateRestrictions(Type type, String paramName, Type returnType) '''
160 «val boolean isArray = returnType.name.contains("[")»
161 «processRestrictions(type, paramName, returnType, isArray)»
164 def generateRestrictions(GeneratedProperty field, String paramName) '''
165 «val Type type = field.returnType»
166 «IF type instanceof ConcreteType»
167 «processRestrictions(type, paramName, field.returnType, type.name.contains("["))»
168 «ELSEIF type instanceof GeneratedTransferObject»
169 «processRestrictions(type, paramName, field.returnType, isArrayType(type as GeneratedTransferObject))»
174 private def processRestrictions(Type type, String paramName, Type returnType, boolean isArray) '''
175 «val restrictions = type.getRestrictions»
176 «IF restrictions !== null»
177 «IF !restrictions.lengthConstraints.empty»
178 «generateLengthRestriction(type, restrictions, paramName, isArray,
179 !(returnType instanceof ConcreteType))»
181 «IF !restrictions.rangeConstraints.empty &&
182 ("java.lang".equals(returnType.packageName) || "java.math".equals(returnType.packageName))»
183 «generateRangeRestriction(type, returnType, restrictions, paramName,
184 !(returnType instanceof ConcreteType))»
189 def generateLengthRestriction(Type type, Restrictions restrictions, String paramName, boolean isArray,
190 boolean isNestedType) '''
191 if («paramName» != null) {
192 boolean isValidLength = false;
193 «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.
195 «FOR r : restrictions.lengthConstraints»
196 lengthConstraints.add(«Range.importedName».closed(«r.min», «r.max»));
198 for («Range.importedName»<«Integer.importedName»> r : lengthConstraints) {
201 if (r.contains(«paramName».getValue().length)) {
203 if (r.contains(«paramName».length)) {
207 if (r.contains(«paramName».getValue().length())) {
209 if (r.contains(«paramName».length())) {
212 isValidLength = true;
215 if (!isValidLength) {
216 throw new IllegalArgumentException("illegal length");
221 def generateRangeRestriction(Type type, Type returnType, Restrictions restrictions, String paramName,
222 boolean isNestedType) '''
223 «val javaType = Class.forName(returnType.fullyQualifiedName)»
224 if («paramName» != null) {
225 boolean isValidRange = false;
226 «List.importedName»<«Range.importedName»<«javaType.importedName»>> rangeConstraints = new «ArrayList.
228 «FOR r : restrictions.rangeConstraints»
229 rangeConstraints.add(«Range.importedName».closed(new «javaType.importedName»(«r.min.toQuote»), new «javaType.
230 importedName»(«r.max.toQuote»)));
232 for («Range.importedName»<«javaType.importedName»> r : rangeConstraints) {
234 if (r.contains(«paramName».getValue())) {
236 if (r.contains(«paramName»)) {
242 throw new IllegalArgumentException("illegal length");
247 def GeneratedProperty getPropByName(GeneratedType gt, String name) {
248 for (GeneratedProperty prop : gt.properties) {
249 if (prop.name.equals(name)) {
256 def GeneratedProperty getPropByName(Collection<GeneratedProperty> props, String name) {
257 for (GeneratedProperty prop : props) {
258 if (prop.name.equals(name)) {
265 def getRestrictions(Type type) {
266 var Restrictions restrictions = null
267 if (type instanceof ConcreteType) {
268 restrictions = (type as ConcreteType).restrictions
269 } else if (type instanceof GeneratedTransferObject) {
270 restrictions = (type as GeneratedTransferObject).restrictions
275 def boolean isArrayType(GeneratedTransferObject type) {
277 val GeneratedTransferObject superType = type.findSuperType
278 val GeneratedProperty value = superType.getPropByName("value")
279 if (value != null && value.returnType.name.contains("[")) {
285 def GeneratedTransferObject findSuperType(GeneratedTransferObject gto) {
286 var GeneratedTransferObject base = gto
287 var GeneratedTransferObject superType = base.superType
288 while (superType !== null) {
290 superType = base.superType
295 def String toQuote(Object obj) {
296 return "\"" + obj.toString + "\"";