Merge "Added support for annotations in generated APIs."
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-java-api-generator / src / main / java / org / opendaylight / controller / sal / java / api / generator / GeneratorUtil.java
1 /*
2  * Copyright (c) 2013 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.controller.sal.java.api.generator;
9
10 import static org.opendaylight.controller.sal.java.api.generator.Constants.CLASS;
11 import static org.opendaylight.controller.sal.java.api.generator.Constants.COMMA;
12 import static org.opendaylight.controller.sal.java.api.generator.Constants.ENUM;
13 import static org.opendaylight.controller.sal.java.api.generator.Constants.FINAL;
14 import static org.opendaylight.controller.sal.java.api.generator.Constants.GAP;
15 import static org.opendaylight.controller.sal.java.api.generator.Constants.IFC;
16 import static org.opendaylight.controller.sal.java.api.generator.Constants.LB;
17 import static org.opendaylight.controller.sal.java.api.generator.Constants.LCB;
18 import static org.opendaylight.controller.sal.java.api.generator.Constants.NL;
19 import static org.opendaylight.controller.sal.java.api.generator.Constants.PKG;
20 import static org.opendaylight.controller.sal.java.api.generator.Constants.PRIVATE;
21 import static org.opendaylight.controller.sal.java.api.generator.Constants.PUBLIC;
22 import static org.opendaylight.controller.sal.java.api.generator.Constants.RB;
23 import static org.opendaylight.controller.sal.java.api.generator.Constants.RCB;
24 import static org.opendaylight.controller.sal.java.api.generator.Constants.SC;
25 import static org.opendaylight.controller.sal.java.api.generator.Constants.STATIC;
26 import static org.opendaylight.controller.sal.java.api.generator.Constants.TAB;
27
28 import java.util.List;
29
30 import org.opendaylight.controller.sal.binding.model.api.AnnotationType;
31 import org.opendaylight.controller.sal.binding.model.api.Constant;
32 import org.opendaylight.controller.sal.binding.model.api.Enumeration;
33 import org.opendaylight.controller.sal.binding.model.api.Enumeration.Pair;
34 import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
35 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
36 import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
37 import org.opendaylight.controller.sal.binding.model.api.MethodSignature;
38 import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter;
39 import org.opendaylight.controller.sal.binding.model.api.ParameterizedType;
40 import org.opendaylight.controller.sal.binding.model.api.Type;
41
42 public class GeneratorUtil {
43
44     private GeneratorUtil() {
45     }
46
47     public static String createIfcDeclarationWithPkgName(
48             final GeneratedType genType, final String indent) {
49         return createFileDeclarationWithPkgName(IFC, genType, indent);
50     }
51
52     public static String createClassDeclarationWithPkgName(
53             final GeneratedTransferObject genTransferObject, final String indent) {
54         return createFileDeclarationWithPkgName(CLASS, genTransferObject,
55                 indent);
56     }
57
58     private static String createFileDeclarationWithPkgName(final String type,
59             final GeneratedType genType, final String indent) {
60         final StringBuilder builder = new StringBuilder();
61         builder.append(PKG + GAP + genType.getPackageName() + SC);
62         builder.append(NL);
63         builder.append(NL);
64
65         if (!genType.getAnnotations().isEmpty()) {
66             final List<AnnotationType> annotations = genType.getAnnotations();
67             appendAnnotations(builder, annotations);
68             builder.append(NL);
69         }
70         builder.append(PUBLIC + GAP + type + GAP + genType.getName() + GAP
71                 + LCB);
72         return builder.toString();
73     }
74
75     private static StringBuilder appendAnnotations(final StringBuilder builder, final List<AnnotationType> annotations) {
76         if ((builder != null) && (annotations != null)) {
77             for (final AnnotationType annotation : annotations) {
78                 builder.append("@");
79                 builder.append(annotation.getPackageName());
80                 builder.append(".");
81                 builder.append(annotation.getName());
82
83                 if (annotation.containsParameters()) {
84                     builder.append("(");
85                     final List<AnnotationType.Parameter> parameters = annotation
86                             .getParameters();
87                     appendAnnotationParams(builder, parameters);
88                     builder.append(")");
89                 }
90             }
91         }
92         return builder;
93     }
94
95     private static StringBuilder appendAnnotationParams(
96             final StringBuilder builder,
97             final List<AnnotationType.Parameter> parameters) {
98         if (parameters != null) {
99             int i = 0;
100             for (final AnnotationType.Parameter param : parameters) {
101                 if (param == null) {
102                     continue;
103                 }
104                 if (i > 0) {
105                     builder.append(", ");
106                 }
107                 final String paramName = param.getName();
108                 if (param.getValue() != null) {
109                     builder.append(paramName);
110                     builder.append(" = ");
111                     builder.append(param.getValue());
112                 } else {
113                     builder.append(paramName);
114                     builder.append(" = {");
115                     final List<String> values = param.getValues();
116                     builder.append(values.get(0));
117                     for (int j = 1; j < values.size(); ++j) {
118                         builder.append(", ");
119                         builder.append(values.get(j));
120                     }
121                     builder.append("}");
122                 }
123                 i++;
124             }
125         }
126         return builder;
127     }
128
129     public static String createConstant(final Constant constant,
130             final String indent) {
131         final StringBuilder builder = new StringBuilder();
132         builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP);
133         builder.append(getExplicitType(constant.getType()) + GAP
134                 + constant.getName());
135         builder.append(GAP + "=" + GAP);
136         builder.append(constant.getValue() + SC);
137         return builder.toString();
138     }
139
140     public static String createField(final GeneratedProperty property,
141             final String indent) {
142         final StringBuilder builder = new StringBuilder();
143         builder.append(indent);
144         if (!property.getAnnotations().isEmpty()) {
145             final List<AnnotationType> annotations = property.getAnnotations();
146             appendAnnotations(builder, annotations);
147             builder.append(NL);
148         }
149         builder.append(indent + PRIVATE + GAP);
150         builder.append(getExplicitType(property.getReturnType()) + GAP
151                 + property.getName());
152         builder.append(SC);
153         return builder.toString();
154     }
155
156     /**
157      * Create method declaration in interface.
158      * 
159      * @param method
160      * @param indent
161      * @return
162      */
163     public static String createMethodDeclaration(final MethodSignature method,
164             final String indent) {
165         final String comment = method.getComment();
166         final Type type = method.getReturnType();
167         final String name = method.getName();
168         final List<Parameter> parameters = method.getParameters();
169
170         final StringBuilder builder = new StringBuilder();
171         createComment(builder, comment, indent);
172         builder.append(NL);
173         builder.append(indent);
174         
175         if (!method.getAnnotations().isEmpty()) {
176             final List<AnnotationType> annotations = method.getAnnotations();
177             appendAnnotations(builder, annotations);
178             builder.append(NL);
179         }
180         
181         builder.append(indent + getExplicitType(type) + GAP + name);
182         builder.append(LB);
183         for (int i = 0; i < parameters.size(); i++) {
184             Parameter p = parameters.get(i);
185             String separator = COMMA;
186             if (i + 1 == parameters.size()) {
187                 separator = "";
188             }
189             builder.append(getExplicitType(p.getType()) + GAP + p.getName()
190                     + separator);
191         }
192         builder.append(RB);
193         builder.append(SC);
194
195         return builder.toString();
196     }
197
198     public static String createConstructor(
199             GeneratedTransferObject genTransferObject, final String indent) {
200         final StringBuilder builder = new StringBuilder();
201
202         final List<GeneratedProperty> properties = genTransferObject
203                 .getProperties();
204         builder.append(indent);
205         builder.append(PUBLIC);
206         builder.append(GAP);
207         builder.append(genTransferObject.getName());
208         builder.append(LB);
209
210         boolean first = true;
211         if (properties != null) {
212             for (final GeneratedProperty property : properties) {
213                 if (first) {
214                     builder.append(getExplicitType(property.getReturnType()));
215                     builder.append(" ");
216                     builder.append(property.getName());
217                     first = false;
218                 } else {
219                     builder.append(", ");
220                     builder.append(getExplicitType(property.getReturnType()));
221                     builder.append(builder.append(" "));
222                     builder.append(property.getName());
223                 }
224             }
225         }
226
227         builder.append(RB);
228         builder.append(GAP);
229         builder.append(LCB);
230         builder.append(NL);
231         builder.append(indent);
232         builder.append(TAB);
233         builder.append("super();");
234         builder.append(NL);
235
236         if (properties != null) {
237             for (final GeneratedProperty property : properties) {
238                 builder.append(indent);
239                 builder.append(TAB);
240                 builder.append("this.");
241                 builder.append(property.getName());
242                 builder.append(" = ");
243                 builder.append(property.getName());
244                 builder.append(SC);
245                 builder.append(NL);
246             }
247         }
248
249         builder.append(indent);
250         builder.append(RCB);
251
252         return builder.toString();
253     }
254
255     public static String createGetter(final GeneratedProperty property,
256             final String indent) {
257         final StringBuilder builder = new StringBuilder();
258
259         final Type type = property.getReturnType();
260         final String varName = property.getName();
261         final char first = Character.toUpperCase(varName.charAt(0));
262         final String methodName = "get" + first + varName.substring(1);
263
264         builder.append(indent + PUBLIC + GAP + getExplicitType(type) + GAP
265                 + methodName);
266         builder.append(LB + RB + LCB + NL);
267
268         String currentIndent = indent + TAB;
269
270         builder.append(currentIndent + "return " + varName + SC + NL);
271
272         builder.append(indent + RCB);
273         return builder.toString();
274     }
275
276     public static String createHashCode(
277             final List<GeneratedProperty> properties, final String indent) {
278         StringBuilder builder = new StringBuilder();
279         builder.append(indent + "public int hashCode() {" + NL);
280         builder.append(indent + TAB + "final int prime = 31;" + NL);
281         builder.append(indent + TAB + "int result = 1;" + NL);
282
283         for (GeneratedProperty property : properties) {
284             String fieldName = property.getName();
285             builder.append(indent + TAB + "result = prime * result + (("
286                     + fieldName + " == null) ? 0 : " + fieldName
287                     + ".hashCode());" + NL);
288         }
289
290         builder.append(indent + TAB + "return result;" + NL);
291         builder.append(indent + RCB + NL);
292         return builder.toString();
293     }
294
295     public static String createEquals(final GeneratedTransferObject type,
296             final List<GeneratedProperty> properties, final String indent) {
297         StringBuilder builder = new StringBuilder();
298         final String indent1 = indent + TAB;
299         final String indent2 = indent + TAB + TAB;
300         final String indent3 = indent + TAB + TAB + TAB;
301
302         builder.append(indent + "public boolean equals(Object obj) {" + NL);
303         builder.append(indent1 + "if (this == obj) {" + NL);
304         builder.append(indent2 + "return true;" + NL);
305         builder.append(indent1 + "}" + NL);
306         builder.append(indent1 + "if (obj == null) {" + NL);
307         builder.append(indent2 + "return false;" + NL);
308         builder.append(indent1 + "}" + NL);
309         builder.append(indent1 + "if (getClass() != obj.getClass()) {" + NL);
310         builder.append(indent2 + "return false;" + NL);
311         builder.append(indent1 + "}" + NL);
312
313         String typeStr = type.getPackageName() + "." + type.getName();
314         builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;"
315                 + NL);
316
317         for (GeneratedProperty property : properties) {
318             String fieldName = property.getName();
319             builder.append(indent1 + "if (" + fieldName + " == null) {" + NL);
320             builder.append(indent2 + "if (other." + fieldName + " != null) {"
321                     + NL);
322             builder.append(indent3 + "return false;" + NL);
323             builder.append(indent2 + "}" + NL);
324             builder.append(indent1 + "} else if (!" + fieldName
325                     + ".equals(other." + fieldName + ")) {" + NL);
326             builder.append(indent2 + "return false;" + NL);
327             builder.append(indent1 + "}" + NL);
328         }
329
330         builder.append(indent1 + "return true;" + NL);
331
332         builder.append(indent + RCB + NL);
333         return builder.toString();
334     }
335
336     public static String createToString(final GeneratedTransferObject type,
337             final List<GeneratedProperty> properties, final String indent) {
338         StringBuilder builder = new StringBuilder();
339         builder.append(indent);
340         builder.append("public String toString() {");
341         builder.append(NL);
342         builder.append(indent);
343         builder.append(TAB);
344         builder.append("StringBuilder builder = new StringBuilder();");
345         builder.append(NL);
346         builder.append(indent);
347         builder.append(TAB);
348         builder.append("builder.append(\"");
349         builder.append(type.getName());
350         builder.append(" [");
351
352         boolean first = true;
353         for (GeneratedProperty property : properties) {
354             if (first) {
355                 builder.append(property.getName());
356                 builder.append("=\");");
357                 builder.append(NL);
358                 builder.append(indent);
359                 builder.append(TAB);
360                 builder.append("builder.append(");
361                 builder.append(property.getName());
362                 builder.append(");");
363                 first = false;
364             } else {
365                 builder.append(NL);
366                 builder.append(indent);
367                 builder.append(TAB);
368                 builder.append("builder.append(\", ");
369                 builder.append(property.getName());
370                 builder.append("=\");");
371                 builder.append(NL);
372                 builder.append(indent);
373                 builder.append(TAB);
374                 builder.append("builder.append(\", ");
375                 builder.append(property.getName());
376                 builder.append(");");
377             }
378         }
379         builder.append(NL);
380         builder.append(indent);
381         builder.append(TAB);
382         builder.append("builder.append(\"]\");");
383         builder.append(NL);
384         builder.append(indent);
385         builder.append(TAB);
386         builder.append("return builder.toString();");
387
388         builder.append(NL);
389         builder.append(indent);
390         builder.append(RCB);
391         builder.append(NL);
392         return builder.toString();
393     }
394
395     public static String createEnum(final Enumeration enumeration,
396             final String indent) {
397         final StringBuilder builder = new StringBuilder(indent + ENUM + GAP
398                 + enumeration.getName() + GAP + LCB + NL);
399
400         String separator = COMMA;
401         final List<Pair> values = enumeration.getValues();
402         builder.append(indent + TAB);
403         for (int i = 0; i < values.size(); i++) {
404             if (i + 1 == values.size()) {
405                 separator = SC;
406             }
407             builder.append(values.get(i).getName() + separator);
408         }
409         builder.append(NL);
410         builder.append(indent + RCB);
411         return builder.toString();
412     }
413
414     private static String getExplicitType(final Type type) {
415         String packageName = type.getPackageName();
416         if (packageName.endsWith(".")) {
417             packageName = packageName.substring(0, packageName.length() - 1);
418         }
419         final StringBuilder builder = new StringBuilder(packageName + "."
420                 + type.getName());
421         if (type instanceof ParameterizedType) {
422             ParameterizedType pType = (ParameterizedType) type;
423             Type[] pTypes = pType.getActualTypeArguments();
424             builder.append("<");
425             builder.append(getParameters(pTypes));
426             builder.append(">");
427         }
428         if (builder.toString().equals("java.lang.Void")) {
429             return "void";
430         }
431         return builder.toString();
432     }
433
434     private static String getParameters(final Type[] pTypes) {
435         final StringBuilder builder = new StringBuilder();
436         for (int i = 0; i < pTypes.length; i++) {
437             Type t = pTypes[i];
438
439             String separator = COMMA;
440             if (i + 1 == pTypes.length) {
441                 separator = "";
442             }
443             builder.append(getExplicitType(t) + separator);
444         }
445         return builder.toString();
446     }
447
448     private static void createComment(final StringBuilder builder,
449             final String comment, final String indent) {
450         if (comment != null && comment.length() > 0) {
451             builder.append(indent + "/*" + NL);
452             builder.append(indent + comment + NL);
453             builder.append(indent + "*/" + NL);
454         }
455     }
456
457 }