870be6c1cc5f8038619f7c63249460abb4a4ed56
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / mdsal / binding / java / api / generator / AbstractBuilderTemplate.xtend
1 /*
2  * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.java.api.generator
9
10 import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTATION_FIELD
11
12 import com.google.common.base.MoreObjects
13 import java.util.ArrayList
14 import java.util.Collection
15 import java.util.Collections
16 import java.util.Comparator
17 import java.util.List
18 import java.util.Map
19 import java.util.Set
20 import org.opendaylight.mdsal.binding.model.api.AnnotationType
21 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty
22 import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject
23 import org.opendaylight.mdsal.binding.model.api.GeneratedType
24 import org.opendaylight.mdsal.binding.model.api.Type
25 import org.opendaylight.mdsal.binding.model.util.Types
26 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping
27 import org.opendaylight.yangtools.yang.binding.CodeHelpers
28 import org.opendaylight.yangtools.yang.binding.Identifiable
29
30 abstract class AbstractBuilderTemplate extends BaseTemplate {
31     static val Comparator<GeneratedProperty> KEY_PROPS_COMPARATOR = [ p1, p2 | return p1.name.compareTo(p2.name) ]
32
33     /**
34      * Generated property is set if among methods is found one with the name GET_AUGMENTATION_METHOD_NAME.
35      */
36     protected val Type augmentType
37
38     /**
39      * Set of class attributes (fields) which are derived from the getter methods names.
40      */
41     protected val Set<GeneratedProperty> properties
42
43     /**
44      * GeneratedType for key type, null if this type does not have a key.
45      */
46     protected val Type keyType
47
48     protected val GeneratedType targetType;
49
50     new(AbstractJavaGeneratedType javaType, GeneratedType type, GeneratedType targetType,
51             Set<GeneratedProperty> properties, Type augmentType, Type keyType) {
52         super(javaType, type)
53         this.targetType = targetType
54         this.properties = properties
55         this.augmentType = augmentType
56         this.keyType = keyType
57     }
58
59     new(GeneratedType type, GeneratedType targetType, Set<GeneratedProperty> properties, Type augmentType,
60             Type keyType) {
61         super(type)
62         this.targetType = targetType
63         this.properties = properties
64         this.augmentType = augmentType
65         this.keyType = keyType
66     }
67
68     /**
69      * Template method which generates class attributes.
70      *
71      * @param makeFinal value which specify whether field is|isn't final
72      * @return string with class attributes and their types
73      */
74     def protected final generateFields(boolean makeFinal) '''
75         «IF properties !== null»
76             «FOR f : properties»
77                 private«IF makeFinal» final«ENDIF» «f.returnType.importedName» «f.fieldName»;
78             «ENDFOR»
79         «ENDIF»
80         «IF keyType !== null»
81             private«IF makeFinal» final«ENDIF» «keyType.importedName» key;
82         «ENDIF»
83     '''
84
85     def protected final generateAugmentField() {
86         val augmentTypeRef = augmentType.importedName
87         return '''
88            «Map.importedName»<«Class.importedName»<? extends «augmentTypeRef»>, «augmentTypeRef»> «AUGMENTATION_FIELD» = «Collections.importedName».emptyMap();
89         '''
90     }
91
92     override generateToString(Collection<GeneratedProperty> properties) '''
93         «IF properties !== null»
94             @«OVERRIDE.importedName»
95             public «String.importedName» toString() {
96                 final «MoreObjects.importedName».ToStringHelper helper = «MoreObjects.importedName».toStringHelper("«targetType.name»");
97                 «FOR property : properties»
98                     «CodeHelpers.importedName».appendValue(helper, "«property.fieldName»", «property.fieldName»);
99                 «ENDFOR»
100                 «IF augmentType !== null»
101                     «CodeHelpers.importedName».appendValue(helper, "«AUGMENTATION_FIELD»", augmentations().values());
102                 «ENDIF»
103                 return helper.toString();
104             }
105         «ENDIF»
106     '''
107
108     /**
109      * Template method which generate getter methods for IMPL class.
110      *
111      * @return string with getter methods
112      */
113     def final generateGetters(boolean addOverride) '''
114         «IF keyType !== null»
115             «IF addOverride»@«OVERRIDE.importedName»«ENDIF»
116             public «keyType.importedName» «BindingMapping.IDENTIFIABLE_KEY_NAME»() {
117                 return key;
118             }
119
120         «ENDIF»
121         «IF !properties.empty»
122             «FOR field : properties SEPARATOR '\n'»
123                 «IF addOverride»@«OVERRIDE.importedName»«ENDIF»
124                 «field.getterMethod»
125             «ENDFOR»
126         «ENDIF»
127     '''
128
129     def protected final CharSequence generateCopyConstructor(Type fromType, Type implType) '''
130         «type.name»(«fromType.importedName» base) {
131             «IF augmentType !== null»
132                 «generateCopyAugmentation(implType)»
133             «ENDIF»
134             «val allProps = new ArrayList(properties)»
135             «val isList = implementsIfc(targetType, Types.parameterizedTypeFor(Types.typeForClass(Identifiable), targetType))»
136             «IF isList && keyType !== null»
137                 «val keyProps = new ArrayList((keyType as GeneratedTransferObject).properties)»
138                 «keyProps.sort(KEY_PROPS_COMPARATOR)»
139                 «FOR field : keyProps»
140                     «removeProperty(allProps, field.name)»
141                 «ENDFOR»
142                 «generateCopyKeys(keyProps)»
143             «ENDIF»
144             «FOR field : allProps»
145                 this.«field.fieldName» = base.«field.getterMethodName»();
146             «ENDFOR»
147         }
148     '''
149
150     def protected final CharSequence generateDeprecatedAnnotation(List<AnnotationType> annotations) {
151         var AnnotationType found = annotations.findDeprecatedAnnotation
152         if (found === null) {
153             return ""
154         }
155         return generateDeprecatedAnnotation(found)
156     }
157
158     def protected abstract CharSequence generateCopyKeys(List<GeneratedProperty> keyProps)
159
160     def protected abstract CharSequence generateCopyAugmentation(Type implType)
161
162     def protected abstract CharSequence generateDeprecatedAnnotation(AnnotationType ann)
163
164     private def boolean implementsIfc(GeneratedType type, Type impl) {
165         for (Type ifc : type.implements) {
166             if (ifc.equals(impl)) {
167                 return true;
168             }
169         }
170         return false;
171     }
172
173     private def void removeProperty(Collection<GeneratedProperty> props, String name) {
174         var GeneratedProperty toRemove = null
175         for (p : props) {
176             if (p.name.equals(name)) {
177                 toRemove = p;
178             }
179         }
180         if (toRemove !== null) {
181             props.remove(toRemove);
182         }
183     }
184
185     private static def findDeprecatedAnnotation(List<AnnotationType> annotations) {
186         if (annotations !== null) {
187             for (annotation : annotations) {
188                 if (DEPRECATED.equals(annotation.identifier)) {
189                     return annotation
190                 }
191             }
192         }
193         return null
194     }
195 }