Skip to content

Commit 7a612f3

Browse files
mp911desothawo
authored andcommitted
DATAES-628 - Adapt mappers to Document API.
1 parent 29ecd48 commit 7a612f3

File tree

8 files changed

+173
-165
lines changed

8 files changed

+173
-165
lines changed

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
import java.io.IOException;
1919
import java.util.ArrayList;
20-
import java.util.HashMap;
20+
import java.util.LinkedHashMap;
2121
import java.util.List;
22-
import java.util.Map;
2322

2423
import org.springframework.data.annotation.ReadOnlyProperty;
24+
import org.springframework.data.elasticsearch.Document;
2525
import org.springframework.data.elasticsearch.core.geo.CustomGeoModule;
2626
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
2727
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
@@ -44,14 +44,15 @@
4444
* @author Petar Tahchiev
4545
* @author Oliver Gierke
4646
* @author Christoph Strobl
47+
* @author Mark Paluch
4748
*/
4849
public class DefaultEntityMapper implements EntityMapper {
4950

5051
private ObjectMapper objectMapper;
5152

5253
/**
5354
* Creates a new {@link DefaultEntityMapper} using the given {@link MappingContext}.
54-
*
55+
*
5556
* @param context must not be {@literal null}.
5657
*/
5758
public DefaultEntityMapper(
@@ -74,18 +75,19 @@ public DefaultEntityMapper(
7475
*/
7576
@Override
7677
public String mapToString(Object object) throws IOException {
77-
return objectMapper.writeValueAsString(object);
78+
return objectMapper
79+
.writeValueAsString(object instanceof Document ? new LinkedHashMap<>((Document) object) : object);
7880
}
7981

8082
/*
8183
* (non-Javadoc)
8284
* @see org.springframework.data.elasticsearch.core.EntityMapper#mapObject(java.lang.Object)
8385
*/
8486
@Override
85-
public Map<String, Object> mapObject(Object source) {
87+
public Document mapObject(Object source) {
8688

8789
try {
88-
return objectMapper.readValue(mapToString(source), HashMap.class);
90+
return objectMapper.readValue(mapToString(source), Document.class);
8991
} catch (IOException e) {
9092
throw new MappingException(e.getMessage(), e);
9193
}
@@ -105,8 +107,7 @@ public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
105107
* @see org.springframework.data.elasticsearch.core.EntityMapper#readObject(java.util.Map, java.lang.Class)
106108
*/
107109
@Override
108-
public <T> T readObject (Map<String, Object> source, Class<T> targetType) {
109-
110+
public <T> T readObject(Document source, Class<T> targetType) {
110111
try {
111112
return mapToObject(mapToString(source), targetType);
112113
} catch (IOException e) {
@@ -126,7 +127,7 @@ private static class SpringDataElasticsearchModule extends SimpleModule {
126127

127128
/**
128129
* Creates a new {@link SpringDataElasticsearchModule} using the given {@link MappingContext}.
129-
*
130+
*
130131
* @param context must not be {@literal null}.
131132
*/
132133
public SpringDataElasticsearchModule(
@@ -156,7 +157,7 @@ public SpringDataSerializerModifier(
156157
this.context = context;
157158
}
158159

159-
/*
160+
/*
160161
* (non-Javadoc)
161162
* @see com.fasterxml.jackson.databind.ser.BeanSerializerModifier#changeProperties(com.fasterxml.jackson.databind.SerializationConfig, com.fasterxml.jackson.databind.BeanDescription, java.util.List)
162163
*/

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

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@
1515
*/
1616
package org.springframework.data.elasticsearch.core;
1717

18-
import java.io.ByteArrayOutputStream;
19-
import java.io.IOException;
20-
import java.nio.charset.Charset;
2118
import java.util.ArrayList;
22-
import java.util.Collection;
2319
import java.util.List;
2420

2521
import org.elasticsearch.action.get.GetResponse;
@@ -45,11 +41,6 @@
4541
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
4642
import org.springframework.lang.Nullable;
4743
import org.springframework.util.Assert;
48-
import org.springframework.util.StringUtils;
49-
50-
import com.fasterxml.jackson.core.JsonEncoding;
51-
import com.fasterxml.jackson.core.JsonFactory;
52-
import com.fasterxml.jackson.core.JsonGenerator;
5344

5445
/**
5546
* @author Artur Konczak
@@ -105,13 +96,7 @@ public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz,
10596
List<T> results = new ArrayList<>();
10697
for (SearchHit hit : response.getHits()) {
10798
if (hit != null) {
108-
T result = null;
109-
String hitSourceAsString = hit.getSourceAsString();
110-
if (!StringUtils.isEmpty(hitSourceAsString)) {
111-
result = mapEntity(hitSourceAsString, clazz);
112-
} else {
113-
result = mapEntity(hit.getFields().values(), clazz);
114-
}
99+
T result = mapSearchHit(hit, clazz);
115100

116101
setPersistentEntityId(result, hit.getId(), clazz);
117102
setPersistentEntityVersion(result, hit.getVersion(), clazz);
@@ -149,38 +134,14 @@ private <T> void populateScriptFields(T result, SearchHit hit) {
149134
}
150135
}
151136

152-
private <T> T mapEntity(Collection<DocumentField> values, Class<T> clazz) {
153-
return mapEntity(buildJSONFromFields(values), clazz);
154-
}
137+
@Override
138+
public <T> T mapResult(GetResponse response, Class<T> clazz) {
155139

156-
private String buildJSONFromFields(Collection<DocumentField> values) {
157-
JsonFactory nodeFactory = new JsonFactory();
158-
try {
159-
ByteArrayOutputStream stream = new ByteArrayOutputStream();
160-
JsonGenerator generator = nodeFactory.createGenerator(stream, JsonEncoding.UTF8);
161-
generator.writeStartObject();
162-
for (DocumentField value : values) {
163-
if (value.getValues().size() > 1) {
164-
generator.writeArrayFieldStart(value.getName());
165-
for (Object val : value.getValues()) {
166-
generator.writeObject(val);
167-
}
168-
generator.writeEndArray();
169-
} else {
170-
generator.writeObjectField(value.getName(), value.getValue());
171-
}
172-
}
173-
generator.writeEndObject();
174-
generator.flush();
175-
return new String(stream.toByteArray(), Charset.forName("UTF-8"));
176-
} catch (IOException e) {
140+
if (!response.isExists()) {
177141
return null;
178142
}
179-
}
180143

181-
@Override
182-
public <T> T mapResult(GetResponse response, Class<T> clazz) {
183-
T result = mapEntity(response.getSourceAsString(), clazz);
144+
T result = mapDocument(DocumentAdapters.from(response), clazz);
184145
if (result != null) {
185146
setPersistentEntityId(result, response.getId(), clazz);
186147
setPersistentEntityVersion(result, response.getVersion(), clazz);
@@ -193,7 +154,7 @@ public <T> List<T> mapResults(MultiGetResponse responses, Class<T> clazz) {
193154
List<T> list = new ArrayList<>();
194155
for (MultiGetItemResponse response : responses.getResponses()) {
195156
if (!response.isFailed() && response.getResponse().isExists()) {
196-
T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
157+
T result = mapResult(response.getResponse(), clazz);
197158
setPersistentEntityId(result, response.getResponse().getId(), clazz);
198159
setPersistentEntityVersion(result, response.getResponse().getVersion(), clazz);
199160
list.add(result);

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

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
*/
1616
package org.springframework.data.elasticsearch.core;
1717

18-
import com.fasterxml.jackson.databind.ObjectReader;
19-
import com.fasterxml.jackson.databind.ObjectWriter;
2018
import lombok.RequiredArgsConstructor;
2119

2220
import java.io.IOException;
@@ -34,6 +32,8 @@
3432
import org.springframework.data.convert.EntityInstantiators;
3533
import org.springframework.data.convert.EntityReader;
3634
import org.springframework.data.convert.EntityWriter;
35+
import org.springframework.data.elasticsearch.Document;
36+
import org.springframework.data.elasticsearch.SearchDocument;
3737
import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions;
3838
import org.springframework.data.elasticsearch.core.convert.ElasticsearchTypeMapper;
3939
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
@@ -52,19 +52,21 @@
5252
import org.springframework.util.ObjectUtils;
5353

5454
import com.fasterxml.jackson.databind.ObjectMapper;
55+
import com.fasterxml.jackson.databind.ObjectReader;
56+
import com.fasterxml.jackson.databind.ObjectWriter;
5557

5658
/**
5759
* Elasticsearch specific {@link EntityReader} & {@link EntityWriter} implementation based on domain type
5860
* {@link ElasticsearchPersistentEntity metadata}.
5961
*
6062
* @author Christoph Strobl
6163
* @author Peter-Josef Meisch
64+
* @author Mark Paluch
6265
* @since 3.2
6366
*/
64-
public class ElasticsearchEntityMapper implements
65-
EntityConverter<ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty, Object, Map<String, Object>>,
66-
EntityWriter<Object, Map<String, Object>>, EntityReader<Object, Map<String, Object>>, InitializingBean,
67-
EntityMapper {
67+
public class ElasticsearchEntityMapper
68+
implements EntityConverter<ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty, Object, Document>,
69+
EntityWriter<Object, Document>, EntityReader<Object, Document>, InitializingBean, EntityMapper {
6870

6971
private final MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
7072
private final GenericConversionService conversionService;
@@ -134,14 +136,14 @@ public void afterPropertiesSet() {
134136
// --> READ
135137

136138
@Override
137-
public <T> T readObject(Map<String, Object> source, Class<T> targetType) {
139+
public <T> T readObject(Document source, Class<T> targetType) {
138140
return read(targetType, source);
139141
}
140142

141143
@SuppressWarnings("unchecked")
142144
@Override
143145
@Nullable
144-
public <R> R read(Class<R> type, Map<String, Object> source) {
146+
public <R> R read(Class<R> type, Document source) {
145147
return doRead(source, ClassTypeInformation.from((Class<R>) ClassUtils.getUserClass(type)));
146148
}
147149

@@ -320,16 +322,16 @@ private Object readSimpleValue(@Nullable Object value, TypeInformation<?> target
320322
// --> WRITE
321323

322324
@Override
323-
public Map<String, Object> mapObject(Object source) {
325+
public Document mapObject(Object source) {
324326

325-
LinkedHashMap<String, Object> target = new LinkedHashMap<>();
327+
Document target = Document.create();
326328
write(source, target);
327329
return target;
328330
}
329331

330332
@SuppressWarnings("unchecked")
331333
@Override
332-
public void write(@Nullable Object source, Map<String, Object> sink) {
334+
public void write(@Nullable Object source, Document sink) {
333335

334336
if (source == null) {
335337
return;
@@ -351,8 +353,7 @@ public void write(@Nullable Object source, Map<String, Object> sink) {
351353
doWrite(source, sink, type);
352354
}
353355

354-
protected void doWrite(@Nullable Object source, Map<String, Object> sink,
355-
@Nullable TypeInformation<? extends Object> typeHint) {
356+
protected void doWrite(@Nullable Object source, Document sink, @Nullable TypeInformation<? extends Object> typeHint) {
356357

357358
if (source == null) {
358359
return;
@@ -382,7 +383,7 @@ protected void doWrite(@Nullable Object source, Map<String, Object> sink,
382383
writeEntity(entity, source, sink, null);
383384
}
384385

385-
protected void writeEntity(ElasticsearchPersistentEntity<?> entity, Object source, Map<String, Object> sink,
386+
protected void writeEntity(ElasticsearchPersistentEntity<?> entity, Object source, Document sink,
386387
@Nullable TypeInformation containingStructure) {
387388

388389
PersistentPropertyAccessor<?> accessor = entity.getPropertyAccessor(source);
@@ -391,11 +392,11 @@ protected void writeEntity(ElasticsearchPersistentEntity<?> entity, Object sourc
391392
typeMapper.writeType(source.getClass(), sink);
392393
}
393394

394-
writeProperties(entity, accessor, sink);
395+
writeProperties(entity, accessor, new MapValueAccessor(sink));
395396
}
396397

397398
protected void writeProperties(ElasticsearchPersistentEntity<?> entity, PersistentPropertyAccessor<?> accessor,
398-
Map<String, Object> sink) {
399+
MapValueAccessor sink) {
399400

400401
for (ElasticsearchPersistentProperty property : entity) {
401402

@@ -412,19 +413,19 @@ protected void writeProperties(ElasticsearchPersistentEntity<?> entity, Persiste
412413
if (!isSimpleType(value)) {
413414
writeProperty(property, value, sink);
414415
} else {
415-
sink.put(property.getFieldName(), getWriteSimpleValue(value));
416+
sink.set(property, getWriteSimpleValue(value));
416417
}
417418
}
418419
}
419420

420-
protected void writeProperty(ElasticsearchPersistentProperty property, Object value, Map<String, Object> sink) {
421+
protected void writeProperty(ElasticsearchPersistentProperty property, Object value, MapValueAccessor sink) {
421422

422423
Optional<Class<?>> customWriteTarget = conversions.getCustomWriteTarget(value.getClass());
423424

424425
if (customWriteTarget.isPresent()) {
425426

426427
Class<?> writeTarget = customWriteTarget.get();
427-
sink.put(property.getFieldName(), conversionService.convert(value, writeTarget));
428+
sink.set(property, conversionService.convert(value, writeTarget));
428429
return;
429430
}
430431

@@ -442,7 +443,7 @@ protected void writeProperty(ElasticsearchPersistentProperty property, Object va
442443
}
443444
}
444445

445-
sink.put(property.getFieldName(), getWriteComplexValue(property, typeHint, value));
446+
sink.set(property, getWriteComplexValue(property, typeHint, value));
446447
}
447448

448449
protected Object getWriteSimpleValue(Object value) {
@@ -479,7 +480,8 @@ protected Object getWriteComplexValue(ElasticsearchPersistentProperty property,
479480
}
480481

481482
private Object writeEntity(Object value, ElasticsearchPersistentProperty property, TypeInformation<?> typeHint) {
482-
Map<String, Object> target = new LinkedHashMap<>();
483+
484+
Document target = Document.create();
483485
writeEntity(mappingContext.getRequiredPersistentEntity(value.getClass()), value, target,
484486
property.getTypeInformation());
485487
return target;
@@ -549,15 +551,15 @@ private Object writeCollectionValue(Object value, ElasticsearchPersistentPropert
549551
@Override
550552
public String mapToString(Object source) throws IOException {
551553

552-
Map<String, Object> sink = new LinkedHashMap<>();
554+
Document sink = Document.create();
553555
write(source, sink);
554556

555-
return objectWriter.writeValueAsString(sink);
557+
return objectWriter.writeValueAsString(new LinkedHashMap<>(sink));
556558
}
557559

558560
@Override
559561
public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
560-
return read(clazz, objectReader.readValue(source));
562+
return read(clazz, Document.from(objectReader.readValue(source)));
561563
}
562564

563565
// --> PRIVATE HELPERS
@@ -669,6 +671,18 @@ static class MapValueAccessor {
669671

670672
public Object get(ElasticsearchPersistentProperty property) {
671673

674+
if (property.isIdProperty() && ((Document) target).hasId()) {
675+
return ((Document) target).getId();
676+
}
677+
678+
if (property.isVersionProperty() && ((Document) target).hasVersion()) {
679+
return ((Document) target).getVersion();
680+
}
681+
682+
if (property.isScoreProperty()) {
683+
return ((SearchDocument) target).getScore();
684+
}
685+
672686
String fieldName = property.getFieldName();
673687

674688
if (!fieldName.contains(".")) {
@@ -691,6 +705,19 @@ public Object get(ElasticsearchPersistentProperty property) {
691705
return result;
692706
}
693707

708+
public void set(ElasticsearchPersistentProperty property, Object value) {
709+
710+
if (property.isIdProperty()) {
711+
((Document) target).setId((String) value);
712+
}
713+
714+
if (property.isVersionProperty()) {
715+
((Document) target).setVersion((Long) value);
716+
}
717+
718+
target.put(property.getFieldName(), value);
719+
}
720+
694721
@SuppressWarnings("unchecked")
695722
private Map<String, Object> getAsMap(Object result) {
696723

0 commit comments

Comments
 (0)