use of io.requery.CascadeAction in project requery by requery.
the class EntityMetaGenerator method generateAttribute.
private FieldSpec generateAttribute(AttributeDescriptor attribute, AttributeDescriptor parent, TypeName targetName, String fieldName, TypeMirror mirror, boolean expression) {
TypeMirror typeMirror = mirror;
TypeName typeName;
if (attribute.isIterable()) {
typeMirror = tryFirstTypeArgument(typeMirror);
typeName = parameterizedCollectionName(attribute.typeMirror());
} else if (attribute.isOptional()) {
typeMirror = tryFirstTypeArgument(typeMirror);
typeName = TypeName.get(typeMirror);
} else {
typeName = nameResolver.generatedTypeNameOf(typeMirror).orElse(null);
}
if (typeName == null) {
typeName = boxedTypeName(typeMirror);
}
ParameterizedTypeName type;
ClassName attributeType = null;
boolean useKotlinDelegate = false;
if (expression) {
type = parameterizedTypeName(QueryExpression.class, typeName);
} else {
// if it's an association don't make it available as a query attribute
boolean isQueryable = attribute.cardinality() == null || attribute.isForeignKey();
Class<?> attributeClass = isQueryable ? QueryAttribute.class : Attribute.class;
attributeType = ClassName.get(attributeClass);
if (isQueryable) {
TypeElement delegateType = elements.getTypeElement(KOTLIN_ATTRIBUTE_DELEGATE);
if (delegateType != null) {
attributeType = ClassName.get(delegateType);
useKotlinDelegate = true;
}
}
type = ParameterizedTypeName.get(attributeType, targetName, typeName);
}
CodeBlock.Builder builder = CodeBlock.builder();
String attributeName = attribute.name();
if (parent != null && parent.isEmbedded()) {
attributeName = embeddedAttributeName(parent, attribute);
}
if (attribute.isIterable()) {
typeMirror = tryFirstTypeArgument(typeMirror);
TypeName name = nameResolver.tryGeneratedTypeName(typeMirror);
TypeElement collection = (TypeElement) types.asElement(attribute.typeMirror());
ParameterizedTypeName builderName = parameterizedTypeName(attribute.builderClass(), targetName, typeName, name);
builder.add("\nnew $T($S, $T.class, $T.class)\n", builderName, attributeName, ClassName.get(collection), name);
} else if (attribute.isMap() && attribute.cardinality() != null) {
List<TypeMirror> parameters = Mirrors.listGenericTypeArguments(typeMirror);
// key type
TypeName keyName = TypeName.get(parameters.get(0));
// value type
typeMirror = parameters.get(1);
TypeName valueName = nameResolver.tryGeneratedTypeName(typeMirror);
TypeElement valueElement = (TypeElement) types.asElement(attribute.typeMirror());
ParameterizedTypeName builderName = parameterizedTypeName(attribute.builderClass(), targetName, typeName, keyName, valueName);
builder.add("\nnew $T($S, $T.class, $T.class, $T.class)\n", builderName, attributeName, ClassName.get(valueElement), keyName, valueName);
} else {
ParameterizedTypeName builderName = parameterizedTypeName(attribute.builderClass(), targetName, typeName);
TypeName classType = typeName;
if (typeMirror.getKind().isPrimitive()) {
// if primitive just use the primitive class not the boxed version
classType = TypeName.get(typeMirror);
}
String statement;
if (Mirrors.listGenericTypeArguments(typeMirror).size() > 0) {
// use the erased type and cast to class
classType = TypeName.get(types.erasure(typeMirror));
statement = "\nnew $T($S, (Class)$T.class)\n";
} else {
statement = "\nnew $T($S, $T.class)\n";
}
builder.add(statement, builderName, attributeName, classType);
}
if (!expression) {
generateProperties(attribute, parent, typeMirror, targetName, typeName, builder);
}
// attribute builder properties
if (attribute.isKey()) {
builder.add(".setKey(true)\n");
}
builder.add(".setGenerated($L)\n", attribute.isGenerated());
builder.add(".setLazy($L)\n", attribute.isLazy());
builder.add(".setNullable($L)\n", attribute.isNullable());
builder.add(".setUnique($L)\n", attribute.isUnique());
if (!Names.isEmpty(attribute.defaultValue())) {
builder.add(".setDefaultValue($S)\n", attribute.defaultValue());
}
if (!Names.isEmpty(attribute.collate())) {
builder.add(".setCollate($S)\n", attribute.collate());
}
if (attribute.columnLength() != null) {
builder.add(".setLength($L)\n", attribute.columnLength());
}
if (!Names.isEmpty(attribute.definition())) {
builder.add(".setDefinition($S)\n", attribute.definition());
}
if (attribute.isVersion()) {
builder.add(".setVersion($L)\n", attribute.isVersion());
}
if (attribute.converterName() != null) {
builder.add(".setConverter(new $L())\n", attribute.converterName());
}
if (attribute.isForeignKey()) {
builder.add(".setForeignKey($L)\n", attribute.isForeignKey());
Optional<EntityDescriptor> referencedType = graph.referencingEntity(attribute);
referencedType.ifPresent(referenced -> {
builder.add(".setReferencedClass($T.class)\n", referenced.isImmutable() ? TypeName.get(referenced.element().asType()) : nameResolver.typeNameOf(referenced));
graph.referencingAttribute(attribute, referenced).ifPresent(referencedAttribute -> {
String name = upperCaseUnderscoreRemovePrefixes(referencedAttribute.fieldName());
TypeSpec provider = CodeGeneration.createAnonymousSupplier(ClassName.get(Attribute.class), CodeBlock.builder().addStatement("return $T.$L", nameResolver.typeNameOf(referenced), name).build());
builder.add(".setReferencedAttribute($L)\n", provider);
});
});
}
if (attribute.isIndexed()) {
builder.add(".setIndexed($L)\n", attribute.isIndexed());
if (!attribute.indexNames().isEmpty()) {
StringJoiner joiner = new StringJoiner(",");
attribute.indexNames().forEach(name -> joiner.add("$S"));
builder.add(".setIndexNames(" + joiner + ")\n", attribute.indexNames().toArray());
}
}
if (attribute.deleteAction() != null) {
builder.add(".setDeleteAction($T.$L)\n", ClassName.get(ReferentialAction.class), attribute.deleteAction());
}
if (attribute.updateAction() != null) {
builder.add(".setUpdateAction($T.$L)\n", ClassName.get(ReferentialAction.class), attribute.updateAction());
}
if (!attribute.cascadeActions().isEmpty()) {
StringJoiner joiner = new StringJoiner(",");
attribute.cascadeActions().forEach(action -> joiner.add("$T.$L"));
int index = 0;
ClassName cascadeClass = ClassName.get(CascadeAction.class);
Object[] args = new Object[attribute.cascadeActions().size() * 2];
for (CascadeAction action : attribute.cascadeActions()) {
args[index++] = cascadeClass;
args[index++] = action;
}
builder.add(".setCascadeAction(" + joiner + ")\n", args);
}
if (attribute.cardinality() != null) {
if (!expression) {
builder.add(".setCardinality($T.$L)\n", ClassName.get(Cardinality.class), attribute.cardinality());
}
graph.referencingEntity(attribute).ifPresent(referenced -> {
Set<AttributeDescriptor> mappings = graph.mappedAttributes(entity, attribute, referenced);
if (attribute.cardinality() == Cardinality.MANY_TO_MANY) {
generateJunctionType(attribute, referenced, mappings).ifPresent(name -> builder.add(".setReferencedClass($T.class)\n", name));
}
if (mappings.size() == 1) {
AttributeDescriptor mapped = mappings.iterator().next();
String staticMemberName = upperCaseUnderscoreRemovePrefixes(mapped.fieldName());
TypeSpec provider = CodeGeneration.createAnonymousSupplier(ClassName.get(Attribute.class), CodeBlock.builder().addStatement("return $T.$L", nameResolver.typeNameOf(referenced), staticMemberName).build());
builder.add(".setMappedAttribute($L)\n", provider);
}
if (attribute.orderBy() != null) {
referenced.attributes().values().stream().filter(entry -> entry.name().equals(attribute.orderBy())).findFirst().ifPresent(orderBy -> {
String staticMemberName = upperCaseUnderscoreRemovePrefixes(orderBy.fieldName());
TypeSpec provider = CodeGeneration.createAnonymousSupplier(ClassName.get(Attribute.class), CodeBlock.builder().addStatement("return $T.$L", nameResolver.typeNameOf(referenced), staticMemberName).build());
builder.add(".setOrderByAttribute($L)\n", provider);
builder.add(".setOrderByDirection($T.$L)\n", ClassName.get(Order.class), attribute.orderByDirection());
});
}
});
}
builder.add(".build()");
FieldSpec.Builder field = FieldSpec.builder(type, fieldName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
if (useKotlinDelegate) {
return field.initializer("new $T($L)", attributeType, builder.build()).build();
} else {
return field.initializer("$L", builder.build()).build();
}
}
Aggregations