io.sundr.builder.internal.functions.ToMethod Maven / Gradle / Ivy
/*
* Copyright 2015 The original authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.sundr.builder.internal.functions;
import io.sundr.Function;
import io.sundr.FunctionFactory;
import io.sundr.builder.Constants;
import io.sundr.builder.internal.BuilderContextManager;
import io.sundr.builder.internal.utils.BuilderUtils;
import io.sundr.codegen.functions.Singularize;
import io.sundr.codegen.model.Attributeable;
import io.sundr.codegen.model.ClassRef;
import io.sundr.codegen.model.Method;
import io.sundr.codegen.model.MethodBuilder;
import io.sundr.codegen.model.Property;
import io.sundr.codegen.model.PropertyBuilder;
import io.sundr.codegen.model.Statement;
import io.sundr.codegen.model.StringStatement;
import io.sundr.codegen.model.TypeDef;
import io.sundr.codegen.model.TypeParamDef;
import io.sundr.codegen.model.TypeRef;
import io.sundr.codegen.utils.StringUtils;
import io.sundr.codegen.utils.TypeUtils;
import javax.lang.model.element.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import static io.sundr.builder.Constants.BUILDABLE_ARRAY_GETTER_SNIPPET;
import static io.sundr.builder.Constants.DESCENDANTS;
import static io.sundr.builder.Constants.DESCENDANT_OF;
import static io.sundr.builder.Constants.GENERIC_TYPE_REF;
import static io.sundr.builder.Constants.N_REF;
import static io.sundr.builder.Constants.OUTER_CLASS;
import static io.sundr.builder.Constants.Q;
import static io.sundr.builder.Constants.SIMPLE_ARRAY_GETTER_SNIPPET;
import static io.sundr.builder.Constants.T_REF;
import static io.sundr.builder.Constants.VOID;
import static io.sundr.builder.internal.functions.CollectionTypes.IS_COLLECTION;
import static io.sundr.builder.internal.functions.CollectionTypes.IS_LIST;
import static io.sundr.builder.internal.functions.CollectionTypes.IS_MAP;
import static io.sundr.builder.internal.functions.CollectionTypes.IS_SET;
import static io.sundr.builder.internal.functions.TypeAs.ARRAY_OF;
import static io.sundr.builder.internal.functions.TypeAs.BUILDER;
import static io.sundr.builder.internal.functions.TypeAs.UNWRAP_ARRAY_OF;
import static io.sundr.builder.internal.functions.TypeAs.UNWRAP_COLLECTION_OF;
import static io.sundr.builder.internal.functions.TypeAs.VISITABLE_BUILDER;
import static io.sundr.builder.internal.functions.TypeAs.combine;
import static io.sundr.builder.internal.utils.BuilderUtils.getInlineableConstructors;
import static io.sundr.builder.internal.utils.BuilderUtils.isAbstract;
import static io.sundr.builder.internal.utils.BuilderUtils.isBoolean;
import static io.sundr.builder.internal.utils.BuilderUtils.isBuildable;
import static io.sundr.builder.internal.utils.BuilderUtils.isList;
import static io.sundr.builder.internal.utils.BuilderUtils.isMap;
import static io.sundr.builder.internal.utils.BuilderUtils.isSet;
import static io.sundr.codegen.utils.StringUtils.captializeFirst;
import static io.sundr.codegen.utils.StringUtils.loadResourceQuietly;
public class ToMethod {
private static final String BUILDABLE_ARRAY_GETTER_TEXT = loadResourceQuietly(BUILDABLE_ARRAY_GETTER_SNIPPET);
private static final String SIMPLE_ARRAY_GETTER_TEXT = loadResourceQuietly(SIMPLE_ARRAY_GETTER_SNIPPET);
public static final Function WITH = FunctionFactory.cache(new Function() {
public Method apply(Property property) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
String methodName = "with" + property.getNameCapitalized();
List alsoImport = new ArrayList();
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withReturnType(returnType)
.withArguments(property)
.withVarArgPreferred(true)
.withNewBlock()
.withStatements(getStatements(property, alsoImport))
.endBlock()
.addToAttributes(Attributeable.ALSO_IMPORT, alsoImport)
.build();
}
private List getStatements(Property property, List alsoImport) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
String name = property.getName();
TypeRef type = property.getTypeRef();
TypeRef unwraped = combine(UNWRAP_COLLECTION_OF, UNWRAP_ARRAY_OF).apply(property.getTypeRef());
List statements = new ArrayList();
Set descendants = property.getAttributes().containsKey(DESCENDANTS) ? (Set) property.getAttributes().get(DESCENDANTS) : Collections.EMPTY_SET;
if (IS_COLLECTION.apply(type) || IS_MAP.apply(type)) {
statements.add(new StringStatement("this." + name + ".clear();"));
if (IS_MAP.apply(type)) {
statements.add(new StringStatement("if (" + name + " != null) {this." + name + ".putAll(" + name + ");} return (" + returnType + ") this;"));
} else if (IS_LIST.apply(type) || IS_SET.apply(type)) {
String addToMethodName = "addTo" + property.getNameCapitalized();
statements.add(new StringStatement("if (" + name + " != null) {for (" + unwraped.toString() + " item : " + name + "){this." + addToMethodName + "(item);}} return (" + returnType + ") this;"));
}
return statements;
} else if (isBuildable(unwraped) && !isAbstract(unwraped)) {
TypeDef builder = BUILDER.apply(((ClassRef) unwraped).getDefinition());
String propertyName = property.getName();
String builderClass = builder.toReference().getName();
if (property.getAttributes().containsKey(DESCENDANT_OF)) {
Property descendantOf = (Property) property.getAttributes().get(DESCENDANT_OF);
propertyName = descendantOf.getName();
}
statements.add(new StringStatement("if (" + propertyName + "!=null){ this." + propertyName + "= new " + builderClass + "("+name+"); _visitables.add(this." + propertyName + ");} return (" + returnType + ") this;"));
return statements;
} else if (!descendants.isEmpty()) {
for (Property descendant : descendants) {
TypeRef dunwraped = combine(UNWRAP_COLLECTION_OF, UNWRAP_ARRAY_OF).apply(descendant.getTypeRef());
TypeDef builder = BUILDER.apply(((ClassRef) dunwraped).getDefinition());
String propertyName = property.getName();
String builderClass = builder.toReference().getName();
statements.add(new StringStatement("if (" + propertyName + " instanceof " + dunwraped + "){ this." + propertyName + "= new " + builderClass + "((" + dunwraped + ")" + propertyName + "); _visitables.add(this." + propertyName + ");}"));
alsoImport.add((ClassRef) dunwraped);
alsoImport.add(builder.toInternalReference());
}
statements.add(new StringStatement("return (" + returnType + ") this;"));
return statements;
}
statements.add(new StringStatement("this." + property.getName() + "=" + property.getName() + "; return (" + returnType + ") this;"));
return statements;
}
});
public static final Function WITH_ARRAY = FunctionFactory.cache(new Function() {
public Method apply(Property property) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
String methodName = "with" + property.getNameCapitalized();
TypeRef unwraped = combine(UNWRAP_COLLECTION_OF, UNWRAP_ARRAY_OF).apply(property.getTypeRef());
String addToMethodName = "addTo" + property.getNameCapitalized();
TypeRef arrayType = ARRAY_OF.apply(unwraped);
Property arrayProperty = new PropertyBuilder(property).withTypeRef(arrayType).build();
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withReturnType(returnType)
.withArguments(arrayProperty)
.withVarArgPreferred(true)
.withNewBlock()
.addNewStringStatementStatement("this." + property.getName() + ".clear(); if (" + property.getName() + " != null) {for (" + unwraped.toString() + " item :" + property.getName() + "){ this." + addToMethodName + "(item);}} return (" + returnType + ") this;")
.endBlock()
.build();
}
});
public static final Function GETTER = FunctionFactory.cache(new Function() {
public Method apply(final Property property) {
TypeRef unwrapped = TypeAs.combine(TypeAs.UNWRAP_COLLECTION_OF, TypeAs.UNWRAP_ARRAY_OF).apply(property.getTypeRef());
String prefix = isBoolean(property.getTypeRef()) ? "is" : "get";
String methodName = prefix + property.getNameCapitalized();
final List statements = new ArrayList();
TreeSet descendants = new TreeSet(new Comparator() {
public int compare(Property left, Property right) {
return left.getName().compareTo(right.getName());
}
});
descendants.addAll(Decendants.PROPERTY_BUILDABLE_DESCENDANTS.apply(property));
if (isMap(property.getTypeRef())) {
statements.add(new StringStatement("return this." + property.getName() + ";"));
} else if (isBuildable(unwrapped)) {
if (isList(property.getTypeRef()) || isSet(property.getTypeRef())) {
statements.add(new StringStatement("return build(" + property.getName() + ");"));
} else {
statements.add(new StringStatement("return this." + property.getName() + "!=null?this." + property.getName() + ".build():null;"));
}
} else if (!descendants.isEmpty()) {
if (isList(property.getTypeRef()) || isSet(property.getTypeRef())) {
statements.add(new StringStatement("return build(" + property.getName() + ");"));
} else {
statements.add(new StringStatement("return this." + property.getName() + "!=null?this." + property.getName() + ".build():null;"));
}
} else {
statements.add(new StringStatement("return this." + property.getName() + ";"));
}
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withReturnType(property.getTypeRef())
.withArguments(new Property[]{})
.withNewBlock()
.withStatements(statements)
.endBlock()
.build();
}
});
public static final Function GETTER_ARRAY = FunctionFactory.cache(new Function() {
public Method apply(Property property) {
String prefix = isBoolean(property.getTypeRef()) ? "is" : "get";
String methodName = prefix + property.getNameCapitalized();
TypeRef type = property.getTypeRef();
Boolean isBuildable = isBuildable(type);
TypeRef targetType = isBuildable ? VISITABLE_BUILDER.apply(type) : TypeAs.UNWRAP_ARRAY_OF.apply(type);
String body = String.format(isBuildable ? BUILDABLE_ARRAY_GETTER_TEXT : SIMPLE_ARRAY_GETTER_TEXT,
type.toString(),
targetType.toString(),
property.getName(),
targetType.toString(),
property.getName()
);
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withReturnType(property.getTypeRef())
.withArguments()
.withNewBlock()
.addNewStringStatementStatement(body)
.endBlock()
.build();
}
});
public static final Function SETTER = FunctionFactory.cache(new Function() {
public Method apply(Property property) {
String methodName = "set" + property.getNameCapitalized();
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withReturnType(VOID)
.withArguments()
.withNewBlock()
.addNewStringStatementStatement("this." + property.getName() + "=" + property.getName() + ";")
.endBlock()
.build();
}
});
public static final Function ADD_TO_COLLECTION = FunctionFactory.cache(new Function() {
public Method apply(final Property property) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
final TypeRef unwrapped = TypeAs.combine(UNWRAP_COLLECTION_OF).apply(property.getTypeRef());
List alsoImport = new ArrayList();
Property item = new PropertyBuilder(property)
.withName("items")
.withTypeRef(unwrapped.withDimensions(1))
.build();
List parameters = new ArrayList();
String methodName = "addTo" + property.getNameCapitalized();
List statements = new ArrayList();
Set descendants = Decendants.PROPERTY_BUILDABLE_DESCENDANTS.apply(property);
if (isBuildable(unwrapped) && !isAbstract(unwrapped)) {
final ClassRef targetType = (ClassRef) unwrapped;
String propertyName = property.getName();
if (property.getAttributes().containsKey(Constants.DESCENDANT_OF)) {
Object attrValue = property.getAttributes().get(Constants.DESCENDANT_OF);
if (attrValue instanceof Property) {
propertyName = ((Property)attrValue).getName();
}
}
String targetClass = targetType.getName();
parameters.addAll(targetType.getDefinition().getParameters());
String builderClass = targetClass + "Builder";
//We need to do it more
alsoImport.add(TypeAs.BUILDER.apply(targetType.getDefinition()).toInternalReference());
statements.add(new StringStatement("for (" + targetClass + " item : items) {" + builderClass + " builder = new " + builderClass + "(item);_visitables.add(builder);this." + propertyName + ".add(builder);} return (" + returnType + ")this;"));
} else if (!descendants.isEmpty()) {
final ClassRef targetType = (ClassRef) unwrapped;
parameters.addAll(targetType.getDefinition().getParameters());
statements.add(new StringStatement("for (" + targetType.toString() + " item : items) {" + StringUtils.join(descendants, new Function() {
public String apply(Property item) {
TypeRef itemRef = TypeAs.combine(UNWRAP_COLLECTION_OF, ARRAY_OF).apply(item.getTypeRef());
String className = ((ClassRef) itemRef).getName();
String addToMethodName = "addTo" + captializeFirst(item.getName());
return "if (item instanceof " + className + "){" + addToMethodName + "((" + className + ")item);}\n";
}
}, " else ") + "} return (" + returnType + ")this;"));
} else {
statements.add(new StringStatement("for (" + unwrapped.toString() + " item : items) {this." + property.getName() + ".add(item);} return (" + returnType + ")this;"));
}
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withParameters(parameters)
.withName(methodName)
.withReturnType(returnType)
.withArguments(item)
.withVarArgPreferred(true)
.withNewBlock()
.withStatements(statements)
.endBlock()
.addToAttributes(Attributeable.ALSO_IMPORT, alsoImport)
.build();
}
});
public static final Function REMOVE_FROM_COLLECTION = FunctionFactory.cache(new Function() {
public Method apply(final Property property) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
final TypeRef unwrapped = TypeAs.combine(UNWRAP_COLLECTION_OF).apply(property.getTypeRef());
List alsoImport = new ArrayList();
Property item = new PropertyBuilder(property)
.withName("items")
.withTypeRef(unwrapped.withDimensions(1))
.build();
List parameters = new ArrayList();
String methodName = "removeFrom" + property.getNameCapitalized();
List statements = new ArrayList();
Set descendants = Decendants.PROPERTY_BUILDABLE_DESCENDANTS.apply(property);
if (isBuildable(unwrapped) && !isAbstract(unwrapped)) {
final ClassRef targetType = (ClassRef) unwrapped;
String propertyName = property.getName();
if (property.getAttributes().containsKey(Constants.DESCENDANT_OF)) {
Object attrValue = property.getAttributes().get(Constants.DESCENDANT_OF);
if (attrValue instanceof Property) {
propertyName = ((Property)attrValue).getName();
}
}
String targetClass = targetType.getName();
parameters.addAll(targetType.getDefinition().getParameters());
String builderClass = targetClass + "Builder";
//We need to do it more elegantly
alsoImport.add(TypeAs.BUILDER.apply(targetType.getDefinition()).toInternalReference());
statements.add(new StringStatement("for (" + targetClass + " item : items) {" + builderClass + " builder = new " + builderClass + "(item);_visitables.remove(builder);this." + propertyName + ".remove(builder);} return (" + returnType + ")this;"));
} else if (!descendants.isEmpty()) {
final ClassRef targetType = (ClassRef) unwrapped;
parameters.addAll(targetType.getDefinition().getParameters());
statements.add(new StringStatement("for (" + targetType.toString() + " item : items) {" + StringUtils.join(descendants, new Function() {
public String apply(Property item) {
TypeRef itemRef = TypeAs.combine(UNWRAP_COLLECTION_OF, ARRAY_OF).apply(item.getTypeRef());
String className = ((ClassRef) itemRef).getName();
String removeFromMethodName = "removeFrom" + captializeFirst(item.getName());
return "if (item instanceof " + className + "){" + removeFromMethodName + "((" + className + ")item);}\n";
}
}, " else ") + "} return (" + returnType + ")this;"));
} else {
statements.add(new StringStatement("for (" + unwrapped.toString() + " item : items) {this." + property.getName() + ".remove(item);} return (" + returnType + ")this;"));
}
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withParameters(parameters)
.withReturnType(returnType)
.withArguments(item)
.withVarArgPreferred(true)
.withNewBlock()
.withStatements(statements)
.endBlock()
.build();
}
});
public static final Function ADD_MAP_TO_MAP = FunctionFactory.cache(new Function() {
public Method apply(Property property) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
ClassRef mapType = (ClassRef) property.getTypeRef();
Property mapProperty = new PropertyBuilder().withName("map").withTypeRef(mapType).build();
String methodName = "addTo" + property.getNameCapitalized();
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withReturnType(returnType)
.withArguments(mapProperty)
.withNewBlock()
.addNewStringStatementStatement("if(map != null) { this." + property.getName() + ".putAll(map);} return (" + returnType + ")this;")
.endBlock()
.build();
}
});
public static final Function ADD_TO_MAP = FunctionFactory.cache(new Function() {
public Method apply(Property property) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
ClassRef mapType = (ClassRef) property.getTypeRef();
TypeRef keyType = mapType.getArguments().get(0);
TypeRef valueType = mapType.getArguments().get(1);
Property keyProperty = new PropertyBuilder().withName("key").withTypeRef(keyType).build();
Property valueProperty = new PropertyBuilder().withName("value").withTypeRef(valueType).build();
String methodName = "addTo" + property.getNameCapitalized();
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withReturnType(returnType)
.withArguments(new Property[]{keyProperty, valueProperty})
.withNewBlock()
.addNewStringStatementStatement("if(key != null && value != null) {this." + property.getName() + ".put(key, value);} return (" + returnType + ")this;")
.endBlock()
.build();
}
});
public static final Function REMOVE_MAP_FROM_MAP = FunctionFactory.cache(new Function() {
public Method apply(Property property) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
TypeRef mapType = property.getTypeRef();
Property mapProperty = new PropertyBuilder().withName("map").withTypeRef(mapType).build();
String methodName = "removeFrom" + property.getNameCapitalized();
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withReturnType(returnType)
.withArguments(mapProperty)
.withNewBlock()
.addNewStringStatementStatement("if(map != null) { for(Object key : map.keySet()) {this." + property.getName() + ".remove(key);}} return (" + returnType + ")this;")
.endBlock()
.build();
}
});
public static final Function REMOVE_FROM_MAP = FunctionFactory.cache(new Function() {
public Method apply(Property property) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
ClassRef mapType = (ClassRef) property.getTypeRef();
TypeRef keyType = mapType.getArguments().get(0);
Property keyProperty = new PropertyBuilder().withName("key").withTypeRef(keyType).build();
String methodName = "removeFrom" + property.getNameCapitalized();
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withName(methodName)
.withReturnType(returnType)
.withArguments(keyProperty)
.withNewBlock()
.addNewStringStatementStatement("if(key != null) {this." + property.getName() + ".remove(key);} return (" + returnType + ")this;")
.endBlock()
.build();
}
});
public static final Function WITH_NEW_NESTED = new Function() {
public Method apply(Property property) {
ClassRef baseType = (ClassRef) TypeAs.UNWRAP_COLLECTION_OF.apply(property.getTypeRef());
//Let's reload the class from the repository if available....
TypeDef propertyTypeDef = BuilderContextManager.getContext().getDefinitionRepository().getDefinition((baseType).getDefinition().getFullyQualifiedName());
if (propertyTypeDef != null) {
baseType = propertyTypeDef.toInternalReference();
}
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
TypeDef nestedType = PropertyAs.NESTED_INTERFACE_TYPE.apply(property);
TypeDef nestedTypeImpl = PropertyAs.NESTED_CLASS_TYPE.apply(property);
List parameters = baseType.getDefinition().getParameters();
List typeArguments = new ArrayList();
for (TypeRef arg : baseType.getArguments()) {
typeArguments.add(arg);
}
typeArguments.add(returnType);
ClassRef rewraped = nestedType.toReference(typeArguments.toArray(new TypeRef[typeArguments.size()]));
ClassRef rewrapedImpl = nestedTypeImpl.toReference(typeArguments.toArray(new TypeRef[typeArguments.size()]));
boolean isCollection = IS_COLLECTION.apply(property.getTypeRef());
String prefix = isCollection ? "addNew" : "withNew";
prefix += TypeUtils.fullyQualifiedNameDiff(baseType);
String methodName = prefix + captializeFirst(isCollection
? Singularize.FUNCTION.apply(property.getName())
: property.getName());
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withParameters(parameters)
.withReturnType(rewraped)
.withName(methodName)
.withNewBlock()
.addNewStringStatementStatement("return new " + rewrapedImpl.getName() + "();")
.endBlock()
.build();
}
};
public static final Function> WITH_NESTED_INLINE = new Function>() {
public Set apply(Property property) {
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
Set result = new LinkedHashSet();
TypeRef unwrappedType = TypeAs.combine(UNWRAP_COLLECTION_OF, UNWRAP_ARRAY_OF).apply(property.getTypeRef());
TypeDef baseType = BuilderContextManager.getContext().getBuildableRepository().getBuildable(unwrappedType);
for (Method constructor : getInlineableConstructors(property)) {
boolean isCollection = IS_COLLECTION.apply(property.getTypeRef());
String ownPrefix = isCollection ? "addNew" : "withNew";
ownPrefix += BuilderUtils.fullyQualifiedNameDiff(property);
String ownName = ownPrefix + captializeFirst(isCollection
? Singularize.FUNCTION.apply(property.getName())
: property.getName());
String delegatePrefix = IS_COLLECTION.apply(property.getTypeRef()) ? "addTo" : "with";
String delegateName = delegatePrefix + captializeFirst(property.getName());
String args = StringUtils.join(constructor.getArguments(), new Function() {
public String apply(Property item) {
return item.getName();
}
}, ", ");
result.add(new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withReturnType(returnType)
.withArguments(constructor.getArguments())
.withName(ownName)
.withParameters(baseType.getParameters())
.withNewBlock()
.addNewStringStatementStatement("return (" + returnType + ")" + delegateName + "(new " + baseType.getName() + "(" + args + "));")
.endBlock()
.build());
}
return result;
}
};
public static final Function EDIT_OR_NEW = new Function() {
public Method apply(Property property) {
ClassRef baseType = (ClassRef) property.getTypeRef();
ClassRef builderType = TypeAs.SHALLOW_BUILDER.apply(baseType.getDefinition()).toReference();
//Let's reload the class from the repository if available....
TypeDef propertyTypeDef = BuilderContextManager.getContext().getDefinitionRepository().getDefinition((baseType).getDefinition().getFullyQualifiedName());
if (propertyTypeDef != null) {
baseType = propertyTypeDef.toInternalReference();
}
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
TypeDef nestedType = PropertyAs.NESTED_INTERFACE_TYPE.apply(property);
List parameters = baseType.getDefinition().getParameters();
List typeArguments = new ArrayList();
for (TypeRef ignore : baseType.getArguments()) {
typeArguments.add(Q);
}
typeArguments.add(returnType);
ClassRef rewraped = nestedType.toReference(typeArguments);
String prefix = "editOrNew";
String methodNameBase = captializeFirst(property.getName());
String methodName = prefix + methodNameBase;
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withParameters(parameters)
.withReturnType(rewraped)
.withName(methodName)
.withNewBlock()
.addNewStringStatementStatement("return withNew" + methodNameBase + "Like(get" + methodNameBase + "() != null ? get" + methodNameBase + "(): new " + builderType.getName() + "().build());")
.endBlock()
.build();
}
};
public static final Function EDIT_OR_NEW_LIKE = new Function() {
public Method apply(Property property) {
ClassRef baseType = (ClassRef) property.getTypeRef();
//Let's reload the class from the repository if available....
TypeDef propertyTypeDef = BuilderContextManager.getContext().getDefinitionRepository().getDefinition((baseType).getDefinition().getFullyQualifiedName());
if (propertyTypeDef != null) {
baseType = propertyTypeDef.toInternalReference();
}
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
TypeDef nestedType = PropertyAs.NESTED_INTERFACE_TYPE.apply(property);
List parameters = baseType.getDefinition().getParameters();
List typeArguments = new ArrayList();
for (TypeRef ignore : baseType.getArguments()) {
typeArguments.add(Q);
}
typeArguments.add(returnType);
ClassRef rewraped = nestedType.toReference(typeArguments);
String prefix = "editOrNew";
String suffix = "Like";
String methodNameBase = captializeFirst(property.getName());
String methodName = prefix + methodNameBase + suffix;
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withParameters(parameters)
.withReturnType(rewraped)
.withName(methodName)
.addNewArgument()
.withName("item")
.withTypeRef(baseType)
.endArgument()
.withNewBlock()
.addNewStringStatementStatement("return withNew" + methodNameBase + "Like(get" + methodNameBase + "() != null ? get"+methodNameBase+"(): item);")
.endBlock()
.build();
}
};
public static final Function WITH_NEW_LIKE_NESTED = new Function() {
public Method apply(Property property) {
ClassRef baseType = (ClassRef) TypeAs.UNWRAP_COLLECTION_OF.apply(property.getTypeRef());
//Let's reload the class from the repository if available....
TypeDef propertyTypeDef = BuilderContextManager.getContext().getDefinitionRepository().getDefinition((baseType).getDefinition().getFullyQualifiedName());
if (propertyTypeDef != null) {
baseType = propertyTypeDef.toInternalReference();
}
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
TypeDef nestedType = PropertyAs.NESTED_INTERFACE_TYPE.apply(property);
TypeDef nestedTypeImpl = PropertyAs.NESTED_CLASS_TYPE.apply(property);
List parameters = baseType.getDefinition().getParameters();
List typeArguments = new ArrayList();
for (TypeRef ignore : baseType.getArguments()) {
typeArguments.add(Q);
}
typeArguments.add(returnType);
ClassRef rewraped = nestedType.toReference(typeArguments);
ClassRef rewrapedImpl = nestedTypeImpl.toReference(typeArguments);
boolean isCollection = IS_COLLECTION.apply(property.getTypeRef());
String prefix = isCollection ? "addNew" : "withNew";
String suffix = "Like";
String methodName = prefix + captializeFirst(isCollection
? Singularize.FUNCTION.apply(property.getName())
: property.getName()) + suffix;
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withParameters(parameters)
.withReturnType(rewraped)
.withName(methodName)
.addNewArgument()
.withName("item")
.withTypeRef(baseType)
.endArgument()
.withNewBlock()
.addNewStringStatementStatement("return new " + rewrapedImpl.getName() + "(item);")
.endBlock()
.build();
}
};
public static final Function EDIT_NESTED =new Function() {
public Method apply(Property property) {
ClassRef baseType = (ClassRef) TypeAs.UNWRAP_COLLECTION_OF.apply(property.getTypeRef());
//Let's reload the class from the repository if available....
TypeDef propertyTypeDef = BuilderContextManager.getContext().getDefinitionRepository().getDefinition((baseType).getDefinition().getFullyQualifiedName());
if (propertyTypeDef != null) {
baseType = propertyTypeDef.toInternalReference();
}
TypeRef returnType = property.getAttributes().containsKey(GENERIC_TYPE_REF) ? (TypeRef) property.getAttributes().get(GENERIC_TYPE_REF) : T_REF;
TypeDef nestedType = PropertyAs.NESTED_INTERFACE_TYPE.apply(property);
TypeDef nestedTypeImpl = PropertyAs.NESTED_CLASS_TYPE.apply(property);
Set parameters = new LinkedHashSet(baseType.getDefinition().getParameters());
List typeArguments = new ArrayList();
for (TypeRef ignore : baseType.getArguments()) {
typeArguments.add(Q);
}
typeArguments.add(returnType);
ClassRef rewraped = nestedType.toReference(typeArguments);
ClassRef rewrapedImpl = nestedTypeImpl.toReference(typeArguments);
String prefix = "edit";
prefix += BuilderUtils.fullyQualifiedNameDiff(property);
String methodNameBase = captializeFirst(property.getName());
String methodName = prefix + methodNameBase;
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withReturnType(rewraped)
.withName(methodName)
.withNewBlock()
.addNewStringStatementStatement("return withNew" + methodNameBase + "Like(get" + methodNameBase + "());")
.endBlock()
.build();
}
};
public static final Function AND = new Function() {
public Method apply(Property property) {
String classPrefix = getClassPrefix(property);
String prefix = IS_COLLECTION.apply(property.getTypeRef()) ? "addTo" : "with";
String withMethodName = prefix + captializeFirst(property.getName());
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withReturnType(N_REF)
.withName("and")
.withNewBlock()
.addNewStringStatementStatement("return (N) " + classPrefix + withMethodName + "(builder.build());")
.endBlock()
.build();
}
private String getClassPrefix(Property property) {
Object memberOf = property.getAttributes().get(OUTER_CLASS);
if (memberOf instanceof TypeDef) {
return ((TypeDef) memberOf).getName() + ".this.";
} else return "";
}
};
public static final Function END = FunctionFactory.cache(new Function() {
public Method apply(Property property) {
String methodName = "end" + BuilderUtils.fullyQualifiedNameDiff(property) + captializeFirst(IS_COLLECTION.apply(property.getTypeRef())
? Singularize.FUNCTION.apply(property.getName())
: property.getName());
return new MethodBuilder()
.withModifiers(TypeUtils.modifiersToInt(Modifier.PUBLIC))
.withReturnType(N_REF)
.withName(methodName)
.withNewBlock()
.addNewStringStatementStatement("return and();")
.endBlock()
.build();
}
});
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy