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 {
21 protected val GeneratedType type;
22 protected val Map<String,String> importMap;
23 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»;'''
35 protected def getFullyQualifiedName() {
36 return type.fullyQualifiedName
39 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();
63 final protected def fieldName(GeneratedProperty property) '''_«property.name»'''
66 final protected def propertyNameFromGetter(MethodSignature getter) {
68 if (getter.name.startsWith("is")) {
70 } else if (getter.name.startsWith("get")) {
73 throw new IllegalArgumentException("Not a getter")
75 return getter.name.substring(prefix).toFirstLower;
79 * Template method which generates the getter method for <code>field</code>
82 * generated property with data about field which is generated as the getter method
83 * @return string with the getter method source code in JAVA format
85 final protected def getterMethod(GeneratedProperty field) {
87 public «field.returnType.importedName» «field.getterMethodName»() {
88 return «field.fieldName»;
93 final protected def getterMethodName(GeneratedProperty field) {
94 val prefix = if(field.returnType.equals(Types.BOOLEAN)) "is" else "get"
95 return '''«prefix»«field.name.toFirstUpper»'''
99 * Template method which generates the setter method for <code>field</code>
102 * generated property with data about field which is generated as the setter method
103 * @return string with the setter method source code in JAVA format
105 final protected def setterMethod(GeneratedProperty field) '''
106 «val returnType = field.returnType.importedName»
107 public «type.name» set«field.name.toFirstUpper»(«returnType» value) {
108 this.«field.fieldName» = value;
113 final protected def importedName(Type intype) {
114 GeneratorUtil.putTypeIntoImports(type, intype, importMap);
115 GeneratorUtil.getExplicitType(type, intype, importMap)
118 final protected def importedName(Class<?> cls) {
119 importedName(Types.typeForClass(cls))
123 * Template method which generates method parameters with their types from <code>parameters</code>.
126 * group of generated property instances which are transformed to the method parameters
127 * @return string with the list of the method parameters with their types in JAVA format
129 def final protected asArgumentsDeclaration(Iterable<GeneratedProperty> parameters)
130 '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.returnType.importedName» «parameter.fieldName»«ENDFOR»«ENDIF»'''
133 * Template method which generates sequence of the names of the class attributes from <code>parameters</code>.
136 * group of generated property instances which are transformed to the sequence of parameter names
137 * @return string with the list of the parameter names of the <code>parameters</code>
139 def final protected asArguments(Iterable<GeneratedProperty> parameters)
140 '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.fieldName»«ENDFOR»«ENDIF»'''
144 * Template method which generates JAVA comments.
146 * @param comment string with the comment for whole JAVA class
147 * @return string with comment in JAVA format
149 def protected CharSequence asJavadoc(String comment) {
150 if (comment==null) return '';
151 val paragraphs = paragraphSplitter.split(comment)
155 «FOR p : paragraphs SEPARATOR "<p>"»
162 def generateLengthRestrictions(Type type, String paramName, Type returnType) '''
163 «val boolean isArray = returnType.name.contains("[")»
164 «IF type instanceof ConcreteType»
165 «val restrictions = (type as ConcreteType).restrictions»
166 «IF restrictions !== null && !restrictions.lengthConstraints.empty»
167 «generateLengthRestriction(type, restrictions, paramName, isArray, !(returnType instanceof ConcreteType))»
170 «IF type instanceof GeneratedTransferObject»
171 «val restrictions = (type as GeneratedTransferObject).restrictions»
172 «IF restrictions !== null && !restrictions.lengthConstraints.empty»
173 «generateLengthRestriction(type, restrictions, paramName, isArray, !(returnType instanceof ConcreteType))»
178 def generateLengthRestrictions(GeneratedProperty field, String paramName) '''
179 «val Type type = field.returnType»
180 «IF type instanceof ConcreteType»
181 «val boolean isArray = type.name.contains("[")»
182 «val restrictions = (type as ConcreteType).restrictions»
183 «IF restrictions !== null && !restrictions.lengthConstraints.empty»
184 «generateLengthRestriction(type, restrictions, paramName, isArray, false)»
187 «IF type instanceof GeneratedTransferObject»
188 «var isArray = isArrayType(type as GeneratedTransferObject)»
189 «val restrictions = (type as GeneratedTransferObject).restrictions»
190 «IF restrictions !== null && !restrictions.lengthConstraints.empty»
191 «generateLengthRestriction(type, restrictions, paramName, isArray, true)»
196 def generateLengthRestriction(Type type, Restrictions restrictions, String paramName, boolean isArray, boolean isNestedType) '''
197 if («paramName» != null) {
198 boolean isValidLength = false;
199 «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.importedName»<>();
200 «FOR r : restrictions.lengthConstraints»
201 lengthConstraints.add(«Range.importedName».closed(«r.min», «r.max»));
203 for («Range.importedName»<«Integer.importedName»> r : lengthConstraints) {
206 if (r.contains(«paramName».getValue().length)) {
208 if (r.contains(«paramName».length)) {
212 if (r.contains(«paramName».getValue().length())) {
214 if (r.contains(«paramName».length())) {
217 isValidLength = true;
220 if (!isValidLength) {
221 throw new IllegalArgumentException("illegal length");
226 def GeneratedProperty getPropByName(GeneratedType gt, String name) {
227 for (GeneratedProperty prop : gt.properties) {
228 if (prop.name.equals(name)) {
235 def GeneratedProperty getPropByName(Collection<GeneratedProperty> props, String name) {
236 for (GeneratedProperty prop : props) {
237 if (prop.name.equals(name)) {
244 def boolean isArrayType(GeneratedTransferObject type) {
246 val GeneratedTransferObject superType = type.findSuperType
247 val GeneratedProperty value = superType.getPropByName("value")
248 if (value != null && value.returnType.name.contains("[")) {
254 def GeneratedTransferObject findSuperType(GeneratedTransferObject gto) {
255 var GeneratedTransferObject base = gto
256 var GeneratedTransferObject superType = base.superType
257 while (superType !== null) {
259 superType = base.superType