X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding2%2Fmdsal-binding2-java-api-generator%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fjavav2%2Fjava%2Fapi%2Fgenerator%2Frenderers%2FBuilderRenderer.java;h=ac4d63fb09001361aa24c686774f6b568258f483;hb=03d720f8a36091935d80a90f713acf12327eb1ae;hp=53a7b94899aa1523160519d2b88b989dc1e5318e;hpb=141e3def6accb5c75feed87d98cfa29acfcd8d61;p=mdsal.git diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/javav2/java/api/generator/renderers/BuilderRenderer.java b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/javav2/java/api/generator/renderers/BuilderRenderer.java old mode 100644 new mode 100755 index 53a7b94899..ac4d63fb09 --- a/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/javav2/java/api/generator/renderers/BuilderRenderer.java +++ b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/javav2/java/api/generator/renderers/BuilderRenderer.java @@ -8,6 +8,7 @@ package org.opendaylight.mdsal.binding.javav2.java.api.generator.renderers; +import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.typeForClass; import static org.opendaylight.mdsal.binding.javav2.java.api.generator.util.TextTemplateUtil.DOT; import static org.opendaylight.mdsal.binding.javav2.java.api.generator.util.TextTemplateUtil.getPropertyList; import static org.opendaylight.mdsal.binding.javav2.java.api.generator.util.TextTemplateUtil.toFirstLower; @@ -16,12 +17,14 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.ClassToInstanceMap; import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSortedSet; + import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -29,53 +32,74 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.regex.Pattern; + +import org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes; import org.opendaylight.mdsal.binding.javav2.generator.util.ReferencedTypeImpl; import org.opendaylight.mdsal.binding.javav2.generator.util.Types; import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl; import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.builderConstructorHelperTemplate; import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.builderTemplate; +import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.constantsTemplate; import org.opendaylight.mdsal.binding.javav2.java.api.generator.util.AlphabeticallyTypeMemberComparator; import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedProperty; import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject; import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType; +import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTypeForBuilder; import org.opendaylight.mdsal.binding.javav2.model.api.MethodSignature; import org.opendaylight.mdsal.binding.javav2.model.api.ParameterizedType; import org.opendaylight.mdsal.binding.javav2.model.api.Type; +import org.opendaylight.mdsal.binding.javav2.spec.base.IdentifiableItem; import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable; import org.opendaylight.mdsal.binding.javav2.spec.base.Item; import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode; +import org.opendaylight.mdsal.binding.javav2.spec.runtime.CodeHelpers; import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentable; import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentation; import org.opendaylight.mdsal.binding.javav2.spec.structural.AugmentationHolder; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.common.QName; public class BuilderRenderer extends BaseRenderer { /** - * Set of class attributes (fields) which are derived from the getter methods names + * Set of class attributes (fields) which are derived from the getter methods names. */ private final Set properties; /** - * Set of name from properties + * Set of name from properties. */ private final Map importedNamesForProperties = new HashMap<>(); /** - * list of all imported names for template - */ - private final Map importedNames = new HashMap<>(); - - /** - * Generated property is set if among methods is found one with the name GET_AUGMENTATION_METHOD_NAME + * Generated property is set if among methods is found one with the name GET_AUGMENTATION_METHOD_NAME. */ private GeneratedProperty augmentField; + boolean instantiable = false; + public BuilderRenderer(final GeneratedType type) { super(type); this.properties = propertiesFromMethods(createMethods()); putToImportMap(Builder.class.getSimpleName(), Builder.class.getPackage().getName()); + putToImportMap(type.getName(), type.getPackageName()); + } + + @Override + protected String packageDefinition() { + final StringBuilder sb = new StringBuilder(); + sb.append("package ") + .append(((GeneratedTypeForBuilder) getType()).getPackageNameForBuilder()) + .append(";\n\n"); + return sb.toString(); + } + + @Override + protected boolean hasSamePackage(final String importedTypePackageName) { + return ((GeneratedTypeForBuilder) getType()).getPackageNameForBuilder() + .equals(importedTypePackageName); } /** @@ -94,6 +118,9 @@ public class BuilderRenderer extends BaseRenderer { if (createdField != null) { result.add(createdField); importedNamesForProperties.put(createdField, importedName(createdField.getReturnType())); + if (createdField.getReturnType().equals(typeForClass(List.class))) { + getImportedNames().put("arrayList", importedName(ArrayList.class)); + } } } return result; @@ -104,22 +131,23 @@ public class BuilderRenderer extends BaseRenderer { * * @param method method signature from which is the method name and return type obtained * @return generated property instance for the getter method - * @throws IllegalArgumentException - *
  • if the method equals null
  • - *
  • if the name of the method equals null
  • - *
  • if the name of the method is empty
  • - *
  • if the return type of the method equals null
  • + * @throws IllegalArgumentException
  • if the method equals null
  • + *
  • if the name of the method equals null
  • + *
  • if the name of the method is empty
  • + *
  • if the return type of the method equals null
  • */ private GeneratedProperty propertyFromGetter(final MethodSignature method) { Preconditions.checkArgument(method != null, "Method cannot be NULL"); - Preconditions.checkArgument(!Strings.isNullOrEmpty(method.getName()), "Method name cannot be NULL or empty"); - Preconditions.checkArgument(method.getReturnType() != null, "Method return type reference cannot be NULL"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(method.getName()), + "Method name cannot be NULL or empty"); + Preconditions.checkArgument(method.getReturnType() != null, + "Method return type reference cannot be NULL"); final String prefix = Types.BOOLEAN.equals(method.getReturnType()) ? "is" : "get"; if (method.getName().startsWith(prefix)) { final String fieldName = toFirstLower(method.getName().substring(prefix.length())); - final GeneratedTOBuilderImpl tmpGenTO = new GeneratedTOBuilderImpl("foo", "foo"); - tmpGenTO.addProperty(fieldName) - .setReturnType(method.getReturnType()); + final GeneratedTOBuilderImpl tmpGenTO = + new GeneratedTOBuilderImpl("foo", "foo", true); + tmpGenTO.addProperty(fieldName).setReturnType(method.getReturnType()); return tmpGenTO.toInstance().getProperties().get(0); } return null; @@ -146,7 +174,7 @@ public class BuilderRenderer extends BaseRenderer { * Adds to the methods set all the methods of the implementedIfcs * and recursively their implemented interfaces. * - * @param methods set of method signatures + * @param methods set of method signatures * @param implementedIfcs list of implemented interfaces */ private void collectImplementedMethods(final Set methods, List implementedIfcs) { @@ -154,7 +182,9 @@ public class BuilderRenderer extends BaseRenderer { for (Type implementedIfc : implementedIfcs) { if ((implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject))) { final GeneratedType ifc = (GeneratedType) implementedIfc; - methods.addAll(ifc.getMethodDefinitions()); + if (implementedIfc instanceof GeneratedTypeForBuilder) { + methods.addAll(ifc.getMethodDefinitions()); + } collectImplementedMethods(methods, ifc.getImplements()); } else if (Augmentable.class.getName().equals(implementedIfc.getFullyQualifiedName())) { for (Method method : Augmentable.class.getMethods()) { @@ -162,22 +192,30 @@ public class BuilderRenderer extends BaseRenderer { final String fullyQualifiedName = method.getReturnType().getName(); final String aPackage = getPackage(fullyQualifiedName); final String name = getName(fullyQualifiedName); - final GeneratedTOBuilderImpl generatedTOBuilder = new GeneratedTOBuilderImpl(aPackage, name); - final ReferencedTypeImpl referencedType = new ReferencedTypeImpl(aPackage, name, true); + final GeneratedTOBuilderImpl generatedTOBuilder = new GeneratedTOBuilderImpl(aPackage, + name, true); + final ReferencedTypeImpl referencedType = new ReferencedTypeImpl(aPackage, name, + true, null); final ReferencedTypeImpl generic = new ReferencedTypeImpl(getType().getPackageName(), - getType().getName(), true); - final ParameterizedType parametrizedReturnType = Types.parameterizedTypeFor(referencedType, generic); + getType().getName(), true, null); + final ParameterizedType parametrizedReturnType = + Types.parameterizedTypeFor(referencedType, generic); generatedTOBuilder.addMethod(method.getName()).setReturnType(parametrizedReturnType); - augmentField = propertyFromGetter(generatedTOBuilder.toInstance().getMethodDefinitions().get(0)); - importedNames.put("map", importedName(Map.class)); - importedNames.put("hashMap", importedName(HashMap.class)); - importedNames.put("class", importedName(Class.class)); + augmentField = propertyFromGetter(generatedTOBuilder.toInstance().getMethodDefinitions() + .get(0)); + getImportedNames().put("map", importedName(Map.class)); + getImportedNames().put("hashMap", importedName(HashMap.class)); + getImportedNames().put("class", importedName(Class.class)); // To do This is for third party, is it needed ? - importedNames.put("augmentationHolder", importedName(AugmentationHolder.class)); - importedNames.put("collections", importedName(Collections.class)); - importedNames.put("augmentFieldReturnType", importedName(augmentField.getReturnType())); + getImportedNames().put("augmentationHolder", importedName(AugmentationHolder.class)); + getImportedNames().put("collections", importedName(Collections.class)); + getImportedNames().put("augmentFieldReturnType", importedName( + augmentField.getReturnType())); } } + } else if (Instantiable.class.getName().equals(implementedIfc.getFullyQualifiedName())) { + getImportedNames().put("class", importedName(Class.class)); + instantiable = true; } } } @@ -195,7 +233,7 @@ public class BuilderRenderer extends BaseRenderer { } /** - * Returns the name of tye type from fullyQualifiedName + * Returns the name of the type from fullyQualifiedName. * * @param fullyQualifiedName string with fully qualified type name (package + type) * @return string with the name of the type @@ -208,8 +246,8 @@ public class BuilderRenderer extends BaseRenderer { public static Set getAllIfcs(final Type type) { final Set baseIfcs = new HashSet<>(); if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) { - for (Type impl : ((GeneratedType)type).getImplements()) { - if (impl instanceof GeneratedType && !(((GeneratedType)impl).getMethodDefinitions().isEmpty())) { + for (Type impl : ((GeneratedType) type).getImplements()) { + if (impl instanceof GeneratedType && !(((GeneratedType) impl).getMethodDefinitions().isEmpty())) { baseIfcs.add(impl); } baseIfcs.addAll(getAllIfcs(impl)); @@ -220,10 +258,13 @@ public class BuilderRenderer extends BaseRenderer { /** * Method is used to find out if given type implements any interface from uses. + * + * @param type type to inspect + * @return has implements from uses-stmt true/false */ public static boolean hasImplementsFromUses(GeneratedType type) { for (Type impl : getAllIfcs(type)) { - if ((impl instanceof GeneratedType) && !(((GeneratedType)impl).getMethodDefinitions().isEmpty())) { + if ((impl instanceof GeneratedType) && !(((GeneratedType) impl).getMethodDefinitions().isEmpty())) { return true; } } @@ -240,56 +281,78 @@ public class BuilderRenderer extends BaseRenderer { @Override protected String body() { - String parentTypeForBuilderName; - importedNames.put("genType", importedName(getType())); - importedNames.put("objects", importedName(Objects.class)); - importedNames.put("object", importedName(Object.class)); - importedNames.put("string", importedName(String.class)); - importedNames.put("stringBuilder", importedName(StringBuilder.class)); - importedNames.put("treeNode", importedName(TreeNode.class)); - importedNames.put("instantiable", importedName(Instantiable.class)); - importedNames.put("item", importedName(Item.class)); + final String parentTypeForBuilderName; + getImportedNames().put("genType", importedName(getType())); + getImportedNames().put("objects", importedName(Objects.class)); + getImportedNames().put("object", importedName(Object.class)); + getImportedNames().put("string", importedName(String.class)); + getImportedNames().put("arrays", importedName(Arrays.class)); + getImportedNames().put("stringBuilder", importedName(StringBuilder.class)); + getImportedNames().put("treeNode", importedName(TreeNode.class)); + getImportedNames().put("instantiable", importedName(Instantiable.class)); + getImportedNames().put("item", importedName(Item.class)); + getImportedNames().put("identifiableItem", importedName(IdentifiableItem.class)); + getImportedNames().put("qname", importedName(QName.class)); + getImportedNames().put("codeHelpers", importedName(CodeHelpers.class)); + getImportedNames().put("list", importedName(List.class)); + getImportedNames().put("immutableList", importedName(ImmutableList.class)); + getImportedNames().put("pattern", importedName(Pattern.class)); + if (getType().getParentType() != null) { - importedNames.put("parent", importedName(getType().getParentType())); - parentTypeForBuilderName = getType().getParentType().getName(); + getImportedNames().put("parent", importedName(getType().getParentType())); + parentTypeForBuilderName = getType().getParentType().getFullyQualifiedName(); + } else if (getType().getParentTypeForBuilder() != null) { + getImportedNames().put("parentTypeForBuilder", importedName(getType().getParentTypeForBuilder())); + parentTypeForBuilderName = getType().getParentTypeForBuilder().getFullyQualifiedName(); } else { - importedNames.put("parentTypeForBuilder", importedName(getType().getParentTypeForBuilder())); - parentTypeForBuilderName = getType().getParentTypeForBuilder().getName(); + parentTypeForBuilderName = null; } - importedNames.put("augmentation", importedName(Augmentation.class)); - importedNames.put("classInstMap", importedName(ClassToInstanceMap.class)); + + boolean childTreeNode = false; + boolean childTreeNodeIdent = false; + String keyTypeName = null; + if (getType().getImplements().contains(BindingTypes.TREE_CHILD_NODE)) { + childTreeNode = true; + if (getType().getImplements().contains(BindingTypes.IDENTIFIABLE)) { + childTreeNodeIdent = true; + final ParameterizedType pType = (ParameterizedType) getType().getImplements().get(getType() + .getImplements().indexOf(BindingTypes.IDENTIFIABLE)); + keyTypeName = pType.getActualTypeArguments()[0].getName(); + } + } + + getImportedNames().put("augmentation", importedName(Augmentation.class)); + getImportedNames().put("classInstMap", importedName(ClassToInstanceMap.class)); + + final String constants = constantsTemplate.render(getType(), getImportedNames(), this::importedName, false) + .body(); // list for generate copy constructor final String copyConstructorHelper = generateListForCopyConstructor(); List getterMethods = new ArrayList<>(Collections2.transform(properties, this::getterMethod)); - return builderTemplate.render(getType(), properties, importedNames, importedNamesForProperties, augmentField, - copyConstructorHelper, getterMethods, parentTypeForBuilderName) - .body(); + return builderTemplate.render(getType(), properties, getImportedNames(), importedNamesForProperties, + augmentField, + copyConstructorHelper, getterMethods, parentTypeForBuilderName, childTreeNode, childTreeNodeIdent, + keyTypeName, instantiable, constants).body(); } private String generateListForCopyConstructor() { final List allProps = new ArrayList<>(properties); - final boolean isList = implementsIfc(getType(), Types.parameterizedTypeFor(Types.typeForClass(Identifiable.class), - getType())); + final boolean isList = implementsIfc(getType(), + Types.parameterizedTypeFor(typeForClass(Identifiable.class), getType())); final Type keyType = getKey(getType()); if (isList && keyType != null) { final List keyProps = ((GeneratedTransferObject) keyType).getProperties(); - final Comparator function = (GeneratedProperty p1, GeneratedProperty p2) -> { - String name2 = p1.getName(); - String name3 = p2.getName(); - return name2.compareTo(name3); - }; - Collections.sort(keyProps, function); for (GeneratedProperty keyProp : keyProps) { removeProperty(allProps, keyProp.getName()); } removeProperty(allProps, "key"); - importedNames.put("keyTypeConstructor", importedName(keyType)); - return builderConstructorHelperTemplate.render(allProps, keyProps, importedNames, getPropertyList(allProps)) - .body(); + getImportedNames().put("keyTypeConstructor", importedName(keyType)); + return builderConstructorHelperTemplate.render(allProps, keyProps, getImportedNames(), + getPropertyList(keyProps)).body(); } - return builderConstructorHelperTemplate.render(allProps, null, importedNames, null).body(); + return builderConstructorHelperTemplate.render(allProps, null, getImportedNames(), null).body(); } private Type getKey(final GeneratedType genType) { @@ -305,10 +368,10 @@ public class BuilderRenderer extends BaseRenderer { return type.getImplements().contains(impl); } - private void removeProperty(final Collection properties, final String name) { - for (final GeneratedProperty property : properties) { + private void removeProperty(final Collection props, final String name) { + for (final GeneratedProperty property : props) { if (name.equals(property.getName())) { - properties.remove(property); + props.remove(property); break; } }