use of io.sundr.model.Property in project sundrio by sundrio.
the class BuilderUtils method toEquals.
public static List<Statement> toEquals(TypeDef type, Collection<Property> properties) {
List<Statement> statements = new ArrayList<>();
String simpleName = type.getName();
ClassRef superClass = type.getExtendsList().isEmpty() ? TypeDef.OBJECT_REF : type.getExtendsList().iterator().next();
statements.add(new StringStatement("if (this == o) return true;"));
statements.add(new StringStatement("if (o == null || getClass() != o.getClass()) return false;"));
// If base fluent is the superclass just skip.
final BuilderContext context = BuilderContextManager.getContext();
final String superClassFQN = superClass.getFullyQualifiedName();
if (!context.getBaseFluentClass().getFullyQualifiedName().equals(superClassFQN) && !OBJECT_FULLY_QUALIFIED_NAME.equals(superClassFQN)) {
statements.add(new StringStatement("if (!super.equals(o)) return false;"));
}
statements.add(new StringStatement(new StringBuilder().append(simpleName).append(" that = (").append(simpleName).append(") o;").toString()));
for (Property property : properties) {
String name = property.getName();
if (Types.isPrimitive(property.getTypeRef())) {
statements.add(new StringStatement(new StringBuilder().append("if (").append(name).append(" != ").append("that.").append(name).append(") return false;").toString()));
} else if (property.getTypeRef() instanceof ClassRef && Descendants.isDescendant(type, GetDefinition.of((ClassRef) property.getTypeRef()))) {
statements.add(new StringStatement(new StringBuilder().append("if (").append(name).append(" != null &&").append(name).append(" != this ? !").append(name).append(".equals(that.").append(name).append(") :").append("that.").append(name).append(" != null &&").append(name).append(" != this ) return false;").append("\n").toString()));
} else {
statements.add(new StringStatement(new StringBuilder().append("if (").append(name).append(" != null ? !").append(name).append(".equals(that.").append(name).append(") :").append("that.").append(name).append(" != null) return false;").toString()));
}
}
statements.add(new StringStatement("return true;"));
return statements;
}
use of io.sundr.model.Property in project sundrio by sundrio.
the class BuilderUtils method getInlineableConstructors.
public static Set<Method> getInlineableConstructors(Property property) {
Set<Method> result = new HashSet<Method>();
TypeRef typeRef = property.getTypeRef();
TypeRef unwrapped = TypeAs.combine(TypeAs.UNWRAP_COLLECTION_OF, TypeAs.UNWRAP_ARRAY_OF, TypeAs.UNWRAP_OPTIONAL_OF).apply(typeRef);
if (unwrapped instanceof ClassRef) {
ClassRef classRef = (ClassRef) unwrapped;
// We need to handle `new String(String str)` as a special case of Inlineable constructor and deprecate Inlineables of it before we acutally remove it, so here goes...
if (STRING_REF.equals(typeRef)) {
result.add(new MethodBuilder().withName("String").addNewArgument().withName("s").withTypeRef(classRef).endArgument().build());
return result;
}
// We only want to inline non java types
String pkg = Nameable.getPackageName(((ClassRef) unwrapped).getFullyQualifiedName());
if (!Stream.of(NON_INLINABLE_PACKAGES).filter(s -> pkg.startsWith(s)).findAny().isPresent()) {
for (Method candidate : GetDefinition.of((ClassRef) unwrapped).getConstructors()) {
if (isInlineable(candidate)) {
result.add(candidate);
}
}
}
}
return result;
}
use of io.sundr.model.Property in project sundrio by sundrio.
the class ToPojo method getDefaultValue.
private static String getDefaultValue(Attributeable attributeable) {
Object value = attributeable.getAttribute(DEFAULT_VALUE);
String stringVal = value != null ? String.valueOf(value) : null;
TypeRef typeRef = null;
if (attributeable instanceof Method) {
typeRef = ((Method) attributeable).getReturnType();
} else if (attributeable instanceof Property) {
typeRef = ((Property) attributeable).getTypeRef();
} else {
throw new IllegalArgumentException("Method 'getDefaultValue' accepts Property or Method as argument!");
}
if (typeRef.getDimensions() > 0) {
StringBuilder sb = new StringBuilder();
if (typeRef instanceof PrimitiveRef) {
sb.append(((PrimitiveRef) typeRef).getName());
} else if (typeRef instanceof ClassRef) {
sb.append("new ").append(((ClassRef) typeRef).getFullyQualifiedName());
}
for (int d = 0; d < typeRef.getDimensions(); d++) {
sb.append("[0]");
}
return sb.toString();
}
if (Types.STRING_REF.equals(typeRef) && value != null && !String.valueOf(value).startsWith("\"")) {
return "\"" + value + "\"";
} else if (value instanceof Element) {
Element element = (Element) value;
if (element.getKind() == ElementKind.ENUM_CONSTANT) {
return element.getEnclosingElement() + "." + element.getSimpleName();
}
} else if (stringVal != null && stringVal.startsWith("@")) {
String annotationFQCN = stringVal.substring(1);
TypeDef annotationDef = DefinitionRepository.getRepository().getDefinition(annotationFQCN);
if (annotationDef != null) {
TypeDef pojoDef = ClazzAs.POJO.apply(TypeArguments.apply(annotationDef));
Optional<AnnotationRef> pojoAnnotation = getPojoAnnotation(pojoDef);
Optional<Method> builderFromDefaults = getBuilderFromDefaults(pojoDef);
if (pojoAnnotation.isPresent() && builderFromDefaults.isPresent()) {
return pojoDef.getFullyQualifiedName() + "." + builderFromDefaults.get().getName() + "().build()";
} else if (BuilderUtils.hasDefaultConstructor(pojoDef)) {
return "new " + pojoDef.getFullyQualifiedName() + "()";
}
}
return "null";
} else if (stringVal == null && typeRef instanceof PrimitiveRef) {
if (((PrimitiveRef) typeRef).getName().equals("boolean")) {
return "false";
} else {
return "0";
}
}
return stringVal;
}
use of io.sundr.model.Property in project sundrio by sundrio.
the class AbstractBuilderProcessor method inlineableOf.
static TypeDef inlineableOf(BuilderContext ctx, TypeDef type, Inline inline) {
final String inlineableName = !inline.name().isEmpty() ? inline.name() : inline.prefix() + type.getName() + inline.suffix();
List<Method> constructors = new ArrayList<Method>();
final TypeDef builderType = TypeAs.BUILDER.apply(type);
TypeDef inlineType = BuilderUtils.getInlineType(ctx, inline);
TypeDef returnType = BuilderUtils.getInlineReturnType(ctx, inline, type);
final ClassRef inlineTypeRef = inlineType.toReference(returnType.toReference());
// Use the builder as the base of the inlineable. Just add interface and change name.
final TypeDef shallowInlineType = new TypeDefBuilder(builderType).withName(inlineableName).withImplementsList(inlineTypeRef).withProperties().withMethods().withConstructors().build();
TypeRef functionType = Constants.FUNCTION.toReference(type.toInternalReference(), returnType.toInternalReference());
Property builderProperty = new PropertyBuilder().withTypeRef(TypeAs.BUILDER.apply(type).toInternalReference()).withName(BUILDER).withModifiers(Types.modifiersToInt(Modifier.PRIVATE, Modifier.FINAL)).build();
Property functionProperty = new PropertyBuilder().withTypeRef(functionType).withName(FUNCTION).withModifiers(Types.modifiersToInt(Modifier.PRIVATE, Modifier.FINAL)).build();
Method inlineMethod = new MethodBuilder().withReturnType(returnType.toInternalReference()).withName(inline.value()).withNewBlock().addNewStringStatementStatement(BUILD_AND_APPLY_FUNCTION).endBlock().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).build();
constructors.add(new MethodBuilder().withReturnType(inlineTypeRef).withName(EMPTY).addNewArgument().withName(FUNCTION).withTypeRef(functionType).and().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).withNewBlock().addNewStringStatementStatement(String.format(NEW_BULDER_AND_SET_FUNCTION_FORMAT, builderType.getName())).endBlock().build());
constructors.add(new MethodBuilder().withReturnType(inlineTypeRef).withName(EMPTY).addNewArgument().withName(ITEM).withTypeRef(type.toInternalReference()).and().addNewArgument().withName(FUNCTION).withTypeRef(functionType).and().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).withNewBlock().addNewStringStatementStatement(String.format(NEW_BULDER_WITH_ITEM_AND_SET_FUNCTION_FORMAT, builderType.getName())).endBlock().build());
if (type.equals(returnType)) {
constructors.add(new MethodBuilder().withReturnType(inlineTypeRef).withName(EMPTY).addNewArgument().withName(ITEM).withTypeRef(type.toInternalReference()).and().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).withNewBlock().addNewStringStatementStatement(String.format(NEW_BUILDER_AND_EMTPY_FUNCTION_FORMAT, builderType.getName(), String.format(EMPTY_FUNCTION_TEXT, type.toInternalReference(), returnType.toInternalReference(), returnType.toInternalReference(), type.toInternalReference()))).endBlock().build());
}
return new TypeDefBuilder(shallowInlineType).withAnnotations().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).withConstructors(constructors).addToProperties(builderProperty, functionProperty).addToMethods(inlineMethod).accept(new TypedVisitor<ClassRefBuilder>() {
@Override
public void visit(ClassRefBuilder builder) {
List<TypeRef> updatedArguments = new ArrayList<TypeRef>();
for (TypeRef arg : builder.getArguments()) {
if (arg.equals(builderType.toInternalReference())) {
updatedArguments.add(shallowInlineType.toInternalReference());
} else {
updatedArguments.add(arg);
}
}
builder.withArguments(updatedArguments);
}
}).build();
}
use of io.sundr.model.Property in project sundrio by sundrio.
the class ClazzAs method toInstanceConstructorBody.
private static List<Statement> toInstanceConstructorBody(TypeDef clazz, TypeDef instance, String fluent) {
Method constructor = findBuildableConstructor(clazz);
List<Statement> statements = new ArrayList<Statement>();
final String ref = fluent != null && !fluent.isEmpty() ? fluent : "this";
// We may use a reference to fluent or we may use directly "this". So we need to check.
if (fluent != null && !fluent.isEmpty()) {
statements.add(new StringStatement("this.fluent = " + fluent + "; "));
}
for (Property property : constructor.getArguments()) {
Optional<Method> getter = Getter.findOptional(instance, property);
getter.ifPresent(g -> {
String cast = property.getTypeRef() instanceof TypeParamRef ? "(" + property.getTypeRef().toString() + ")" : "";
statements.add(new StringStatement(new StringBuilder().append(ref).append(".with").append(property.getNameCapitalized()).append("(").append(cast).append("instance.").append(g.getName()).append("()); ").toString()));
});
// } else {
// throw new IllegalStateException("Could not find getter for property:" + property + " in class:" + clazz);
// }
}
TypeDef target = clazz;
// Iterate parent objects and check for properties with setters but not ctor arguments.
while (target != null && !Types.OBJECT.equals(target) && BuilderUtils.isBuildable(target)) {
for (Property property : target.getProperties()) {
if (!hasBuildableConstructorWithArgument(target, property) && Setter.has(target, property)) {
Getter.findOptional(instance, property).map(Method::getName).ifPresent(getterName -> {
String withName = "with" + property.getNameCapitalized();
statements.add(new StringStatement(new StringBuilder().append(ref).append(".").append(withName).append("(instance.").append(getterName).append("());\n").toString()));
});
}
}
if (!target.getExtendsList().isEmpty()) {
target = BuilderContextManager.getContext().getBuildableRepository().getBuildable(target.getExtendsList().iterator().next());
} else {
return statements;
}
}
return statements;
}
Aggregations