X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fsal%2Fyang-prototype%2Fcode-generator%2Fbinding-java-api-generator%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fjava%2Fapi%2Fgenerator%2FGeneratorUtil.java;h=0e2da819371cf7b962ba0eba39fa980e1e66bdbd;hp=16074c7e98ba0b1fac549c2c1fa6c42c67abe71c;hb=52df0e555243605003ee090150cf61b53c097563;hpb=b36cea2d468e8f572f0159332b0668fc35c95912 diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java index 16074c7e98..0e2da81937 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java @@ -10,25 +10,16 @@ package org.opendaylight.controller.sal.java.api.generator; import static org.opendaylight.controller.sal.java.api.generator.Constants.*; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.opendaylight.controller.binding.generator.util.TypeConstants; +import org.opendaylight.controller.sal.binding.model.api.*; import org.opendaylight.controller.binding.generator.util.Types; -import org.opendaylight.controller.sal.binding.model.api.AnnotationType; -import org.opendaylight.controller.sal.binding.model.api.Constant; -import org.opendaylight.controller.sal.binding.model.api.Enumeration; import org.opendaylight.controller.sal.binding.model.api.Enumeration.Pair; -import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty; -import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; -import org.opendaylight.controller.sal.binding.model.api.GeneratedType; -import org.opendaylight.controller.sal.binding.model.api.MethodSignature; import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter; -import org.opendaylight.controller.sal.binding.model.api.ParameterizedType; -import org.opendaylight.controller.sal.binding.model.api.Type; -import org.opendaylight.controller.sal.binding.model.api.WildcardType; public final class GeneratorUtil { @@ -36,13 +27,13 @@ public final class GeneratorUtil { } public static String createIfcDeclaration(final GeneratedType genType, final String indent, - final Map> availableImports) { - return createFileDeclaration(IFC, genType, indent, availableImports, false); + final Map availableImports) { + return createFileDeclaration(IFC, genType, indent, availableImports, false, false); } public static String createClassDeclaration(final GeneratedTransferObject genTransferObject, final String indent, - final Map> availableImports, boolean isIdentity) { - return createFileDeclaration(CLASS, genTransferObject, indent, availableImports, isIdentity); + final Map availableImports, boolean isIdentity, boolean isInnerClass) { + return createFileDeclaration(CLASS, genTransferObject, indent, availableImports, isIdentity, isInnerClass); } public static String createPackageDeclaration(final String packageName) { @@ -50,7 +41,7 @@ public final class GeneratorUtil { } private static String createFileDeclaration(final String type, final GeneratedType genType, final String indent, - final Map> availableImports, boolean isIdentity) { + final Map availableImports, boolean isIdentity, boolean innerClass) { final StringBuilder builder = new StringBuilder(); final String currentPkg = genType.getPackageName(); @@ -62,13 +53,15 @@ public final class GeneratorUtil { builder.append(NL); } - if (isIdentity) { + if (innerClass) { + builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP + type + GAP + genType.getName() + GAP); + } else if (isIdentity) { if (!(CLASS.equals(type))) { throw new IllegalArgumentException("'identity' has to be generated as a class"); } - builder.append(PUBLIC + GAP + ABSTRACT + GAP + type + GAP + genType.getName() + GAP); + builder.append(indent + PUBLIC + GAP + ABSTRACT + GAP + type + GAP + genType.getName() + GAP); } else { - builder.append(PUBLIC + GAP + type + GAP + genType.getName() + GAP); + builder.append(indent + PUBLIC + GAP + type + GAP + genType.getName() + GAP); } if (genType instanceof GeneratedTransferObject) { @@ -95,7 +88,6 @@ public final class GeneratorUtil { builder.append(getExplicitType(genImplements.get(i), availableImports, currentPkg)); } } - builder.append(GAP + LCB); return builder.toString(); } @@ -153,33 +145,16 @@ public final class GeneratorUtil { } public static String createConstant(final Constant constant, final String indent, - final Map> availableImports, final String currentPkg) { + final Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); if (constant == null) throw new IllegalArgumentException(); builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP); builder.append(getExplicitType(constant.getType(), availableImports, currentPkg) + GAP + constant.getName()); builder.append(GAP + "=" + GAP); - final Object constValue = constant.getValue(); if (constant.getName().equals(TypeConstants.PATTERN_CONSTANT_NAME)) { - if (constant.getName() == null || constant.getType() == null || constant.getValue() == null) - throw new IllegalArgumentException(); - if (constValue instanceof List) { - builder.append("Arrays.asList" + LB); - final List constantValues = (List) constValue; - int stringsCount = 0; - for (Object value : constantValues) { - if (value instanceof String) { - if (stringsCount > 0) { - builder.append(COMMA); - } - stringsCount++; - builder.append(DOUBLE_QUOTE + (String) value + DOUBLE_QUOTE); - } - } - builder.append(RB); - } + return ""; } else { builder.append(constant.getValue()); } @@ -189,7 +164,7 @@ public final class GeneratorUtil { } public static String createField(final GeneratedProperty property, final String indent, - Map> availableImports, final String currentPkg) { + final Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); if (!property.getAnnotations().isEmpty()) { final List annotations = property.getAnnotations(); @@ -211,7 +186,7 @@ public final class GeneratorUtil { * @return */ public static String createMethodDeclaration(final MethodSignature method, final String indent, - Map> availableImports, final String currentPkg) { + Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); if (method == null) { @@ -233,9 +208,9 @@ public final class GeneratorUtil { createComment(builder, comment, indent); builder.append(NL); - builder.append(indent); if (!method.getAnnotations().isEmpty()) { + builder.append(indent); final List annotations = method.getAnnotations(); appendAnnotations(builder, annotations); builder.append(NL); @@ -257,83 +232,357 @@ public final class GeneratorUtil { return builder.toString(); } - public static String createConstructor(GeneratedTransferObject genTransferObject, final String indent, - Map> availableImports, boolean isIdentity) { - final StringBuilder builder = new StringBuilder(); + public static String createConstructor(final GeneratedTransferObject genTransferObject, final String indent, + final Map availableImports, final boolean isIdentity, final boolean oneConstructor) { + if (genTransferObject == null) { + throw new IllegalArgumentException("Generated transfer object can't be null"); + } + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + GeneratedTransferObject genTOTopParent = getTopParrentTransportObject(genTransferObject); + final List ctorProperties = resolveReadOnlyPropertiesFromTO(genTransferObject + .getProperties()); + final List ctorPropertiesAllParents = getPropertiesOfAllParents(genTransferObject + .getExtends()); final String currentPkg = genTransferObject.getPackageName(); - final List properties = genTransferObject.getProperties(); - final List ctorParams = new ArrayList(); + final String className = genTransferObject.getName(); + + String constructorPart = ""; + if (oneConstructor) { + if (genTOTopParent != genTransferObject && genTOTopParent.isUnionType()) { + constructorPart = createConstructorForEveryParentProperty(indent, isIdentity, ctorProperties, + ctorPropertiesAllParents, availableImports, currentPkg, className); + + } else { + constructorPart = createOneConstructor(indent, isIdentity, ctorProperties, ctorPropertiesAllParents, + availableImports, currentPkg, className); + } + + } else { // union won't be extended + constructorPart = createConstructorForEveryProperty(indent, isIdentity, ctorProperties, + ctorPropertiesAllParents, availableImports, currentPkg, className); + } + + return constructorPart; + } + + private static String createOneConstructor(final String indent, boolean isIdentity, + final List properties, final List propertiesAllParents, + final Map availableImports, final String currentPkg, final String className) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (properties == null) { + throw new IllegalArgumentException("List of generated properties can't be null"); + } + if (propertiesAllParents == null) { + throw new IllegalArgumentException( + "List of generated properties of all parent transport objects can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } + if (className == null) { + throw new IllegalArgumentException("String with class name can't be null"); + } + + final StringBuilder builder = new StringBuilder(); + + List propertiesAll = new ArrayList(properties); + propertiesAll.addAll(propertiesAllParents); + + builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity)); + builder.append(createMethodPropertiesDeclaration(propertiesAll, availableImports, currentPkg, COMMA + GAP)); + builder.append(createConstructorDeclarationFromRightParenthesis()); + builder.append(createConstructorSuper(propertiesAllParents, indent)); + builder.append(createClassPropertiesInitialization(propertiesAll, indent)); + builder.append(createConstructorClosingPart(indent)); + return builder.toString(); + } + + private static String createConstructorForEveryParentProperty(final String indent, final boolean isIdentity, + final List properties, final List propertiesAllParents, + final Map availableImports, final String currentPkg, final String className) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (properties == null) { + throw new IllegalArgumentException("List of generated properties can't be null"); + } + if (propertiesAllParents == null) { + throw new IllegalArgumentException( + "List of generated properties of all parent transport objects can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } + if (className == null) { + throw new IllegalArgumentException("String with class name can't be null"); + } + final StringBuilder builder = new StringBuilder(); + GeneratedProperty parentProperty; + Iterator parentPropertyIterator = propertiesAllParents.iterator(); + + do { + parentProperty = null; + if (parentPropertyIterator.hasNext()) { + parentProperty = parentPropertyIterator.next(); + } + + List propertiesAndParentProperties = new ArrayList(); + if (parentProperty != null) { + propertiesAndParentProperties.add(parentProperty); + } + propertiesAndParentProperties.addAll(properties); + + builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity)); + builder.append(createMethodPropertiesDeclaration(propertiesAndParentProperties, availableImports, + currentPkg, COMMA + GAP)); + builder.append(createConstructorDeclarationFromRightParenthesis()); + builder.append(createConstructorSuper(parentProperty, indent)); + builder.append(createClassPropertiesInitialization(properties, indent)); + builder.append(createConstructorClosingPart(indent)); + } while (parentPropertyIterator.hasNext()); + + return builder.toString(); + } + + private static String createConstructorForEveryProperty(final String indent, final boolean isIdentity, + final List properties, final List propertiesAllParents, + final Map availableImports, final String currentPkg, final String className) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (properties == null) { + throw new IllegalArgumentException("List of generated properties can't be null"); + } + if (propertiesAllParents == null) { + throw new IllegalArgumentException( + "List of generated properties of all parent transport objects can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } + if (className == null) { + throw new IllegalArgumentException("String with class name can't be null"); + } + + final StringBuilder builder = new StringBuilder(); + + GeneratedProperty property; + Iterator propertyIterator = properties.iterator(); + + do { + property = null; + if (propertyIterator.hasNext()) { + property = propertyIterator.next(); + } + + List propertyAndTopParentProperties = new ArrayList(); + if (property != null) { + propertyAndTopParentProperties.add(property); + } + propertyAndTopParentProperties.addAll(propertiesAllParents); + + builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity)); + builder.append(createMethodPropertiesDeclaration(propertyAndTopParentProperties, availableImports, + currentPkg, COMMA + GAP)); + builder.append(createConstructorDeclarationFromRightParenthesis()); + builder.append(createConstructorSuper(propertiesAllParents, indent)); + builder.append(createClassPropertyInitialization(property, indent)); + builder.append(createConstructorClosingPart(indent)); + } while (propertyIterator.hasNext()); + + return builder.toString(); + } + + /** + * The method selects from input list of properties only those which have + * read only attribute set to true. + * + * @param properties + * contains list of properties of generated transfer object + * @return subset of properties which have read only attribute + * set to true + */ + private static List resolveReadOnlyPropertiesFromTO(List properties) { + List readOnlyProperties = new ArrayList(); if (properties != null) { for (final GeneratedProperty property : properties) { if (property.isReadOnly()) { - ctorParams.add(property); + readOnlyProperties.add(property); } } } + return readOnlyProperties; + } + private static String createMethodPropertiesDeclaration(final List parameters, + final Map availableImports, final String currentPkg, final String parameterSeparator) { + StringBuilder builder = new StringBuilder(); + if (parameters == null) { + throw new IllegalArgumentException("List of generated properties can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } + if (parameterSeparator == null) { + throw new IllegalArgumentException("String with separator of parameters can't be null"); + } + + for (final GeneratedProperty parameter : parameters) { + builder.append(createMethodPropertyDeclaration(parameter, availableImports, currentPkg)); + builder.append(parameterSeparator); + } + if (!parameters.isEmpty()) { + builder = builder.delete(builder.length() - parameterSeparator.length(), builder.length()); + } + return builder.toString(); + } + + private static String createConstructorDeclarationToLeftParenthesis(final String className, final String indent, + final boolean isIdentity) { + if (className == null) { + throw new IllegalArgumentException("String with class name can't be null"); + } + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + final StringBuilder builder = new StringBuilder(); builder.append(indent); builder.append(isIdentity ? PROTECTED : PUBLIC); builder.append(GAP); - builder.append(genTransferObject.getName()); + builder.append(className); builder.append(LB); + return builder.toString(); + } - if (!ctorParams.isEmpty()) { - builder.append(getExplicitType(ctorParams.get(0).getReturnType(), availableImports, currentPkg)); - builder.append(" "); - builder.append(ctorParams.get(0).getName()); - for (int i = 1; i < ctorParams.size(); ++i) { - final GeneratedProperty param = ctorParams.get(i); - builder.append(", "); - builder.append(getExplicitType(param.getReturnType(), availableImports, currentPkg)); - builder.append(GAP); - builder.append(param.getName()); - } + private static String createConstructorDeclarationFromRightParenthesis() { + final StringBuilder builder = new StringBuilder(); + builder.append(RB + GAP + LCB + NL); + return builder.toString(); + } + + private static String createConstructorSuper(final List propertiesAllParents, final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); } - builder.append(RB + GAP + LCB + NL + indent + TAB + "super();" + NL); - if (!ctorParams.isEmpty()) { - for (final GeneratedProperty property : ctorParams) { - builder.append(indent); - builder.append(TAB); - builder.append("this."); - builder.append(property.getName()); - builder.append(" = "); - builder.append(property.getName()); - builder.append(SC); - builder.append(NL); - } + if (propertiesAllParents == null) { + throw new IllegalArgumentException("List of all parent's properties can't be null"); + } + StringBuilder builder = new StringBuilder(); + builder.append(indent + TAB + "super("); + String propertySeparator = COMMA + GAP; + for (GeneratedProperty superProperty : propertiesAllParents) { + builder.append(superProperty.getName()); + builder.append(propertySeparator); + } + if (!propertiesAllParents.isEmpty()) { + builder = builder.delete(builder.length() - propertySeparator.length(), builder.length()); } - List consts = genTransferObject.getConstantDefinitions(); - for (Constant con : consts) { - if (con.getName() == null || con.getType() == null || con.getValue() == null) - continue; - if (con.getName().equals(TypeConstants.PATTERN_CONSTANT_NAME)) { - Object values = con.getValue(); - if (values instanceof List) { - for (Object regEx : (List) values) { - if (regEx instanceof String) { - builder.append(indent + TAB + "for (String regEx : " + TypeConstants.PATTERN_CONSTANT_NAME - + ") {" + NL); - builder.append(indent + TAB + TAB + "this." + MEMBER_PATTERN_LIST - + ".add(Pattern.compile(regEx))" + SC + NL); - builder.append(indent + TAB + RCB + NL); - - break; - } - } - } - } + builder.append(");" + NL); + return builder.toString(); + } + private static String createConstructorSuper(final GeneratedProperty parentProperty, final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); } + if (parentProperty == null) { + throw new IllegalArgumentException("Parent property can't be null"); + } + StringBuilder builder = new StringBuilder(); + if (parentProperty != null) { + builder.append(indent + TAB + "super("); + builder.append(parentProperty.getName()); + builder.append(");" + NL); + } + return builder.toString(); + } + private static String createConstructorClosingPart(final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + final StringBuilder builder = new StringBuilder(); builder.append(indent); builder.append(RCB); + builder.append(NL + NL); + return builder.toString(); + } + + private static String createClassPropertiesInitialization(final List properties, + final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (properties == null) { + throw new IllegalArgumentException("List of generated class properties can't be null"); + } + final StringBuilder builder = new StringBuilder(); + for (final GeneratedProperty property : properties) { + createClassPropertyInitialization(property, indent); + } + return builder.toString(); + } + + private static String createClassPropertyInitialization(final GeneratedProperty property, final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (property == null) { + throw new IllegalArgumentException("List of generated class properties can't be null"); + } + final StringBuilder builder = new StringBuilder(); + builder.append(indent); + builder.append(TAB); + builder.append("this."); + builder.append(property.getName()); + builder.append(" = "); + builder.append(property.getName()); + builder.append(SC); + builder.append(NL); + return builder.toString(); + } + + private static String createMethodPropertyDeclaration(final GeneratedProperty property, + final Map availableImports, final String currentPkg) { + if (property == null) { + throw new IllegalArgumentException("Generated property can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } + final StringBuilder builder = new StringBuilder(); + builder.append(getExplicitType(property.getReturnType(), availableImports, currentPkg)); + builder.append(GAP); + builder.append(property.getName()); return builder.toString(); } public static String createGetter(final GeneratedProperty property, final String indent, - Map> availableImports, final String currentPkg) { + final Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); final Type type = property.getReturnType(); @@ -353,7 +602,7 @@ public final class GeneratorUtil { } public static String createSetter(final GeneratedProperty property, final String indent, - Map> availableImports, String currentPkg) { + final Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); final Type type = property.getReturnType(); @@ -388,7 +637,7 @@ public final class GeneratorUtil { public static String createEquals(final GeneratedTransferObject type, final List properties, final String indent) { - StringBuilder builder = new StringBuilder(); + final StringBuilder builder = new StringBuilder(); final String indent1 = indent + TAB; final String indent2 = indent1 + TAB; final String indent3 = indent2 + TAB; @@ -407,7 +656,7 @@ public final class GeneratorUtil { String typeStr = type.getName(); builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;" + NL); - for (GeneratedProperty property : properties) { + for (final GeneratedProperty property : properties) { String fieldName = property.getName(); builder.append(indent1 + "if (" + fieldName + " == null) {" + NL); builder.append(indent2 + "if (other." + fieldName + " != null) {" + NL); @@ -419,7 +668,6 @@ public final class GeneratorUtil { } builder.append(indent1 + "return true;" + NL); - builder.append(indent + RCB + NL); return builder.toString(); } @@ -441,7 +689,7 @@ public final class GeneratorUtil { builder.append(" ["); boolean first = true; - for (GeneratedProperty property : properties) { + for (final GeneratedProperty property : properties) { if (first) { builder.append(property.getName()); builder.append("=\");"); @@ -514,22 +762,30 @@ public final class GeneratorUtil { return builder.toString(); } - private static String getExplicitType(final Type type, - Map> availableImports, final String currentPkg) { + private static String getExplicitType(final Type type, final Map imports, final String currentPkg) { if (type == null) { throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!"); } - String packageName = type.getPackageName(); - - LinkedHashMap imports = availableImports.get(type.getName()); + if (type.getName() == null) { + throw new IllegalArgumentException("Type name cannot be NULL!"); + } + if (type.getPackageName() == null) { + throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!"); + } + if (imports == null) { + throw new IllegalArgumentException("Imports Map cannot be NULL!"); + } - if ((imports != null && packageName.equals(findMaxValue(imports).get(0))) || packageName.equals(currentPkg)) { + final String typePackageName = type.getPackageName(); + final String typeName = type.getName(); + final String importedPackageName = imports.get(typeName); + if (typePackageName.equals(importedPackageName) || typePackageName.equals(currentPkg)) { final StringBuilder builder = new StringBuilder(type.getName()); if (type instanceof ParameterizedType) { - ParameterizedType pType = (ParameterizedType) type; - Type[] pTypes = pType.getActualTypeArguments(); + final ParameterizedType pType = (ParameterizedType) type; + final Type[] pTypes = pType.getActualTypeArguments(); builder.append("<"); - builder.append(getParameters(pTypes, availableImports, currentPkg)); + builder.append(getParameters(pTypes, imports, currentPkg)); builder.append(">"); } if (builder.toString().equals("Void")) { @@ -538,67 +794,53 @@ public final class GeneratorUtil { return builder.toString(); } else { final StringBuilder builder = new StringBuilder(); - if (packageName.startsWith("java.lang")) { + if (typePackageName.startsWith("java.lang")) { builder.append(type.getName()); } else { - if (!packageName.isEmpty()) { - builder.append(packageName + "." + type.getName()); + if (!typePackageName.isEmpty()) { + builder.append(typePackageName + "." + type.getName()); } else { builder.append(type.getName()); } - + } + if (type.equals(Types.voidType())) { + return "void"; } if (type instanceof ParameterizedType) { - ParameterizedType pType = (ParameterizedType) type; - Type[] pTypes = pType.getActualTypeArguments(); + final ParameterizedType pType = (ParameterizedType) type; + final Type[] pTypes = pType.getActualTypeArguments(); builder.append("<"); - builder.append(getParameters(pTypes, availableImports, currentPkg)); + builder.append(getParameters(pTypes, imports, currentPkg)); builder.append(">"); } - if (builder.toString().equals("Void")) { - return "void"; - } return builder.toString(); } } - private static String getParameters(final Type[] pTypes, - Map> availableImports, String currentPkg) { + private static String getParameters(final Type[] pTypes, Map availableImports, String currentPkg) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < pTypes.length; i++) { - Type t = pTypes[i]; + final Type t = pTypes[i]; String separator = COMMA; - if (i + 1 == pTypes.length) { + if (i == (pTypes.length - 1)) { separator = ""; } String wildcardParam = ""; - if (t instanceof WildcardType) { - wildcardParam = "? extends "; - } - - builder.append(wildcardParam + getExplicitType(t, availableImports, currentPkg) + separator); - } - return builder.toString(); - } + if (t.equals(Types.voidType())) { + builder.append("java.lang.Void" + separator); + continue; + } else { - private static List findMaxValue(LinkedHashMap imports) { - final List result = new ArrayList(); + if (t instanceof WildcardType) { + wildcardParam = "? extends "; + } - int maxValue = 0; - int currentValue = 0; - for (Map.Entry entry : imports.entrySet()) { - currentValue = entry.getValue(); - if (currentValue > maxValue) { - result.clear(); - result.add(entry.getKey()); - maxValue = currentValue; - } else if (currentValue == maxValue) { - result.add(entry.getKey()); + builder.append(wildcardParam + getExplicitType(t, availableImports, currentPkg) + separator); } } - return result; + return builder.toString(); } private static void createComment(final StringBuilder builder, final String comment, final String indent) { @@ -609,104 +851,141 @@ public final class GeneratorUtil { } } - public static Map> createImports(GeneratedType genType) { - final Map> imports = new HashMap>(); - final String genTypePkg = genType.getPackageName(); + public static Map createImports(GeneratedType genType) { + if (genType == null) { + throw new IllegalArgumentException("Generated Type cannot be NULL!"); + } + final Map imports = new LinkedHashMap<>(); + List childGeneratedTypes = genType.getEnclosedTypes(); + if (!childGeneratedTypes.isEmpty()) { + for (GeneratedType genTypeChild : childGeneratedTypes) { + imports.putAll(createImports(genTypeChild)); + } + } final List constants = genType.getConstantDefinitions(); final List methods = genType.getMethodDefinitions(); - List impl = genType.getImplements(); + final List impl = genType.getImplements(); // IMPLEMENTATIONS if (impl != null) { - for (Type t : impl) { - addTypeToImports(t, imports, genTypePkg); + for (final Type type : impl) { + putTypeIntoImports(genType, type, imports); } } // CONSTANTS if (constants != null) { - for (Constant c : constants) { - Type ct = c.getType(); - addTypeToImports(ct, imports, genTypePkg); + for (final Constant constant : constants) { + final Type constantType = constant.getType(); + putTypeIntoImports(genType, constantType, imports); + } + } + + // REGULAR EXPRESSION + if (genType instanceof GeneratedTransferObject) { + if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) { + putTypeIntoImports(genType, Types.typeForClass(java.util.regex.Pattern.class), imports); + putTypeIntoImports(genType, Types.typeForClass(java.util.Arrays.class), imports); + putTypeIntoImports(genType, Types.typeForClass(java.util.ArrayList.class), imports); } } // METHODS if (methods != null) { - for (MethodSignature m : methods) { - Type ct = m.getReturnType(); - addTypeToImports(ct, imports, genTypePkg); - for (MethodSignature.Parameter p : m.getParameters()) { - addTypeToImports(p.getType(), imports, genTypePkg); + for (final MethodSignature method : methods) { + final Type methodReturnType = method.getReturnType(); + putTypeIntoImports(genType, methodReturnType, imports); + for (final MethodSignature.Parameter methodParam : method.getParameters()) { + putTypeIntoImports(genType, methodParam.getType(), imports); } } } // PROPERTIES if (genType instanceof GeneratedTransferObject) { - GeneratedTransferObject genTO = (GeneratedTransferObject) genType; - - List props = genTO.getProperties(); - if (props != null) { - for (GeneratedProperty prop : props) { - Type pt = prop.getReturnType(); - addTypeToImports(pt, imports, genTypePkg); + final GeneratedTransferObject genTO = (GeneratedTransferObject) genType; + final List properties = genTO.getProperties(); + if (properties != null) { + for (GeneratedProperty property : properties) { + final Type propertyType = property.getReturnType(); + putTypeIntoImports(genType, propertyType, imports); } } } - // REGULAR EXPRESSION - if (genType instanceof GeneratedTransferObject) { - if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) { - addTypeToImports(Types.typeForClass(java.util.regex.Pattern.class), imports, genTypePkg); - addTypeToImports(Types.typeForClass(java.util.Arrays.class), imports, genTypePkg); - addTypeToImports(Types.typeForClass(java.util.ArrayList.class), imports, genTypePkg); + return imports; + } + + public static Map createChildImports(GeneratedType genType) { + Map childImports = new LinkedHashMap<>(); + List childGeneratedTypes = genType.getEnclosedTypes(); + if (!childGeneratedTypes.isEmpty()) { + for (GeneratedType genTypeChild : childGeneratedTypes) { + createChildImports(genTypeChild); + childImports.put(genTypeChild.getName(), genTypeChild.getPackageName()); } } - - return imports; + return childImports; } - private static void addTypeToImports(Type type, Map> importedTypes, - String genTypePkg) { - String typeName = type.getName(); - String typePkg = type.getPackageName(); - if (typePkg.startsWith("java.lang") || typePkg.equals(genTypePkg) || typePkg.isEmpty()) { - return; + private static void putTypeIntoImports(final GeneratedType parentGenType, final Type type, + final Map imports) { + if (parentGenType == null) { + throw new IllegalArgumentException("Parent Generated Type parameter MUST be specified and cannot be " + + "NULL!"); } - LinkedHashMap packages = importedTypes.get(typeName); - if (packages == null) { - packages = new LinkedHashMap(); - packages.put(typePkg, 1); - importedTypes.put(typeName, packages); - } else { - Integer occurrence = packages.get(typePkg); - if (occurrence == null) { - packages.put(typePkg, 1); - } else { - occurrence++; - packages.put(typePkg, occurrence); - } + if (parentGenType.getName() == null) { + throw new IllegalArgumentException("Parent Generated Type name cannot be NULL!"); + } + if (parentGenType.getPackageName() == null) { + throw new IllegalArgumentException("Parent Generated Type cannot have Package Name referenced as NULL!"); + } + if (type == null) { + throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!"); + } + if (type.getName() == null) { + throw new IllegalArgumentException("Type name cannot be NULL!"); + } + if (type.getPackageName() == null) { + throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!"); } + final String typeName = type.getName(); + final String typePackageName = type.getPackageName(); + final String parentTypeName = parentGenType.getName(); + final String parentTypePackageName = parentGenType.getPackageName(); + if (typeName.equals(parentTypeName) || typePackageName.startsWith("java.lang") + || typePackageName.equals(parentTypePackageName) || typePackageName.isEmpty()) { + return; + } + if (!imports.containsKey(typeName)) { + imports.put(typeName, typePackageName); + } if (type instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) type; - Type[] params = pt.getActualTypeArguments(); + final ParameterizedType paramType = (ParameterizedType) type; + final Type[] params = paramType.getActualTypeArguments(); for (Type param : params) { - addTypeToImports(param, importedTypes, genTypePkg); + putTypeIntoImports(parentGenType, param, imports); } } } - public static List createImportLines(Map> imports) { - List importLines = new ArrayList(); - - for (Map.Entry> entry : imports.entrySet()) { - String typeName = entry.getKey(); - LinkedHashMap typePkgMap = entry.getValue(); - String typePkg = typePkgMap.keySet().iterator().next(); - importLines.add("import " + typePkg + "." + typeName + SC); + public static List createImportLines(final Map imports, + final Map innerTypeImports) { + final List importLines = new ArrayList<>(); + + for (Map.Entry entry : imports.entrySet()) { + final String typeName = entry.getKey(); + final String packageName = entry.getValue(); + if (innerTypeImports != null) { + String innerTypePackageName = innerTypeImports.get(typeName); + if (innerTypePackageName != null) { + if (innerTypePackageName.equals(packageName)) + continue; + } + } + importLines.add("import " + packageName + "." + typeName + SC); } return importLines; } @@ -724,4 +1003,94 @@ public final class GeneratorUtil { return false; } + /** + * The method returns reference to highest (top parent) Generated Transfer + * Object. + * + * @param childTransportObject + * is generated transfer object which can be extended by other + * generated transfer object + * @return in first case that childTransportObject isn't + * extended then childTransportObject is returned. In + * second case the method is recursive called until first case. + */ + private static GeneratedTransferObject getTopParrentTransportObject(GeneratedTransferObject childTransportObject) { + if (childTransportObject == null) { + throw new IllegalArgumentException("Parameter childTransportObject can't be null."); + } + if (childTransportObject.getExtends() == null) { + return childTransportObject; + } else { + return getTopParrentTransportObject(childTransportObject.getExtends()); + } + } + + /** + * The method returns the list of the properties of all extending generated + * transfer object from genTO to highest parent generated + * transfer object + * + * @param genTO + * @return the list of all properties from actual to highest parent + * generated transfer object. In case when extension exists the + * method is recursive called. + */ + private static List getPropertiesOfAllParents(GeneratedTransferObject genTO) { + List propertiesOfAllParents = new ArrayList(); + if (genTO != null) { + final List allPropertiesOfTO = genTO.getProperties(); + List readOnlyPropertiesOfTO = resolveReadOnlyPropertiesFromTO(allPropertiesOfTO); + propertiesOfAllParents.addAll(readOnlyPropertiesOfTO); + if (genTO.getExtends() != null) { + propertiesOfAllParents.addAll(getPropertiesOfAllParents(genTO.getExtends())); + } + } + return propertiesOfAllParents; + } + + public static String createStaticInicializationBlock(GeneratedTransferObject genTransferObject, String indent) { + + final StringBuilder builder = new StringBuilder(); + + List constants = genTransferObject.getConstantDefinitions(); + for (Constant constant : constants) { + if (constant.getName() == null || constant.getType() == null || constant.getValue() == null) { + continue; + } + if (constant.getName().equals(TypeConstants.PATTERN_CONSTANT_NAME)) { + final Object constValue = constant.getValue(); + List regularExpressions = new ArrayList<>(); + if (constValue instanceof List) { + builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP + "List" + GAP + + TypeConstants.PATTERN_CONSTANT_NAME + GAP + "=" + GAP + "Arrays.asList" + LB); + final List constantValues = (List) constValue; + int stringsCount = 0; + for (Object value : constantValues) { + if (value instanceof String) { + if (stringsCount > 0) { + builder.append(COMMA); + } + stringsCount++; + regularExpressions.add((String) value); + builder.append(DOUBLE_QUOTE + (String) value + DOUBLE_QUOTE); + } + } + builder.append(RB + SC + NL); + } + builder.append(indent + PRIVATE + GAP + STATIC + GAP + FINAL + GAP + "List" + GAP + + MEMBER_PATTERN_LIST + GAP + ASSIGN + GAP + "new ArrayList()" + GAP + SC + NL + NL); + + if (!regularExpressions.isEmpty()) { + builder.append(indent + STATIC + LCB + NL); + builder.append(indent + TAB + "for (String regEx : " + TypeConstants.PATTERN_CONSTANT_NAME + ") {" + + NL); + builder.append(indent + TAB + TAB + MEMBER_PATTERN_LIST + ".add(Pattern.compile(regEx))" + SC + NL); + builder.append(indent + TAB + RCB + NL); + builder.append(indent + RCB + NL + NL); + } + + } + } + return builder.toString(); + } }