-package org.opendaylight.yangtools.sal.java.api.generator
-
-import java.util.LinkedHashSet
-import java.util.List
-import java.util.Map
-import java.util.Set
-import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
-import org.opendaylight.yangtools.binding.generator.util.Types
-import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
-import org.opendaylight.yangtools.sal.binding.model.api.Type
-import org.opendaylight.yangtools.yang.binding.Augmentable
-
-class BuilderTemplate {
-
- val static GET_PREFIX = "get"
- val static JAVA_UTIL = "java.util"
- val static HASH_MAP = "HashMap"
- val static MAP = "Map"
- val static GET_AUGMENTATION_METHOD_NAME = "getAugmentation"
- val static BUILDER = 'Builder'
- val static IMPL = 'Impl'
-
- val GeneratedType genType
- val Map<String, String> imports
- var GeneratedProperty augmentField
- val Set<GeneratedProperty> fields
-
- new(GeneratedType genType) {
- if (genType == null) {
- throw new IllegalArgumentException("Generated type reference cannot be NULL!")
- }
-
- this.genType = genType
- this.imports = GeneratorUtil.createChildImports(genType)
- this.fields = createFieldsFromMethods(createMethods)
- }
-
- def private Set<MethodSignature> createMethods() {
- val Set<MethodSignature> methods = new LinkedHashSet
- methods.addAll(genType.methodDefinitions)
- storeMethodsOfImplementedIfcs(methods, genType.implements)
- return methods
- }
-
- def private void storeMethodsOfImplementedIfcs(Set<MethodSignature> methods, List<Type> implementedIfcs) {
- if (implementedIfcs == null || implementedIfcs.empty) {
- return
- }
- for (implementedIfc : implementedIfcs) {
- if ((implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject))) {
- val ifc = implementedIfc as GeneratedType
- methods.addAll(ifc.methodDefinitions)
- storeMethodsOfImplementedIfcs(methods, ifc.implements)
- } else if (implementedIfc.fullyQualifiedName == Augmentable.name) {
- for (m : Augmentable.methods) {
- if (m.name == GET_AUGMENTATION_METHOD_NAME) {
- addToImports(JAVA_UTIL, HASH_MAP)
- addToImports(JAVA_UTIL, MAP)
- val fullyQualifiedName = m.returnType.name
- val pkg = fullyQualifiedName.package
- val name = fullyQualifiedName.name
- addToImports(pkg, name)
- val tmpGenTO = new GeneratedTOBuilderImpl(pkg, name)
- val type = new ReferencedTypeImpl(pkg, name)
- val generic = new ReferencedTypeImpl(genType.packageName, genType.name)
- val parametrizedReturnType = Types.parameterizedTypeFor(type, generic)
- tmpGenTO.addMethod(m.name).setReturnType(parametrizedReturnType)
- augmentField = tmpGenTO.toInstance.methodDefinitions.first.createFieldFromGetter
- }
- }
- }
- }
- }
-
- def private void addToImports(String typePackageName,String typeName) {
- if (typePackageName.startsWith("java.lang") || typePackageName.isEmpty()) {
- return
- }
- if (!imports.containsKey(typeName)) {
- imports.put(typeName, typePackageName)
- }
- }
-
- def private <E> first(List<E> elements) {
- elements.get(0)
- }
-
- def private String getPackage(String fullyQualifiedName) {
- val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT)
- return if (lastDotIndex == -1) "" else fullyQualifiedName.substring(0, lastDotIndex)
- }
-
- def private String getName(String fullyQualifiedName) {
- val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT)
- return if (lastDotIndex == -1) fullyQualifiedName else fullyQualifiedName.substring(lastDotIndex + 1)
- }
-
- def private createFieldsFromMethods(Set<MethodSignature> methods) {
- val Set<GeneratedProperty> result = new LinkedHashSet
-
- if (methods == null || methods.isEmpty()) {
- return result
- }
-
- for (m : methods) {
- val createdField = m.createFieldFromGetter
- if (createdField != null) {
- result.add(createdField)
- }
- }
- return result
- }
-
- def private GeneratedProperty createFieldFromGetter(MethodSignature method) {
- if (method == null || method.name == null || method.name.empty || method.returnType == null) {
- throw new IllegalArgumentException("Method, method name, method return type reference cannot be NULL or empty!")
- }
- if (method.name.startsWith(GET_PREFIX)) {
- val fieldName = method.getName().substring(GET_PREFIX.length()).toFirstLower
- val tmpGenTO = new GeneratedTOBuilderImpl("foo", "foo")
- tmpGenTO.addProperty(fieldName).setReturnType(method.returnType)
- return tmpGenTO.toInstance.properties.first
- }
- }
-
- def generate() {
- val body = generateBody
- val pkgAndImports = generatePkgAndImports
- return pkgAndImports.toString + body.toString
- }
-
- def private generateBody() '''
- public class «genType.name»«BUILDER» {
-
- «generateFields»
-
- «generateSetters»
-
- public «genType.name» build() {
- return new «genType.name»«IMPL»();
- }
-
- private class «genType.name»«IMPL» implements «genType.name» {
-
- «generateFields»
-
- «generateConstructor»
-
- «generateGetters»
-
- }
-
- }
- '''
-
- def private generateFields() '''
- «IF !fields.empty»
- «FOR f : fields»
- private «f.returnType.resolveName» «f.name»;
- «ENDFOR»
- «ENDIF»
- «IF augmentField != null»
- private Map<Class<? extends «augmentField.returnType.resolveName»>, «augmentField.returnType.resolveName»> «augmentField.name» = new HashMap<>();
- «ENDIF»
- '''
-
- def private generateSetters() '''
- «FOR field : fields SEPARATOR '\n'»
- public «genType.name»«BUILDER» set«field.name.toFirstUpper»(«field.returnType.resolveName» «field.name») {
- this.«field.name» = «field.name»;
- return this;
- }
- «ENDFOR»
- «IF augmentField != null»
-
- public «genType.name»«BUILDER» add«augmentField.name.toFirstUpper»(Class<? extends «augmentField.returnType.resolveName»> augmentationType, «augmentField.returnType.resolveName» augmentation) {
- this.«augmentField.name».put(augmentationType, augmentation);
- return this;
- }
- «ENDIF»
- '''
-
- def private generateConstructor() '''
- private «genType.name»«IMPL»() {
- «IF !fields.empty»
- «FOR field : fields»
- this.«field.name» = «genType.name»«BUILDER».this.«field.name»;
- «ENDFOR»
- «ENDIF»
- «IF augmentField != null»
- this.«augmentField.name».putAll(«genType.name»«BUILDER».this.«augmentField.name»);
- «ENDIF»
- }
- '''
-
- def private generateGetters() '''
- «IF !fields.empty»
- «FOR field : fields SEPARATOR '\n'»
- @Override
- public «field.returnType.resolveName» get«field.name.toFirstUpper»() {
- return «field.name»;
- }
- «ENDFOR»
- «ENDIF»
- «IF augmentField != null»
-
- @SuppressWarnings("unchecked")
- @Override
- public <E extends «augmentField.returnType.resolveName»> E get«augmentField.name.toFirstUpper»(Class<E> augmentationType) {
- if (augmentationType == null) {
- throw new IllegalArgumentException("Augmentation Type reference cannot be NULL!");
- }
- return (E) «augmentField.name».get(augmentationType);
- }
- «ENDIF»
- '''
-
- def private generatePkgAndImports() '''
- package «genType.packageName»;
-
-
- «IF !imports.empty»
- «FOR entry : imports.entrySet»
- import «entry.value».«entry.key»;
- «ENDFOR»
- «ENDIF»
-
- '''
-
- def private resolveName(Type type) {
- GeneratorUtil.putTypeIntoImports(genType, type, imports);
- GeneratorUtil.getExplicitType(genType, type, imports)
- }
-
-}
+package org.opendaylight.yangtools.sal.java.api.generator\r
+\r
+import java.util.Arrays;\r
+import java.util.LinkedHashSet\r
+import java.util.List\r
+import java.util.Map\r
+import java.util.Set\r
+import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl\r
+import org.opendaylight.yangtools.binding.generator.util.Types\r
+import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl\r
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty\r
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject\r
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType\r
+import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature\r
+import org.opendaylight.yangtools.sal.binding.model.api.Type\r
+import org.opendaylight.yangtools.yang.binding.Augmentable\r
+import static org.opendaylight.yangtools.binding.generator.util.Types.*\r
+import java.util.HashMap\r
+import java.util.Collections\rimport org.opendaylight.yangtools.yang.binding.DataObject
+import java.util.ArrayList
+import java.util.HashSet
+import java.util.Collection
+import org.opendaylight.yangtools.yang.binding.Identifiable
+/**\r
+ * Template for generating JAVA builder classes. \r
+ */\r
+\r
+class BuilderTemplate extends BaseTemplate {\r
+\r
+ /**\r
+ * Constant with the name of the concrete method.\r
+ */\r
+ val static GET_AUGMENTATION_METHOD_NAME = "getAugmentation"\r
+\r
+ /**\r
+ * Constant with the suffix for builder classes.\r
+ */\r
+ val static BUILDER = 'Builder'\r
+\r
+ /**\r
+ * Constant with suffix for the classes which are generated from the builder classes.\r
+ */\r
+ val static IMPL = 'Impl'\r
+\r
+ /**\r
+ * Generated property is set if among methods is found one with the name GET_AUGMENTATION_METHOD_NAME\r
+ */\r
+ var GeneratedProperty augmentField\r
+\r
+ /**\r
+ * Set of class attributes (fields) which are derived from the getter methods names\r
+ */\r
+ val Set<GeneratedProperty> properties\r
+\r
+ /**\r
+ * Constructs new instance of this class.\r
+ * @throws IllegalArgumentException if <code>genType</code> equals <code>null</code>\r
+ */\r
+ new(GeneratedType genType) {\r
+ super(genType)\r
+ this.properties = propertiesFromMethods(createMethods)\r
+ }\r
+\r
+ /**\r
+ * Returns set of method signature instances which contains all the methods of the <code>genType</code>\r
+ * and all the methods of the implemented interfaces.\r
+ * \r
+ * @returns set of method signature instances\r
+ */\r
+ def private Set<MethodSignature> createMethods() {\r
+ val Set<MethodSignature> methods = new LinkedHashSet\r
+ methods.addAll(type.methodDefinitions)\r
+ collectImplementedMethods(methods, type.implements)\r
+ return methods\r
+ }\r
+\r
+ /**\r
+ * Adds to the <code>methods</code> set all the methods of the <code>implementedIfcs</code> \r
+ * and recursivelly their implemented interfaces.\r
+ * \r
+ * @param methods set of method signatures\r
+ * @param implementedIfcs list of implemented interfaces\r
+ */\r
+ def private void collectImplementedMethods(Set<MethodSignature> methods, List<Type> implementedIfcs) {\r
+ if (implementedIfcs == null || implementedIfcs.empty) {\r
+ return\r
+ }\r
+ for (implementedIfc : implementedIfcs) {\r
+ if ((implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject))) {\r
+ val ifc = implementedIfc as GeneratedType\r
+ methods.addAll(ifc.methodDefinitions)\r
+ collectImplementedMethods(methods, ifc.implements)\r
+ } else if (implementedIfc.fullyQualifiedName == Augmentable.name) {\r
+ for (m : Augmentable.methods) {\r
+ if (m.name == GET_AUGMENTATION_METHOD_NAME) {\r
+ val fullyQualifiedName = m.returnType.name\r
+ val pkg = fullyQualifiedName.package\r
+ val name = fullyQualifiedName.name\r
+ val tmpGenTO = new GeneratedTOBuilderImpl(pkg, name)\r
+ val refType = new ReferencedTypeImpl(pkg, name)\r
+ val generic = new ReferencedTypeImpl(type.packageName, type.name)\r
+ val parametrizedReturnType = Types.parameterizedTypeFor(refType, generic)\r
+ tmpGenTO.addMethod(m.name).setReturnType(parametrizedReturnType)\r
+ augmentField = tmpGenTO.toInstance.methodDefinitions.first.propertyFromGetter\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Returns the first element of the list <code>elements</code>.\r
+ * \r
+ * @param list of elements\r
+ */\r
+ def private <E> first(List<E> elements) {\r
+ elements.get(0)\r
+ }\r
+\r
+ /**\r
+ * Returns the name of the package from <code>fullyQualifiedName</code>.\r
+ * \r
+ * @param fullyQualifiedName string with fully qualified type name (package + type)\r
+ * @return string with the package name\r
+ */\r
+ def private String getPackage(String fullyQualifiedName) {\r
+ val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT)\r
+ return if (lastDotIndex == -1) "" else fullyQualifiedName.substring(0, lastDotIndex)\r
+ }\r
+\r
+ /**\r
+ * Returns the name of tye type from <code>fullyQualifiedName</code>\r
+ * \r
+ * @param fullyQualifiedName string with fully qualified type name (package + type)\r
+ * @return string with the name of the type\r
+ */\r
+ def private String getName(String fullyQualifiedName) {\r
+ val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT)\r
+ return if (lastDotIndex == -1) fullyQualifiedName else fullyQualifiedName.substring(lastDotIndex + 1)\r
+ }\r
+\r
+ /**\r
+ * Creates set of generated property instances from getter <code>methods</code>.\r
+ * \r
+ * @param set of method signature instances which should be transformed to list of properties \r
+ * @return set of generated property instances which represents the getter <code>methods</code>\r
+ */\r
+ def private propertiesFromMethods(Set<MethodSignature> methods) {\r
+ if (methods == null || methods.isEmpty()) {\r
+ return Collections.emptySet\r
+ }\r
+ val Set<GeneratedProperty> result = new LinkedHashSet\r
+ for (m : methods) {\r
+ val createdField = m.propertyFromGetter\r
+ if (createdField != null) {\r
+ result.add(createdField)\r
+ }\r
+ }\r
+ return result\r
+ }\r
+\r
+ /**\r
+ * Creates generated property instance from the getter <code>method</code> name and return type.\r
+ * \r
+ * @param method method signature from which is the method name and return type obtained\r
+ * @return generated property instance for the getter <code>method</code>\r
+ * @throws IllegalArgumentException<ul>\r
+ * <li>if the <code>method</code> equals <code>null</code></li>\r
+ * <li>if the name of the <code>method</code> equals <code>null</code></li>\r
+ * <li>if the name of the <code>method</code> is empty</li>\r
+ * <li>if the return type of the <code>method</code> equals <code>null</code></li>\r
+ * </ul>\r
+ */\r
+ def private GeneratedProperty propertyFromGetter(MethodSignature method) {\r
+ if (method == null || method.name == null || method.name.empty || method.returnType == null) {\r
+ throw new IllegalArgumentException("Method, method name, method return type reference cannot be NULL or empty!")\r
+ }\r
+ var prefix = "get";\r
+ if(BOOLEAN.equals(method.returnType)) {\r
+ prefix = "is";\r
+ } \r
+ if (method.name.startsWith(prefix)) {\r
+ val fieldName = method.getName().substring(prefix.length()).toFirstLower\r
+ val tmpGenTO = new GeneratedTOBuilderImpl("foo", "foo")\r
+ tmpGenTO.addProperty(fieldName).setReturnType(method.returnType)\r
+ return tmpGenTO.toInstance.properties.first\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Template method which generates JAVA class body for builder class and for IMPL class. \r
+ * \r
+ * @return string with JAVA source code\r
+ */\r
+ override body() '''\r
+\r
+ public class «type.name»«BUILDER» {\r
+\r
+ «generateFields(false)»\r
+\r
+ «generateConstructorsFromIfcs(type)»\r
+\r
+ «generateMethodFieldsFrom(type)»\r
+\r
+ «generateGetters(false)»\r
+\r
+ «generateSetters»\r
+\r
+ public «type.name» build() {\r
+ return new «type.name»«IMPL»(this);\r
+ }\r
+\r
+ private static final class «type.name»«IMPL» implements «type.name» {\r
+\r
+ «implementedInterfaceGetter»\r
+\r
+ «generateFields(true)»\r
+\r
+ «generateConstructor»\r
+\r
+ «generateGetters(true)»\r
+\r
+ «generateHashCode()»\r
+\r
+ «generateEquals()»\r
+ }\r
+\r
+ }\r
+ '''\r
+\r
+ /**\r
+ * Generate default constructor and constructor for every implemented interface from uses statements.\r
+ */\r
+ def private generateConstructorsFromIfcs(Type type) '''\r
+ public «type.name»«BUILDER»() {\r
+ } \r
+ «IF (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject))»\r
+ «val ifc = type as GeneratedType»\r
+ «FOR impl : ifc.implements»\r
+ «generateConstructorFromIfc(impl)»\r
+ «ENDFOR»\r
+ «ENDIF»\r
+ '''\r
+\r
+ /**\r
+ * Generate constructor with argument of given type.\r
+ */\r
+ def private generateConstructorFromIfc(Type impl) '''\r
+ «IF (impl instanceof GeneratedType) && !((impl as GeneratedType).methodDefinitions.empty)»\r
+ «val implType = impl as GeneratedType»\r
+\r
+ public «type.name»«BUILDER»(«implType.fullyQualifiedName» arg) {\r
+ «printConstructorPropertySetter(implType)»\r
+ }\r
+ «FOR implTypeImplement : implType.implements»\r
+ «generateConstructorFromIfc(implTypeImplement)»\r
+ «ENDFOR»\r
+ «ENDIF»\r
+ '''\r
+\r
+ def private printConstructorPropertySetter(Type implementedIfc) '''\r
+ «IF (implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject))»\r
+ «val ifc = implementedIfc as GeneratedType»\r
+ «FOR getter : ifc.methodDefinitions»\r
+ this._«getter.propertyNameFromGetter» = arg.«getter.name»();\r
+ «ENDFOR»\r
+ «FOR impl : ifc.implements»\r
+ «printConstructorPropertySetter(impl)»\r
+ «ENDFOR»\r
+ «ENDIF»\r
+ '''\r
+\r
+ /**\r
+ * Generate 'fieldsFrom' method to set builder properties based on type of given argument.\r
+ */\r
+ def private generateMethodFieldsFrom(Type type) '''\r
+ «IF (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject))»\r
+ «val ifc = type as GeneratedType»\r
+ «IF ifc.hasImplementsFromUses»\r
+ «val List<Type> done = ifc.getBaseIfcs»\r
+ «generateMethodFieldsFromComment(ifc)»\r
+ public void fieldsFrom(«DataObject.importedName» arg) {\r
+ boolean isValidArg = false;\r
+ «FOR impl : ifc.getAllIfcs»\r
+ «generateIfCheck(impl, done)»\r
+ «ENDFOR»\r
+ if (!isValidArg) {\r
+ throw new IllegalArgumentException(\r
+ "expected one of: «ifc.getAllIfcs.toListOfNames» \n" +\r
+ "but was: " + arg\r
+ );\r
+ }\r
+ }\r
+ «ENDIF»\r
+ «ENDIF»\r
+ '''\r
+\r
+ def private generateMethodFieldsFromComment(GeneratedType type) '''\r
+ /**\r
+ Set fields from given grouping argument. Valid argument is instance of one of following types:\r
+ * <ul>\r
+ «FOR impl : type.getAllIfcs»\r
+ * <li>«impl.fullyQualifiedName»</li>\r
+ «ENDFOR»\r
+ * </ul>\r
+ *\r
+ * @param arg grouping object\r
+ * @throws IllegalArgumentException if given argument is none of valid types\r
+ */\r
+ '''\r
+\r
+ /**\r
+ * Method is used to find out if given type implements any interface from uses.\r
+ */\r
+ def boolean hasImplementsFromUses(GeneratedType type) {\r
+ var i = 0\r
+ for (impl : type.getAllIfcs) {\r
+ if ((impl instanceof GeneratedType) && !((impl as GeneratedType).methodDefinitions.empty)) {\r
+ i = i + 1\r
+ }\r
+ }\r
+ return i > 0\r
+ }\r
+\r
+ def private generateIfCheck(Type impl, List<Type> done) '''\r
+ «IF (impl instanceof GeneratedType) && !((impl as GeneratedType).methodDefinitions.empty)»\r
+ «val implType = impl as GeneratedType»\r
+ if (arg instanceof «implType.fullyQualifiedName») {\r
+ «printPropertySetter(implType)»\r
+ isValidArg = true;\r
+ }\r
+ «ENDIF»\r
+ '''\r
+\r
+ def private printPropertySetter(Type implementedIfc) '''\r
+ «IF (implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject))»\r
+ «val ifc = implementedIfc as GeneratedType»\r
+ «FOR getter : ifc.methodDefinitions»\r
+ this._«getter.propertyNameFromGetter» = ((«implementedIfc.fullyQualifiedName»)arg).«getter.name»();\r
+ «ENDFOR»\r
+ «ENDIF»\r
+ '''\r
+\r
+ private def List<Type> getBaseIfcs(GeneratedType type) {\r
+ val List<Type> baseIfcs = new ArrayList();\r
+ for (ifc : type.implements) {\r
+ if (ifc instanceof GeneratedType && !(ifc as GeneratedType).methodDefinitions.empty) {\r
+ baseIfcs.add(ifc)\r
+ }\r
+ }\r
+ return baseIfcs \r
+ }\r
+\r
+ private def Set<Type> getAllIfcs(Type type) {\r
+ val Set<Type> baseIfcs = new HashSet()\r
+ if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) {\r
+ val ifc = type as GeneratedType\r
+ for (impl : ifc.implements) {\r
+ if (impl instanceof GeneratedType && !(impl as GeneratedType).methodDefinitions.empty) {\r
+ baseIfcs.add(impl)\r
+ }\r
+ baseIfcs.addAll(impl.getAllIfcs)\r
+ }\r
+ }\r
+ return baseIfcs \r
+ }\r
+\r
+ private def List<String> toListOfNames(Collection<Type> types) {\r
+ val List<String> names = new ArrayList\r
+ for (type : types) {\r
+ names.add(type.fullyQualifiedName)\r
+ }\r
+ return names\r
+ }\r
+\r
+ /**\r
+ * Template method which generates class attributes.\r
+ * \r
+ * @param boolean value which specify whether field is|isn't final\r
+ * @return string with class attributes and their types\r
+ */\r
+ def private generateFields(boolean _final) '''\r
+ «IF !properties.empty»\r
+ «FOR f : properties»\r
+ private«IF _final» final«ENDIF» «f.returnType.importedName» «f.fieldName»;\r
+ «ENDFOR»\r
+ «ENDIF»\r
+ «IF augmentField != null»\r
+ private «Map.importedName»<Class<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»> «augmentField.name» = new «HashMap.importedName»<>();\r
+ «ENDIF»\r
+ '''\r
+\r
+ /**\r
+ * Template method which generates setter methods\r
+ * \r
+ * @return string with the setter methods \r
+ */\r
+ def private generateSetters() '''\r
+ «FOR field : properties SEPARATOR '\n'»\r
+ public «type.name»«BUILDER» set«field.name.toFirstUpper»(«field.returnType.importedName» value) {\r
+ «generateRestrictions(field, "value")»\r
+\r
+ this.«field.fieldName» = value;\r
+ return this;\r
+ }\r
+ «ENDFOR»\r
+ «IF augmentField != null»\r
+\r
+ public «type.name»«BUILDER» add«augmentField.name.toFirstUpper»(Class<? extends «augmentField.returnType.importedName»> augmentationType, «augmentField.returnType.importedName» augmentation) {\r
+ this.«augmentField.name».put(augmentationType, augmentation);\r
+ return this;\r
+ }\r
+ «ENDIF»\r
+ '''\r
+\r
+ /**\r
+ * Template method which generate constructor for IMPL class.\r
+ * \r
+ * @return string with IMPL class constructor\r
+ */\r
+ def private generateConstructor() '''\r
+ private «type.name»«IMPL»(«type.name»«BUILDER» builder) {\r
+ «val allProps = new ArrayList(properties)»\r
+ «val isList = implementsIfc(type, Types.parameterizedTypeFor(Types.typeForClass(Identifiable), type))»\r
+ «val keyType = type.getKey»\r
+ «IF isList && keyType != null»\r
+ «val keyProps = new ArrayList((keyType as GeneratedTransferObject).properties)»\r
+ «Collections.sort(keyProps,\r
+ [ p1, p2 |\r
+ return p1.name.compareTo(p2.name)\r
+ ])\r
+ »\r
+ «FOR field : keyProps»\r
+ «removeProperty(allProps, field.name)»\r
+ «ENDFOR»\r
+ «removeProperty(allProps, "key")»\r
+ if (builder.getKey() == null) {\r
+ this._key = new «keyType.importedName»(\r
+ «FOR keyProp : keyProps SEPARATOR ", "»\r
+ builder.«keyProp.getterMethodName»()\r
+ «ENDFOR»\r
+ );\r
+ «FOR field : keyProps»\r
+ this.«field.fieldName» = builder.«field.getterMethodName»();\r
+ «ENDFOR»\r
+ } else {\r
+ this._key = builder.getKey();\r
+ «FOR field : keyProps»\r
+ this.«field.fieldName» = _key.«field.getterMethodName»();\r
+ «ENDFOR»\r
+ }\r
+ «ENDIF»\r
+ «FOR field : allProps»\r
+ this.«field.fieldName» = builder.«field.getterMethodName»();\r
+ «ENDFOR»\r
+ «IF augmentField != null»\r
+ this.«augmentField.name».putAll(builder.«augmentField.name»);\r
+ «ENDIF»\r
+ }\r
+ '''\r
+\r
+ private def boolean implementsIfc(GeneratedType type, Type impl) {\r
+ for (Type ifc : type.implements) {\r
+ if (ifc.equals(impl)) {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ private def Type getKey(GeneratedType type) {\r
+ for (m : type.methodDefinitions) {\r
+ if ("getKey".equals(m.name)) {\r
+ return m.returnType;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ private def void removeProperty(Collection<GeneratedProperty> props, String name) {\r
+ var GeneratedProperty toRemove = null\r
+ for (p : props) {\r
+ if (p.name.equals(name)) {\r
+ toRemove = p;\r
+ }\r
+ }\r
+ if (toRemove != null) {\r
+ props.remove(toRemove);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Template method which generate getter methods for IMPL class.\r
+ * \r
+ * @return string with getter methods\r
+ */\r
+ def private generateGetters(boolean addOverride) '''\r
+ «IF !properties.empty»\r
+ «FOR field : properties SEPARATOR '\n'»\r
+ «IF addOverride»@Override«ENDIF»\r
+ «field.getterMethod»\r
+ «ENDFOR»\r
+ «ENDIF»\r
+ «IF augmentField != null»\r
+\r
+ @SuppressWarnings("unchecked")\r
+ «IF addOverride»@Override«ENDIF»\r
+ public <E extends «augmentField.returnType.importedName»> E get«augmentField.name.toFirstUpper»(Class<E> augmentationType) {\r
+ if (augmentationType == null) {\r
+ throw new IllegalArgumentException("Augmentation Type reference cannot be NULL!");\r
+ }\r
+ return (E) «augmentField.name».get(augmentationType);\r
+ }\r
+ «ENDIF»\r
+ '''\r
+\r
+ /**\r
+ * Template method which generates the method <code>hashCode()</code>.\r
+ * \r
+ * @return string with the <code>hashCode()</code> method definition in JAVA format\r
+ */\r
+ def protected generateHashCode() '''\r
+ «IF !properties.empty || augmentField != null»\r
+ @Override\r
+ public int hashCode() {\r
+ final int prime = 31;\r
+ int result = 1;\r
+ «FOR property : properties»\r
+ «IF property.returnType.name.contains("[")»\r
+ result = prime * result + ((«property.fieldName» == null) ? 0 : «Arrays.importedName».hashCode(«property.fieldName»));\r
+ «ELSE»\r
+ result = prime * result + ((«property.fieldName» == null) ? 0 : «property.fieldName».hashCode());\r
+ «ENDIF»\r
+ «ENDFOR»\r
+ «IF augmentField != null»\r
+ result = prime * result + ((«augmentField.name» == null) ? 0 : «augmentField.name».hashCode());\r
+ «ENDIF»\r
+ return result;\r
+ }\r
+ «ENDIF»\r
+ '''\r
+\r
+ /**\r
+ * Template method which generates the method <code>equals()</code>.\r
+ * \r
+ * @return string with the <code>equals()</code> method definition in JAVA format \r
+ */\r
+ def protected generateEquals() '''\r
+ «IF !properties.empty || augmentField != null»\r
+ @Override\r
+ public boolean equals(java.lang.Object obj) {\r
+ if (this == obj) {\r
+ return true;\r
+ }\r
+ if (obj == null) {\r
+ return false;\r
+ }\r
+ if (getClass() != obj.getClass()) {\r
+ return false;\r
+ }\r
+ «type.name»«IMPL» other = («type.name»«IMPL») obj;\r
+ «FOR property : properties»\r
+ «val fieldName = property.fieldName»\r
+ if («fieldName» == null) {\r
+ if (other.«fieldName» != null) {\r
+ return false;\r
+ }\r
+ «IF property.returnType.name.contains("[")»\r
+ } else if(!«Arrays.importedName».equals(«fieldName», other.«fieldName»)) {\r
+ «ELSE»\r
+ } else if(!«fieldName».equals(other.«fieldName»)) {\r
+ «ENDIF»\r
+ return false;\r
+ }\r
+ «ENDFOR»\r
+ «IF augmentField != null»\r
+ «val fieldName = augmentField.name»\r
+ if («fieldName» == null) {\r
+ if (other.«fieldName» != null) {\r
+ return false;\r
+ }\r
+ } else if(!«fieldName».equals(other.«fieldName»)) {\r
+ return false;\r
+ }\r
+ «ENDIF»\r
+ return true;\r
+ }\r
+ «ENDIF»\r
+ '''\r
+\r
+ override protected getFullyQualifiedName() {\r
+ '''«type.fullyQualifiedName»Builder'''.toString\r
+ }\r
+ \r
+ def implementedInterfaceGetter() '''\r
+ public «Class.importedName»<«type.importedName»> getImplementedInterface() {\r
+ return «type.importedName».class;\r
+ }\r
+ '''\r
+\r
+}\r
+\r