Maping of union leaf a bits leaf YANG type to JAVA inner classes.
[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 instanceof ParameterizedType) {
588                 final ParameterizedType pType = (ParameterizedType) type;
589                 final Type[] pTypes = pType.getActualTypeArguments();
590                 builder.append("<");
591                 builder.append(getParameters(pTypes, imports, currentPkg));
592                 builder.append(">");
593             }
594             if (builder.toString().equals("Void")) {
595                 return "void";
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 instanceof WildcardType) {
613                 wildcardParam = "? extends ";
614             }
615             builder.append(wildcardParam + getExplicitType(t, availableImports, currentPkg) + separator);
616         }
617         return builder.toString();
618     }
619
620     private static void createComment(final StringBuilder builder, final String comment, final String indent) {
621         if (comment != null && comment.length() > 0) {
622             builder.append(indent + "/*" + NL);
623             builder.append(indent + comment + NL);
624             builder.append(indent + "*/" + NL);
625         }
626     }
627
628     public static Map<String, String> createImports(GeneratedType genType) {
629         if (genType == null) {
630             throw new IllegalArgumentException("Generated Type cannot be NULL!");
631         }
632         final Map<String, String> imports = new LinkedHashMap<>();
633         List<GeneratedType> childGeneratedTypes = genType.getEnclosedTypes();
634         if (!childGeneratedTypes.isEmpty()) {
635             for (GeneratedType genTypeChild : childGeneratedTypes) {
636                 imports.putAll(createImports(genTypeChild));
637             }
638         }
639
640         final List<Constant> constants = genType.getConstantDefinitions();
641         final List<MethodSignature> methods = genType.getMethodDefinitions();
642         final List<Type> impl = genType.getImplements();
643
644         // IMPLEMENTATIONS
645         if (impl != null) {
646             for (final Type type : impl) {
647                 putTypeIntoImports(genType, type, imports);
648             }
649         }
650
651         // CONSTANTS
652         if (constants != null) {
653             for (final Constant constant : constants) {
654                 final Type constantType = constant.getType();
655                 putTypeIntoImports(genType, constantType, imports);
656             }
657         }
658
659         // REGULAR EXPRESSION
660         if (genType instanceof GeneratedTransferObject) {
661             if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) {
662                 putTypeIntoImports(genType, Types.typeForClass(java.util.regex.Pattern.class), imports);
663                 putTypeIntoImports(genType, Types.typeForClass(java.util.Arrays.class), imports);
664                 putTypeIntoImports(genType, Types.typeForClass(java.util.ArrayList.class), imports);
665             }
666         }
667
668         // METHODS
669         if (methods != null) {
670             for (final MethodSignature method : methods) {
671                 final Type methodReturnType = method.getReturnType();
672                 putTypeIntoImports(genType, methodReturnType, imports);
673                 for (final MethodSignature.Parameter methodParam : method.getParameters()) {
674                     putTypeIntoImports(genType, methodParam.getType(), imports);
675                 }
676             }
677         }
678
679         // PROPERTIES
680         if (genType instanceof GeneratedTransferObject) {
681             final GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
682             final List<GeneratedProperty> properties = genTO.getProperties();
683             if (properties != null) {
684                 for (GeneratedProperty property : properties) {
685                     final Type propertyType = property.getReturnType();
686                     putTypeIntoImports(genType, propertyType, imports);
687                 }
688             }
689         }
690
691         return imports;
692     }
693
694     public static Map<String, String> createChildImports(GeneratedType genType) {
695         Map<String, String> childImports = new LinkedHashMap<>();
696         List<GeneratedType> childGeneratedTypes = genType.getEnclosedTypes();
697         if (!childGeneratedTypes.isEmpty()) {
698             for (GeneratedType genTypeChild : childGeneratedTypes) {
699                 createChildImports(genTypeChild);
700                 childImports.put(genTypeChild.getName(), genTypeChild.getPackageName());
701             }
702         }
703         return childImports;
704     }
705
706     private static void putTypeIntoImports(final GeneratedType parentGenType, final Type type,
707             final Map<String, String> imports) {
708         if (parentGenType == null) {
709             throw new IllegalArgumentException("Parent Generated Type parameter MUST be specified and cannot be "
710                     + "NULL!");
711         }
712         if (parentGenType.getName() == null) {
713             throw new IllegalArgumentException("Parent Generated Type name cannot be NULL!");
714         }
715         if (parentGenType.getPackageName() == null) {
716             throw new IllegalArgumentException("Parent Generated Type cannot have Package Name referenced as NULL!");
717         }
718         if (type == null) {
719             throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!");
720         }
721         if (type.getName() == null) {
722             throw new IllegalArgumentException("Type name cannot be NULL!");
723         }
724         if (type.getPackageName() == null) {
725             throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!");
726         }
727
728         final String typeName = type.getName();
729         final String typePackageName = type.getPackageName();
730         final String parentTypeName = parentGenType.getName();
731         final String parentTypePackageName = parentGenType.getPackageName();
732         if (typeName.equals(parentTypeName) || typePackageName.startsWith("java.lang")
733                 || typePackageName.equals(parentTypePackageName) || typePackageName.isEmpty()) {
734             return;
735         }
736         if (!imports.containsKey(typeName)) {
737             imports.put(typeName, typePackageName);
738         }
739         if (type instanceof ParameterizedType) {
740             final ParameterizedType paramType = (ParameterizedType) type;
741             final Type[] params = paramType.getActualTypeArguments();
742             for (Type param : params) {
743                 putTypeIntoImports(parentGenType, param, imports);
744             }
745         }
746     }
747
748     public static List<String> createImportLines(final Map<String, String> imports,
749             final Map<String, String> innerTypeImports) {
750         final List<String> importLines = new ArrayList<>();
751
752         for (Map.Entry<String, String> entry : imports.entrySet()) {
753             final String typeName = entry.getKey();
754             final String packageName = entry.getValue();
755             if (innerTypeImports != null) {
756                 String innerTypePackageName = innerTypeImports.get(typeName);
757                 if (innerTypePackageName != null) {
758                     if (innerTypePackageName.equals(packageName))
759                         continue;
760                 }
761             }
762             importLines.add("import " + packageName + "." + typeName + SC);
763         }
764         return importLines;
765     }
766
767     public static boolean isConstantInTO(String constName, GeneratedTransferObject genTO) {
768         if (constName == null || genTO == null)
769             throw new IllegalArgumentException();
770         List<Constant> consts = genTO.getConstantDefinitions();
771         for (Constant cons : consts) {
772             if (cons.getName().equals(constName)) {
773                 return true;
774             }
775
776         }
777         return false;
778     }
779
780     public static String createStaticInicializationBlock(GeneratedTransferObject genTransferObject, String indent) {
781
782         final StringBuilder builder = new StringBuilder();
783
784         List<Constant> constants = genTransferObject.getConstantDefinitions();
785         for (Constant constant : constants) {
786             if (constant.getName() == null || constant.getType() == null || constant.getValue() == null) {
787                 continue;
788             }
789             if (constant.getName().equals(TypeConstants.PATTERN_CONSTANT_NAME)) {
790                 final Object constValue = constant.getValue();
791                 List<String> regularExpressions = new ArrayList<>();
792                 if (constValue instanceof List) {
793                     builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP + "List<String>" + GAP
794                             + TypeConstants.PATTERN_CONSTANT_NAME + GAP + "=" + GAP + "Arrays.asList" + LB);
795                     final List<?> constantValues = (List<?>) constValue;
796                     int stringsCount = 0;
797                     for (Object value : constantValues) {
798                         if (value instanceof String) {
799                             if (stringsCount > 0) {
800                                 builder.append(COMMA);
801                             }
802                             stringsCount++;
803                             regularExpressions.add((String) value);
804                             builder.append(DOUBLE_QUOTE + (String) value + DOUBLE_QUOTE);
805                         }
806                     }
807                     builder.append(RB + SC + NL);
808                 }
809                 builder.append(indent + PRIVATE + GAP + STATIC + GAP + FINAL + GAP + "List<Pattern>" + GAP
810                         + MEMBER_PATTERN_LIST + GAP + ASSIGN + GAP + "new ArrayList<Pattern>()" + GAP + SC + NL + NL);
811
812                 if (!regularExpressions.isEmpty()) {
813                     builder.append(indent + STATIC + LCB + NL);
814                     builder.append(indent + TAB + "for (String regEx : " + TypeConstants.PATTERN_CONSTANT_NAME + ") {"
815                             + NL);
816                     builder.append(indent + TAB + TAB + MEMBER_PATTERN_LIST + ".add(Pattern.compile(regEx))" + SC + NL);
817                     builder.append(indent + TAB + RCB + NL);
818                     builder.append(indent + RCB + NL + NL);
819                 }
820
821             }
822         }
823         return builder.toString();
824     }
825 }