in mapper-processor/src/main/java/com/datastax/oss/driver/internal/mapper/processor/dao/DaoDeleteMethodGenerator.java [90:288]
public Optional<MethodSpec> generate() {
Delete annotation = methodElement.getAnnotation(Delete.class);
assert annotation != null;
if (annotation.ifExists() && !annotation.customIfClause().isEmpty()) {
context
.getMessager()
.error(
methodElement,
"Invalid annotation parameters: %s cannot have both ifExists and customIfClause",
Delete.class.getSimpleName());
return Optional.empty();
}
// Validate the arguments: either an entity instance, or the PK components (in the latter case,
// the entity class has to be provided via the annotation).
// In either case, a Function<BoundStatementBuilder, BoundStatementBuilder> can be added in last
// position.
List<? extends VariableElement> parameters = methodElement.getParameters();
VariableElement boundStatementFunction = findBoundStatementFunction(methodElement);
if (boundStatementFunction != null) {
parameters = parameters.subList(0, parameters.size() - 1);
}
TypeElement entityElement;
EntityDefinition entityDefinition;
boolean hasEntityParameter;
if (parameters.isEmpty()) {
context
.getMessager()
.error(
methodElement,
"Wrong number of parameters: %s methods with no custom clause "
+ "must take either an entity instance, or the primary key components",
Delete.class.getSimpleName());
return Optional.empty();
}
String customWhereClause = annotation.customWhereClause();
String customIfClause = annotation.customIfClause();
VariableElement firstParameter = parameters.get(0);
entityElement = EntityUtils.asEntityElement(firstParameter, typeParameters);
hasEntityParameter = (entityElement != null);
// the number of primary key parameters provided, if -1 this implies a custom
// where clause where number of parameters that are primary key are irrelevant.
final int primaryKeyParameterCount;
if (hasEntityParameter) {
if (!customWhereClause.isEmpty()) {
context
.getMessager()
.error(
methodElement,
"Invalid parameter list: %s methods that have a custom where clause "
+ "must not take an Entity (%s) as a parameter",
Delete.class.getSimpleName(),
entityElement.getSimpleName());
}
entityDefinition = context.getEntityFactory().getDefinition(entityElement);
primaryKeyParameterCount = entityDefinition.getPrimaryKey().size();
} else {
entityElement = getEntityClassFromAnnotation(Delete.class);
if (entityElement == null) {
context
.getMessager()
.error(
methodElement,
"Missing entity class: %s methods that do not operate on an entity "
+ "instance must have an 'entityClass' argument",
Delete.class.getSimpleName());
return Optional.empty();
} else {
entityDefinition = context.getEntityFactory().getDefinition(entityElement);
}
if (customWhereClause.isEmpty()) {
/* if a custom if clause is provided, the whole primary key must also be provided.
* we only do this check if there is no custom where clause as the order of
* keys may differ in that case.*/
List<? extends VariableElement> primaryKeyParameters = parameters;
if (!customIfClause.isEmpty()) {
if (primaryKeyParameters.size() < entityDefinition.getPrimaryKey().size()) {
List<TypeName> primaryKeyTypes =
entityDefinition.getPrimaryKey().stream()
.map(d -> d.getType().asTypeName())
.collect(Collectors.toList());
context
.getMessager()
.error(
methodElement,
"Invalid parameter list: %s methods that have a custom if clause"
+ "must specify the entire primary key (expected primary keys of %s: %s)",
Delete.class.getSimpleName(),
entityElement.getSimpleName(),
primaryKeyTypes);
return Optional.empty();
} else {
// restrict parameters to primary key length.
primaryKeyParameters =
primaryKeyParameters.subList(0, entityDefinition.getPrimaryKey().size());
}
}
primaryKeyParameterCount = primaryKeyParameters.size();
if (!EntityUtils.areParametersValid(
entityElement,
entityDefinition,
primaryKeyParameters,
Delete.class,
context,
methodElement,
processedType,
"do not operate on an entity instance and lack a custom where clause")) {
return Optional.empty();
}
} else {
primaryKeyParameterCount = -1;
}
}
// Validate the return type:
DaoReturnType returnType =
parseAndValidateReturnType(getSupportedReturnTypes(), Delete.class.getSimpleName());
if (returnType == null) {
return Optional.empty();
}
// Generate the method
String helperFieldName = enclosingClass.addEntityHelperField(ClassName.get(entityElement));
String statementName =
enclosingClass.addPreparedStatement(
methodElement,
(methodBuilder, requestName) ->
generatePrepareRequest(
methodBuilder, requestName, helperFieldName, primaryKeyParameterCount));
CodeBlock.Builder createStatementBlock = CodeBlock.builder();
createStatementBlock.addStatement(
"$T boundStatementBuilder = $L.boundStatementBuilder()",
BoundStatementBuilder.class,
statementName);
populateBuilderWithStatementAttributes(createStatementBlock, methodElement);
populateBuilderWithFunction(createStatementBlock, boundStatementFunction);
int nextParameterIndex = 0;
if (hasEntityParameter) {
warnIfCqlNamePresent(Collections.singletonList(firstParameter));
// Bind entity's PK properties
for (PropertyDefinition property : entityDefinition.getPrimaryKey()) {
GeneratedCodePatterns.setValue(
property.getCqlName(),
property.getType(),
CodeBlock.of("$L.$L()", firstParameter.getSimpleName(), property.getGetterName()),
"boundStatementBuilder",
createStatementBlock,
enclosingClass);
}
nextParameterIndex = 1;
} else if (customWhereClause.isEmpty()) {
// The PK components are passed as arguments to the method (we've already checked that the
// types match).
List<CodeBlock> primaryKeyNames =
entityDefinition.getPrimaryKey().stream()
.map(PropertyDefinition::getCqlName)
.collect(Collectors.toList())
.subList(0, primaryKeyParameterCount);
List<? extends VariableElement> bindMarkers = parameters.subList(0, primaryKeyParameterCount);
warnIfCqlNamePresent(bindMarkers);
GeneratedCodePatterns.bindParameters(
bindMarkers, primaryKeyNames, createStatementBlock, enclosingClass, context, false);
nextParameterIndex = primaryKeyNames.size();
}
// Bind any remaining parameters, assuming they are values for a custom WHERE or IF clause
if (nextParameterIndex < parameters.size()) {
if (customIfClause.isEmpty() && customWhereClause.isEmpty()) {
context
.getMessager()
.error(
methodElement,
"Wrong number of parameters: %s methods can only have additional "
+ "parameters if they specify a custom WHERE or IF clause",
Delete.class.getSimpleName());
}
List<? extends VariableElement> bindMarkers =
parameters.subList(nextParameterIndex, parameters.size());
if (validateCqlNamesPresent(bindMarkers)) {
GeneratedCodePatterns.bindParameters(
bindMarkers, createStatementBlock, enclosingClass, context, false);
} else {
return Optional.empty();
}
}
createStatementBlock.addStatement(
"$T boundStatement = boundStatementBuilder.build()", BoundStatement.class);
return crudMethod(createStatementBlock, returnType, helperFieldName);
}