diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoConverters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoConverters.java index d9260d4e6..ba69103f0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoConverters.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoConverters.java @@ -25,17 +25,24 @@ import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; +import org.springframework.data.geo.Shape; import org.springframework.data.mongodb.core.geo.Sphere; +import org.springframework.data.mongodb.core.query.GeoCommand; import org.springframework.util.Assert; import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; /** * Wrapper class to contain useful geo structure converters for the usage with Mongo. * * @author Thomas Darimont + * @author Oliver Gierke * @since 1.5 */ abstract class GeoConverters { @@ -45,318 +52,6 @@ abstract class GeoConverters { */ private GeoConverters() {} - /** - * Converts a {@link List} of {@link Double}s into a {@link Point}. - * - * @author Thomas Darimont - * @since 1.5 - */ - @ReadingConverter - public static enum ListToPointConverter implements Converter, Point> { - - INSTANCE; - - @SuppressWarnings("deprecation") - public Point convert(List source) { - - Assert.notEmpty(source, "Source must not be empty!"); - Assert.isTrue(source.size() == 2, "Source must contain 2 elements"); - - return source == null ? null : new org.springframework.data.mongodb.core.geo.Point(source.get(0), source.get(1)); - } - } - - /** - * Converts a {@link Point} into a {@link List} of {@link Double}s. - * - * @author Thomas Darimont - * @since 1.5 - */ - public static enum PointToListConverter implements Converter> { - - INSTANCE; - - @Override - public List convert(Point source) { - return source == null ? null : Arrays.asList(source.getX(), source.getY()); - } - } - - /** - * Converts a {@link Box} into a {@link BasicDBList}. - * - * @author Thomas Darimont - * @since 1.5 - */ - @WritingConverter - public static enum BoxToDbObjectConverter implements Converter { - - INSTANCE; - - @Override - public BasicDBList convert(Box source) { - - if (source == null) { - return null; - } - - BasicDBList result = new BasicDBList(); - result.add(toList(source.getFirst())); - result.add(toList(source.getSecond())); - return result; - } - } - - /** - * Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Box}. - * - * @author Thomas Darimont - * @since 1.5 - */ - @ReadingConverter - public static enum DbObjectToBoxConverter implements Converter { - - INSTANCE; - - @SuppressWarnings("deprecation") - @Override - public Box convert(BasicDBList source) { - - if (source == null) { - return null; - } - - return new org.springframework.data.mongodb.core.geo.Box(toPoint(source.get(0)), toPoint(source.get(1))); - } - } - - /** - * Converts a {@link Circle} into a {@link BasicDBList}. - * - * @author Thomas Darimont - * @since 1.5 - */ - public static enum CircleToDbObjectConverter implements Converter { - - INSTANCE; - - @Override - public BasicDBList convert(Circle source) { - - if (source == null) { - return null; - } - - BasicDBList result = new BasicDBList(); - result.add(toList(source.getCenter())); - result.add(source.getRadius().getNormalizedValue()); - return result; - } - } - - /** - * Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Circle}. - * - * @author Thomas Darimont - * @since 1.5 - */ - @ReadingConverter - public static enum DbObjectToCircleConverter implements Converter { - - INSTANCE; - - @Override - public Circle convert(BasicDBList source) { - - if (source == null) { - return null; - } - - return new Circle(toPoint(source.get(0)), (Double) source.get(1)); - } - } - - /** - * Converts a {@link Circle} into a {@link BasicDBList}. - * - * @author Thomas Darimont - * @since 1.5 - */ - @SuppressWarnings("deprecation") - public static enum LegacyCircleToDbObjectConverter implements - Converter { - - INSTANCE; - - @Override - public BasicDBList convert(org.springframework.data.mongodb.core.geo.Circle source) { - - if (source == null) { - return null; - } - - BasicDBList result = new BasicDBList(); - result.add(toList(source.getCenter())); - result.add(source.getRadius()); - return result; - } - } - - /** - * Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Circle}. - * - * @author Thomas Darimont - * @since 1.5 - */ - @ReadingConverter - @SuppressWarnings("deprecation") - public static enum DbObjectToLegacyCircleConverter implements - Converter { - - INSTANCE; - - @Override - public org.springframework.data.mongodb.core.geo.Circle convert(BasicDBList source) { - - if (source == null) { - return null; - } - - return new org.springframework.data.mongodb.core.geo.Circle(toPoint(source.get(0)), (Double) source.get(1)); - } - } - - /** - * Converts a {@link Sphere} into a {@link BasicDBList}. - * - * @author Thomas Darimont - * @since 1.5 - */ - public static enum SphereToDbObjectConverter implements Converter { - - INSTANCE; - - @Override - public BasicDBList convert(Sphere source) { - - if (source == null) { - return null; - } - - BasicDBList result = new BasicDBList(); - result.add(toList(source.getCenter())); - result.add(source.getRadius().getNormalizedValue()); - return result; - } - } - - /** - * Converts a {@link BasicDBList} into a {@link Sphere}. - * - * @author Thomas Darimont - * @since 1.5 - */ - @ReadingConverter - public static enum DbObjectToSphereConverter implements Converter { - - INSTANCE; - - @Override - public Sphere convert(BasicDBList source) { - - if (source == null) { - return null; - } - - return new Sphere(toPoint(source.get(0)), (Double) source.get(1)); - } - } - - /** - * Converts a {@link Polygon} into a {@link BasicDBList}. - * - * @author Thomas Darimont - * @since 1.5 - */ - public static enum PolygonToDbObjectConverter implements Converter { - - INSTANCE; - - @Override - public BasicDBList convert(Polygon source) { - - if (source == null) { - return null; - } - - List points = source.getPoints(); - List> pointTuples = new ArrayList>(points.size()); - - for (Point point : points) { - pointTuples.add(toList(point)); - } - - BasicDBList result = new BasicDBList(); - result.addAll(pointTuples); - return result; - } - } - - /** - * Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Polygon}. - * - * @author Thomas Darimont - * @since 1.5 - */ - @ReadingConverter - public static enum DbObjectToPolygonConverter implements Converter { - - INSTANCE; - - @SuppressWarnings("deprecation") - @Override - public Polygon convert(BasicDBList source) { - - if (source == null) { - return null; - } - - List points = new ArrayList(source.size()); - for (Object element : source) { - - Assert.notNull(element, "point elements of polygon must not be null!"); - - points.add(toPoint(element)); - } - - return new org.springframework.data.mongodb.core.geo.Polygon(points); - } - } - - /** - * Converts the given item into a {@link Point}. - * - * @param item - * @return - */ - @SuppressWarnings("unchecked") - private static Point toPoint(Object item) { - - Assert.isInstanceOf(List.class, item); - - return ListToPointConverter.INSTANCE.convert((List) item); - } - - /** - * Converts the given {@link Point} into a {@link List} representation with X,Y coordinates as {@link Double}s. - * - * @param point - * @return - */ - private static List toList(Point point) { - return PointToListConverter.INSTANCE.convert(point); - } - /** * Returns the geo converters to be registered. * @@ -375,8 +70,451 @@ abstract class GeoConverters { , DbObjectToCircleConverter.INSTANCE // , DbObjectToLegacyCircleConverter.INSTANCE // , DbObjectToSphereConverter.INSTANCE // - , ListToPointConverter.INSTANCE // - , PointToListConverter.INSTANCE // - ); + , DbObjectToPointConverter.INSTANCE // + , PointToDbObjectConverter.INSTANCE // + , GeoCommandToDbObjectConverter.INSTANCE); + } + + /** + * Converts a {@link List} of {@link Double}s into a {@link Point}. + * + * @author Thomas Darimont + * @since 1.5 + */ + @ReadingConverter + public static enum DbObjectToPointConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + @SuppressWarnings("deprecation") + public Point convert(DBObject source) { + + Assert.isTrue(source.keySet().size() == 2, "Source must contain 2 elements"); + + return source == null ? null : new org.springframework.data.mongodb.core.geo.Point((Double) source.get("x"), + (Double) source.get("y")); + } + } + + /** + * Converts a {@link Point} into a {@link List} of {@link Double}s. + * + * @author Thomas Darimont + * @since 1.5 + */ + public static enum PointToDbObjectConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + public DBObject convert(Point source) { + return source == null ? null : new BasicDBObject("x", source.getX()).append("y", source.getY()); + } + } + + /** + * Converts a {@link Box} into a {@link BasicDBList}. + * + * @author Thomas Darimont + * @since 1.5 + */ + @WritingConverter + public static enum BoxToDbObjectConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + public DBObject convert(Box source) { + + if (source == null) { + return null; + } + + BasicDBObject result = new BasicDBObject(); + result.put("first", PointToDbObjectConverter.INSTANCE.convert(source.getFirst())); + result.put("second", PointToDbObjectConverter.INSTANCE.convert(source.getSecond())); + return result; + } + } + + /** + * Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Box}. + * + * @author Thomas Darimont + * @since 1.5 + */ + @ReadingConverter + public static enum DbObjectToBoxConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + @SuppressWarnings("deprecation") + public Box convert(DBObject source) { + + if (source == null) { + return null; + } + + Point first = DbObjectToPointConverter.INSTANCE.convert((DBObject) source.get("first")); + Point second = DbObjectToPointConverter.INSTANCE.convert((DBObject) source.get("second")); + + return new org.springframework.data.mongodb.core.geo.Box(first, second); + } + } + + /** + * Converts a {@link Circle} into a {@link BasicDBList}. + * + * @author Thomas Darimont + * @since 1.5 + */ + public static enum CircleToDbObjectConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + public DBObject convert(Circle source) { + + if (source == null) { + return null; + } + + DBObject result = new BasicDBObject(); + result.put("center", PointToDbObjectConverter.INSTANCE.convert(source.getCenter())); + result.put("radius", source.getRadius().getNormalizedValue()); + result.put("metric", source.getRadius().getMetric().toString()); + return result; + } + } + + /** + * Converts a {@link DBObject} into a {@link org.springframework.data.mongodb.core.geo.Circle}. + * + * @author Thomas Darimont + * @since 1.5 + */ + @ReadingConverter + public static enum DbObjectToCircleConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + public Circle convert(DBObject source) { + + if (source == null) { + return null; + } + + DBObject center = (DBObject) source.get("center"); + Double radius = (Double) source.get("radius"); + + Distance distance = new Distance(radius); + + if (source.containsField("metric")) { + + String metricString = (String) source.get("metric"); + Assert.notNull(metricString, "Metric must not be null!"); + + distance = distance.in(Metrics.valueOf(metricString)); + } + + Assert.notNull(center, "Center must not be null!"); + Assert.notNull(radius, "Radius must not be null!"); + + return new Circle(DbObjectToPointConverter.INSTANCE.convert(center), distance); + } + } + + /** + * Converts a {@link Circle} into a {@link BasicDBList}. + * + * @author Thomas Darimont + * @since 1.5 + */ + @SuppressWarnings("deprecation") + public static enum LegacyCircleToDbObjectConverter implements + Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + public DBObject convert(org.springframework.data.mongodb.core.geo.Circle source) { + + if (source == null) { + return null; + } + + DBObject result = new BasicDBObject(); + result.put("center", PointToDbObjectConverter.INSTANCE.convert(source.getCenter())); + result.put("radius", source.getRadius()); + return result; + } + } + + /** + * Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Circle}. + * + * @author Thomas Darimont + * @since 1.5 + */ + @ReadingConverter + @SuppressWarnings("deprecation") + public static enum DbObjectToLegacyCircleConverter implements + Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + public org.springframework.data.mongodb.core.geo.Circle convert(DBObject source) { + + if (source == null) { + return null; + } + + DBObject centerSource = (DBObject) source.get("center"); + Double radius = (Double) source.get("radius"); + + Assert.notNull(centerSource, "Center must not be null!"); + Assert.notNull(radius, "Radius must not be null!"); + + Point center = DbObjectToPointConverter.INSTANCE.convert(centerSource); + return new org.springframework.data.mongodb.core.geo.Circle(center, radius); + } + } + + /** + * Converts a {@link Sphere} into a {@link BasicDBList}. + * + * @author Thomas Darimont + * @since 1.5 + */ + public static enum SphereToDbObjectConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + public DBObject convert(Sphere source) { + + if (source == null) { + return null; + } + + DBObject result = new BasicDBObject(); + result.put("center", PointToDbObjectConverter.INSTANCE.convert(source.getCenter())); + result.put("radius", source.getRadius().getNormalizedValue()); + result.put("metric", source.getRadius().getMetric().toString()); + return result; + } + } + + /** + * Converts a {@link BasicDBList} into a {@link Sphere}. + * + * @author Thomas Darimont + * @since 1.5 + */ + @ReadingConverter + public static enum DbObjectToSphereConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + public Sphere convert(DBObject source) { + + if (source == null) { + return null; + } + + DBObject center = (DBObject) source.get("center"); + Double radius = (Double) source.get("radius"); + + Distance distance = new Distance(radius); + + if (source.containsField("metric")) { + + String metricString = (String) source.get("metric"); + Assert.notNull(metricString, "Metric must not be null!"); + + distance = distance.in(Metrics.valueOf(metricString)); + } + + Assert.notNull(center, "Center must not be null!"); + Assert.notNull(radius, "Radius must not be null!"); + + return new Sphere(DbObjectToPointConverter.INSTANCE.convert(center), distance); + } + } + + /** + * Converts a {@link Polygon} into a {@link BasicDBList}. + * + * @author Thomas Darimont + * @since 1.5 + */ + public static enum PolygonToDbObjectConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + public DBObject convert(Polygon source) { + + if (source == null) { + return null; + } + + List points = source.getPoints(); + List pointTuples = new ArrayList(points.size()); + + for (Point point : points) { + pointTuples.add(PointToDbObjectConverter.INSTANCE.convert(point)); + } + + DBObject result = new BasicDBObject(); + result.put("points", pointTuples); + return result; + } + } + + /** + * Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Polygon}. + * + * @author Thomas Darimont + * @since 1.5 + */ + @ReadingConverter + public static enum DbObjectToPolygonConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + @SuppressWarnings({ "deprecation", "unchecked" }) + public Polygon convert(DBObject source) { + + if (source == null) { + return null; + } + + List points = (List) source.get("points"); + List newPoints = new ArrayList(points.size()); + + for (DBObject element : points) { + + Assert.notNull(element, "Point elements of polygon must not be null!"); + newPoints.add(DbObjectToPointConverter.INSTANCE.convert(element)); + } + + return new org.springframework.data.mongodb.core.geo.Polygon(newPoints); + } + } + + /** + * Converts a {@link Sphere} into a {@link BasicDBList}. + * + * @author Thomas Darimont + * @since 1.5 + */ + public static enum GeoCommandToDbObjectConverter implements Converter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ + @Override + @SuppressWarnings("deprecation") + public DBObject convert(GeoCommand source) { + + if (source == null) { + return null; + } + + BasicDBList argument = new BasicDBList(); + + Shape shape = source.getShape(); + + if (shape instanceof Box) { + + argument.add(toList(((Box) shape).getFirst())); + argument.add(toList(((Box) shape).getSecond())); + + } else if (shape instanceof Circle) { + + argument.add(toList(((Circle) shape).getCenter())); + argument.add(((Circle) shape).getRadius().getNormalizedValue()); + + } else if (shape instanceof org.springframework.data.mongodb.core.geo.Circle) { + + argument.add(toList(((org.springframework.data.mongodb.core.geo.Circle) shape).getCenter())); + argument.add(((org.springframework.data.mongodb.core.geo.Circle) shape).getRadius()); + + } else if (shape instanceof Polygon) { + + for (Point point : ((Polygon) shape).getPoints()) { + argument.add(toList(point)); + } + + } else if (shape instanceof Sphere) { + + argument.add(toList(((Sphere) shape).getCenter())); + argument.add(((Sphere) shape).getRadius().getNormalizedValue()); + } + + return new BasicDBObject(source.getCommand(), argument); + } + } + + static List toList(Point point) { + return Arrays.asList(point.getX(), point.getY()); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java index 44310ff3a..4be68b3bb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java @@ -25,10 +25,8 @@ import java.util.List; import java.util.regex.Pattern; import org.bson.BSON; -import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Point; -import org.springframework.data.geo.Polygon; import org.springframework.data.geo.Shape; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; import org.springframework.data.mongodb.core.geo.Sphere; @@ -386,7 +384,7 @@ public class Criteria implements CriteriaDefinition { */ public Criteria withinSphere(Circle circle) { Assert.notNull(circle); - criteria.put("$within", wrapInCommand(new Sphere(circle))); + criteria.put("$within", new GeoCommand(new Sphere(circle))); return this; } @@ -400,7 +398,7 @@ public class Criteria implements CriteriaDefinition { @Deprecated public Criteria withinSphere(org.springframework.data.mongodb.core.geo.Circle circle) { Assert.notNull(circle); - criteria.put("$within", wrapInCommand(new Sphere(circle))); + criteria.put("$within", new GeoCommand(new Sphere(circle))); return this; } @@ -414,7 +412,7 @@ public class Criteria implements CriteriaDefinition { public Criteria within(Shape shape) { Assert.notNull(shape); - criteria.put("$within", wrapInCommand(shape)); + criteria.put("$within", new GeoCommand(shape)); return this; } @@ -660,43 +658,6 @@ public class Criteria implements CriteriaDefinition { return ObjectUtils.nullSafeEquals(left, right); } - /** - * Wraps the given {@link Shape} in an appropriate MongoDB command. - * - * @param shape must not be {@literal null}. - * @return - */ - private DBObject wrapInCommand(Shape shape) { - - Assert.notNull(shape, "Shape must not be null!"); - - return new BasicDBObject(getCommand(shape), shape); - } - - /** - * Returns the MongoDB command for the given {@link Shape}. - * - * @param shape must not be {@literal null}. - * @return - */ - @SuppressWarnings("deprecation") - private String getCommand(Shape shape) { - - Assert.notNull(shape, "Shape must not be null!"); - - if (shape instanceof Box) { - return org.springframework.data.mongodb.core.geo.Box.COMMAND; - } else if (shape instanceof Circle || shape instanceof org.springframework.data.mongodb.core.geo.Circle) { - return org.springframework.data.mongodb.core.geo.Circle.COMMAND; - } else if (shape instanceof Polygon) { - return org.springframework.data.mongodb.core.geo.Polygon.COMMAND; - } else if (shape instanceof Sphere) { - return org.springframework.data.mongodb.core.geo.Sphere.COMMAND; - } - - throw new IllegalArgumentException("Unknown shape: " + shape); - } - /* * (non-Javadoc) * @see java.lang.Object#hashCode() diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoCommandUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/GeoCommand.java similarity index 76% rename from spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoCommandUtils.java rename to spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/GeoCommand.java index db7d5b262..7717c7d60 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoCommandUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/GeoCommand.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.mongodb.core.convert; +package org.springframework.data.mongodb.core.query; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; @@ -22,27 +22,42 @@ import org.springframework.data.geo.Shape; import org.springframework.data.mongodb.core.geo.Sphere; import org.springframework.util.Assert; -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; - /** + * Wrapper around a {@link Shape} to allow appropriate query rendering. + * * @author Thomas Darimont + * @since 1.5 */ -public enum GeoCommandUtils { +public class GeoCommand { - INSTANCE; + private final Shape shape; + private final String command; /** - * Wraps the given {@link Shape} in an appropriate MongoDB command. + * Creates a new {@link GeoCommand}. * * @param shape must not be {@literal null}. - * @return */ - public DBObject wrapInCommand(Shape shape) { + public GeoCommand(Shape shape) { Assert.notNull(shape, "Shape must not be null!"); - return new BasicDBObject(getCommand(shape), shape); + this.shape = shape; + this.command = getCommand(shape); + } + + /** + * @return the shape + */ + public Shape getShape() { + return shape; + } + + /** + * @return the command + */ + public String getCommand() { + return command; } /** @@ -51,6 +66,7 @@ public enum GeoCommandUtils { * @param shape must not be {@literal null}. * @return */ + @SuppressWarnings("deprecation") private String getCommand(Shape shape) { Assert.notNull(shape, "Shape must not be null!"); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/GeoConvertersUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/GeoConvertersUnitTests.java index ab3408a8c..cc0589e10 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/GeoConvertersUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/GeoConvertersUnitTests.java @@ -18,11 +18,13 @@ package org.springframework.data.mongodb.core.convert; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; -import java.util.List; +import java.util.Arrays; import org.junit.Test; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; import org.springframework.data.mongodb.core.convert.GeoConverters.BoxToDbObjectConverter; @@ -30,21 +32,24 @@ import org.springframework.data.mongodb.core.convert.GeoConverters.CircleToDbObj import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToBoxConverter; import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToCircleConverter; import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToLegacyCircleConverter; +import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToPointConverter; import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToPolygonConverter; import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToSphereConverter; +import org.springframework.data.mongodb.core.convert.GeoConverters.GeoCommandToDbObjectConverter; import org.springframework.data.mongodb.core.convert.GeoConverters.LegacyCircleToDbObjectConverter; -import org.springframework.data.mongodb.core.convert.GeoConverters.ListToPointConverter; -import org.springframework.data.mongodb.core.convert.GeoConverters.PointToListConverter; +import org.springframework.data.mongodb.core.convert.GeoConverters.PointToDbObjectConverter; import org.springframework.data.mongodb.core.convert.GeoConverters.PolygonToDbObjectConverter; import org.springframework.data.mongodb.core.convert.GeoConverters.SphereToDbObjectConverter; import org.springframework.data.mongodb.core.geo.Sphere; +import org.springframework.data.mongodb.core.query.GeoCommand; -import com.mongodb.BasicDBList; +import com.mongodb.DBObject; /** * Unit tests for {@link GeoConverters}. * * @author Thomas Darimont + * @author Oliver Gierke * @since 1.5 */ @SuppressWarnings("deprecation") @@ -58,7 +63,7 @@ public class GeoConvertersUnitTests { Box box = new Box(new Point(1, 2), new Point(3, 4)); - BasicDBList dbo = BoxToDbObjectConverter.INSTANCE.convert(box); + DBObject dbo = BoxToDbObjectConverter.INSTANCE.convert(box); Box result = DbObjectToBoxConverter.INSTANCE.convert(dbo); assertThat(result, is(box)); @@ -69,16 +74,32 @@ public class GeoConvertersUnitTests { * @see DATAMONGO-858 */ @Test - public void convertsCircleToDbObjectAndBackCorrectly() { + public void convertsCircleToDbObjectAndBackCorrectlyNeutralDistance() { Circle circle = new Circle(new Point(1, 2), 3); - BasicDBList dbo = CircleToDbObjectConverter.INSTANCE.convert(circle); + DBObject dbo = CircleToDbObjectConverter.INSTANCE.convert(circle); Circle result = DbObjectToCircleConverter.INSTANCE.convert(dbo); assertThat(result, is(circle)); } + /** + * @see DATAMONGO-858 + */ + @Test + public void convertsCircleToDbObjectAndBackCorrectlyMilesDistance() { + + Distance radius = new Distance(3, Metrics.MILES); + Circle circle = new Circle(new Point(1, 2), radius); + + DBObject dbo = CircleToDbObjectConverter.INSTANCE.convert(circle); + Circle result = DbObjectToCircleConverter.INSTANCE.convert(dbo); + + assertThat(result, is(circle)); + assertThat(result.getRadius(), is(radius)); + } + /** * @see DATAMONGO-858 */ @@ -88,7 +109,7 @@ public class GeoConvertersUnitTests { org.springframework.data.mongodb.core.geo.Circle circle = new org.springframework.data.mongodb.core.geo.Circle( new Point(1, 2), 3); - BasicDBList dbo = LegacyCircleToDbObjectConverter.INSTANCE.convert(circle); + DBObject dbo = LegacyCircleToDbObjectConverter.INSTANCE.convert(circle); org.springframework.data.mongodb.core.geo.Circle result = DbObjectToLegacyCircleConverter.INSTANCE.convert(dbo); assertThat(result, is(circle)); @@ -102,7 +123,7 @@ public class GeoConvertersUnitTests { Polygon polygon = new Polygon(new Point(1, 2), new Point(2, 3), new Point(3, 4), new Point(5, 6)); - BasicDBList dbo = PolygonToDbObjectConverter.INSTANCE.convert(polygon); + DBObject dbo = PolygonToDbObjectConverter.INSTANCE.convert(polygon); Polygon result = DbObjectToPolygonConverter.INSTANCE.convert(dbo); assertThat(result, is(polygon)); @@ -113,17 +134,34 @@ public class GeoConvertersUnitTests { * @see DATAMONGO-858 */ @Test - public void convertsSphereToDbObjectAndBackCorrectly() { + public void convertsSphereToDbObjectAndBackCorrectlyWithNeutralDistance() { Sphere sphere = new Sphere(new Point(1, 2), 3); - BasicDBList dbo = SphereToDbObjectConverter.INSTANCE.convert(sphere); + DBObject dbo = SphereToDbObjectConverter.INSTANCE.convert(sphere); Sphere result = DbObjectToSphereConverter.INSTANCE.convert(dbo); assertThat(result, is(sphere)); assertThat(result.getClass().equals(org.springframework.data.mongodb.core.geo.Sphere.class), is(true)); } + /** + * @see DATAMONGO-858 + */ + @Test + public void convertsSphereToDbObjectAndBackCorrectlyWithKilometerDistance() { + + Distance radius = new Distance(3, Metrics.KILOMETERS); + Sphere sphere = new Sphere(new Point(1, 2), radius); + + DBObject dbo = SphereToDbObjectConverter.INSTANCE.convert(sphere); + Sphere result = DbObjectToSphereConverter.INSTANCE.convert(dbo); + + assertThat(result, is(sphere)); + assertThat(result.getRadius(), is(radius)); + assertThat(result.getClass().equals(org.springframework.data.mongodb.core.geo.Sphere.class), is(true)); + } + /** * @see DATAMONGO-858 */ @@ -132,10 +170,30 @@ public class GeoConvertersUnitTests { Point point = new Point(1, 2); - List list = PointToListConverter.INSTANCE.convert(point); - Point result = ListToPointConverter.INSTANCE.convert(list); + DBObject dbo = PointToDbObjectConverter.INSTANCE.convert(point); + Point result = DbObjectToPointConverter.INSTANCE.convert(dbo); assertThat(result, is(point)); assertThat(result.getClass().equals(org.springframework.data.mongodb.core.geo.Point.class), is(true)); } + + /** + * @see DATAMONGO-858 + */ + @Test + @SuppressWarnings("unchecked") + public void convertsGeoCommandToDbObjectCorrectly() { + + Box box = new Box(new double[] { 1, 2 }, new double[] { 3, 4 }); + GeoCommand cmd = new GeoCommand(box); + + DBObject dbo = GeoCommandToDbObjectConverter.INSTANCE.convert(cmd); + + assertThat(dbo, is(notNullValue())); + + DBObject boxObject = (DBObject) dbo.get("$box"); + + assertThat(boxObject, + is((Object) Arrays.asList(GeoConverters.toList(box.getFirst()), GeoConverters.toList(box.getSecond())))); + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index 8bf724ce5..da18bb430 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -57,6 +57,8 @@ import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; import org.springframework.data.geo.Shape; @@ -1493,7 +1495,7 @@ public class MappingMongoConverterUnitTests { assertThat(result.enumMap.size(), is(1)); assertThat(result.enumMap.get(SampleEnum.FIRST), is("Dave")); } - + /** * @see DATAMONGO-887 */ @@ -1532,13 +1534,11 @@ public class MappingMongoConverterUnitTests { DBObject entry = getAsDBObject(map, "key"); assertThat(entry.get("foo"), is((Object) "Dave")); } - - + /** * @DATAMONGO-858 */ @Test - @SuppressWarnings({ "deprecation", "unchecked" }) public void shouldWriteEntityWithGeoBoxCorrectly() { ClassWithGeoBox object = new ClassWithGeoBox(); @@ -1548,10 +1548,13 @@ public class MappingMongoConverterUnitTests { converter.write(object, dbo); assertThat(dbo, is(notNullValue())); - assertThat(dbo.get("box"), is(instanceOf(List.class))); - assertThat(dbo.get("box"), is((Object) Arrays.asList( - org.springframework.data.mongodb.core.geo.Point.asList(object.box.getFirst()), - org.springframework.data.mongodb.core.geo.Point.asList(object.box.getSecond())))); + assertThat(dbo.get("box"), is(instanceOf(DBObject.class))); + assertThat(dbo.get("box"), is((Object) new BasicDBObject().append("first", toDbObject(object.box.getFirst())) + .append("second", toDbObject(object.box.getSecond())))); + } + + private static DBObject toDbObject(Point point) { + return new BasicDBObject("x", point.getX()).append("y", point.getY()); } /** @@ -1586,10 +1589,15 @@ public class MappingMongoConverterUnitTests { assertThat(dbo, is(notNullValue())); - BasicDBList polygon = getAsDBList(dbo, "polygon"); + assertThat(dbo.get("polygon"), is(instanceOf(DBObject.class))); + DBObject polygonDbo = (DBObject) dbo.get("polygon"); - assertThat(polygon, hasSize(3)); - assertThat(polygon, Matchers. hasItems(Arrays.asList(1d, 2d), Arrays.asList(3d, 4d), Arrays.asList(4d, 5d))); + @SuppressWarnings("unchecked") + List points = (List) polygonDbo.get("points"); + + assertThat(points, hasSize(3)); + assertThat(points, Matchers. hasItems(toDbObject(object.polygon.getPoints().get(0)), + toDbObject(object.polygon.getPoints().get(1)), toDbObject(object.polygon.getPoints().get(2)))); } /** @@ -1614,19 +1622,23 @@ public class MappingMongoConverterUnitTests { * @DATAMONGO-858 */ @Test - @SuppressWarnings("deprecation") public void shouldWriteEntityWithGeoCircleCorrectly() { ClassWithGeoCircle object = new ClassWithGeoCircle(); - object.circle = new Circle(new Point(1, 2), 3); + Circle circle = new Circle(new Point(1, 2), 3); + Distance radius = circle.getRadius(); + object.circle = circle; DBObject dbo = new BasicDBObject(); converter.write(object, dbo); assertThat(dbo, is(notNullValue())); - assertThat(dbo.get("circle"), is(instanceOf(List.class))); - assertThat(dbo.get("circle"), is((Object) Arrays.asList(org.springframework.data.mongodb.core.geo.Point - .asList(object.circle.getCenter()), object.circle.getRadius().getNormalizedValue()))); + assertThat(dbo.get("circle"), is(instanceOf(DBObject.class))); + assertThat( + dbo.get("circle"), + is((Object) new BasicDBObject("center", new BasicDBObject("x", circle.getCenter().getX()).append("y", circle + .getCenter().getY())).append("radius", radius.getNormalizedValue()).append("metric", + radius.getMetric().toString()))); } /** @@ -1655,15 +1667,17 @@ public class MappingMongoConverterUnitTests { public void shouldWriteEntityWithGeoLegacyCircleCorrectly() { ClassWithGeoLegacyCircle object = new ClassWithGeoLegacyCircle(); - object.circle = new org.springframework.data.mongodb.core.geo.Circle(new Point(1, 2), 3); + org.springframework.data.mongodb.core.geo.Circle circle = new org.springframework.data.mongodb.core.geo.Circle( + new Point(1, 2), 3); + object.circle = circle; DBObject dbo = new BasicDBObject(); converter.write(object, dbo); assertThat(dbo, is(notNullValue())); - assertThat(dbo.get("circle"), is(instanceOf(List.class))); - assertThat(dbo.get("circle"), is((Object) Arrays.asList( - org.springframework.data.mongodb.core.geo.Point.asList(object.circle.getCenter()), object.circle.getRadius()))); + assertThat(dbo.get("circle"), is(instanceOf(DBObject.class))); + assertThat(dbo.get("circle"), is((Object) new BasicDBObject("center", new BasicDBObject("x", circle.getCenter() + .getX()).append("y", circle.getCenter().getY())).append("radius", circle.getRadius()))); } /** @@ -1689,19 +1703,46 @@ public class MappingMongoConverterUnitTests { * @DATAMONGO-858 */ @Test - @SuppressWarnings("deprecation") public void shouldWriteEntityWithGeoSphereCorrectly() { ClassWithGeoSphere object = new ClassWithGeoSphere(); - object.sphere = new Sphere(new Point(1, 2), 3); + Sphere sphere = new Sphere(new Point(1, 2), 3); + Distance radius = sphere.getRadius(); + object.sphere = sphere; DBObject dbo = new BasicDBObject(); converter.write(object, dbo); assertThat(dbo, is(notNullValue())); - assertThat(dbo.get("sphere"), is(instanceOf(List.class))); - assertThat(dbo.get("sphere"), is((Object) Arrays.asList(org.springframework.data.mongodb.core.geo.Point - .asList(object.sphere.getCenter()), object.sphere.getRadius().getNormalizedValue()))); + assertThat(dbo.get("sphere"), is(instanceOf(DBObject.class))); + assertThat( + dbo.get("sphere"), + is((Object) new BasicDBObject("center", new BasicDBObject("x", sphere.getCenter().getX()).append("y", sphere + .getCenter().getY())).append("radius", radius.getNormalizedValue()).append("metric", + radius.getMetric().toString()))); + } + + /** + * @DATAMONGO-858 + */ + @Test + public void shouldWriteEntityWithGeoSphereWithMetricDistanceCorrectly() { + + ClassWithGeoSphere object = new ClassWithGeoSphere(); + Sphere sphere = new Sphere(new Point(1, 2), new Distance(3, Metrics.KILOMETERS)); + Distance radius = sphere.getRadius(); + object.sphere = sphere; + + DBObject dbo = new BasicDBObject(); + converter.write(object, dbo); + + assertThat(dbo, is(notNullValue())); + assertThat(dbo.get("sphere"), is(instanceOf(DBObject.class))); + assertThat( + dbo.get("sphere"), + is((Object) new BasicDBObject("center", new BasicDBObject("x", sphere.getCenter().getX()).append("y", sphere + .getCenter().getY())).append("radius", radius.getNormalizedValue()).append("metric", + radius.getMetric().toString()))); } /** @@ -1726,20 +1767,23 @@ public class MappingMongoConverterUnitTests { * @DATAMONGO-858 */ @Test - @SuppressWarnings("deprecation") public void shouldWriteEntityWithGeoShapeCorrectly() { ClassWithGeoShape object = new ClassWithGeoShape(); Sphere sphere = new Sphere(new Point(1, 2), 3); + Distance radius = sphere.getRadius(); object.shape = sphere; DBObject dbo = new BasicDBObject(); converter.write(object, dbo); assertThat(dbo, is(notNullValue())); - assertThat(dbo.get("shape"), is(instanceOf(List.class))); - assertThat(dbo.get("shape"), is((Object) Arrays.asList(org.springframework.data.mongodb.core.geo.Point - .asList(sphere.getCenter()), sphere.getRadius().getNormalizedValue()))); + assertThat(dbo.get("shape"), is(instanceOf(DBObject.class))); + assertThat( + dbo.get("shape"), + is((Object) new BasicDBObject("center", new BasicDBObject("x", sphere.getCenter().getX()).append("y", sphere + .getCenter().getY())).append("radius", radius.getNormalizedValue()).append("metric", + radius.getMetric().toString()))); } /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersUnitTests.java index d4d13fdcf..0f4ace0e0 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersUnitTests.java @@ -19,7 +19,6 @@ import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import java.math.BigDecimal; -import java.util.List; import org.junit.Test; import org.springframework.data.geo.Box; @@ -31,7 +30,7 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalT import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter; import org.springframework.data.mongodb.core.geo.Sphere; -import com.mongodb.BasicDBList; +import com.mongodb.DBObject; /** * Unit tests for {@link MongoConverters}. @@ -60,7 +59,7 @@ public class MongoConvertersUnitTests { Box box = new Box(new Point(1, 2), new Point(3, 4)); - BasicDBList dbo = GeoConverters.BoxToDbObjectConverter.INSTANCE.convert(box); + DBObject dbo = GeoConverters.BoxToDbObjectConverter.INSTANCE.convert(box); Shape shape = GeoConverters.DbObjectToBoxConverter.INSTANCE.convert(dbo); assertThat(shape, is((org.springframework.data.geo.Shape) box)); @@ -74,7 +73,7 @@ public class MongoConvertersUnitTests { Circle circle = new Circle(new Point(1, 2), 3); - BasicDBList dbo = GeoConverters.CircleToDbObjectConverter.INSTANCE.convert(circle); + DBObject dbo = GeoConverters.CircleToDbObjectConverter.INSTANCE.convert(circle); Shape shape = GeoConverters.DbObjectToCircleConverter.INSTANCE.convert(dbo); assertThat(shape, is((org.springframework.data.geo.Shape) circle)); @@ -88,7 +87,7 @@ public class MongoConvertersUnitTests { Polygon polygon = new Polygon(new Point(1, 2), new Point(2, 3), new Point(3, 4), new Point(5, 6)); - BasicDBList dbo = GeoConverters.PolygonToDbObjectConverter.INSTANCE.convert(polygon); + DBObject dbo = GeoConverters.PolygonToDbObjectConverter.INSTANCE.convert(polygon); Shape shape = GeoConverters.DbObjectToPolygonConverter.INSTANCE.convert(dbo); assertThat(shape, is((org.springframework.data.geo.Shape) polygon)); @@ -102,7 +101,7 @@ public class MongoConvertersUnitTests { Sphere sphere = new Sphere(new Point(1, 2), 3); - BasicDBList dbo = GeoConverters.SphereToDbObjectConverter.INSTANCE.convert(sphere); + DBObject dbo = GeoConverters.SphereToDbObjectConverter.INSTANCE.convert(sphere); org.springframework.data.geo.Shape shape = GeoConverters.DbObjectToSphereConverter.INSTANCE.convert(dbo); assertThat(shape, is((org.springframework.data.geo.Shape) sphere)); @@ -116,8 +115,8 @@ public class MongoConvertersUnitTests { Point point = new Point(1, 2); - List list = GeoConverters.PointToListConverter.INSTANCE.convert(point); - org.springframework.data.geo.Point converted = GeoConverters.ListToPointConverter.INSTANCE.convert(list); + DBObject dbo = GeoConverters.PointToDbObjectConverter.INSTANCE.convert(point); + org.springframework.data.geo.Point converted = GeoConverters.DbObjectToPointConverter.INSTANCE.convert(dbo); assertThat(converted, is((org.springframework.data.geo.Point) point)); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialIndexTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialIndexTests.java index 6197d56d1..e013ca833 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialIndexTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialIndexTests.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.mongodb.core.index; +package org.springframework.data.mongodb.core.geo; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @@ -29,6 +29,8 @@ import org.springframework.data.mongodb.config.AbstractIntegrationTests; import org.springframework.data.mongodb.core.CollectionCallback; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.WriteResultChecking; +import org.springframework.data.mongodb.core.index.GeoSpatialIndexType; +import org.springframework.data.mongodb.core.index.GeoSpatialIndexed; import com.mongodb.DBCollection; import com.mongodb.DBObject; @@ -40,6 +42,7 @@ import com.mongodb.WriteConcern; * * @author Laurent Canet * @author Oliver Gierke + * @author Thomas Darimont */ public class GeoSpatialIndexTests extends AbstractIntegrationTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java index 12ab03b6c..9dc4f4f72 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java @@ -43,6 +43,7 @@ import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.repository.Person.Sex; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -763,7 +764,7 @@ public abstract class AbstractPersonRepositoryIntegrationTests { assertThat(result, is(arrayWithSize(1))); assertThat(result, is(arrayContaining(leroi))); } - + /** * @see DATAMONGO-821 */