6b954361439f9967456a68ebab6387c33f487794
[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 java.util.List
11 import org.opendaylight.mdsal.binding.model.api.AnnotationType
12 import org.opendaylight.mdsal.binding.model.api.Constant
13 import org.opendaylight.mdsal.binding.model.api.Enumeration
14 import org.opendaylight.mdsal.binding.model.api.GeneratedType
15 import org.opendaylight.mdsal.binding.model.api.JavaTypeName
16 import org.opendaylight.mdsal.binding.model.api.MethodSignature
17 import org.opendaylight.mdsal.binding.model.api.Type
18 import org.opendaylight.mdsal.binding.model.util.TypeConstants
19
20 /**
21  * Template for generating JAVA interfaces.
22  */
23 class InterfaceTemplate extends BaseTemplate {
24     static val JavaTypeName NULLABLE = JavaTypeName.create("org.eclipse.jdt.annotation", "Nullable")
25
26     /**
27      * List of constant instances which are generated as JAVA public static final attributes.
28      */
29     val List<Constant> consts
30
31     /**
32      * List of method signatures which are generated as method declarations.
33      */
34     val List<MethodSignature> methods
35
36     /**
37      * List of enumeration which are generated as JAVA enum type.
38      */
39     val List<Enumeration> enums
40
41     /**
42      * List of generated types which are enclosed inside <code>genType</code>
43      */
44     val List<GeneratedType> enclosedGeneratedTypes
45
46     /**
47      * Creates the instance of this class which is used for generating the interface file source
48      * code from <code>genType</code>.
49      *
50      * @throws IllegalArgumentException if <code>genType</code> equals <code>null</code>
51      */
52     new(GeneratedType genType) {
53         super(genType)
54         if (genType === null) {
55             throw new IllegalArgumentException("Generated type reference cannot be NULL!")
56         }
57
58         consts = genType.constantDefinitions
59         methods = genType.methodDefinitions
60         enums = genType.enumerations
61         enclosedGeneratedTypes = genType.enclosedTypes
62     }
63
64     /**
65      * Template method which generate the whole body of the interface.
66      *
67      * @return string with code for interface body in JAVA format
68      */
69     override body() '''
70         «wrapToDocumentation(formatDataForJavaDoc(type))»
71         «type.annotations.generateAnnotations»
72         public interface «type.name»
73             «superInterfaces»
74         {
75
76             «generateInnerClasses»
77
78             «generateEnums»
79
80             «generateConstants»
81
82             «generateMethods»
83
84         }
85
86     '''
87
88
89     def private generateAnnotations(List<AnnotationType> annotations) '''
90         «IF annotations !== null && !annotations.empty»
91             «FOR annotation : annotations»
92                 @«annotation.importedName»
93                 «IF annotation.parameters !== null && !annotation.parameters.empty»
94                 (
95                 «FOR param : annotation.parameters SEPARATOR ","»
96                     «param.name»=«param.value»
97                 «ENDFOR»
98                 )
99                 «ENDIF»
100             «ENDFOR»
101         «ENDIF»
102     '''
103
104     /**
105      * Template method which generates the interface name declaration.
106      *
107      * @return string with the code for the interface declaration in JAVA format
108      */
109     def private superInterfaces()
110     '''
111     «IF (!type.implements.empty)»
112          extends
113          «FOR type : type.implements SEPARATOR ","»
114              «type.importedName»
115          «ENDFOR»
116      « ENDIF»
117      '''
118
119     /**
120      * Template method which generates inner classes inside this interface.
121      *
122      * @return string with the source code for inner classes in JAVA format
123      */
124     def private generateInnerClasses() '''
125         «IF !enclosedGeneratedTypes.empty»
126             «FOR innerClass : enclosedGeneratedTypes SEPARATOR "\n"»
127                 «generateInnerClass(innerClass)»
128             «ENDFOR»
129         «ENDIF»
130     '''
131
132     /**
133      * Template method which generates JAVA enum type.
134      *
135      * @return string with inner enum source code in JAVA format
136      */
137     def private generateEnums() '''
138         «IF !enums.empty»
139             «FOR e : enums SEPARATOR "\n"»
140                 «val enumTemplate = new EnumTemplate(javaType.getEnclosedType(e.identifier), e)»
141                 «enumTemplate.generateAsInnerClass»
142             «ENDFOR»
143         «ENDIF»
144     '''
145
146     /**
147      * Template method wich generates JAVA constants.
148      *
149      * @return string with constants in JAVA format
150      */
151     def private generateConstants() '''
152         «IF !consts.empty»
153             «FOR c : consts»
154                 «IF !c.name.startsWith(TypeConstants.PATTERN_CONSTANT_NAME)»
155                     «emitConstant(c)»
156                 «ENDIF»
157             «ENDFOR»
158         «ENDIF»
159     '''
160
161     /**
162      * Template method which generates the declaration of the methods.
163      *
164      * @return string with the declaration of methods source code in JAVA format
165      */
166     def private generateMethods() '''
167         «IF !methods.empty»
168             «FOR m : methods SEPARATOR "\n"»
169                 «val accessor = m.isAccessor»
170                 «val ret = m.returnType»
171                 «IF accessor»
172                     «formatDataForJavaDoc(m, "@return " + asCode(ret.fullyQualifiedName) + " "
173                     + asCode(propertyNameFromGetter(m)) + ", or " + asCode("null") + " if not present")»
174                 «ELSE»
175                     «m.comment.asJavadoc»
176                 «ENDIF»
177                 «m.annotations.generateAnnotations»
178                 «nullableType(ret, accessor)» «m.name»(«m.parameters.generateParameters»);
179             «ENDFOR»
180         «ENDIF»
181     '''
182
183     def private String nullableType(Type type, boolean accessor) {
184         if (accessor && type.isObject) {
185             return importedName(type, NULLABLE.importedName)
186         }
187         return type.importedName
188     }
189
190     def private static boolean isObject(Type type) {
191         // The return type has a package, so it's not a primitive type
192         return !type.getPackageName().isEmpty()
193     }
194 }