Generate legacy value contructors for all classes
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / mdsal / binding / java / api / generator / InterfaceTemplate.xtend
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. 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 extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME
11 import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.getGetterMethodForNonnull
12 import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.isGetterMethodName
13 import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.isNonnullMethodName
14
15 import java.util.List
16 import org.gaul.modernizer_maven_annotations.SuppressModernizer
17 import org.opendaylight.mdsal.binding.model.api.AnnotationType
18 import org.opendaylight.mdsal.binding.model.api.Constant
19 import org.opendaylight.mdsal.binding.model.api.Enumeration
20 import org.opendaylight.mdsal.binding.model.api.GeneratedType
21 import org.opendaylight.mdsal.binding.model.api.MethodSignature
22 import org.opendaylight.mdsal.binding.model.api.Type
23 import org.opendaylight.mdsal.binding.model.util.TypeConstants
24 import org.opendaylight.yangtools.yang.binding.CodeHelpers
25
26 /**
27  * Template for generating JAVA interfaces.
28  */
29  @SuppressModernizer
30 class InterfaceTemplate extends BaseTemplate {
31     /**
32      * List of constant instances which are generated as JAVA public static final attributes.
33      */
34     val List<Constant> consts
35
36     /**
37      * List of method signatures which are generated as method declarations.
38      */
39     val List<MethodSignature> methods
40
41     /**
42      * List of enumeration which are generated as JAVA enum type.
43      */
44     val List<Enumeration> enums
45
46     /**
47      * List of generated types which are enclosed inside <code>genType</code>
48      */
49     val List<GeneratedType> enclosedGeneratedTypes
50
51     /**
52      * Creates the instance of this class which is used for generating the interface file source
53      * code from <code>genType</code>.
54      *
55      * @throws NullPointerException if <code>genType</code> is <code>null</code>
56      */
57     new(GeneratedType genType) {
58         super(genType)
59         consts = genType.constantDefinitions
60         methods = genType.methodDefinitions
61         enums = genType.enumerations
62         enclosedGeneratedTypes = genType.enclosedTypes
63     }
64
65     /**
66      * Template method which generate the whole body of the interface.
67      *
68      * @return string with code for interface body in JAVA format
69      */
70     override body() '''
71         «wrapToDocumentation(formatDataForJavaDoc(type))»
72         «type.annotations.generateAnnotations»
73         public interface «type.name»
74             «superInterfaces»
75         {
76
77             «generateInnerClasses»
78
79             «generateEnums»
80
81             «generateConstants»
82
83             «generateMethods»
84
85         }
86
87     '''
88
89
90     def private generateAnnotations(List<AnnotationType> annotations) '''
91         «IF annotations !== null && !annotations.empty»
92             «FOR annotation : annotations»
93                 @«annotation.importedName»
94                 «IF annotation.parameters !== null && !annotation.parameters.empty»
95                 (
96                 «FOR param : annotation.parameters SEPARATOR ","»
97                     «param.name»=«param.value»
98                 «ENDFOR»
99                 )
100                 «ENDIF»
101             «ENDFOR»
102         «ENDIF»
103     '''
104
105     /**
106      * Template method which generates the interface name declaration.
107      *
108      * @return string with the code for the interface declaration in JAVA format
109      */
110     def private superInterfaces()
111     '''
112     «IF (!type.implements.empty)»
113          extends
114          «FOR type : type.implements SEPARATOR ","»
115              «type.importedName»
116          «ENDFOR»
117      « ENDIF»
118      '''
119
120     /**
121      * Template method which generates inner classes inside this interface.
122      *
123      * @return string with the source code for inner classes in JAVA format
124      */
125     def private generateInnerClasses() '''
126         «IF !enclosedGeneratedTypes.empty»
127             «FOR innerClass : enclosedGeneratedTypes SEPARATOR "\n"»
128                 «generateInnerClass(innerClass)»
129             «ENDFOR»
130         «ENDIF»
131     '''
132
133     /**
134      * Template method which generates JAVA enum type.
135      *
136      * @return string with inner enum source code in JAVA format
137      */
138     def private generateEnums() '''
139         «IF !enums.empty»
140             «FOR e : enums SEPARATOR "\n"»
141                 «val enumTemplate = new EnumTemplate(javaType.getEnclosedType(e.identifier), e)»
142                 «enumTemplate.generateAsInnerClass»
143             «ENDFOR»
144         «ENDIF»
145     '''
146
147     /**
148      * Template method wich generates JAVA constants.
149      *
150      * @return string with constants in JAVA format
151      */
152     def private generateConstants() '''
153         «IF !consts.empty»
154             «FOR c : consts»
155                 «IF !c.name.startsWith(TypeConstants.PATTERN_CONSTANT_NAME)»
156                     «emitConstant(c)»
157                 «ENDIF»
158             «ENDFOR»
159         «ENDIF»
160     '''
161
162     /**
163      * Template method which generates the declaration of the methods.
164      *
165      * @return string with the declaration of methods source code in JAVA format
166      */
167     def private generateMethods() '''
168         «IF !methods.empty»
169             «FOR m : methods SEPARATOR "\n"»
170                 «IF m.isDefault»
171                     «generateDefaultMethod(m)»
172                 «ELSEIF m.parameters.empty && m.name.isGetterMethodName»
173                     «generateAccessorMethod(m)»
174                 «ELSE»
175                     «generateMethod(m)»
176                 «ENDIF»
177             «ENDFOR»
178         «ENDIF»
179     '''
180
181     def private generateDefaultMethod(MethodSignature method) {
182         if (method.name.isNonnullMethodName) {
183             generateNonnullMethod(method)
184         } else {
185             switch method.name {
186                 case DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME : generateDefaultImplementedInterface
187             }
188         }
189     }
190
191     def private generateMethod(MethodSignature method) '''
192         «method.comment.asJavadoc»
193         «method.annotations.generateAnnotations»
194         «method.returnType.importedName» «method.name»(«method.parameters.generateParameters»);
195     '''
196
197     def private generateAccessorMethod(MethodSignature method) '''
198         «val ret = method.returnType»
199         «formatDataForJavaDoc(method, "@return " + asCode(ret.fullyQualifiedName) + " " + asCode(propertyNameFromGetter(method)) + ", or " + asCode("null") + " if not present")»
200         «method.annotations.generateAnnotations»
201         «nullableType(ret)» «method.name»();
202     '''
203
204     def private generateDefaultImplementedInterface() '''
205         @«Override.importedName»
206         default «Class.importedName»<«type.fullyQualifiedName»> «DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME»() {
207             return «type.fullyQualifiedName».class;
208         }
209     '''
210
211     def private generateNonnullMethod(MethodSignature method) '''
212         «val ret = method.returnType»
213         «val name = method.name»
214         «formatDataForJavaDoc(method, "@return " + asCode(ret.fullyQualifiedName) + " " + asCode(propertyNameFromGetter(method)) + ", or an empty list if it is not present")»
215         «method.annotations.generateAnnotations»
216         default «ret.importedNonNull» «name»() {
217             return «CodeHelpers.importedName».nonnull(«getGetterMethodForNonnull(name)»());
218         }
219     '''
220
221     def private String nullableType(Type type) {
222         if (type.isObject) {
223             return type.importedNullable
224         }
225         return type.importedName
226     }
227
228     def private static boolean isObject(Type type) {
229         // The return type has a package, so it's not a primitive type
230         return !type.getPackageName().isEmpty()
231     }
232 }