Skip to content

Commit 21ff7e5

Browse files
committed
DATAES-206 - added GEO_POINT support for Point from Spring Data Commons
1 parent 909caa7 commit 21ff7e5

24 files changed

+480
-417
lines changed

src/main/java/org/springframework/data/elasticsearch/core/DefaultEntityMapper.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,27 @@
1616
package org.springframework.data.elasticsearch.core;
1717

1818
import java.io.IOException;
19+
import java.util.List;
20+
21+
import com.fasterxml.jackson.annotation.JsonIgnore;
22+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
23+
import com.fasterxml.jackson.annotation.JsonProperty;
24+
import com.fasterxml.jackson.core.*;
25+
import com.fasterxml.jackson.databind.*;
26+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
27+
import com.fasterxml.jackson.databind.module.SimpleModule;
28+
import org.springframework.data.elasticsearch.annotations.Document;
29+
import org.springframework.data.elasticsearch.core.geo.CustomGeoModule;
30+
import org.springframework.data.geo.*;
31+
import java.util.List;
32+
33+
import com.fasterxml.jackson.annotation.JsonIgnore;
34+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
35+
import com.fasterxml.jackson.annotation.JsonProperty;
36+
import com.fasterxml.jackson.core.Version;
37+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
38+
import com.fasterxml.jackson.databind.module.SimpleModule;
1939

20-
import com.fasterxml.jackson.databind.DeserializationFeature;
21-
import com.fasterxml.jackson.databind.ObjectMapper;
2240

2341
/**
2442
* DocumentMapper using jackson
@@ -34,6 +52,7 @@ public DefaultEntityMapper() {
3452
objectMapper = new ObjectMapper();
3553
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
3654
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
55+
objectMapper.registerModule(new CustomGeoModule());
3756
}
3857

3958
@Override

src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.data.elasticsearch.annotations.*;
3434
import org.springframework.data.elasticsearch.core.completion.Completion;
3535
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
36+
import org.springframework.data.geo.*;
3637
import org.springframework.data.mapping.model.SimpleTypeHolder;
3738
import org.springframework.data.util.ClassTypeInformation;
3839
import org.springframework.data.util.TypeInformation;
@@ -111,11 +112,11 @@ private static void mapEntity(XContentBuilder xContentBuilder, Class clazz, bool
111112
continue;
112113
}
113114

114-
boolean isGeoField = isGeoField(field);
115+
boolean isGeoPointField = isGeoPointField(field);
115116
boolean isCompletionField = isCompletionField(field);
116117

117118
Field singleField = field.getAnnotation(Field.class);
118-
if (!isGeoField && !isCompletionField && isEntity(field) && isAnnotated(field)) {
119+
if (!isGeoPointField && !isCompletionField && isEntity(field) && isAnnotated(field)) {
119120
if (singleField == null) {
120121
continue;
121122
}
@@ -128,7 +129,7 @@ private static void mapEntity(XContentBuilder xContentBuilder, Class clazz, bool
128129

129130
MultiField multiField = field.getAnnotation(MultiField.class);
130131

131-
if (isGeoField) {
132+
if (isGeoPointField) {
132133
applyGeoPointFieldMapping(xContentBuilder, field);
133134
}
134135

@@ -167,7 +168,10 @@ private static java.lang.reflect.Field[] retrieveFields(Class clazz) {
167168
}
168169

169170
private static boolean isAnnotated(java.lang.reflect.Field field) {
170-
return field.getAnnotation(Field.class) != null || field.getAnnotation(MultiField.class) != null || field.getAnnotation(GeoPointField.class) != null || field.getAnnotation(CompletionField.class) != null;
171+
return field.getAnnotation(Field.class) != null ||
172+
field.getAnnotation(MultiField.class) != null ||
173+
field.getAnnotation(GeoPointField.class) != null ||
174+
field.getAnnotation(CompletionField.class) != null;
171175
}
172176

173177
private static void applyGeoPointFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field) throws IOException {
@@ -333,7 +337,7 @@ private static boolean isNestedOrObjectField(java.lang.reflect.Field field) {
333337
return fieldAnnotation != null && (FieldType.Nested == fieldAnnotation.type() || FieldType.Object == fieldAnnotation.type());
334338
}
335339

336-
private static boolean isGeoField(java.lang.reflect.Field field) {
340+
private static boolean isGeoPointField(java.lang.reflect.Field field) {
337341
return field.getType() == GeoPoint.class || field.getAnnotation(GeoPointField.class) != null;
338342
}
339343

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.springframework.data.elasticsearch.core.geo;
2+
3+
import java.io.IOException;
4+
5+
import com.fasterxml.jackson.core.JsonGenerator;
6+
import com.fasterxml.jackson.core.JsonParser;
7+
import com.fasterxml.jackson.core.JsonProcessingException;
8+
import com.fasterxml.jackson.core.Version;
9+
import com.fasterxml.jackson.databind.DeserializationContext;
10+
import com.fasterxml.jackson.databind.JsonDeserializer;
11+
import com.fasterxml.jackson.databind.JsonSerializer;
12+
import com.fasterxml.jackson.databind.SerializerProvider;
13+
import com.fasterxml.jackson.databind.module.SimpleModule;
14+
import org.springframework.data.geo.Point;
15+
16+
/**
17+
* @author Artur Konaczak
18+
*/
19+
public class CustomGeoModule extends SimpleModule {
20+
21+
private static final long serialVersionUID = 1L;
22+
23+
/**
24+
* Creates a new {@link org.springframework.data.elasticsearch.core.geo.CustomGeoModule} registering serializers and deserializers for spring data commons geo-spatial types.
25+
*/
26+
public CustomGeoModule() {
27+
28+
super("Spring Data Elasticsearch Geo", new Version(1, 0, 0, null, "org.springframework.data.elasticsearch", "spring-data-elasticsearch-geo"));
29+
addSerializer(Point.class, new PointSerializer());
30+
addDeserializer(Point.class, new PointDeserializer());
31+
}
32+
}
33+
34+
class PointSerializer extends JsonSerializer<Point> {
35+
36+
@Override
37+
public void serialize(Point value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
38+
gen.writeObject(GeoPoint.fromPoint(value));
39+
// gen.writeStartObject();
40+
// gen.writeNumberField("lat", value.getY());
41+
// gen.writeNumberField("lon", value.getX());
42+
// gen.writeEndObject();
43+
}
44+
}
45+
46+
class PointDeserializer extends JsonDeserializer<Point> {
47+
48+
@Override
49+
public Point deserialize(JsonParser p, DeserializationContext context) throws IOException, JsonProcessingException {
50+
51+
GeoPoint point = p.readValueAs(GeoPoint.class);
52+
// Double lat = null;
53+
// Double lon = null;
54+
// //skipp field name
55+
// p.nextFieldName();
56+
// if ("lat".equals(p.getCurrentName())) {
57+
// //get value
58+
// p.nextFieldName();
59+
// lat = p.getDoubleValue();
60+
// p.nextFieldName();
61+
// }
62+
// if ("lon".equals(p.getCurrentName())) {
63+
// //get value
64+
// p.nextFieldName();
65+
// lon = p.getDoubleValue();
66+
// }
67+
// return new Point(lon, lat);
68+
return GeoPoint.toPoint(point);
69+
}
70+
}

src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public double getLon() {
5353
public static GeoPoint fromPoint(Point point) {
5454
return new GeoPoint(point.getY(), point.getX());
5555
}
56+
57+
public static Point toPoint(GeoPoint point) {
58+
return new Point(point.getLat(), point.getLon());
59+
}
5660
}
5761

5862

src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.dao.InvalidDataAccessApiUsageException;
2222
import org.springframework.data.elasticsearch.core.geo.GeoBox;
2323
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
24+
import org.springframework.data.geo.Box;
2425
import org.springframework.data.geo.Distance;
2526
import org.springframework.data.geo.Point;
2627
import org.springframework.util.Assert;
@@ -453,6 +454,17 @@ public Criteria boundedBy(GeoBox boundingBox) {
453454
return this;
454455
}
455456

457+
/**
458+
* Creates new CriteriaEntry for {@code location Box bounding box}
459+
*
460+
* @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + right bottom corner)
461+
* @return Criteria the chaind criteria with the new 'boundingBox' criteria included.
462+
*/
463+
public Criteria boundedBy(Box boundingBox) {
464+
Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null");
465+
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{boundingBox.getFirst(), boundingBox.getSecond()}));
466+
return this;
467+
}
456468

457469
/**
458470
* Creates new CriteriaEntry for bounding box created from points
@@ -482,6 +494,13 @@ public Criteria boundedBy(GeoPoint topLeftPoint, GeoPoint bottomRightPoint) {
482494
return this;
483495
}
484496

497+
public Criteria boundedBy(Point topLeftPoint, Point bottomRightPoint) {
498+
Assert.notNull(topLeftPoint, "topLeftPoint must not be null");
499+
Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null");
500+
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint)}));
501+
return this;
502+
}
503+
485504
private void assertNoBlankInWildcardedQuery(String searchString, boolean leadingWildcard, boolean trailingWildcard) {
486505
if (StringUtils.contains(searchString, CRITERIA_VALUE_SEPERATOR)) {
487506
throw new InvalidDataAccessApiUsageException("Cannot constructQuery '" + (leadingWildcard ? "*" : "") + "\""

src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.springframework.data.elasticsearch.entities.GirlFriend;
4949
import org.springframework.data.elasticsearch.entities.Person;
5050
import org.springframework.data.elasticsearch.entities.PersonMultipleLevelNested;
51+
import org.springframework.data.geo.Point;
5152
import org.springframework.test.context.ContextConfiguration;
5253
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
5354

src/test/java/org/springframework/data/elasticsearch/builder/CarBuilder.java

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/test/java/org/springframework/data/elasticsearch/builder/SampleEntityBuilder.java

Lines changed: 0 additions & 75 deletions
This file was deleted.

src/test/java/org/springframework/data/elasticsearch/builder/StockPriceBuilder.java

Lines changed: 0 additions & 60 deletions
This file was deleted.

0 commit comments

Comments
 (0)