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;
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;
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<GeneratedProperty> properties;
/**
- * Set of name from properties
+ * Set of name from properties.
*/
private final Map<GeneratedProperty, String> importedNamesForProperties = new HashMap<>();
/**
- * list of all imported names for template
- */
- private final Map<String, String> 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);
}
/**
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;
*
* @param method method signature from which is the method name and return type obtained
* @return generated property instance for the getter <code>method</code>
- * @throws IllegalArgumentException
- * <li>if the <code>method</code> equals <code>null</code></li>
- * <li>if the name of the <code>method</code> equals <code>null</code></li>
- * <li>if the name of the <code>method</code> is empty</li>
- * <li>if the return type of the <code>method</code> equals <code>null</code></li>
+ * @throws IllegalArgumentException <li>if the <code>method</code> equals <code>null</code></li>
+ * <li>if the name of the <code>method</code> equals <code>null</code></li>
+ * <li>if the name of the <code>method</code> is empty</li>
+ * <li>if the return type of the <code>method</code> equals <code>null</code></li>
*/
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;
* Adds to the <code>methods</code> set all the methods of the <code>implementedIfcs</code>
* 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<MethodSignature> methods, List<Type> implementedIfcs) {
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()) {
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;
}
}
}
}
/**
- * Returns the name of tye type from <code>fullyQualifiedName</code>
+ * Returns the name of the type from <code>fullyQualifiedName</code>.
*
* @param fullyQualifiedName string with fully qualified type name (package + type)
* @return string with the name of the type
public static Set<Type> getAllIfcs(final Type type) {
final Set<Type> 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));
/**
* 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;
}
}
@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<String> 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<GeneratedProperty> keyProps = ((GeneratedTransferObject) keyType).getProperties();
- final Comparator<GeneratedProperty> 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) {
return type.getImplements().contains(impl);
}
- private void removeProperty(final Collection<GeneratedProperty> properties, final String name) {
- for (final GeneratedProperty property : properties) {
+ private void removeProperty(final Collection<GeneratedProperty> props, final String name) {
+ for (final GeneratedProperty property : props) {
if (name.equals(property.getName())) {
- properties.remove(property);
+ props.remove(property);
break;
}
}