When a node is going down, remove edges in both directions associated with the node.
[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.*;
11
12 import java.util.ArrayList;
13 import java.util.Iterator;
14 import java.util.LinkedHashMap;
15 import java.util.List;
16 import java.util.Map;
17
18 import org.opendaylight.controller.binding.generator.util.TypeConstants;
19 import org.opendaylight.controller.sal.binding.model.api.*;
20 import org.opendaylight.controller.sal.binding.model.api.Enumeration.Pair;
21 import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter;
22 import org.opendaylight.controller.binding.generator.util.Types;
23
24 public final class GeneratorUtil {
25
26     private GeneratorUtil() {
27     }
28
29     public static String createIfcDeclaration(final GeneratedType genType, final String indent,
30             final Map<String, String> availableImports) {
31         return createFileDeclaration(IFC, genType, indent, availableImports, false, false);
32     }
33
34     public static String createClassDeclaration(final GeneratedTransferObject genTransferObject, final String indent,
35             final Map<String, String> availableImports, boolean isIdentity, boolean isInnerClass) {
36         return createFileDeclaration(CLASS, genTransferObject, indent, availableImports, isIdentity, isInnerClass);
37     }
38
39     public static String createPackageDeclaration(final String packageName) {
40         return PKG + GAP + packageName + SC;
41     }
42
43     private static String createFileDeclaration(final String type, final GeneratedType genType, final String indent,
44             final Map<String, String> availableImports, boolean isIdentity, boolean innerClass) {
45         final StringBuilder builder = new StringBuilder();
46         final String currentPkg = genType.getPackageName();
47
48         createComment(builder, genType.getComment(), indent);
49
50         if (!genType.getAnnotations().isEmpty()) {
51             final List<AnnotationType> annotations = genType.getAnnotations();
52             appendAnnotations(builder, annotations);
53             builder.append(NL);
54         }
55
56         if (innerClass) {
57             builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP + type + GAP + genType.getName() + GAP);
58         } else if (isIdentity) {
59             if (!(CLASS.equals(type))) {
60                 throw new IllegalArgumentException("'identity' has to be generated as a class");
61             }
62             builder.append(indent + PUBLIC + GAP + ABSTRACT + GAP + type + GAP + genType.getName() + GAP);
63         } else {
64             builder.append(indent + PUBLIC + GAP + type + GAP + genType.getName() + GAP);
65         }
66
67         if (genType instanceof GeneratedTransferObject) {
68             GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
69
70             if (genTO.getExtends() != null) {
71                 builder.append(EXTENDS + GAP);
72                 String gtoString = getExplicitType(genTO.getExtends(), availableImports, currentPkg);
73                 builder.append(gtoString + GAP);
74             }
75         }
76
77         final List<Type> genImplements = genType.getImplements();
78         if (!genImplements.isEmpty()) {
79             if (genType instanceof GeneratedTransferObject) {
80                 builder.append(IMPLEMENTS + GAP);
81             } else {
82                 builder.append(EXTENDS + GAP);
83             }
84             builder.append(getExplicitType(genImplements.get(0), availableImports, currentPkg));
85
86             for (int i = 1; i < genImplements.size(); ++i) {
87                 builder.append(", ");
88                 builder.append(getExplicitType(genImplements.get(i), availableImports, currentPkg));
89             }
90         }
91         builder.append(GAP + LCB);
92         return builder.toString();
93     }
94
95     private static StringBuilder appendAnnotations(final StringBuilder builder, final List<AnnotationType> annotations) {
96         if ((builder != null) && (annotations != null)) {
97             for (final AnnotationType annotation : annotations) {
98                 builder.append("@");
99                 builder.append(annotation.getPackageName());
100                 builder.append(".");
101                 builder.append(annotation.getName());
102
103                 if (annotation.containsParameters()) {
104                     builder.append("(");
105                     final List<AnnotationType.Parameter> parameters = annotation.getParameters();
106                     appendAnnotationParams(builder, parameters);
107                     builder.append(")");
108                 }
109             }
110         }
111         return builder;
112     }
113
114     private static StringBuilder appendAnnotationParams(final StringBuilder builder,
115             final List<AnnotationType.Parameter> parameters) {
116         if (parameters != null) {
117             int i = 0;
118             for (final AnnotationType.Parameter param : parameters) {
119                 if (param == null) {
120                     continue;
121                 }
122                 if (i > 0) {
123                     builder.append(", ");
124                 }
125                 final String paramName = param.getName();
126                 if (param.getValue() != null) {
127                     builder.append(paramName);
128                     builder.append(" = ");
129                     builder.append(param.getValue());
130                 } else {
131                     builder.append(paramName);
132                     builder.append(" = {");
133                     final List<String> values = param.getValues();
134                     builder.append(values.get(0));
135                     for (int j = 1; j < values.size(); ++j) {
136                         builder.append(", ");
137                         builder.append(values.get(j));
138                     }
139                     builder.append("}");
140                 }
141                 i++;
142             }
143         }
144         return builder;
145     }
146
147     public static String createConstant(final Constant constant, final String indent,
148             final Map<String, String> availableImports, final String currentPkg) {
149         final StringBuilder builder = new StringBuilder();
150         if (constant == null)
151             throw new IllegalArgumentException();
152         builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP);
153         builder.append(getExplicitType(constant.getType(), availableImports, currentPkg) + GAP + constant.getName());
154         builder.append(GAP + "=" + GAP);
155
156         if (constant.getName().equals(TypeConstants.PATTERN_CONSTANT_NAME)) {
157             return "";
158         } else {
159             builder.append(constant.getValue());
160         }
161         builder.append(SC);
162
163         return builder.toString();
164     }
165
166     public static String createField(final GeneratedProperty property, final String indent,
167             final Map<String, String> availableImports, final String currentPkg) {
168         final StringBuilder builder = new StringBuilder();
169         if (!property.getAnnotations().isEmpty()) {
170             final List<AnnotationType> annotations = property.getAnnotations();
171             appendAnnotations(builder, annotations);
172             builder.append(NL);
173         }
174         builder.append(indent + PRIVATE + GAP);
175         builder.append(getExplicitType(property.getReturnType(), availableImports, currentPkg) + GAP
176                 + property.getName());
177         builder.append(SC);
178         return builder.toString();
179     }
180
181     /**
182      * Create method declaration in interface.
183      * 
184      * @param method
185      * @param indent
186      * @return
187      */
188     public static String createMethodDeclaration(final MethodSignature method, final String indent,
189             Map<String, String> availableImports, final String currentPkg) {
190         final StringBuilder builder = new StringBuilder();
191
192         if (method == null) {
193             throw new IllegalArgumentException("Method Signature parameter MUST be specified and cannot be NULL!");
194         }
195
196         final String comment = method.getComment();
197         final String name = method.getName();
198         if (name == null) {
199             throw new IllegalStateException("Method Name cannot be NULL!");
200         }
201
202         final Type type = method.getReturnType();
203         if (type == null) {
204             throw new IllegalStateException("Method Return type cannot be NULL!");
205         }
206
207         final List<Parameter> parameters = method.getParameters();
208
209         createComment(builder, comment, indent);
210         builder.append(NL);
211
212         if (!method.getAnnotations().isEmpty()) {
213             builder.append(indent);
214             final List<AnnotationType> annotations = method.getAnnotations();
215             appendAnnotations(builder, annotations);
216             builder.append(NL);
217         }
218
219         builder.append(indent + getExplicitType(type, availableImports, currentPkg) + GAP + name);
220         builder.append(LB);
221         for (int i = 0; i < parameters.size(); i++) {
222             Parameter p = parameters.get(i);
223             String separator = COMMA;
224             if (i + 1 == parameters.size()) {
225                 separator = "";
226             }
227             builder.append(getExplicitType(p.getType(), availableImports, currentPkg) + GAP + p.getName() + separator);
228         }
229         builder.append(RB);
230         builder.append(SC);
231
232         return builder.toString();
233     }
234
235     public static String createConstructor(GeneratedTransferObject genTransferObject, final String indent,
236             final Map<String, String> availableImports, boolean isIdentity) {
237         StringBuilder builder = new StringBuilder();
238
239         final String currentPkg = genTransferObject.getPackageName();
240         final List<GeneratedProperty> properties = genTransferObject.getProperties();
241         final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
242         if (properties != null) {
243             for (final GeneratedProperty property : properties) {
244                 if (property.isReadOnly()) {
245                     ctorParams.add(property);
246                 }
247             }
248         }
249
250         builder.append(createConstructorDeclarationToLeftParenthesis(genTransferObject, indent, isIdentity));
251
252         final String parameterSeparator = COMMA + GAP;
253         for (final GeneratedProperty ctorParam : ctorParams) {
254             builder.append(createMethodParamDeclaration(ctorParam, availableImports, currentPkg));
255             builder.append(parameterSeparator);
256         }
257         if (!ctorParams.isEmpty()) {
258             builder = builder.delete(builder.length() - parameterSeparator.length(), builder.length());
259         }
260         builder.append(createConstructorDeclarationFromRightParenthesis());
261         builder.append(createConstructorSuperCalling(indent));
262
263         for (final GeneratedProperty ctorParam : ctorParams) {
264             builder.append(createClassAttributeInitialization(indent, ctorParam));
265         }
266
267         builder.append(createConstructorClosingPart(indent));
268         return builder.toString();
269     }
270
271     public static String createConstructors(GeneratedTransferObject genTransferObject, final String indent,
272             final Map<String, String> availableImports, boolean isIdentity) {
273         final StringBuilder builder = new StringBuilder();
274
275         final String currentPkg = genTransferObject.getPackageName();
276         final List<GeneratedProperty> properties = genTransferObject.getProperties();
277         final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
278         if (properties != null) {
279             for (final GeneratedProperty property : properties) {
280                 if (property.isReadOnly()) {
281                     ctorParams.add(property);
282                 }
283             }
284         }
285
286         GeneratedProperty ctorParam;
287         Iterator<GeneratedProperty> iteratorCtorParams = ctorParams.iterator();
288
289         do {
290             ctorParam = null;
291             if (iteratorCtorParams.hasNext()) {
292                 ctorParam = iteratorCtorParams.next();
293             }
294             builder.append(createConstructorDeclarationToLeftParenthesis(genTransferObject, indent, isIdentity));
295
296             if (ctorParam != null) {
297                 builder.append(createMethodParamDeclaration(ctorParam, availableImports, currentPkg));
298             }
299             builder.append(createConstructorDeclarationFromRightParenthesis());
300             builder.append(createConstructorSuperCalling(indent));
301
302             if (ctorParam != null) {
303                 builder.append(createClassAttributeInitialization(indent, ctorParam));
304             }
305
306             builder.append(createConstructorClosingPart(indent));
307         } while (iteratorCtorParams.hasNext());
308
309         return builder.toString();
310     }
311
312     private static String createConstructorDeclarationToLeftParenthesis(GeneratedTransferObject genTransferObject,
313             final String indent, boolean isIdentity) {
314         final StringBuilder builder = new StringBuilder();
315         builder.append(indent);
316         builder.append(isIdentity ? PROTECTED : PUBLIC);
317         builder.append(GAP);
318         builder.append(genTransferObject.getName());
319         builder.append(LB);
320         return builder.toString();
321     }
322
323     private static String createConstructorDeclarationFromRightParenthesis() {
324         final StringBuilder builder = new StringBuilder();
325         builder.append(RB + GAP + LCB + NL);
326         return builder.toString();
327     }
328
329     private static String createConstructorSuperCalling(String indent) {
330         final StringBuilder builder = new StringBuilder();
331         builder.append(indent + TAB + "super();" + NL);
332         return builder.toString();
333     }
334
335     private static String createConstructorClosingPart(String indent) {
336         final StringBuilder builder = new StringBuilder();
337         builder.append(indent);
338         builder.append(RCB);
339         builder.append(NL + NL);
340         return builder.toString();
341     }
342
343     private static String createClassAttributeInitialization(String indent, GeneratedProperty methodParameter) {
344         final StringBuilder builder = new StringBuilder();
345         builder.append(indent);
346         builder.append(TAB);
347         builder.append("this.");
348         builder.append(methodParameter.getName());
349         builder.append(" = ");
350         builder.append(methodParameter.getName());
351         builder.append(SC);
352         builder.append(NL);
353         return builder.toString();
354     }
355
356     private static String createMethodParamDeclaration(GeneratedProperty methodParameter,
357             final Map<String, String> availableImports, String currentPkg) {
358         final StringBuilder builder = new StringBuilder();
359         builder.append(getExplicitType(methodParameter.getReturnType(), availableImports, currentPkg));
360         builder.append(GAP);
361         builder.append(methodParameter.getName());
362         return builder.toString();
363     }
364
365     public static String createGetter(final GeneratedProperty property, final String indent,
366             final Map<String, String> availableImports, final String currentPkg) {
367         final StringBuilder builder = new StringBuilder();
368
369         final Type type = property.getReturnType();
370         final String varName = property.getName();
371         final char first = Character.toUpperCase(varName.charAt(0));
372         final String methodName = "get" + first + varName.substring(1);
373
374         builder.append(indent + PUBLIC + GAP + getExplicitType(type, availableImports, currentPkg) + GAP + methodName);
375         builder.append(LB + RB + LCB + NL);
376
377         String currentIndent = indent + TAB;
378
379         builder.append(currentIndent + "return " + varName + SC + NL);
380
381         builder.append(indent + RCB);
382         return builder.toString();
383     }
384
385     public static String createSetter(final GeneratedProperty property, final String indent,
386             final Map<String, String> availableImports, final String currentPkg) {
387         final StringBuilder builder = new StringBuilder();
388
389         final Type type = property.getReturnType();
390         final String varName = property.getName();
391         final char first = Character.toUpperCase(varName.charAt(0));
392         final String methodName = "set" + first + varName.substring(1);
393
394         builder.append(indent + PUBLIC + GAP + "void" + GAP + methodName);
395         builder.append(LB + getExplicitType(type, availableImports, currentPkg) + GAP + varName + RB + LCB + NL);
396         String currentIndent = indent + TAB;
397         builder.append(currentIndent + "this." + varName + " = " + varName + SC + NL);
398         builder.append(indent + RCB);
399         return builder.toString();
400     }
401
402     public static String createHashCode(final List<GeneratedProperty> properties, final String indent) {
403         StringBuilder builder = new StringBuilder();
404         builder.append(indent + "public int hashCode() {" + NL);
405         builder.append(indent + TAB + "final int prime = 31;" + NL);
406         builder.append(indent + TAB + "int result = 1;" + NL);
407
408         for (GeneratedProperty property : properties) {
409             String fieldName = property.getName();
410             builder.append(indent + TAB + "result = prime * result + ((" + fieldName + " == null) ? 0 : " + fieldName
411                     + ".hashCode());" + NL);
412         }
413
414         builder.append(indent + TAB + "return result;" + NL);
415         builder.append(indent + RCB + NL);
416         return builder.toString();
417     }
418
419     public static String createEquals(final GeneratedTransferObject type, final List<GeneratedProperty> properties,
420             final String indent) {
421         final StringBuilder builder = new StringBuilder();
422         final String indent1 = indent + TAB;
423         final String indent2 = indent1 + TAB;
424         final String indent3 = indent2 + TAB;
425
426         builder.append(indent + "public boolean equals(Object obj) {" + NL);
427         builder.append(indent1 + "if (this == obj) {" + NL);
428         builder.append(indent2 + "return true;" + NL);
429         builder.append(indent1 + "}" + NL);
430         builder.append(indent1 + "if (obj == null) {" + NL);
431         builder.append(indent2 + "return false;" + NL);
432         builder.append(indent1 + "}" + NL);
433         builder.append(indent1 + "if (getClass() != obj.getClass()) {" + NL);
434         builder.append(indent2 + "return false;" + NL);
435         builder.append(indent1 + "}" + NL);
436
437         String typeStr = type.getName();
438         builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;" + NL);
439
440         for (final GeneratedProperty property : properties) {
441             String fieldName = property.getName();
442             builder.append(indent1 + "if (" + fieldName + " == null) {" + NL);
443             builder.append(indent2 + "if (other." + fieldName + " != null) {" + NL);
444             builder.append(indent3 + "return false;" + NL);
445             builder.append(indent2 + "}" + NL);
446             builder.append(indent1 + "} else if (!" + fieldName + ".equals(other." + fieldName + ")) {" + NL);
447             builder.append(indent2 + "return false;" + NL);
448             builder.append(indent1 + "}" + NL);
449         }
450
451         builder.append(indent1 + "return true;" + NL);
452         builder.append(indent + RCB + NL);
453         return builder.toString();
454     }
455
456     public static String createToString(final GeneratedTransferObject type, final List<GeneratedProperty> properties,
457             final String indent) {
458         StringBuilder builder = new StringBuilder();
459         builder.append(indent);
460         builder.append("public String toString() {");
461         builder.append(NL);
462         builder.append(indent);
463         builder.append(TAB);
464         builder.append("StringBuilder builder = new StringBuilder();");
465         builder.append(NL);
466         builder.append(indent);
467         builder.append(TAB);
468         builder.append("builder.append(\"");
469         builder.append(type.getName());
470         builder.append(" [");
471
472         boolean first = true;
473         for (final GeneratedProperty property : properties) {
474             if (first) {
475                 builder.append(property.getName());
476                 builder.append("=\");");
477                 builder.append(NL);
478                 builder.append(indent);
479                 builder.append(TAB);
480                 builder.append("builder.append(");
481                 builder.append(property.getName());
482                 builder.append(");");
483                 first = false;
484             } else {
485                 builder.append(NL);
486                 builder.append(indent);
487                 builder.append(TAB);
488                 builder.append("builder.append(\", ");
489                 builder.append(property.getName());
490                 builder.append("=\");");
491                 builder.append(NL);
492                 builder.append(indent);
493                 builder.append(TAB);
494                 builder.append("builder.append(");
495                 builder.append(property.getName());
496                 builder.append(");");
497             }
498         }
499         builder.append(NL);
500         builder.append(indent);
501         builder.append(TAB);
502         builder.append("builder.append(\"]\");");
503         builder.append(NL);
504         builder.append(indent);
505         builder.append(TAB);
506         builder.append("return builder.toString();");
507
508         builder.append(NL);
509         builder.append(indent);
510         builder.append(RCB);
511         builder.append(NL);
512         return builder.toString();
513     }
514
515     public static String createEnum(final Enumeration enumeration, final String indent) {
516         if (enumeration == null || indent == null)
517             throw new IllegalArgumentException();
518         final StringBuilder builder = new StringBuilder(indent + PUBLIC + GAP + ENUM + GAP + enumeration.getName()
519                 + GAP + LCB + NL);
520
521         String separator = COMMA + NL;
522         final List<Pair> values = enumeration.getValues();
523
524         for (int i = 0; i < values.size(); i++) {
525             if (i + 1 == values.size()) {
526                 separator = SC;
527             }
528             builder.append(indent + TAB + values.get(i).getName() + LB + values.get(i).getValue() + RB + separator);
529         }
530         builder.append(NL);
531         builder.append(NL);
532         final String ENUMERATION_NAME = "value";
533         final String ENUMERATION_TYPE = "int";
534         builder.append(indent + TAB + ENUMERATION_TYPE + GAP + ENUMERATION_NAME + SC);
535         builder.append(NL);
536         builder.append(indent + TAB + PRIVATE + GAP + enumeration.getName() + LB + ENUMERATION_TYPE + GAP
537                 + ENUMERATION_NAME + RB + GAP + LCB + NL);
538         builder.append(indent + TAB + TAB + "this." + ENUMERATION_NAME + GAP + "=" + GAP + ENUMERATION_NAME + SC + NL);
539         builder.append(indent + TAB + RCB + NL);
540
541         builder.append(indent + RCB);
542         builder.append(NL);
543         return builder.toString();
544     }
545
546     private static String getExplicitType(final Type type, final Map<String, String> imports, final String currentPkg) {
547         if (type == null) {
548             throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!");
549         }
550         if (type.getName() == null) {
551             throw new IllegalArgumentException("Type name cannot be NULL!");
552         }
553         if (type.getPackageName() == null) {
554             throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!");
555         }
556         if (imports == null) {
557             throw new IllegalArgumentException("Imports Map cannot be NULL!");
558         }
559
560         final String typePackageName = type.getPackageName();
561         final String typeName = type.getName();
562         final String importedPackageName = imports.get(typeName);
563         if (typePackageName.equals(importedPackageName) || typePackageName.equals(currentPkg)) {
564             final StringBuilder builder = new StringBuilder(type.getName());
565             if (type instanceof ParameterizedType) {
566                 final ParameterizedType pType = (ParameterizedType) type;
567                 final Type[] pTypes = pType.getActualTypeArguments();
568                 builder.append("<");
569                 builder.append(getParameters(pTypes, imports, currentPkg));
570                 builder.append(">");
571             }
572             if (builder.toString().equals("Void")) {
573                 return "void";
574             }
575             return builder.toString();
576         } else {
577             final StringBuilder builder = new StringBuilder();
578             if (typePackageName.startsWith("java.lang")) {
579                 builder.append(type.getName());
580             } else {
581                 if (!typePackageName.isEmpty()) {
582                     builder.append(typePackageName + "." + type.getName());
583                 } else {
584                     builder.append(type.getName());
585                 }
586             }
587             if (type.equals(Types.voidType())) {
588                 return "void";
589             }
590             if (type instanceof ParameterizedType) {
591                 final ParameterizedType pType = (ParameterizedType) type;
592                 final Type[] pTypes = pType.getActualTypeArguments();
593                 builder.append("<");
594                 builder.append(getParameters(pTypes, imports, currentPkg));
595                 builder.append(">");
596             }
597             return builder.toString();
598         }
599     }
600
601     private static String getParameters(final Type[] pTypes, Map<String, String> availableImports, String currentPkg) {
602         final StringBuilder builder = new StringBuilder();
603         for (int i = 0; i < pTypes.length; i++) {
604             final Type t = pTypes[i];
605
606             String separator = COMMA;
607             if (i == (pTypes.length - 1)) {
608                 separator = "";
609             }
610
611             String wildcardParam = "";
612             if (t.equals(Types.voidType())) {
613                 builder.append("java.lang.Void" + separator);
614                 continue;
615             } else {
616
617                 if (t instanceof WildcardType) {
618                     wildcardParam = "? extends ";
619                 }
620
621                 builder.append(wildcardParam + getExplicitType(t, availableImports, currentPkg) + separator);
622             }
623         }
624         return builder.toString();
625     }
626
627     private static void createComment(final StringBuilder builder, final String comment, final String indent) {
628         if (comment != null && comment.length() > 0) {
629             builder.append(indent + "/*" + NL);
630             builder.append(indent + comment + NL);
631             builder.append(indent + "*/" + NL);
632         }
633     }
634
635     public static Map<String, String> createImports(GeneratedType genType) {
636         if (genType == null) {
637             throw new IllegalArgumentException("Generated Type cannot be NULL!");
638         }
639         final Map<String, String> imports = new LinkedHashMap<>();
640         List<GeneratedType> childGeneratedTypes = genType.getEnclosedTypes();
641         if (!childGeneratedTypes.isEmpty()) {
642             for (GeneratedType genTypeChild : childGeneratedTypes) {
643                 imports.putAll(createImports(genTypeChild));
644             }
645         }
646
647         final List<Constant> constants = genType.getConstantDefinitions();
648         final List<MethodSignature> methods = genType.getMethodDefinitions();
649         final List<Type> impl = genType.getImplements();
650
651         // IMPLEMENTATIONS
652         if (impl != null) {
653             for (final Type type : impl) {
654                 putTypeIntoImports(genType, type, imports);
655             }
656         }
657
658         // CONSTANTS
659         if (constants != null) {
660             for (final Constant constant : constants) {
661                 final Type constantType = constant.getType();
662                 putTypeIntoImports(genType, constantType, imports);
663             }
664         }
665
666         // REGULAR EXPRESSION
667         if (genType instanceof GeneratedTransferObject) {
668             if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) {
669                 putTypeIntoImports(genType, Types.typeForClass(java.util.regex.Pattern.class), imports);
670                 putTypeIntoImports(genType, Types.typeForClass(java.util.Arrays.class), imports);
671                 putTypeIntoImports(genType, Types.typeForClass(java.util.ArrayList.class), imports);
672             }
673         }
674
675         // METHODS
676         if (methods != null) {
677             for (final MethodSignature method : methods) {
678                 final Type methodReturnType = method.getReturnType();
679                 putTypeIntoImports(genType, methodReturnType, imports);
680                 for (final MethodSignature.Parameter methodParam : method.getParameters()) {
681                     putTypeIntoImports(genType, methodParam.getType(), imports);
682                 }
683             }
684         }
685
686         // PROPERTIES
687         if (genType instanceof GeneratedTransferObject) {
688             final GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
689             final List<GeneratedProperty> properties = genTO.getProperties();
690             if (properties != null) {
691                 for (GeneratedProperty property : properties) {
692                     final Type propertyType = property.getReturnType();
693                     putTypeIntoImports(genType, propertyType, imports);
694                 }
695             }
696         }
697
698         return imports;
699     }
700
701     public static Map<String, String> createChildImports(GeneratedType genType) {
702         Map<String, String> childImports = new LinkedHashMap<>();
703         List<GeneratedType> childGeneratedTypes = genType.getEnclosedTypes();
704         if (!childGeneratedTypes.isEmpty()) {
705             for (GeneratedType genTypeChild : childGeneratedTypes) {
706                 createChildImports(genTypeChild);
707                 childImports.put(genTypeChild.getName(), genTypeChild.getPackageName());
708             }
709         }
710         return childImports;
711     }
712
713     private static void putTypeIntoImports(final GeneratedType parentGenType, final Type type,
714             final Map<String, String> imports) {
715         if (parentGenType == null) {
716             throw new IllegalArgumentException("Parent Generated Type parameter MUST be specified and cannot be "
717                     + "NULL!");
718         }
719         if (parentGenType.getName() == null) {
720             throw new IllegalArgumentException("Parent Generated Type name cannot be NULL!");
721         }
722         if (parentGenType.getPackageName() == null) {
723             throw new IllegalArgumentException("Parent Generated Type cannot have Package Name referenced as NULL!");
724         }
725         if (type == null) {
726             throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!");
727         }
728         if (type.getName() == null) {
729             throw new IllegalArgumentException("Type name cannot be NULL!");
730         }
731         if (type.getPackageName() == null) {
732             throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!");
733         }
734
735         final String typeName = type.getName();
736         final String typePackageName = type.getPackageName();
737         final String parentTypeName = parentGenType.getName();
738         final String parentTypePackageName = parentGenType.getPackageName();
739         if (typeName.equals(parentTypeName) || typePackageName.startsWith("java.lang")
740                 || typePackageName.equals(parentTypePackageName) || typePackageName.isEmpty()) {
741             return;
742         }
743         if (!imports.containsKey(typeName)) {
744             imports.put(typeName, typePackageName);
745         }
746         if (type instanceof ParameterizedType) {
747             final ParameterizedType paramType = (ParameterizedType) type;
748             final Type[] params = paramType.getActualTypeArguments();
749             for (Type param : params) {
750                 putTypeIntoImports(parentGenType, param, imports);
751             }
752         }
753     }
754
755     public static List<String> createImportLines(final Map<String, String> imports,
756             final Map<String, String> innerTypeImports) {
757         final List<String> importLines = new ArrayList<>();
758
759         for (Map.Entry<String, String> entry : imports.entrySet()) {
760             final String typeName = entry.getKey();
761             final String packageName = entry.getValue();
762             if (innerTypeImports != null) {
763                 String innerTypePackageName = innerTypeImports.get(typeName);
764                 if (innerTypePackageName != null) {
765                     if (innerTypePackageName.equals(packageName))
766                         continue;
767                 }
768             }
769             importLines.add("import " + packageName + "." + typeName + SC);
770         }
771         return importLines;
772     }
773
774     public static boolean isConstantInTO(String constName, GeneratedTransferObject genTO) {
775         if (constName == null || genTO == null)
776             throw new IllegalArgumentException();
777         List<Constant> consts = genTO.getConstantDefinitions();
778         for (Constant cons : consts) {
779             if (cons.getName().equals(constName)) {
780                 return true;
781             }
782
783         }
784         return false;
785     }
786
787     public static String createStaticInicializationBlock(GeneratedTransferObject genTransferObject, String indent) {
788
789         final StringBuilder builder = new StringBuilder();
790
791         List<Constant> constants = genTransferObject.getConstantDefinitions();
792         for (Constant constant : constants) {
793             if (constant.getName() == null || constant.getType() == null || constant.getValue() == null) {
794                 continue;
795             }
796             if (constant.getName().equals(TypeConstants.PATTERN_CONSTANT_NAME)) {
797                 final Object constValue = constant.getValue();
798                 List<String> regularExpressions = new ArrayList<>();
799                 if (constValue instanceof List) {
800                     builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP + "List<String>" + GAP
801                             + TypeConstants.PATTERN_CONSTANT_NAME + GAP + "=" + GAP + "Arrays.asList" + LB);
802                     final List<?> constantValues = (List<?>) constValue;
803                     int stringsCount = 0;
804                     for (Object value : constantValues) {
805                         if (value instanceof String) {
806                             if (stringsCount > 0) {
807                                 builder.append(COMMA);
808                             }
809                             stringsCount++;
810                             regularExpressions.add((String) value);
811                             builder.append(DOUBLE_QUOTE + (String) value + DOUBLE_QUOTE);
812                         }
813                     }
814                     builder.append(RB + SC + NL);
815                 }
816                 builder.append(indent + PRIVATE + GAP + STATIC + GAP + FINAL + GAP + "List<Pattern>" + GAP
817                         + MEMBER_PATTERN_LIST + GAP + ASSIGN + GAP + "new ArrayList<Pattern>()" + GAP + SC + NL + NL);
818
819                 if (!regularExpressions.isEmpty()) {
820                     builder.append(indent + STATIC + LCB + NL);
821                     builder.append(indent + TAB + "for (String regEx : " + TypeConstants.PATTERN_CONSTANT_NAME + ") {"
822                             + NL);
823                     builder.append(indent + TAB + TAB + MEMBER_PATTERN_LIST + ".add(Pattern.compile(regEx))" + SC + NL);
824                     builder.append(indent + TAB + RCB + NL);
825                     builder.append(indent + RCB + NL + NL);
826                 }
827
828             }
829         }
830         return builder.toString();
831     }
832 }