1 package org.opendaylight.yangtools.sal.java.api.generator
3 import java.util.LinkedHashSet
7 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
8 import org.opendaylight.yangtools.binding.generator.util.Types
9 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl
10 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
11 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
12 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
13 import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
14 import org.opendaylight.yangtools.sal.binding.model.api.Type
15 import org.opendaylight.yangtools.yang.binding.Augmentable
17 class BuilderTemplate {
19 val static GET_PREFIX = "get"
20 val static JAVA_UTIL = "java.util"
21 val static HASH_MAP = "HashMap"
22 val static MAP = "Map"
23 val static GET_AUGMENTATION_METHOD_NAME = "getAugmentation"
24 val static BUILDER = 'Builder'
25 val static IMPL = 'Impl'
27 val GeneratedType genType
28 val Map<String, String> imports
29 var GeneratedProperty augmentField
30 val Set<GeneratedProperty> fields
32 new(GeneratedType genType) {
33 if (genType == null) {
34 throw new IllegalArgumentException("Generated type reference cannot be NULL!")
37 this.genType = genType
38 this.imports = GeneratorUtil.createChildImports(genType)
39 this.fields = createFieldsFromMethods(createMethods)
42 def private Set<MethodSignature> createMethods() {
43 val Set<MethodSignature> methods = new LinkedHashSet
44 methods.addAll(genType.methodDefinitions)
45 storeMethodsOfImplementedIfcs(methods, genType.implements)
49 def private void storeMethodsOfImplementedIfcs(Set<MethodSignature> methods, List<Type> implementedIfcs) {
50 if (implementedIfcs == null || implementedIfcs.empty) {
53 for (implementedIfc : implementedIfcs) {
54 if ((implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject))) {
55 val ifc = implementedIfc as GeneratedType
56 methods.addAll(ifc.methodDefinitions)
57 storeMethodsOfImplementedIfcs(methods, ifc.implements)
58 } else if (implementedIfc.fullyQualifiedName == Augmentable.name) {
59 for (m : Augmentable.methods) {
60 if (m.name == GET_AUGMENTATION_METHOD_NAME) {
61 addToImports(JAVA_UTIL, HASH_MAP)
62 addToImports(JAVA_UTIL, MAP)
63 val fullyQualifiedName = m.returnType.name
64 val pkg = fullyQualifiedName.package
65 val name = fullyQualifiedName.name
66 addToImports(pkg, name)
67 val tmpGenTO = new GeneratedTOBuilderImpl(pkg, name)
68 val type = new ReferencedTypeImpl(pkg, name)
69 val generic = new ReferencedTypeImpl(genType.packageName, genType.name)
70 val parametrizedReturnType = Types.parameterizedTypeFor(type, generic)
71 tmpGenTO.addMethod(m.name).setReturnType(parametrizedReturnType)
72 augmentField = tmpGenTO.toInstance.methodDefinitions.first.createFieldFromGetter
79 def private void addToImports(String typePackageName,String typeName) {
80 if (typePackageName.startsWith("java.lang") || typePackageName.isEmpty()) {
83 if (!imports.containsKey(typeName)) {
84 imports.put(typeName, typePackageName)
88 def private <E> first(List<E> elements) {
92 def private String getPackage(String fullyQualifiedName) {
93 val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT)
94 return if (lastDotIndex == -1) "" else fullyQualifiedName.substring(0, lastDotIndex)
97 def private String getName(String fullyQualifiedName) {
98 val lastDotIndex = fullyQualifiedName.lastIndexOf(Constants.DOT)
99 return if (lastDotIndex == -1) fullyQualifiedName else fullyQualifiedName.substring(lastDotIndex + 1)
102 def private createFieldsFromMethods(Set<MethodSignature> methods) {
103 val Set<GeneratedProperty> result = new LinkedHashSet
105 if (methods == null || methods.isEmpty()) {
110 val createdField = m.createFieldFromGetter
111 if (createdField != null) {
112 result.add(createdField)
118 def private GeneratedProperty createFieldFromGetter(MethodSignature method) {
119 if (method == null || method.name == null || method.name.empty || method.returnType == null) {
120 throw new IllegalArgumentException("Method, method name, method return type reference cannot be NULL or empty!")
122 if (method.name.startsWith(GET_PREFIX)) {
123 val fieldName = method.getName().substring(GET_PREFIX.length()).toFirstLower
124 val tmpGenTO = new GeneratedTOBuilderImpl("foo", "foo")
125 tmpGenTO.addProperty(fieldName).setReturnType(method.returnType)
126 return tmpGenTO.toInstance.properties.first
131 val body = generateBody
132 val pkgAndImports = generatePkgAndImports
133 return pkgAndImports.toString + body.toString
136 def private generateBody() '''
137 public class «genType.name»«BUILDER» {
143 public «genType.name» build() {
144 return new «genType.name»«IMPL»();
147 private class «genType.name»«IMPL» implements «genType.name» {
151 «generateConstructor»
160 def private generateFields() '''
163 private «f.returnType.resolveName» «f.name»;
166 «IF augmentField != null»
167 private Map<Class<? extends «augmentField.returnType.resolveName»>, «augmentField.returnType.resolveName»> «augmentField.name» = new HashMap<>();
171 def private generateSetters() '''
172 «FOR field : fields SEPARATOR '\n'»
173 public «genType.name»«BUILDER» set«field.name.toFirstUpper»(«field.returnType.resolveName» «field.name») {
174 this.«field.name» = «field.name»;
178 «IF augmentField != null»
180 public «genType.name»«BUILDER» add«augmentField.name.toFirstUpper»(Class<? extends «augmentField.returnType.resolveName»> augmentationType, «augmentField.returnType.resolveName» augmentation) {
181 this.«augmentField.name».put(augmentationType, augmentation);
187 def private generateConstructor() '''
188 private «genType.name»«IMPL»() {
191 this.«field.name» = «genType.name»«BUILDER».this.«field.name»;
194 «IF augmentField != null»
195 this.«augmentField.name».putAll(«genType.name»«BUILDER».this.«augmentField.name»);
200 def private generateGetters() '''
202 «FOR field : fields SEPARATOR '\n'»
204 public «field.returnType.resolveName» get«field.name.toFirstUpper»() {
209 «IF augmentField != null»
211 @SuppressWarnings("unchecked")
213 public <E extends «augmentField.returnType.resolveName»> E get«augmentField.name.toFirstUpper»(Class<E> augmentationType) {
214 if (augmentationType == null) {
215 throw new IllegalArgumentException("Augmentation Type reference cannot be NULL!");
217 return (E) «augmentField.name».get(augmentationType);
222 def private generatePkgAndImports() '''
223 package «genType.packageName»;
227 «FOR entry : imports.entrySet»
228 import «entry.value».«entry.key»;
234 def private resolveName(Type type) {
235 GeneratorUtil.putTypeIntoImports(genType, type, imports);
236 GeneratorUtil.getExplicitType(genType, type, imports)