Browse Source

DATACMNS-61 - Adapted changes in Spring Data Commons.

Use QueryMethod accessor methods instead of dropped Type enum to determine query execution. Added custom MongoParameters and MongoParameter to allow discovering a Distance parameter for repository queries which will transparently add a 'maxDistance' clause for *Near criterias in query methods. If the given Distance is equipped with a Metric we will rather use $nearSphere over $near.

Added asList() to Point class to circumvent bug in BasicBSONObject.equals(…) which breaks equals(…) comparisons of DBObjects in case they use arrays as values. See [0] for details. Adapted usage of Point objects to use asList() over asArray().

[0] https://jira.mongodb.org/browse/JAVA-416
pull/1/head
Oliver Gierke 15 years ago
parent
commit
e130fb5a2d
  1. 7
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/Point.java
  2. 19
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java
  3. 2
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/NearQuery.java
  4. 17
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/AbstractMongoQuery.java
  5. 17
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/ConvertingParameterAccessor.java
  6. 35
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoParameterAccessor.java
  7. 63
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoParameters.java
  8. 47
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoParametersParameterAccessor.java
  9. 24
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoQueryCreator.java
  10. 26
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoQueryMethod.java
  11. 66
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoParametersParameterAccessorUnitTests.java
  12. 57
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoParametersUnitTests.java
  13. 47
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoQueryCreatorUnitTests.java
  14. 11
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/StubParameterAccessor.java

7
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/Point.java

@ -15,6 +15,9 @@ @@ -15,6 +15,9 @@
*/
package org.springframework.data.mongodb.core.geo;
import java.util.Arrays;
import java.util.List;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.util.Assert;
@ -55,6 +58,10 @@ public class Point { @@ -55,6 +58,10 @@ public class Point {
public double[] asArray() {
return new double[] { x, y };
}
public List<Double> asList() {
return Arrays.asList(x, y);
}
@Override
public int hashCode() {

19
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java

@ -18,7 +18,6 @@ package org.springframework.data.mongodb.core.query; @@ -18,7 +18,6 @@ package org.springframework.data.mongodb.core.query;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import com.mongodb.BasicDBObject;
@ -295,8 +294,8 @@ public class Criteria implements CriteriaDefinition { @@ -295,8 +294,8 @@ public class Criteria implements CriteriaDefinition {
*/
public Criteria withinCenter(Circle circle) {
Assert.notNull(circle);
LinkedList<Object> list = new LinkedList<Object>();
list.addLast(circle.getCenter().asArray());
List<Object> list = new ArrayList<Object>();
list.add(circle.getCenter().asList());
list.add(circle.getRadius());
criteria.put("$within", new BasicDBObject("$center", list));
return this;
@ -311,8 +310,8 @@ public class Criteria implements CriteriaDefinition { @@ -311,8 +310,8 @@ public class Criteria implements CriteriaDefinition {
*/
public Criteria withinCenterSphere(Circle circle) {
Assert.notNull(circle);
LinkedList<Object> list = new LinkedList<Object>();
list.addLast(circle.getCenter().asArray());
List<Object> list = new ArrayList<Object>();
list.add(circle.getCenter().asList());
list.add(circle.getRadius());
criteria.put("$within", new BasicDBObject("$centerSphere", list));
return this;
@ -326,9 +325,9 @@ public class Criteria implements CriteriaDefinition { @@ -326,9 +325,9 @@ public class Criteria implements CriteriaDefinition {
*/
public Criteria withinBox(Box box) {
Assert.notNull(box);
LinkedList<double[]> list = new LinkedList<double[]>();
list.addLast(box.getLowerLeft().asArray());
list.addLast(box.getUpperRight().asArray());
List<List<Double>> list = new ArrayList<List<Double>>();
list.add(box.getLowerLeft().asList());
list.add(box.getUpperRight().asList());
criteria.put("$within", new BasicDBObject("$box", list));
return this;
}
@ -342,7 +341,7 @@ public class Criteria implements CriteriaDefinition { @@ -342,7 +341,7 @@ public class Criteria implements CriteriaDefinition {
*/
public Criteria near(Point point) {
Assert.notNull(point);
criteria.put("$near", point.asArray());
criteria.put("$near", point.asList());
return this;
}
@ -355,7 +354,7 @@ public class Criteria implements CriteriaDefinition { @@ -355,7 +354,7 @@ public class Criteria implements CriteriaDefinition {
*/
public Criteria nearSphere(Point point) {
Assert.notNull(point);
criteria.put("$nearSphere", point.asArray());
criteria.put("$nearSphere", point.asList());
return this;
}

2
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/NearQuery.java

@ -46,7 +46,7 @@ public class NearQuery { @@ -46,7 +46,7 @@ public class NearQuery {
Assert.notNull(point);
this.criteria = new BasicDBObject();
this.criteria.put("near", point.asArray());
this.criteria.put("near", point.asList());
this.metric = metric;
if (metric != null) {

17
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/AbstractMongoQuery.java

@ -19,19 +19,19 @@ import static org.springframework.data.mongodb.repository.QueryUtils.*; @@ -19,19 +19,19 @@ import static org.springframework.data.mongodb.repository.QueryUtils.*;
import java.util.List;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.CollectionCallback;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.data.repository.query.ParametersParameterAccessor;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.util.Assert;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
/**
* Base class for {@link RepositoryQuery} implementations for Mongo.
*
@ -72,15 +72,14 @@ public abstract class AbstractMongoQuery implements RepositoryQuery { @@ -72,15 +72,14 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
*/
public Object execute(Object[] parameters) {
ParameterAccessor accessor = new ParametersParameterAccessor(method.getParameters(), parameters);
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(method.getParameters(), parameters);
Query query = createQuery(new ConvertingParameterAccessor(template.getConverter(), accessor));
switch (method.getType()) {
case COLLECTION:
if (method.isCollectionQuery()) {
return new CollectionExecution().execute(query);
case PAGING:
} else if (method.isPageQuery()) {
return new PagedExecution(accessor.getPageable()).execute(query);
default:
} else {
return new SingleEntityExecution().execute(query);
}
}

17
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/ConvertingParameterAccessor.java

@ -21,6 +21,7 @@ import org.springframework.data.domain.Pageable; @@ -21,6 +21,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoWriter;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.repository.query.ParameterAccessor;
import com.mongodb.BasicDBList;
@ -31,17 +32,17 @@ import com.mongodb.DBObject; @@ -31,17 +32,17 @@ import com.mongodb.DBObject;
*
* @author Oliver Gierke
*/
public class ConvertingParameterAccessor implements ParameterAccessor {
public class ConvertingParameterAccessor implements MongoParameterAccessor {
private final MongoWriter<Object> writer;
private final ParameterAccessor delegate;
private final MongoParameterAccessor delegate;
/**
* Creates a new {@link ConvertingParameterAccessor} with the given {@link MongoWriter} and delegate.
*
* @param writer
*/
public ConvertingParameterAccessor(MongoWriter<Object> writer, ParameterAccessor delegate) {
public ConvertingParameterAccessor(MongoWriter<Object> writer, MongoParameterAccessor delegate) {
this.writer = writer;
this.delegate = delegate;
}
@ -51,7 +52,7 @@ public class ConvertingParameterAccessor implements ParameterAccessor { @@ -51,7 +52,7 @@ public class ConvertingParameterAccessor implements ParameterAccessor {
*
* @see java.lang.Iterable#iterator()
*/
public Iterator<Object> iterator() {
public PotentiallyConvertingIterator iterator() {
return new ConvertingIterator(delegate.iterator());
}
@ -80,6 +81,14 @@ public class ConvertingParameterAccessor implements ParameterAccessor { @@ -80,6 +81,14 @@ public class ConvertingParameterAccessor implements ParameterAccessor {
return getConvertedValue(delegate.getBindableValue(index));
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getMaxDistance()
*/
public Distance getMaxDistance() {
return delegate.getMaxDistance();
}
/**
* Converts the given value with the underlying {@link MongoWriter}.

35
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoParameterAccessor.java

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
/*
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.repository;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.repository.query.ParameterAccessor;
/**
* Mongo-specific {@link ParameterAccessor} exposing a maximum distance parameter.
*
* @author Oliver Gierke
*/
public interface MongoParameterAccessor extends ParameterAccessor {
/**
* Returns a {@link Distance} to be applied to Mongo geo queries.
*
* @return the maximum distance to apply to the geo query or {@literal null} if there's no {@link Distance} parameter
* at all or the given value for it was {@literal null}.
*/
Distance getMaxDistance();
}

63
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoParameters.java

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
package org.springframework.data.mongodb.repository;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.core.MethodParameter;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.repository.query.Parameter;
import org.springframework.data.repository.query.Parameters;
/**
* Custom extension of {@link Parameters} discovering additional
*
* @author Oliver Gierke
*/
public class MongoParameters extends Parameters {
private int distanceIndex = -1;
public MongoParameters(Method method) {
super(method);
this.distanceIndex = Arrays.asList(method.getParameterTypes()).indexOf(Distance.class);
}
/* (non-Javadoc)
* @see org.springframework.data.repository.query.Parameters#createParameter(org.springframework.core.MethodParameter)
*/
@Override
protected Parameter createParameter(MethodParameter parameter) {
return new MongoParameter(parameter, this);
}
public int getDistanceIndex() {
return distanceIndex;
}
/**
* Custom {@link Parameter} implementation adding parameters of type {@link Distance} to the special ones.
*
* @author Oliver Gierke
*/
static class MongoParameter extends Parameter {
/**
*
* @param parameter
* @param parameters
*/
MongoParameter(MethodParameter parameter, Parameters parameters) {
super(parameter, parameters);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.Parameter#isSpecialParameter()
*/
@Override
public boolean isSpecialParameter() {
return super.isSpecialParameter() || getType().equals(Distance.class);
}
}
}

47
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoParametersParameterAccessor.java

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
/*
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.repository;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.repository.query.ParametersParameterAccessor;
/**
* Mongo-specific {@link ParametersParameterAccessor} to allow access to the {@link Distance} parameter.
*
* @author Oliver Gierke
*/
public class MongoParametersParameterAccessor extends ParametersParameterAccessor implements MongoParameterAccessor {
private final MongoParameters parameters;
/**
* @param parameters
* @param values
*/
public MongoParametersParameterAccessor(MongoParameters parameters, Object[] values) {
super(parameters, values);
this.parameters = parameters;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getMaxDistance()
*/
public Distance getMaxDistance() {
int index = parameters.getDistanceIndex();
return index == -1 ? null : (Distance) getValue(index);
}
}

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

@ -26,12 +26,12 @@ import org.apache.commons.logging.LogFactory; @@ -26,12 +26,12 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.geo.Box;
import org.springframework.data.mongodb.core.geo.Circle;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.mongodb.core.geo.Point;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.ConvertingParameterAccessor.PotentiallyConvertingIterator;
import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.data.repository.query.ParametersParameterAccessor;
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
import org.springframework.data.repository.query.parser.Part;
@ -46,6 +46,7 @@ import org.springframework.data.repository.query.parser.PartTree; @@ -46,6 +46,7 @@ import org.springframework.data.repository.query.parser.PartTree;
class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
private static final Log LOG = LogFactory.getLog(MongoQueryCreator.class);
private final MongoParameterAccessor accessor;
/**
* Creates a new {@link MongoQueryCreator} from the given {@link PartTree} and {@link ParametersParameterAccessor}.
@ -53,9 +54,10 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> { @@ -53,9 +54,10 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
* @param tree
* @param accessor
*/
public MongoQueryCreator(PartTree tree, ParameterAccessor accessor) {
public MongoQueryCreator(PartTree tree, ConvertingParameterAccessor accessor) {
super(tree, accessor);
this.accessor = accessor;
}
/*
@ -144,9 +146,23 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> { @@ -144,9 +146,23 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
String value = parameters.next().toString();
return criteria.is(toLikeRegex(value));
case NEAR:
return criteria.near(nextAs(parameters, Point.class));
Distance distance = accessor.getMaxDistance();
Point point = nextAs(parameters, Point.class);
if (distance == null) {
return criteria.near(point);
} else {
if (distance.getMetric() != null) {
criteria.nearSphere(point);
} else {
criteria.near(point);
}
criteria.maxDistance(distance.getNormalizedValue());
}
return criteria;
case WITHIN:
Object parameter = parameters.next();
if (parameter instanceof Box) {
return criteria.withinBox((Box) parameter);

26
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoQueryMethod.java

@ -20,6 +20,7 @@ import java.lang.reflect.Method; @@ -20,6 +20,7 @@ import java.lang.reflect.Method;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.mongodb.repository.MongoRepositoryFactoryBean.EntityInformationCreator;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.Parameters;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.repository.util.ClassUtils;
import org.springframework.util.StringUtils;
@ -45,6 +46,15 @@ class MongoQueryMethod extends QueryMethod { @@ -45,6 +46,15 @@ class MongoQueryMethod extends QueryMethod {
this.method = method;
this.entityInformation = entityInformationCreator.getEntityInformation(ClassUtils.getReturnedDomainClass(method));
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryMethod#getParameters(java.lang.reflect.Method)
*/
@Override
protected Parameters createParameters(Method method) {
return new MongoParameters(method);
}
/**
* Returns whether the method has an annotated query.
@ -78,14 +88,24 @@ class MongoQueryMethod extends QueryMethod { @@ -78,14 +88,24 @@ class MongoQueryMethod extends QueryMethod {
return StringUtils.hasText(value) ? value : null;
}
/* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryMethod#getEntityMetadata()
*/
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryMethod#getEntityInformation()
*/
@Override
public MongoEntityInformation<?, ?> getEntityInformation() {
return entityInformation;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryMethod#getParameters()
*/
@Override
public MongoParameters getParameters() {
return (MongoParameters) super.getParameters();
}
/**
* Returns the {@link Query} annotation that is applied to the method or {@code null} if none available.

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

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
/*
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.repository;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import java.util.List;
import org.junit.Test;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.mongodb.core.geo.Metrics;
import org.springframework.data.mongodb.core.geo.Point;
/**
* Unit tests for {@link MongoParametersParameterAccessor}.
*
* @author Oliver Gierke
*/
public class MongoParametersParameterAccessorUnitTests {
private static final Distance DISTANCE = new Distance(2.5, Metrics.KILOMETERS);
@Test
public void returnsNullForDistanceIfNoneAvailable() throws NoSuchMethodException, SecurityException {
Method method = PersonRepository.class.getMethod("findByLocationNear", Point.class);
MongoParameters parameters = new MongoParameters(method);
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(parameters,
new Object[] { new Point(10, 20) });
assertThat(accessor.getMaxDistance(), is(nullValue()));
}
@Test
public void returnsDistanceIfAvailable() throws NoSuchMethodException, SecurityException {
Method method = PersonRepository.class.getMethod("findByLocationNear", Point.class, Distance.class);
MongoParameters parameters = new MongoParameters(method);
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(parameters, new Object[] {
new Point(10, 20), DISTANCE });
assertThat(accessor.getMaxDistance(), is(DISTANCE));
}
interface PersonRepository {
List<Person> findByLocationNear(Point point);
List<Person> findByLocationNear(Point point, Distance distance);
}
}

57
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoParametersUnitTests.java

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
/*
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.repository;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import java.util.List;
import org.junit.Test;
import org.springframework.core.MethodParameter;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.mongodb.core.geo.Point;
import org.springframework.data.mongodb.repository.MongoParameters.MongoParameter;
/**
* Unit tests for {@link MongoParameters}.
*
* @author Oliver Gierke
*/
public class MongoParametersUnitTests {
@Test
public void discoversDistanceParameter() throws NoSuchMethodException, SecurityException {
Method method = PersonRepository.class.getMethod("findByLocationNear", Point.class, Distance.class);
MongoParameters parameters = new MongoParameters(method);
assertThat(parameters.getNumberOfParameters(), is(2));
assertThat(parameters.getDistanceIndex(), is(1));
assertThat(parameters.getBindableParameters().getNumberOfParameters(), is(1));
MongoParameter parameter = new MongoParameters.MongoParameter(new MethodParameter(method,
parameters.getDistanceIndex()), parameters);
assertThat(parameter.isSpecialParameter(), is(true));
assertThat(parameter.isBindable(), is(false));
}
interface PersonRepository {
List<Person> findByLocationNear(Point point, Distance distance);
}
}

47
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoQueryCreatorUnitTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,8 +19,12 @@ import static org.junit.Assert.*; @@ -19,8 +19,12 @@ import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.hamcrest.CoreMatchers.*;
import static org.springframework.data.mongodb.repository.StubParameterAccessor.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import java.lang.reflect.Method;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -31,6 +35,9 @@ import org.mockito.runners.MockitoJUnitRunner; @@ -31,6 +35,9 @@ import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.springframework.data.mongodb.core.Person;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.mongodb.core.geo.Metrics;
import org.springframework.data.mongodb.core.geo.Point;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.MongoQueryCreator;
@ -96,4 +103,42 @@ public class MongoQueryCreatorUnitTests { @@ -96,4 +103,42 @@ public class MongoQueryCreatorUnitTests {
assertThat(query.getQueryObject(), is(new Query(Criteria.where("firstName").is(null)).getQueryObject()));
}
@Test
public void bindsMetricDistanceParameterToNearSphereCorrectly() throws Exception {
Point point = new Point(10, 20);
Distance distance = new Distance(2.5, Metrics.KILOMETERS);
Query query = query(where("location").nearSphere(point).maxDistance(distance.getNormalizedValue()).and("firstname").is("Dave"));
assertBindsDistanceToQuery(point, distance, query);
}
@Test
public void bindsDistanceParameterToNearCorrectly() throws Exception {
Point point = new Point(10, 20);
Distance distance = new Distance(2.5);
Query query = query(where("location").near(point).maxDistance(distance.getNormalizedValue()).and("firstname").is("Dave"));
assertBindsDistanceToQuery(point, distance, query);
}
private void assertBindsDistanceToQuery(Point point, Distance distance, Query reference) throws Exception {
when(converter.convertToMongoType("Dave")).thenReturn("Dave");
PartTree tree = new PartTree("findByLocationNearAndFirstname", org.springframework.data.mongodb.repository.Person.class);
MongoParameters parameters = new MongoParameters(PersonRepository.class.getMethod("findByLocationNearAndFirstname", Point.class, Distance.class, String.class));
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(parameters, new Object[] { point, distance, "Dave" });
Query query = new MongoQueryCreator(tree, new ConvertingParameterAccessor(converter, accessor)).createQuery();
assertThat(query.getQueryObject(), is(query.getQueryObject()));
}
interface PersonRepository {
List<Person> findByLocationNearAndFirstname(Point location, Distance maxDistance, String firstname);
}
}

11
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/StubParameterAccessor.java

@ -21,6 +21,7 @@ import java.util.Iterator; @@ -21,6 +21,7 @@ import java.util.Iterator;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.convert.MongoWriter;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.mongodb.repository.ConvertingParameterAccessor;
import org.springframework.data.repository.query.ParameterAccessor;
@ -29,7 +30,7 @@ import org.springframework.data.repository.query.ParameterAccessor; @@ -29,7 +30,7 @@ import org.springframework.data.repository.query.ParameterAccessor;
*
* @author Oliver Gierke
*/
class StubParameterAccessor implements ParameterAccessor {
class StubParameterAccessor implements MongoParameterAccessor {
private final Object[] values;
@ -74,6 +75,14 @@ class StubParameterAccessor implements ParameterAccessor { @@ -74,6 +75,14 @@ class StubParameterAccessor implements ParameterAccessor {
public Sort getSort() {
return null;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getMaxDistance()
*/
public Distance getMaxDistance() {
return null;
}
/*
* (non-Javadoc)

Loading…
Cancel
Save