Skip to content

Commit 779e819

Browse files
committed
Refine JavaPoet usage.
See: #1566 Original pull request: #1600
1 parent 0d8f318 commit 779e819

File tree

1 file changed

+77
-108
lines changed

1 file changed

+77
-108
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/aot/CassandraCodeBlocks.java

Lines changed: 77 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import java.nio.ByteBuffer;
1919
import java.util.Map;
20-
import java.util.Optional;
2120

2221
import org.jspecify.annotations.NullUnmarked;
2322
import org.jspecify.annotations.Nullable;
@@ -39,7 +38,10 @@
3938
import org.springframework.data.convert.CustomConversions;
4039
import org.springframework.data.domain.Limit;
4140
import org.springframework.data.domain.Sort;
41+
import org.springframework.data.javapoet.LordOfTheStrings;
42+
import org.springframework.data.javapoet.TypeNames;
4243
import org.springframework.data.repository.aot.generate.AotQueryMethodGenerationContext;
44+
import org.springframework.data.repository.aot.generate.MethodReturn;
4345
import org.springframework.javapoet.CodeBlock;
4446
import org.springframework.javapoet.CodeBlock.Builder;
4547
import org.springframework.javapoet.TypeName;
@@ -88,7 +90,6 @@ static class QueryBlockBuilder {
8890

8991
private final AotQueryMethodGenerationContext context;
9092
private final CassandraQueryMethod queryMethod;
91-
private final String parameterNames;
9293

9394
private @Nullable AotQuery query;
9495
private String queryVariableName;
@@ -98,14 +99,6 @@ static class QueryBlockBuilder {
9899

99100
this.context = context;
100101
this.queryMethod = queryMethod;
101-
102-
String parameterNames = StringUtils.collectionToDelimitedString(context.getAllParameterNames(), ", ");
103-
104-
if (StringUtils.hasText(parameterNames)) {
105-
this.parameterNames = ", " + parameterNames;
106-
} else {
107-
this.parameterNames = "";
108-
}
109102
}
110103

111104
QueryBlockBuilder query(AotQuery query) {
@@ -178,8 +171,7 @@ private CodeBlock buildQuery(StringAotQuery query) {
178171
for (ParameterBinding binding : query.getParameterBindings()) {
179172

180173
// TODO:Conversion, Data type
181-
builder.addStatement("$1L[$2L] = $3L", context.localVariable("args"), index++,
182-
getParameter(binding.getOrigin()));
174+
builder.addStatement("$1L[$2L] = $3L", context.localVariable("args"), index++, getParameter(binding));
183175
}
184176

185177
builder.addStatement("$1T $2L = $1T.newInstance($3S, $4L)", SimpleStatement.class, queryVariableName,
@@ -259,28 +251,22 @@ private CodeBlock buildQuery(org.springframework.data.cassandra.core.query.Query
259251
return queryBuilder.build();
260252
}
261253

262-
boolean first = true;
263-
queryBuilder.add("$[");
264-
queryBuilder.add("$1T $2L = $1T.query(", org.springframework.data.cassandra.core.query.Query.class,
265-
queryVariableName);
254+
LordOfTheStrings.CodeBlockBuilder CodeBlockBuilder = LordOfTheStrings.builder(queryBuilder);
255+
CodeBlockBuilder.addStatement(it -> {
256+
it.add("$1T $2L = $1T.query(", org.springframework.data.cassandra.core.query.Query.class, queryVariableName);
266257

267-
for (CriteriaDefinition criteriaDefinition : query) {
258+
it.addAll(query, ".and(", (criteria) -> {
268259

269-
if (first) {
270-
first = false;
271-
} else {
272-
queryBuilder.add(".and(");
273-
}
260+
LordOfTheStrings.CodeBlockBuilder builder = LordOfTheStrings.builder("$1T.where($2S)", Criteria.class,
261+
criteria.getColumnName().toCql());
262+
appendPredicate(criteria, builder);
263+
builder.add(")");
274264

275-
queryBuilder.add("$1T.where($2S)", Criteria.class, criteriaDefinition.getColumnName().toCql());
276-
appendPredicate(criteriaDefinition, queryBuilder);
277-
278-
queryBuilder.add(")");
279-
}
265+
return builder.build();
266+
});
267+
});
280268

281-
queryBuilder.add(";\n$]");
282-
283-
return queryBuilder.build();
269+
return CodeBlockBuilder.build();
284270
}
285271

286272
private CodeBlock buildColumns(Columns columns) {
@@ -368,27 +354,21 @@ private CodeBlock buildSortScrollLimit(DerivedAotQuery derived,
368354

369355
private static CodeBlock buildSort(Sort sort) {
370356

371-
Builder sortBuilder = CodeBlock.builder();
372-
sortBuilder.add("$T.by(", Sort.class);
357+
LordOfTheStrings.InvocationBuilder invocation = LordOfTheStrings.invoke("$T.by($L)", Sort.class);
373358

374-
boolean first = true;
375-
for (Sort.Order order : sort) {
359+
invocation.arguments(sort, order -> {
376360

377-
sortBuilder.add("$T.$L($S)", Sort.Order.class, order.isAscending() ? "asc" : "desc", order.getProperty());
378-
if (order.isIgnoreCase()) {
379-
sortBuilder.add(".ignoreCase()");
380-
}
361+
LordOfTheStrings.CodeBlockBuilder builder = LordOfTheStrings.builder("$T.$L($S)", Sort.Order.class,
362+
order.isAscending() ? "asc" : "desc", order.getProperty());
381363

382-
if (first) {
383-
first = false;
384-
} else {
385-
sortBuilder.add(", ");
364+
if (order.isIgnoreCase()) {
365+
builder.add(".ignoreCase()");
386366
}
387-
}
388367

389-
sortBuilder.add(")");
368+
return builder.build();
369+
});
390370

391-
return sortBuilder.build();
371+
return invocation.build();
392372
}
393373

394374
private CodeBlock buildQueryOptions(DerivedAotQuery derived) {
@@ -456,7 +436,8 @@ private void applyOptions(Limit limit, Builder builder) {
456436
}
457437
}
458438

459-
private void appendPredicate(CriteriaDefinition criteriaDefinition, Builder criteriaBuilder) {
439+
private void appendPredicate(CriteriaDefinition criteriaDefinition,
440+
LordOfTheStrings.CodeBlockBuilder criteriaBuilder) {
460441

461442
CriteriaDefinition.Predicate predicate = criteriaDefinition.getPredicate();
462443

@@ -524,42 +505,26 @@ String getParameterName(ParameterBinding binding) {
524505
throw new UnsupportedOperationException("Unsupported origin: " + binding.getOrigin());
525506
}
526507

527-
private CodeBlock getParameter(ParameterBinding.ParameterOrigin origin) {
508+
private CodeBlock getParameter(ParameterBinding binding) {
528509

510+
ParameterBinding.ParameterOrigin origin = binding.getOrigin();
529511
if (origin.isMethodArgument() && origin instanceof ParameterBinding.MethodInvocationArgument mia) {
530-
531-
CodeBlock.Builder builder = CodeBlock.builder();
532-
533-
builder.add("potentiallyConvertBindingValue(");
534-
535-
if (mia.identifier().hasPosition()) {
536-
builder.add("$L", context.getRequiredBindableParameterName(mia.identifier().getPosition()));
537-
} else if (mia.identifier().hasName()) {
538-
builder.add("$L", context.getMethodParameter(mia.identifier().getName()).getParameterName());
539-
}
540-
else {
541-
throw new IllegalStateException(
542-
"MethodInvocationArgument '%s' does not define a name or a position".formatted(mia));
543-
}
544-
builder.add(")");
545-
546-
return builder.build();
512+
return CodeBlock.of("potentiallyConvertBindingValue($L)", getParameterName(binding));
547513
}
548514

549515
if (origin.isExpression() && origin instanceof ParameterBinding.Expression expr) {
550516

551-
Builder builder = CodeBlock.builder();
552-
553517
String expressionString = expr.expression().getExpressionString();
554518
// re-wrap expression
555519
if (!expressionString.startsWith("$")) {
556520
expressionString = "#{" + expressionString + "}";
557521
}
558522

559-
builder.add("evaluateExpression($L, $S$L)", context.getExpressionMarker().enclosingMethod(), expressionString,
560-
parameterNames);
561-
562-
return builder.build();
523+
return LordOfTheStrings.invoke("evaluateExpression($L)")
524+
.argument(context.getExpressionMarker().enclosingMethod()) //
525+
.argument("$S", expressionString) //
526+
.arguments(context.getAllParameterNames()) //
527+
.build();
563528
}
564529

565530
throw new UnsupportedOperationException("Not supported yet for: " + origin);
@@ -598,43 +563,49 @@ QueryExecutionBlockBuilder usingQueryVariableName(String queryVariableName) {
598563
CodeBlock build() {
599564

600565
Builder builder = CodeBlock.builder();
566+
MethodReturn methodReturn = context.getMethodReturn();
601567

602568
boolean isProjecting = !query.isCount() && !query.isExists()
603-
&& (context.getReturnedType().isProjecting()
604-
&& !customConversions.isSimpleType(context.getReturnedType().getReturnedType()))
569+
&& (context.getMethodReturn().isProjecting()
570+
&& !customConversions.isSimpleType(context.getMethodReturn().toClass()))
605571
|| StringUtils.hasText(context.getDynamicProjectionParameterName());
606572
Class<?> domainType = context.getRepositoryInformation().getDomainType();
607573

608574
builder.add("\n");
609575

610576
if (query.isDelete()) {
611577

578+
LordOfTheStrings.InvocationBuilder method;
612579
if (query instanceof StringAotQuery) {
613580

614-
builder.addStatement("boolean $1L = $2L.getCqlOperations().execute($3L)", context.localVariable("result"),
581+
method = LordOfTheStrings.invoke("$L.getCqlOperations().execute($L)",
615582
context.fieldNameOf(CassandraOperations.class), queryVariableName);
616583
} else {
617-
builder.addStatement("boolean $1L = $2L.delete($3L, $4T.class)", context.localVariable("result"),
618-
context.fieldNameOf(CassandraOperations.class), queryVariableName, domainType);
584+
method = LordOfTheStrings.invoke("$L.delete($L, $T.class)", context.fieldNameOf(CassandraOperations.class),
585+
queryVariableName, domainType);
619586
}
620587

621-
if (context.getReturnType().isAssignableFrom(Boolean.class)
622-
|| context.getReturnType().isAssignableFrom(Boolean.TYPE)) {
623-
builder.addStatement("return $1L", context.localVariable("result"));
588+
if (methodReturn.isVoid()) {
589+
builder.addStatement(method.build());
590+
} else {
591+
builder.addStatement(method.assignTo("boolean $L", context.localVariable("result")));
624592
}
625593

594+
builder.addStatement(LordOfTheStrings.returning(methodReturn.toClass()) //
595+
.whenBoolean("$L", context.localVariable("result")) //
596+
.build());
597+
626598
return builder.build();
627599
}
628600

629-
boolean isInterfaceProjection = context.getActualReturnType().toClass().isInterface();
601+
boolean isInterfaceProjection = methodReturn.isInterfaceProjection();
630602
boolean requiresConversion = false;
631603

632-
boolean isMapProjection = Map.class.isAssignableFrom(context.getActualReturnType().toClass());
633-
boolean rawProjection = isMapProjection || ResultSet.class.isAssignableFrom(context.getReturnType().toClass());
604+
boolean isMapProjection = methodReturn.getActualReturnClass().equals(Map.class);
605+
boolean rawProjection = isMapProjection || methodReturn.toClass().equals(ResultSet.class);
634606

635-
TypeName actualReturnType = isMapProjection
636-
? TypeName.get(Map.class)
637-
: context.getActualReturnTypeName();
607+
TypeName actualReturnType = isMapProjection ? methodReturn.getActualClassName()
608+
: TypeNames.typeNameOrWrapper(methodReturn.getActualType());
638609
Object asDynamicTypeNameOrProjectionTypeParameter = actualReturnType;
639610

640611
if (StringUtils.hasText(context.getDynamicProjectionParameterName())) {
@@ -703,54 +674,52 @@ CodeBlock build() {
703674
} else if (query.isLimited()) {
704675
terminatingMethod = "firstValue()";
705676
} else {
706-
terminatingMethod = Optional.class.isAssignableFrom(context.getReturnType().toClass()) ? "one()" : "oneValue()";
677+
terminatingMethod = "oneValue()";
707678
}
708679

709680
Builder execution = CodeBlock.builder();
710681

711682
if (queryMethod.isScrollQuery()) {
712683
execution.add("$T.of($L.$L)", WindowUtil.class, context.localVariable("select"), terminatingMethod);
713-
} else if (context.getReturnType().isArray()) {
684+
} else if (methodReturn.isArray()) {
714685
execution.add("$L.$L.toArray(new $T[0])", context.localVariable("select"), terminatingMethod,
715-
context.getActualReturnTypeName());
686+
methodReturn.getActualClassName());
716687
} else {
717688

718689
if (rawProjection && isMapProjection) {
719-
execution.add("($T) $L.$L", context.getReturnType().toClass(), context.localVariable("select"),
690+
execution.add("($T) $L.$L", methodReturn.getClassName(), context.localVariable("select"),
720691
terminatingMethod);
721692
} else {
722693
execution.add("$L.$L", context.localVariable("select"), terminatingMethod);
723694
}
724695
}
725696

697+
LordOfTheStrings.TypedReturnBuilder returnBuilder = LordOfTheStrings.returning(methodReturn.toClass());
726698
if (requiresConversion) {
727699

728-
if (Optional.class.isAssignableFrom(context.getReturnType().toClass())) {
729-
builder.addStatement("return ($T) $T.ofNullable(convertOne($L, $T.class))", context.getReturnTypeName(),
730-
Optional.class, execution.build(), actualReturnType);
731-
} else {
732-
733-
String conversionMethod;
734-
735-
if (queryMethod.isCollectionQuery() || queryMethod.isPageQuery() || queryMethod.isSliceQuery()
736-
|| queryMethod.isStreamQuery()) {
737-
conversionMethod = "convertMany";
738-
} else {
739-
conversionMethod = "convertOne";
740-
}
700+
String conversionMethod;
741701

742-
builder.addStatement("return ($T) $L($L, $T.class)", context.getReturnTypeName(), conversionMethod,
743-
execution.build(), actualReturnType);
702+
if (queryMethod.isCollectionQuery() || queryMethod.isPageQuery() || queryMethod.isSliceQuery()
703+
|| queryMethod.isStreamQuery()) {
704+
conversionMethod = "convertMany";
705+
} else {
706+
conversionMethod = "convertOne";
744707
}
745708

709+
builder.addStatement(returnBuilder //
710+
.optional("($T) $L($L, $T.class)", methodReturn.getTypeName(), conversionMethod, execution.build(),
711+
actualReturnType) //
712+
.build());
746713
} else {
747714

748-
if (query.isCount() && (context.getReturnType().isAssignableFrom(Integer.class)
749-
|| context.getReturnType().isAssignableFrom(int.class))) {
750-
builder.addStatement("return (int) $L", execution.build());
751-
} else {
752-
builder.addStatement("return $L", execution.build());
715+
CodeBlock executionBlock = execution.build();
716+
717+
if (query.isCount()) {
718+
returnBuilder.whenPrimitiveOrBoxed(Integer.class, "(int) $L", executionBlock);
753719
}
720+
721+
builder.addStatement(returnBuilder.optional(executionBlock) //
722+
.build());
754723
}
755724

756725
return builder.build();

0 commit comments

Comments
 (0)