Skip to content

Commit 01cda35

Browse files
committed
DATAES-568 - Polishing.
Add package-info and nullability annotations to org.springframework.data.elasticsearch.core.mapping. Extract method to avoid excessive nesting. Add ticket references/convert old references to test methods. Move test models to inner classes. Use static imports for JSON Assert. Formatting. Original pull request: #281.
1 parent 66b77ec commit 01cda35

12 files changed

+347
-338
lines changed

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

+20-8
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import org.elasticsearch.search.suggest.SuggestBuilder;
9090
import org.slf4j.Logger;
9191
import org.slf4j.LoggerFactory;
92+
9293
import org.springframework.beans.BeansException;
9394
import org.springframework.context.ApplicationContext;
9495
import org.springframework.context.ApplicationContextAware;
@@ -108,7 +109,21 @@
108109
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
109110
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
110111
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
111-
import org.springframework.data.elasticsearch.core.query.*;
112+
import org.springframework.data.elasticsearch.core.query.AliasQuery;
113+
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
114+
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
115+
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
116+
import org.springframework.data.elasticsearch.core.query.GetQuery;
117+
import org.springframework.data.elasticsearch.core.query.IndexBoost;
118+
import org.springframework.data.elasticsearch.core.query.IndexQuery;
119+
import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
120+
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
121+
import org.springframework.data.elasticsearch.core.query.Query;
122+
import org.springframework.data.elasticsearch.core.query.ScriptField;
123+
import org.springframework.data.elasticsearch.core.query.SearchQuery;
124+
import org.springframework.data.elasticsearch.core.query.SourceFilter;
125+
import org.springframework.data.elasticsearch.core.query.StringQuery;
126+
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
112127
import org.springframework.data.util.CloseableIterator;
113128
import org.springframework.util.Assert;
114129
import org.springframework.util.StringUtils;
@@ -224,7 +239,7 @@ public <T> boolean putMapping(Class<T> clazz) {
224239
}
225240
try {
226241
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
227-
return putMapping(clazz, mappingBuilder.buildMapping(clazz));
242+
return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz));
228243
} catch (Exception e) {
229244
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
230245
}
@@ -497,8 +512,7 @@ public <T> Page<T> queryForPage(StringQuery query, Class<T> clazz, SearchResultM
497512
@Override
498513
public <T> CloseableIterator<T> stream(CriteriaQuery query, Class<T> clazz) {
499514
final long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis();
500-
return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz,
501-
resultsMapper);
515+
return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz, resultsMapper);
502516
}
503517

504518
@Override
@@ -509,8 +523,7 @@ public <T> CloseableIterator<T> stream(SearchQuery query, Class<T> clazz) {
509523
@Override
510524
public <T> CloseableIterator<T> stream(SearchQuery query, final Class<T> clazz, final SearchResultMapper mapper) {
511525
final long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis();
512-
return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz, mapper), clazz,
513-
mapper);
526+
return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz, mapper), clazz, mapper);
514527
}
515528

516529
private <T> CloseableIterator<T> doStream(final long scrollTimeInMillis, final ScrolledPage<T> page,
@@ -1453,8 +1466,7 @@ List<AliasMetaData> convertAliasResponse(String aliasResponse) {
14531466
node = node.findValue("aliases");
14541467

14551468
Map<String, AliasData> aliasData = mapper.readValue(mapper.writeValueAsString(node),
1456-
new TypeReference<Map<String, AliasData>>() {
1457-
});
1469+
new TypeReference<Map<String, AliasData>>() {});
14581470

14591471
Iterable<Map.Entry<String, AliasData>> aliasIter = aliasData.entrySet();
14601472
List<AliasMetaData> aliasMetaDataList = new ArrayList<AliasMetaData>();

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ public <T> boolean putMapping(Class<T> clazz) {
206206
}
207207
try {
208208
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
209-
return putMapping(clazz, mappingBuilder.buildMapping(clazz));
209+
return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz));
210210
} catch (Exception e) {
211211
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
212212
}

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

+95-80
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,25 @@
2727
import org.elasticsearch.common.xcontent.XContentType;
2828
import org.slf4j.Logger;
2929
import org.slf4j.LoggerFactory;
30+
3031
import org.springframework.core.io.ClassPathResource;
3132
import org.springframework.data.annotation.Transient;
32-
import org.springframework.data.elasticsearch.annotations.*;
33+
import org.springframework.data.elasticsearch.annotations.CompletionContext;
34+
import org.springframework.data.elasticsearch.annotations.CompletionField;
35+
import org.springframework.data.elasticsearch.annotations.DateFormat;
36+
import org.springframework.data.elasticsearch.annotations.DynamicTemplates;
37+
import org.springframework.data.elasticsearch.annotations.Field;
38+
import org.springframework.data.elasticsearch.annotations.FieldType;
39+
import org.springframework.data.elasticsearch.annotations.GeoPointField;
40+
import org.springframework.data.elasticsearch.annotations.InnerField;
41+
import org.springframework.data.elasticsearch.annotations.Mapping;
42+
import org.springframework.data.elasticsearch.annotations.MultiField;
3343
import org.springframework.data.elasticsearch.core.completion.Completion;
3444
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
3545
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
3646
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
3747
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
3848
import org.springframework.data.mapping.PropertyHandler;
39-
import org.springframework.data.mapping.model.SimpleTypeHolder;
4049
import org.springframework.data.util.TypeInformation;
4150
import org.springframework.lang.Nullable;
4251
import org.springframework.util.StringUtils;
@@ -61,34 +70,33 @@
6170
*/
6271
class MappingBuilder {
6372

64-
public static final String FIELD_DATA = "fielddata";
65-
public static final String FIELD_STORE = "store";
66-
public static final String FIELD_TYPE = "type";
67-
public static final String FIELD_INDEX = "index";
68-
public static final String FIELD_FORMAT = "format";
69-
public static final String FIELD_SEARCH_ANALYZER = "search_analyzer";
70-
public static final String FIELD_INDEX_ANALYZER = "analyzer";
71-
public static final String FIELD_NORMALIZER = "normalizer";
72-
public static final String FIELD_PROPERTIES = "properties";
73-
public static final String FIELD_PARENT = "_parent";
74-
public static final String FIELD_COPY_TO = "copy_to";
75-
public static final String FIELD_CONTEXT_NAME = "name";
76-
public static final String FIELD_CONTEXT_TYPE = "type";
77-
public static final String FIELD_CONTEXT_PRECISION = "precision";
78-
public static final String FIELD_DYNAMIC_TEMPLATES = "dynamic_templates";
79-
80-
public static final String COMPLETION_PRESERVE_SEPARATORS = "preserve_separators";
81-
public static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments";
82-
public static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length";
83-
public static final String COMPLETION_CONTEXTS = "contexts";
84-
85-
public static final String TYPE_VALUE_KEYWORD = "keyword";
86-
public static final String TYPE_VALUE_GEO_POINT = "geo_point";
87-
public static final String TYPE_VALUE_COMPLETION = "completion";
88-
public static final String TYPE_VALUE_GEO_HASH_PREFIX = "geohash_prefix";
89-
public static final String TYPE_VALUE_GEO_HASH_PRECISION = "geohash_precision";
73+
private static final String FIELD_DATA = "fielddata";
74+
private static final String FIELD_STORE = "store";
75+
private static final String FIELD_TYPE = "type";
76+
private static final String FIELD_INDEX = "index";
77+
private static final String FIELD_FORMAT = "format";
78+
private static final String FIELD_SEARCH_ANALYZER = "search_analyzer";
79+
private static final String FIELD_INDEX_ANALYZER = "analyzer";
80+
private static final String FIELD_NORMALIZER = "normalizer";
81+
private static final String FIELD_PROPERTIES = "properties";
82+
private static final String FIELD_PARENT = "_parent";
83+
private static final String FIELD_COPY_TO = "copy_to";
84+
private static final String FIELD_CONTEXT_NAME = "name";
85+
private static final String FIELD_CONTEXT_TYPE = "type";
86+
private static final String FIELD_CONTEXT_PRECISION = "precision";
87+
private static final String FIELD_DYNAMIC_TEMPLATES = "dynamic_templates";
88+
89+
private static final String COMPLETION_PRESERVE_SEPARATORS = "preserve_separators";
90+
private static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments";
91+
private static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length";
92+
private static final String COMPLETION_CONTEXTS = "contexts";
93+
94+
private static final String TYPE_VALUE_KEYWORD = "keyword";
95+
private static final String TYPE_VALUE_GEO_POINT = "geo_point";
96+
private static final String TYPE_VALUE_COMPLETION = "completion";
97+
9098
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class);
91-
private static SimpleTypeHolder SIMPLE_TYPE_HOLDER = SimpleTypeHolder.DEFAULT;
99+
92100
private final ElasticsearchConverter elasticsearchConverter;
93101

94102
MappingBuilder(ElasticsearchConverter elasticsearchConverter) {
@@ -101,7 +109,7 @@ class MappingBuilder {
101109
* @return JSON string
102110
* @throws IOException
103111
*/
104-
String buildMapping(Class<?> clazz) throws IOException {
112+
String buildPropertyMapping(Class<?> clazz) throws IOException {
105113

106114
ElasticsearchPersistentEntity<?> entity = elasticsearchConverter.getMappingContext()
107115
.getRequiredPersistentEntity(clazz);
@@ -157,70 +165,76 @@ private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersisten
157165
return;
158166
}
159167

160-
if (property.isAnnotationPresent(Mapping.class)) {
168+
buildPropertyMapping(builder, isRootObject, property);
169+
} catch (IOException e) {
170+
logger.warn("error mapping property with name {}", property.getName(), e);
171+
}
172+
});
173+
}
161174

162-
String mappingPath = property.getRequiredAnnotation(Mapping.class).mappingPath();
163-
if (!StringUtils.isEmpty(mappingPath)) {
175+
if (writeNestedProperties) {
176+
builder.endObject().endObject();
177+
}
178+
}
164179

165-
ClassPathResource mappings = new ClassPathResource(mappingPath);
166-
if (mappings.exists()) {
167-
builder.rawField(property.getFieldName(), mappings.getInputStream(), XContentType.JSON);
168-
return;
169-
}
170-
}
171-
}
180+
private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject,
181+
ElasticsearchPersistentProperty property) throws IOException {
172182

173-
boolean isGeoPointProperty = isGeoPointProperty(property);
174-
boolean isCompletionProperty = isCompletionProperty(property);
175-
boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property);
183+
if (property.isAnnotationPresent(Mapping.class)) {
176184

177-
Field fieldAnnotation = property.findAnnotation(Field.class);
178-
if (!isGeoPointProperty && !isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) {
185+
String mappingPath = property.getRequiredAnnotation(Mapping.class).mappingPath();
186+
if (!StringUtils.isEmpty(mappingPath)) {
179187

180-
if (fieldAnnotation == null) {
181-
return;
182-
}
188+
ClassPathResource mappings = new ClassPathResource(mappingPath);
189+
if (mappings.exists()) {
190+
builder.rawField(property.getFieldName(), mappings.getInputStream(), XContentType.JSON);
191+
return;
192+
}
193+
}
194+
}
183195

184-
Iterator<? extends TypeInformation<?>> iterator = property.getPersistentEntityTypes().iterator();
185-
ElasticsearchPersistentEntity<?> persistentEntity = iterator.hasNext()
186-
? elasticsearchConverter.getMappingContext().getPersistentEntity(iterator.next())
187-
: null;
196+
boolean isGeoPointProperty = isGeoPointProperty(property);
197+
boolean isCompletionProperty = isCompletionProperty(property);
198+
boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property);
188199

189-
mapEntity(builder, persistentEntity, false, property.getFieldName(), isNestedOrObjectProperty,
190-
fieldAnnotation.type(), fieldAnnotation);
200+
Field fieldAnnotation = property.findAnnotation(Field.class);
201+
if (!isGeoPointProperty && !isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) {
191202

192-
if (isNestedOrObjectProperty) {
193-
return;
194-
}
195-
}
203+
if (fieldAnnotation == null) {
204+
return;
205+
}
196206

197-
MultiField multiField = property.findAnnotation(MultiField.class);
207+
Iterator<? extends TypeInformation<?>> iterator = property.getPersistentEntityTypes().iterator();
208+
ElasticsearchPersistentEntity<?> persistentEntity = iterator.hasNext()
209+
? elasticsearchConverter.getMappingContext().getPersistentEntity(iterator.next())
210+
: null;
198211

199-
if (isGeoPointProperty) {
200-
applyGeoPointFieldMapping(builder, property);
201-
return;
202-
}
212+
mapEntity(builder, persistentEntity, false, property.getFieldName(), isNestedOrObjectProperty,
213+
fieldAnnotation.type(), fieldAnnotation);
203214

204-
if (isCompletionProperty) {
205-
CompletionField completionField = property.findAnnotation(CompletionField.class);
206-
applyCompletionFieldMapping(builder, property, completionField);
207-
}
215+
if (isNestedOrObjectProperty) {
216+
return;
217+
}
218+
}
208219

209-
if (isRootObject && fieldAnnotation != null && property.isIdProperty()) {
210-
applyDefaultIdFieldMapping(builder, property);
211-
} else if (multiField != null) {
212-
addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty);
213-
} else if (fieldAnnotation != null) {
214-
addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty);
215-
}
216-
} catch (IOException e) {
217-
logger.warn("error mapping property with name {}", property.getName(), e);
218-
}
219-
});
220+
MultiField multiField = property.findAnnotation(MultiField.class);
221+
222+
if (isGeoPointProperty) {
223+
applyGeoPointFieldMapping(builder, property);
224+
return;
220225
}
221226

222-
if (writeNestedProperties) {
223-
builder.endObject().endObject();
227+
if (isCompletionProperty) {
228+
CompletionField completionField = property.findAnnotation(CompletionField.class);
229+
applyCompletionFieldMapping(builder, property, completionField);
230+
}
231+
232+
if (isRootObject && fieldAnnotation != null && property.isIdProperty()) {
233+
applyDefaultIdFieldMapping(builder, property);
234+
} else if (multiField != null) {
235+
addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty);
236+
} else if (fieldAnnotation != null) {
237+
addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty);
224238
}
225239
}
226240

@@ -321,6 +335,7 @@ private void addMultiFieldMapping(XContentBuilder builder, ElasticsearchPersiste
321335

322336
private void addFieldMappingParameters(XContentBuilder builder, Object annotation, boolean nestedOrObjectField)
323337
throws IOException {
338+
324339
boolean index = true;
325340
boolean store = false;
326341
boolean fielddata = false;

src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.springframework.data.mapping.model.Property;
2323
import org.springframework.data.mapping.model.SimpleTypeHolder;
2424
import org.springframework.data.util.TypeInformation;
25+
import org.springframework.lang.Nullable;
2526

2627
/**
2728
* SimpleElasticsearchMappingContext
@@ -30,10 +31,11 @@
3031
* @author Mohsin Husen
3132
* @author Mark Paluch
3233
*/
33-
public class SimpleElasticsearchMappingContext extends
34-
AbstractMappingContext<SimpleElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> implements ApplicationContextAware {
34+
public class SimpleElasticsearchMappingContext
35+
extends AbstractMappingContext<SimpleElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty>
36+
implements ApplicationContextAware {
3537

36-
private ApplicationContext context;
38+
private @Nullable ApplicationContext context;
3739

3840
@Override
3941
protected <T> SimpleElasticsearchPersistentEntity<?> createPersistentEntity(TypeInformation<T> typeInformation) {

0 commit comments

Comments
 (0)