Updated code generation
[yangtools.git] / code-generator / binding-java-api-generator / src / main / java / org / opendaylight / yangtools / sal / java / api / generator / BuilderTemplate.xtend
index 5f842a29ffe1ae661dec30eb4a381b125c994c6e..1aef46dd202220d29764f6b1311127e3d2349a8c 100644 (file)
-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
-
-/**
- * Template for generating JAVA builder classes. 
- */
-class BuilderTemplate {
-
-       /**
-        * Constant with prefix for getter methods.
-        */
-    val static GET_PREFIX = "get"
-    
-    /**
-     * Constant with the name of the concrete package prefix. 
-     */
-    val static JAVA_UTIL = "java.util"
-    
-    /**
-     * Constant with the name of the concrete JAVA type
-     */
-    val static HASH_MAP = "HashMap"
-    
-    /**
-     * Constant with the name of the concrete JAVA interface.
-     */
-    val static MAP = "Map"
-    
-    /**
-     * Constant with the name of the concrete method.
-     */
-    val static GET_AUGMENTATION_METHOD_NAME = "getAugmentation"
-    
-    /**
-     * Constant with the suffix for builder classes.
-     */
-    val static BUILDER = 'Builder'
-    
-    /**
-     * Constant with suffix for the classes which are generated from the builder classes.
-     */
-    val static IMPL = 'Impl'
-    
-    /**
-     * Reference to type for which is generated builder class
-     */
-    val GeneratedType genType
-    
-    /**
-     * Map of imports. The keys are type names and the values are package names.
-     */
-    val Map<String, String> imports
-    
-    /**
-     * Generated property is set if among methods is found one with the name GET_AUGMENTATION_METHOD_NAME
-     */
-    var GeneratedProperty augmentField
-    
-    /**
-     * Set of class attributes (fields) which are derived from the getter methods names
-     */
-    val Set<GeneratedProperty> fields
-    
-    /**
-     * Constructs new instance of this class.
-     * @throws IllegalArgumentException if <code>genType</code> equals <code>null</code>
-     */
-    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)
-    }
-    
-    /**
-     * Returns set of method signature instances which contains all the methods of the <code>genType</code>
-     * and all the methods of the implemented interfaces.
-     * 
-     * @returns set of method signature instances
-     */
-    def private Set<MethodSignature> createMethods() {
-        val Set<MethodSignature> methods = new LinkedHashSet
-        methods.addAll(genType.methodDefinitions)
-        storeMethodsOfImplementedIfcs(methods, genType.implements)
-        return methods
-    }
-    
-    /**
-     * Adds to the <code>methods</code> set all the methods of the <code>implementedIfcs</code> 
-     * and recursivelly their implemented interfaces.
-     * 
-     * @param methods set of method signatures
-     * @param implementedIfcs list of implemented interfaces
-     */
-    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
-                    }
-                }
-            }
-        }
-    }
-    
-    /**
-     * Adds to the <code>imports</code> map the package <code>typePackageName</code>.
-     * 
-     * @param typePackageName 
-     * string with the name of the package which is added to <code>imports</code> as a value
-     * @param typeName 
-     * string with the name of the package which is added to <code>imports</code> as a key
-     */
-    def private void addToImports(String typePackageName,String typeName) {
-        if (typePackageName.startsWith("java.lang") || typePackageName.isEmpty()) {
-            return
-        }
-        if (!imports.containsKey(typeName)) {
-            imports.put(typeName, typePackageName)
-        }
-    }
-    
-    /**
-     * Returns the first element of the list <code>elements</code>.
-     * 
-     * @param list of elements
-     */
-    def private <E> first(List<E> elements) {
-        elements.get(0)
-    }
-    
-    /**
-     * Returns the name of the package from <code>fullyQualifiedName</code>.
-     * 
-     * @param fullyQualifiedName string with fully qualified type name (package + type)
-     * @return string with the package name
-     */
-    def private String getPackage(String fullyQualifiedName) {
-        val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT)
-        return if (lastDotIndex == -1) "" else fullyQualifiedName.substring(0, lastDotIndex)
-    }
-
-       /**
-        * Returns the name of tye type from <code>fullyQualifiedName</code>
-        * 
-        * @param fullyQualifiedName string with fully qualified type name (package + type)
-        * @return string with the name of the type
-        */
-    def private String getName(String fullyQualifiedName) {
-        val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT)
-        return if (lastDotIndex == -1) fullyQualifiedName else fullyQualifiedName.substring(lastDotIndex + 1)
-    }
-    
-    /**
-     * Creates set of generated property instances from getter <code>methods</code>.
-     * 
-     * @param set of method signature instances which should be transformed to list of properties 
-     * @return set of generated property instances which represents the getter <code>methods</code>
-     */
-    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
-    }
-    
-    /**
-     * Creates generated property instance from the getter <code>method</code> name and return type.
-     * 
-     * @param method method signature from which is the method name and return type obtained
-     * @return generated property instance for the getter <code>method</code>
-     * @throws IllegalArgumentException<ul>
-     *         <li>if the <code>method</code> equals <code>null</code></li>
-     *         <li>if the name of the <code>method</code> equals <code>null</code></li>
-     *         <li>if the name of the <code>method</code> is empty</li>
-     *         <li>if the return type of the <code>method</code> equals <code>null</code></li>
-     * </ul>
-     */
-    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
-        }
-    }
-
-       /**
-        * Builds string which contains JAVA source code.
-        * 
-        * @return string with JAVA source code
-        */
-    def String generate() {
-        val body = generateBody
-        val pkgAndImports = generatePkgAndImports
-        return pkgAndImports.toString + body.toString
-    }
-    
-    /**
-     * Template method which generates JAVA class body for builder class and for IMPL class. 
-     * 
-     * @return string with JAVA source code
-     */
-    def private generateBody() '''
-        public class «genType.name»«BUILDER» {
-        
-            «generateFields(false)»
-
-            «generateSetters»
-
-            public «genType.name» build() {
-                return new «genType.name»«IMPL»();
-            }
-
-            private class «genType.name»«IMPL» implements «genType.name» {
-
-                «generateFields(true)»
-
-                «generateConstructor»
-
-                «generateGetters»
-
-            }
-
-        }
-    '''
-
-       /**
-        * Template method which generates class attributes.
-        * 
-        * @param boolean value which specify whether field is|isn't final
-        * @return string with class attributes and their types
-        */
-    def private generateFields(boolean _final) '''
-        «IF !fields.empty»
-            «FOR f : fields»
-                private  «IF _final»final«ENDIF»  «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»
-    '''
-
-       /**
-        * Template method which generates setter methods
-        * 
-        * @return string with the setter methods 
-        */
-    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»
-    '''
-    
-    /**
-     * Template method which generate constructor for IMPL class.
-     * 
-     * @return string with IMPL class constructor
-     */
-    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»
-        }
-    '''
-    
-    /**
-     * Template method which generate getter methods for IMPL class.
-     * 
-     * @return string with getter methods
-     */
-    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»
-    '''    
-    
-    /**
-     * Template method which generate package name line and import lines.
-     * 
-     * @result string with package and import lines in JAVA format
-     */
-    def private generatePkgAndImports() '''
-        package «genType.packageName»;
-        
-        
-        «IF !imports.empty»
-            «FOR entry : imports.entrySet»
-                import «entry.value».«entry.key»;
-            «ENDFOR»
-        «ENDIF»
-        
-    '''
-    
-    /**
-     * Adds package to imports if it is necessary and returns necessary type name (with or without package name)
-     * 
-     * @param type JAVA <code>Type</code>
-     * @return string with the type name (with or without package name)
-     */
-    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.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\r
+\r
+/**\r
+ * Template for generating JAVA builder classes. \r
+ */\r
+\r
+class BuilderTemplate extends BaseTemplate {\r
+       /**\r
+        * Constant with prefix for getter methods.\r
+        */\r
+    val static GET_PREFIX = "get"\r
+\r
+    \r
+    /**\r
+     * Constant with the name of the concrete package prefix. \r
+     */\r
+    val static JAVA_UTIL = "java.util"\r
+    \r
+    /**\r
+     * Constant with the name of the concrete JAVA type\r
+     */\r
+    val static HASH_MAP = "HashMap"\r
+    \r
+    /**\r
+     * Constant with the name of the concrete JAVA interface.\r
+     */\r
+    val static MAP = "Map"\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
+    /**\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
+                        //addToImports(JAVA_UTIL, HASH_MAP)\r
+                        //addToImports(JAVA_UTIL, MAP)\r
+                        val fullyQualifiedName = m.returnType.name\r
+                        val pkg = fullyQualifiedName.package\r
+                        val name = fullyQualifiedName.name\r
+                        //addToImports(pkg, 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
+    /**\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
+    /**\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
+        \r
+\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
+\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
+            «generateGetters(false)»\r
+            \r
+            «generateSetters»\r
+            \r
+\r
+            public «type.name» build() {\r
+                return new «type.name»«IMPL»(this);\r
+            }\r
+\r
+            private static class «type.name»«IMPL» implements «type.name» {\r
+\r
+                «generateFields(true)»\r
+\r
+                «generateConstructor»\r
+\r
+                «generateGetters(true)»\r
+\r
+            }\r
+\r
+        }\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
+                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
+            «IF !properties.empty»\r
+                «FOR field : properties»\r
+                    this.«field.fieldName» = builder.«field.fieldName»;\r
+                «ENDFOR»\r
+            «ENDIF»\r
+            «IF augmentField != null»\r
+                this.«augmentField.name».putAll(builder.«augmentField.name»);\r
+            «ENDIF»\r
+        }\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