Skip to content

Commit e01c745

Browse files
committed
DATAMONGO-1674 - Adapted to Range API changes.
1 parent 9ae3a29 commit e01c745

File tree

7 files changed

+94
-94
lines changed

7 files changed

+94
-94
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mongodb.core.aggregation;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
21+
import org.springframework.data.domain.Range;
22+
import org.springframework.util.Assert;
23+
24+
/**
25+
* Utility methods for aggregation ooperation implementations.
26+
*
27+
* @author Oliver Gierke
28+
*/
29+
interface AggregationUtils {
30+
31+
/**
32+
* Converts the given {@link Range} into an array of values.
33+
*
34+
* @param range must not be {@literal null}.
35+
* @return
36+
*/
37+
public static List<Long> toRangeValues(Range<Long> range) {
38+
39+
Assert.notNull(range, "Range must not be null!");
40+
41+
List<Long> result = new ArrayList<Long>(2);
42+
result.add(range.getLowerBound().getValue()
43+
.orElseThrow(() -> new IllegalArgumentException("Lower bound of range must be bounded!")));
44+
range.getUpperBound().getValue().ifPresent(it -> result.add(it));
45+
46+
return result;
47+
}
48+
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java

+1-10
Original file line numberDiff line numberDiff line change
@@ -849,16 +849,7 @@ public static IndexOfArrayBuilder arrayOf(AggregationExpression expression) {
849849
}
850850

851851
public IndexOfArray within(Range<Long> range) {
852-
853-
Assert.notNull(range, "Range must not be null!");
854-
855-
List<Long> rangeValues = new ArrayList<Long>(2);
856-
rangeValues.add(range.getLowerBound());
857-
if (range.getUpperBound() != null) {
858-
rangeValues.add(range.getUpperBound());
859-
}
860-
861-
return new IndexOfArray(append(rangeValues));
852+
return new IndexOfArray(append(AggregationUtils.toRangeValues(range)));
862853
}
863854

864855
/**

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java

+2-21
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package org.springframework.data.mongodb.core.aggregation;
1717

18-
import java.util.ArrayList;
1918
import java.util.Arrays;
2019
import java.util.Collections;
2120
import java.util.List;
@@ -732,16 +731,7 @@ public static SubstringBuilder valueOf(AggregationExpression expression) {
732731
* @return
733732
*/
734733
public IndexOfBytes within(Range<Long> range) {
735-
736-
Assert.notNull(range, "Range must not be null!");
737-
738-
List<Long> rangeValues = new ArrayList<Long>(2);
739-
rangeValues.add(range.getLowerBound());
740-
if (range.getUpperBound() != null) {
741-
rangeValues.add(range.getUpperBound());
742-
}
743-
744-
return new IndexOfBytes(append(rangeValues));
734+
return new IndexOfBytes(append(AggregationUtils.toRangeValues(range)));
745735
}
746736

747737
public static class SubstringBuilder {
@@ -831,16 +821,7 @@ public static SubstringBuilder valueOf(AggregationExpression expression) {
831821
* @return
832822
*/
833823
public IndexOfCP within(Range<Long> range) {
834-
835-
Assert.notNull(range, "Range must not be null!");
836-
837-
List<Long> rangeValues = new ArrayList<Long>(2);
838-
rangeValues.add(range.getLowerBound());
839-
if (range.getUpperBound() != null) {
840-
rangeValues.add(range.getUpperBound());
841-
}
842-
843-
return new IndexOfCP(append(rangeValues));
824+
return new IndexOfCP(append(AggregationUtils.toRangeValues(range)));
844825
}
845826

846827
public static class SubstringBuilder {

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java

+16-17
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.Collection;
2222
import java.util.Iterator;
2323
import java.util.Optional;
24-
import java.util.regex.Pattern;
2524

2625
import org.slf4j.Logger;
2726
import org.slf4j.LoggerFactory;
@@ -61,7 +60,6 @@
6160
class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
6261

6362
private static final Logger LOG = LoggerFactory.getLogger(MongoQueryCreator.class);
64-
private static final Pattern PUNCTATION_PATTERN = Pattern.compile("\\p{Punct}");
6563
private final MongoParameterAccessor accessor;
6664
private final boolean isGeoNearQuery;
6765

@@ -217,28 +215,29 @@ private Criteria from(Part part, MongoPersistentProperty property, Criteria crit
217215
case NEAR:
218216

219217
Range<Distance> range = accessor.getDistanceRange();
220-
Distance distance = range.getUpperBound();
221-
Distance minDistance = range.getLowerBound();
218+
Optional<Distance> distance = range.getUpperBound().getValue();
219+
Optional<Distance> minDistance = range.getLowerBound().getValue();
222220

223221
Point point = accessor.getGeoNearLocation();
224-
point = point == null ? nextAs(parameters, Point.class) : point;
222+
Point pointToUse = point == null ? nextAs(parameters, Point.class) : point;
225223

226224
boolean isSpherical = isSpherical(property);
227225

228-
if (distance == null) {
229-
return isSpherical ? criteria.nearSphere(point) : criteria.near(point);
230-
} else {
231-
if (isSpherical || !Metrics.NEUTRAL.equals(distance.getMetric())) {
232-
criteria.nearSphere(point);
226+
return distance.map(it -> {
227+
228+
if (isSpherical || !Metrics.NEUTRAL.equals(it.getMetric())) {
229+
criteria.nearSphere(pointToUse);
233230
} else {
234-
criteria.near(point);
235-
}
236-
criteria.maxDistance(distance.getNormalizedValue());
237-
if (minDistance != null) {
238-
criteria.minDistance(minDistance.getNormalizedValue());
231+
criteria.near(pointToUse);
239232
}
240-
}
241-
return criteria;
233+
234+
criteria.maxDistance(it.getNormalizedValue());
235+
minDistance.ifPresent(min -> criteria.minDistance(min.getNormalizedValue()));
236+
237+
return criteria;
238+
239+
}).orElseGet(() -> isSpherical ? criteria.nearSphere(pointToUse) : criteria.near(pointToUse));
240+
242241
case WITHIN:
243242

244243
Object parameter = parameters.next();

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java

+10-20
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,13 @@ public Object execute(final Query query, final Class<?> type, final String colle
140140

141141
// Adjust limit if page would exceed the overall limit
142142
if (overallLimit != 0 && pageable.getOffset() + pageable.getPageSize() > overallLimit) {
143-
query.limit((int)(overallLimit - pageable.getOffset()));
143+
query.limit((int) (overallLimit - pageable.getOffset()));
144144
}
145145

146146
return PageableExecutionUtils.getPage(operations.find(query, type, collection), pageable, () -> {
147147

148-
long count = operations.count(query, type, collection);
149-
return overallLimit != 0 ? Math.min(count, overallLimit) : count;
148+
long count = operations.count(query, type, collection);
149+
return overallLimit != 0 ? Math.min(count, overallLimit) : count;
150150

151151
});
152152
}
@@ -249,17 +249,8 @@ protected GeoResults<Object> doExecuteQuery(Query query, Class<?> type, String c
249249
}
250250

251251
Range<Distance> distances = accessor.getDistanceRange();
252-
Distance maxDistance = distances.getUpperBound();
253-
254-
if (maxDistance != null) {
255-
nearQuery.maxDistance(maxDistance).in(maxDistance.getMetric());
256-
}
257-
258-
Distance minDistance = distances.getLowerBound();
259-
260-
if (minDistance != null) {
261-
nearQuery.minDistance(minDistance).in(minDistance.getMetric());
262-
}
252+
distances.getLowerBound().getValue().ifPresent(it -> nearQuery.minDistance(it).in(it.getMetric()));
253+
distances.getUpperBound().getValue().ifPresent(it -> nearQuery.maxDistance(it).in(it.getMetric()));
263254

264255
Pageable pageable = accessor.getPageable();
265256

@@ -315,13 +306,12 @@ public Object execute(Query query, Class<?> type, final String collection) {
315306
Page<GeoResult<Object>> page = PageableExecutionUtils.getPage(geoResults.getContent(), accessor.getPageable(),
316307
() -> {
317308

309+
ConvertingParameterAccessor parameterAccessor = new ConvertingParameterAccessor(operations.getConverter(),
310+
accessor);
311+
Query countQuery = mongoQuery
312+
.applyQueryMetaAttributesWhenPresent(mongoQuery.createCountQuery(parameterAccessor));
318313

319-
ConvertingParameterAccessor parameterAccessor = new ConvertingParameterAccessor(operations.getConverter(),
320-
accessor);
321-
Query countQuery = mongoQuery
322-
.applyQueryMetaAttributesWhenPresent(mongoQuery.createCountQuery(parameterAccessor));
323-
324-
return operations.count(countQuery, collection);
314+
return operations.count(countQuery, collection);
325315

326316
});
327317

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java

+9-20
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@
1515
*/
1616
package org.springframework.data.mongodb.repository.query;
1717

18+
import lombok.NonNull;
19+
import lombok.RequiredArgsConstructor;
20+
import reactor.core.publisher.Flux;
21+
1822
import java.util.Optional;
1923

2024
import org.springframework.core.convert.converter.Converter;
2125
import org.springframework.data.convert.EntityInstantiators;
2226
import org.springframework.data.domain.Pageable;
2327
import org.springframework.data.domain.Range;
24-
import org.springframework.data.domain.Slice;
2528
import org.springframework.data.geo.Distance;
2629
import org.springframework.data.geo.GeoResult;
2730
import org.springframework.data.geo.Point;
@@ -34,17 +37,12 @@
3437
import org.springframework.data.util.TypeInformation;
3538
import org.springframework.util.ClassUtils;
3639

37-
import lombok.NonNull;
38-
import lombok.RequiredArgsConstructor;
39-
import reactor.core.publisher.Flux;
40-
import reactor.core.publisher.Mono;
41-
4240
import com.mongodb.client.result.DeleteResult;
4341

4442
/**
4543
* Set of classes to contain query execution strategies. Depending (mostly) on the return type of a
46-
* {@link org.springframework.data.repository.query.QueryMethod} a {@link AbstractReactiveMongoQuery} can be executed in various
47-
* flavors.
44+
* {@link org.springframework.data.repository.query.QueryMethod} a {@link AbstractReactiveMongoQuery} can be executed in
45+
* various flavors.
4846
*
4947
* @author Mark Paluch
5048
* @since 2.0
@@ -127,7 +125,7 @@ public Object execute(Query query, Class<?> type, String collection) {
127125
return isStreamOfGeoResult() ? results : results.map(GeoResult::getContent);
128126
}
129127

130-
@SuppressWarnings("unchecked")
128+
@SuppressWarnings({ "unchecked", "rawtypes" })
131129
protected Flux<GeoResult<Object>> doExecuteQuery(Query query, Class<?> type, String collection) {
132130

133131
Point nearLocation = accessor.getGeoNearLocation();
@@ -138,17 +136,8 @@ protected Flux<GeoResult<Object>> doExecuteQuery(Query query, Class<?> type, Str
138136
}
139137

140138
Range<Distance> distances = accessor.getDistanceRange();
141-
Distance maxDistance = distances.getUpperBound();
142-
143-
if (maxDistance != null) {
144-
nearQuery.maxDistance(maxDistance).in(maxDistance.getMetric());
145-
}
146-
147-
Distance minDistance = distances.getLowerBound();
148-
149-
if (minDistance != null) {
150-
nearQuery.minDistance(minDistance).in(minDistance.getMetric());
151-
}
139+
distances.getUpperBound().getValue().ifPresent(it -> nearQuery.maxDistance(it).in(it.getMetric()));
140+
distances.getLowerBound().getValue().ifPresent(it -> nearQuery.minDistance(it).in(it.getMetric()));
152141

153142
Pageable pageable = accessor.getPageable();
154143

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessorUnitTests.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
*/
1616
package org.springframework.data.mongodb.repository.query;
1717

18+
import static org.assertj.core.api.Assertions.assertThat;
1819
import static org.hamcrest.CoreMatchers.*;
19-
import static org.junit.Assert.*;
20+
import static org.junit.Assert.assertThat;
2021

2122
import java.lang.reflect.Method;
2223
import java.util.List;
@@ -25,6 +26,7 @@
2526
import org.hamcrest.core.IsNull;
2627
import org.junit.Test;
2728
import org.springframework.data.domain.Range;
29+
import org.springframework.data.domain.Range.Bound;
2830
import org.springframework.data.geo.Distance;
2931
import org.springframework.data.geo.Metrics;
3032
import org.springframework.data.geo.Point;
@@ -51,14 +53,14 @@ public class MongoParametersParameterAccessorUnitTests {
5153
ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
5254

5355
@Test
54-
public void returnsNullForDistanceIfNoneAvailable() throws NoSuchMethodException, SecurityException {
56+
public void returnsUnboundedForDistanceIfNoneAvailable() throws NoSuchMethodException, SecurityException {
5557

5658
Method method = PersonRepository.class.getMethod("findByLocationNear", Point.class);
5759
MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, factory, context);
5860

5961
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(queryMethod,
6062
new Object[] { new Point(10, 20) });
61-
assertThat(accessor.getDistanceRange().getUpperBound(), is(nullValue()));
63+
assertThat(accessor.getDistanceRange().getUpperBound().isBounded()).isFalse();
6264
}
6365

6466
@Test
@@ -69,7 +71,7 @@ public void returnsDistanceIfAvailable() throws NoSuchMethodException, SecurityE
6971

7072
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(queryMethod,
7173
new Object[] { new Point(10, 20), DISTANCE });
72-
assertThat(accessor.getDistanceRange().getUpperBound(), is(DISTANCE));
74+
assertThat(accessor.getDistanceRange().getUpperBound()).isEqualTo(Bound.inclusive(DISTANCE));
7375
}
7476

7577
@Test // DATAMONGO-973
@@ -109,8 +111,8 @@ public void shouldDetectMinAndMaxDistance() throws NoSuchMethodException, Securi
109111

110112
Range<Distance> range = accessor.getDistanceRange();
111113

112-
assertThat(range.getLowerBound(), is(min));
113-
assertThat(range.getUpperBound(), is(max));
114+
assertThat(range.getLowerBound(), is(Bound.inclusive(min)));
115+
assertThat(range.getUpperBound(), is(Bound.inclusive(max)));
114116
}
115117

116118
interface PersonRepository extends Repository<Person, Long> {

0 commit comments

Comments
 (0)