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