All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mongodb.morphia.geo.GeometryShapeConverter Maven / Gradle / Ivy

The newest version!
package org.mongodb.morphia.geo;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.mongodb.morphia.converters.SimpleValueConverter;
import org.mongodb.morphia.converters.TypeConverter;
import org.mongodb.morphia.mapping.MappedField;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.mongodb.morphia.geo.GeoJsonType.LINE_STRING;
import static org.mongodb.morphia.geo.GeoJsonType.MULTI_LINE_STRING;
import static org.mongodb.morphia.geo.GeoJsonType.MULTI_POINT;
import static org.mongodb.morphia.geo.GeoJsonType.MULTI_POLYGON;
import static org.mongodb.morphia.geo.GeoJsonType.POINT;
import static org.mongodb.morphia.geo.GeoJsonType.POLYGON;

/**
 * Converter that understands most Geometry instances are effectively just lists of either other geometry objects or double coordinates.
 * Recursively encodes and decodes Geometry objects, but needs to be instantiated with a List of GeometryFactory instances that represented
 * the hierarchy of Geometries that make up the required Geometry object.
 * 

* Overridden by subclasses to define exact behaviour for specific Geometry concrete classes. */ public class GeometryShapeConverter extends TypeConverter implements SimpleValueConverter { private final GeoJsonType geoJsonType; private final List factories; GeometryShapeConverter(final GeoJsonType... geoJsonTypes) { super(geoJsonTypes[0].getTypeClass()); geoJsonType = geoJsonTypes[0]; this.factories = Arrays.asList(geoJsonTypes); } @Override public Geometry decode(final Class targetClass, final Object fromDBObject, final MappedField optionalExtraInfo) { return decodeObject((List) ((DBObject) fromDBObject).get("coordinates"), factories); } @Override public Object encode(final Object value, final MappedField optionalExtraInfo) { if (value != null) { Object encodedObjects = encodeObjects(((Geometry) value).getCoordinates()); return new BasicDBObject("type", geoJsonType.getType()) .append("coordinates", encodedObjects); } else { return null; } } /* * We're expecting a List that can be turned into a geometry using a series of factories */ @SuppressWarnings("unchecked") // always have unchecked casts when dealing with raw classes private Geometry decodeObject(final List mongoDBGeometry, final List geometryFactories) { GeometryFactory factory = geometryFactories.get(0); if (geometryFactories.size() == 1) { // This should be the last list, so no need to decode further return factory.createGeometry(mongoDBGeometry); } else { List decodedObjects = new ArrayList(); for (final Object objectThatNeedsDecoding : mongoDBGeometry) { // MongoDB geometries are lists of lists of lists... decodedObjects.add(decodeObject((List) objectThatNeedsDecoding, geometryFactories.subList(1, geometryFactories.size()))); } return factory.createGeometry(decodedObjects); } } private Object encodeObjects(final List value) { List encodedObjects = new ArrayList(); for (final Object object : value) { if (object instanceof Geometry) { //iterate through the list of geometry objects recursively until you find the lowest-level encodedObjects.add(encodeObjects(((Geometry) object).getCoordinates())); } else { encodedObjects.add(getMapper().getConverters().encode(object)); } } return encodedObjects; } /** * Extends and therefore configures GeometryShapeConverter to provide the specific configuration for converting MultiPolygon objects to * and from MongoDB representations of the GeoJson. */ public static class MultiPolygonConverter extends GeometryShapeConverter { /** * Creates a new MultiPolygonConverter. */ public MultiPolygonConverter() { super(MULTI_POLYGON, POLYGON, LINE_STRING, POINT); } } /** * Defines a new PolygonConverter. This extends and therefore configures GeometryShapeConverter to provide the specific * configuration for converting Polygon objects to and from MongoDB * representations of the GeoJson. */ public static class PolygonConverter extends GeometryShapeConverter { /** * Creates a new PolygonConverter. */ public PolygonConverter() { super(POLYGON, LINE_STRING, POINT); } } /** * Defines a new MultiLineStringConverter. This extends and therefore configures GeometryShapeConverter to provide the specific * configuration for converting MultiLineString objects to and from MongoDB * representations of the GeoJson. */ public static class MultiLineStringConverter extends GeometryShapeConverter { /** * Creates a new MultiLineStringConverter. */ public MultiLineStringConverter() { super(MULTI_LINE_STRING, LINE_STRING, POINT); } } /** * Defines a new MultiPointConverter. This extends and therefore configures GeometryShapeConverter to provide the specific * configuration for converting MultiPoint objects to and from MongoDB * representations of the GeoJson. */ public static class MultiPointConverter extends GeometryShapeConverter { /** * Creates a new MultiPointConverter. */ public MultiPointConverter() { super(MULTI_POINT, POINT); } } /** * Defines a new LineStringConverter. This extends and therefore configures GeometryShapeConverter to provide the specific * configuration for converting LineString objects to and from MongoDB * representations of the GeoJson. */ public static class LineStringConverter extends GeometryShapeConverter { /** * Creates a new LineStringConverter. */ public LineStringConverter() { super(LINE_STRING, POINT); } } /** * Defines a new PointConverter. This extends and therefore configures GeometryShapeConverter to provide the specific configuration * for converting Point objects to and from MongoDB representations of the * GeoJson. */ public static class PointConverter extends GeometryShapeConverter { /** * Creates a new PointConverter. */ public PointConverter() { super(POINT); } } }