-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Align AOT and reflective repository behavior. #5038
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1d91d1d
35ba071
a67cdb7
b7ca35d
f6d7ff7
3e6c32d
75d1984
30a69fb
da88469
d0a9b73
c84a6c2
9bdb6a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,13 +22,13 @@ | |
|
||
import org.bson.Document; | ||
import org.jspecify.annotations.NullUnmarked; | ||
|
||
import org.springframework.core.ResolvableType; | ||
import org.springframework.core.annotation.MergedAnnotation; | ||
import org.springframework.data.domain.SliceImpl; | ||
import org.springframework.data.domain.Sort.Order; | ||
import org.springframework.data.mongodb.core.MongoOperations; | ||
import org.springframework.data.mongodb.core.aggregation.Aggregation; | ||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation; | ||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions; | ||
import org.springframework.data.mongodb.core.aggregation.AggregationPipeline; | ||
import org.springframework.data.mongodb.core.aggregation.AggregationResults; | ||
|
@@ -80,12 +80,7 @@ CodeBlock build() { | |
|
||
builder.add("\n"); | ||
|
||
Class<?> outputType = queryMethod.getReturnedObjectType(); | ||
if (MongoSimpleTypes.HOLDER.isSimpleType(outputType)) { | ||
outputType = Document.class; | ||
} else if (ClassUtils.isAssignable(AggregationResults.class, outputType)) { | ||
outputType = queryMethod.getReturnType().getComponentType().getType(); | ||
} | ||
Class<?> outputType = getOutputType(queryMethod); | ||
|
||
if (ReflectionUtils.isVoid(queryMethod.getReturnedObjectType())) { | ||
builder.addStatement("$L.aggregate($L, $T.class)", mongoOpsRef, aggregationVariableName, outputType); | ||
|
@@ -146,7 +141,6 @@ CodeBlock build() { | |
builder.addStatement("return $L.aggregateStream($L, $T.class)", mongoOpsRef, aggregationVariableName, | ||
outputType); | ||
} else { | ||
|
||
builder.addStatement("return $L.aggregate($L, $T.class).getMappedResults()", mongoOpsRef, | ||
aggregationVariableName, outputType); | ||
} | ||
|
@@ -155,6 +149,17 @@ CodeBlock build() { | |
|
||
return builder.build(); | ||
} | ||
|
||
} | ||
|
||
private static Class<?> getOutputType(MongoQueryMethod queryMethod) { | ||
Class<?> outputType = queryMethod.getReturnedObjectType(); | ||
if (MongoSimpleTypes.HOLDER.isSimpleType(outputType)) { | ||
outputType = Document.class; | ||
} else if (ClassUtils.isAssignable(AggregationResults.class, outputType) && queryMethod.getReturnType().getComponentType() != null) { | ||
outputType = queryMethod.getReturnType().getComponentType().getType(); | ||
} | ||
return outputType; | ||
} | ||
|
||
@NullUnmarked | ||
|
@@ -173,13 +178,7 @@ static class AggregationCodeBlockBuilder { | |
|
||
this.context = context; | ||
this.queryMethod = queryMethod; | ||
String parameterNames = StringUtils.collectionToDelimitedString(context.getAllParameterNames(), ", "); | ||
|
||
if (StringUtils.hasText(parameterNames)) { | ||
this.parameterNames = ", " + parameterNames; | ||
} else { | ||
this.parameterNames = ""; | ||
} | ||
this.parameterNames = StringUtils.collectionToDelimitedString(context.getAllParameterNames(), ", "); | ||
} | ||
|
||
AggregationCodeBlockBuilder stages(AggregationInteraction aggregation) { | ||
|
@@ -231,7 +230,8 @@ private CodeBlock pipeline(String pipelineVariableName) { | |
builder.add(aggregationStages(context.localVariable("stages"), source.stages())); | ||
|
||
if (StringUtils.hasText(sortParameter)) { | ||
builder.add(sortingStage(sortParameter)); | ||
Class<?> outputType = getOutputType(queryMethod); | ||
builder.add(sortingStage(sortParameter, outputType)); | ||
} | ||
|
||
if (StringUtils.hasText(limitParameter)) { | ||
|
@@ -244,6 +244,7 @@ private CodeBlock pipeline(String pipelineVariableName) { | |
|
||
builder.addStatement("$T $L = createPipeline($L)", AggregationPipeline.class, pipelineVariableName, | ||
context.localVariable("stages")); | ||
|
||
return builder.build(); | ||
} | ||
|
||
|
@@ -303,7 +304,7 @@ private CodeBlock aggregationStages(String stageListVariableName, Collection<Str | |
|
||
VariableSnippet stageSnippet = Snippet.declare(builder) | ||
.variable(Document.class, context.localVariable("stage_%s".formatted(stageCounter))) | ||
.of(MongoCodeBlocks.asDocument(stage, parameterNames)); | ||
.of(MongoCodeBlocks.asDocument(context.getExpressionMarker(), stage, parameterNames)); | ||
builder.addStatement("$L.add($L)", stageListVariableName, stageSnippet.getVariableName()); | ||
|
||
stageCounter++; | ||
|
@@ -312,7 +313,7 @@ private CodeBlock aggregationStages(String stageListVariableName, Collection<Str | |
return builder.build(); | ||
} | ||
|
||
private CodeBlock sortingStage(String sortProvider) { | ||
private CodeBlock sortingStage(String sortProvider, Class<?> outputType) { | ||
|
||
Builder builder = CodeBlock.builder(); | ||
|
||
|
@@ -322,8 +323,17 @@ private CodeBlock sortingStage(String sortProvider) { | |
builder.addStatement("$1L.append($2L.getProperty(), $2L.isAscending() ? 1 : -1);", | ||
context.localVariable("sortDocument"), context.localVariable("order")); | ||
builder.endControlFlow(); | ||
builder.addStatement("stages.add(new $T($S, $L))", Document.class, "$sort", | ||
context.localVariable("sortDocument")); | ||
|
||
if (outputType == Document.class || MongoSimpleTypes.HOLDER.isSimpleType(outputType) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|| ClassUtils.isAssignable(context.getRepositoryInformation().getDomainType(), outputType)) { | ||
builder.addStatement("$L.add(new $T($S, $L))", context.localVariable("stages"), Document.class, "$sort", | ||
context.localVariable("sortDocument")); | ||
} else { | ||
builder.addStatement("$L.add(($T) _ctx -> new $T($S, _ctx.getMappedObject($L, $T.class)))", | ||
context.localVariable("stages"), AggregationOperation.class, Document.class, "$sort", | ||
context.localVariable("sortDocument"), outputType); | ||
} | ||
|
||
builder.endControlFlow(); | ||
|
||
return builder.build(); | ||
|
@@ -333,7 +343,7 @@ private CodeBlock pagingStage(String pageableProvider, boolean slice) { | |
|
||
Builder builder = CodeBlock.builder(); | ||
|
||
builder.add(sortingStage(pageableProvider + ".getSort()")); | ||
builder.add(sortingStage(pageableProvider + ".getSort()", getOutputType(queryMethod))); | ||
|
||
builder.beginControlFlow("if ($L.isPaged())", pageableProvider); | ||
builder.beginControlFlow("if ($L.getOffset() > 0)", pageableProvider); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
|
||
import java.util.List; | ||
|
||
import org.jspecify.annotations.Nullable; | ||
import org.springframework.data.geo.Box; | ||
import org.springframework.data.geo.Circle; | ||
import org.springframework.data.geo.Distance; | ||
|
@@ -52,7 +53,7 @@ static Placeholder indexed(int position) { | |
* @param type | ||
* @return | ||
*/ | ||
public static Shape geoJson(int index, String type) { | ||
static Shape geoJson(int index, String type) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, I liked to keep There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather have them aligned with the type scope in such cases. |
||
return new GeoJsonPlaceholder(index, type); | ||
} | ||
|
||
|
@@ -62,7 +63,7 @@ public static Shape geoJson(int index, String type) { | |
* @param index zero-based index referring to the bindable method parameter. | ||
* @return | ||
*/ | ||
public static Point point(int index) { | ||
static Point point(int index) { | ||
return new PointPlaceholder(index); | ||
} | ||
|
||
|
@@ -72,7 +73,7 @@ public static Point point(int index) { | |
* @param index zero-based index referring to the bindable method parameter. | ||
* @return | ||
*/ | ||
public static Shape circle(int index) { | ||
static Shape circle(int index) { | ||
return new CirclePlaceholder(index); | ||
} | ||
|
||
|
@@ -82,7 +83,7 @@ public static Shape circle(int index) { | |
* @param index zero-based index referring to the bindable method parameter. | ||
* @return | ||
*/ | ||
public static Shape box(int index) { | ||
static Shape box(int index) { | ||
return new BoxPlaceholder(index); | ||
} | ||
|
||
|
@@ -92,7 +93,7 @@ public static Shape box(int index) { | |
* @param index zero-based index referring to the bindable method parameter. | ||
* @return | ||
*/ | ||
public static Shape sphere(int index) { | ||
static Shape sphere(int index) { | ||
return new SpherePlaceholder(index); | ||
} | ||
|
||
|
@@ -102,20 +103,23 @@ public static Shape sphere(int index) { | |
* @param index zero-based index referring to the bindable method parameter. | ||
* @return | ||
*/ | ||
public static Shape polygon(int index) { | ||
static Shape polygon(int index) { | ||
return new PolygonPlaceholder(index); | ||
} | ||
|
||
static RegexPlaceholder regex(int index, @Nullable String options) { | ||
return new RegexPlaceholder(index, options); | ||
} | ||
|
||
/** | ||
* A placeholder expression used when rending queries to JSON. | ||
* | ||
* @since 5.0 | ||
* @author Christoph Strobl | ||
*/ | ||
public interface Placeholder { | ||
interface Placeholder { | ||
|
||
String getValue(); | ||
|
||
} | ||
|
||
/** | ||
|
@@ -139,7 +143,7 @@ private static class PointPlaceholder extends Point implements Placeholder { | |
|
||
private final int index; | ||
|
||
public PointPlaceholder(int index) { | ||
PointPlaceholder(int index) { | ||
super(Double.NaN, Double.NaN); | ||
this.index = index; | ||
} | ||
|
@@ -184,7 +188,7 @@ private static class CirclePlaceholder extends Circle implements Placeholder { | |
|
||
private final int index; | ||
|
||
public CirclePlaceholder(int index) { | ||
CirclePlaceholder(int index) { | ||
super(new PointPlaceholder(index), Distance.of(1, Metrics.NEUTRAL)); // | ||
this.index = index; | ||
} | ||
|
@@ -205,7 +209,7 @@ private static class BoxPlaceholder extends Box implements Placeholder { | |
|
||
private final int index; | ||
|
||
public BoxPlaceholder(int index) { | ||
BoxPlaceholder(int index) { | ||
super(new PointPlaceholder(index), new PointPlaceholder(index)); | ||
this.index = index; | ||
} | ||
|
@@ -226,7 +230,7 @@ private static class SpherePlaceholder extends Sphere implements Placeholder { | |
|
||
private final int index; | ||
|
||
public SpherePlaceholder(int index) { | ||
SpherePlaceholder(int index) { | ||
super(new PointPlaceholder(index), Distance.of(1, Metrics.NEUTRAL)); // | ||
this.index = index; | ||
} | ||
|
@@ -247,7 +251,7 @@ private static class PolygonPlaceholder extends Polygon implements Placeholder { | |
|
||
private final int index; | ||
|
||
public PolygonPlaceholder(int index) { | ||
PolygonPlaceholder(int index) { | ||
super(new PointPlaceholder(index), new PointPlaceholder(index), new PointPlaceholder(index), | ||
new PointPlaceholder(index)); | ||
this.index = index; | ||
|
@@ -265,4 +269,29 @@ public String toString() { | |
|
||
} | ||
|
||
static class RegexPlaceholder implements Placeholder { | ||
|
||
private final int index; | ||
private final @Nullable String options; | ||
|
||
RegexPlaceholder(int index, @Nullable String options) { | ||
this.index = index; | ||
this.options = options; | ||
} | ||
|
||
@Nullable String regexOptions() { | ||
return options; | ||
} | ||
|
||
@Override | ||
public String getValue() { | ||
return "?" + index; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return getValue(); | ||
} | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use
SimpleTypeHolder
fromMongoRepositoryContributor
.