@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -22,6 +23,9 @@ import java.util.List;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoPage;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.query.Collation;
|
||||
import org.springframework.data.mongodb.core.query.TextCriteria;
|
||||
@@ -44,6 +48,9 @@ import org.springframework.lang.Nullable;
|
||||
*/
|
||||
public class MongoParameters extends Parameters<MongoParameters, MongoParameter> {
|
||||
|
||||
private static final List<Class<? extends Serializable>> GEO_NEAR_RESULTS = Arrays.asList(GeoResult.class,
|
||||
GeoResults.class, GeoPage.class);
|
||||
|
||||
private final int rangeIndex;
|
||||
private final int maxDistanceIndex;
|
||||
private final @Nullable Integer fullTextIndex;
|
||||
@@ -56,7 +63,17 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
|
||||
* Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}.
|
||||
*
|
||||
* @param parametersSource must not be {@literal null}.
|
||||
* @param isGeoNearMethod indicate if this is a geo spatial query method
|
||||
* @since 4.5
|
||||
*/
|
||||
public MongoParameters(ParametersSource parametersSource) {
|
||||
this(parametersSource, isGeoNearQuery(parametersSource.getMethod()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}.
|
||||
*
|
||||
* @param parametersSource must not be {@literal null}.
|
||||
* @param isGeoNearMethod indicate if this is a geo-spatial query method
|
||||
*/
|
||||
public MongoParameters(ParametersSource parametersSource, boolean isGeoNearMethod) {
|
||||
this(parametersSource, new NearIndex(parametersSource, isGeoNearMethod));
|
||||
@@ -104,6 +121,24 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
|
||||
this.domainType = domainType;
|
||||
}
|
||||
|
||||
static boolean isGeoNearQuery(Method method) {
|
||||
|
||||
Class<?> returnType = method.getReturnType();
|
||||
|
||||
for (Class<?> type : GEO_NEAR_RESULTS) {
|
||||
if (type.isAssignableFrom(returnType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Iterable.class.isAssignableFrom(returnType)) {
|
||||
TypeInformation<?> from = TypeInformation.fromReturnTypeOf(method);
|
||||
return GeoResult.class.equals(from.getRequiredComponentType().getType());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static class NearIndex {
|
||||
|
||||
private final @Nullable Integer nearIndex;
|
||||
|
||||
@@ -15,18 +15,13 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.data.geo.GeoPage;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.annotation.Collation;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
@@ -65,15 +60,12 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class MongoQueryMethod extends QueryMethod {
|
||||
|
||||
@SuppressWarnings("unchecked") private static final List<Class<? extends Serializable>> GEO_NEAR_RESULTS = Arrays
|
||||
.asList(GeoResult.class, GeoResults.class, GeoPage.class);
|
||||
|
||||
private final Method method;
|
||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
private final Map<Class<? extends Annotation>, Optional<Annotation>> annotationCache;
|
||||
|
||||
private @Nullable MongoEntityMetadata<?> metadata;
|
||||
private Lazy<Boolean> isModifying = Lazy.of(this::resolveModifyingQueryIndicators);
|
||||
private final Lazy<Boolean> isModifying = Lazy.of(this::resolveModifyingQueryIndicators);
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoQueryMethod} from the given {@link Method}.
|
||||
@@ -85,8 +77,22 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
*/
|
||||
public MongoQueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory projectionFactory,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
this(method, metadata, projectionFactory, mappingContext, MongoParameters::new);
|
||||
}
|
||||
|
||||
super(method, metadata, projectionFactory);
|
||||
/**
|
||||
* Creates a new {@link MongoQueryMethod} from the given {@link Method}.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param metadata must not be {@literal null}.
|
||||
* @param projectionFactory must not be {@literal null}.
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
*/
|
||||
MongoQueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory projectionFactory,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext,
|
||||
Function<ParametersSource, ? extends MongoParameters> parametersFunction) {
|
||||
|
||||
super(method, metadata, projectionFactory, parametersFunction);
|
||||
|
||||
Assert.notNull(mappingContext, "MappingContext must not be null");
|
||||
|
||||
@@ -95,11 +101,6 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
this.annotationCache = new ConcurrentReferenceHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MongoParameters createParameters(ParametersSource parametersSource) {
|
||||
return new MongoParameters(parametersSource, isGeoNearQuery(parametersSource.getMethod()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the method has an annotated query.
|
||||
*
|
||||
@@ -186,25 +187,7 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
* @return
|
||||
*/
|
||||
public boolean isGeoNearQuery() {
|
||||
return isGeoNearQuery(this.method);
|
||||
}
|
||||
|
||||
private boolean isGeoNearQuery(Method method) {
|
||||
|
||||
Class<?> returnType = method.getReturnType();
|
||||
|
||||
for (Class<?> type : GEO_NEAR_RESULTS) {
|
||||
if (type.isAssignableFrom(returnType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Iterable.class.isAssignableFrom(returnType)) {
|
||||
TypeInformation<?> from = TypeInformation.fromReturnTypeOf(method);
|
||||
return GeoResult.class.equals(from.getRequiredComponentType().getType());
|
||||
}
|
||||
|
||||
return false;
|
||||
return MongoParameters.isGeoNearQuery(this.method);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import static org.springframework.data.repository.util.ClassUtils.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
@@ -31,10 +29,10 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.repository.query.MongoParameters.MongoParameter;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.ParametersSource;
|
||||
import org.springframework.data.repository.util.ReactiveWrapperConverters;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.data.util.ReactiveWrappers;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -64,18 +62,16 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod {
|
||||
public ReactiveMongoQueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory projectionFactory,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
|
||||
super(method, metadata, projectionFactory, mappingContext);
|
||||
super(method, metadata, projectionFactory, mappingContext, parametersSource -> {
|
||||
return new MongoParameters(parametersSource,
|
||||
MongoParameters.isGeoNearQuery(parametersSource.getMethod()) || isGeoNearQuery(parametersSource.getMethod()));
|
||||
});
|
||||
|
||||
this.method = method;
|
||||
this.isCollectionQuery = Lazy.of(() -> (!(isPageQuery() || isSliceQuery() || isScrollQuery())
|
||||
&& ReactiveWrappers.isMultiValueType(metadata.getReturnType(method).getType()) || super.isCollectionQuery()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MongoParameters createParameters(ParametersSource parametersSource) {
|
||||
return new MongoParameters(parametersSource, isGeoNearQuery(parametersSource.getMethod()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollectionQuery() {
|
||||
return isCollectionQuery.get();
|
||||
@@ -86,7 +82,7 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod {
|
||||
return isGeoNearQuery(method);
|
||||
}
|
||||
|
||||
private boolean isGeoNearQuery(Method method) {
|
||||
private static boolean isGeoNearQuery(Method method) {
|
||||
|
||||
if (ReactiveWrappers.supports(method.getReturnType())) {
|
||||
TypeInformation<?> from = TypeInformation.fromReturnTypeOf(method);
|
||||
@@ -130,7 +126,7 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod {
|
||||
@Override
|
||||
public void verify() {
|
||||
|
||||
if (hasParameterOfType(method, Pageable.class)) {
|
||||
if (ReflectionUtils.hasParameterOfType(method, Pageable.class)) {
|
||||
|
||||
TypeInformation<?> returnType = TypeInformation.fromReturnTypeOf(method);
|
||||
|
||||
@@ -139,7 +135,7 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod {
|
||||
&& (PAGE_TYPE.isAssignableFrom(returnType.getRequiredComponentType())
|
||||
|| SLICE_TYPE.isAssignableFrom(returnType.getRequiredComponentType()));
|
||||
|
||||
if (hasParameterOfType(method, Sort.class)) {
|
||||
if (ReflectionUtils.hasParameterOfType(method, Sort.class)) {
|
||||
throw new IllegalStateException(String.format("Method must not have Pageable *and* Sort parameter;"
|
||||
+ " Use sorting capabilities on Pageable instead; Offending method: %s", method));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user