Skip to content

Commit d26d01b

Browse files
committed
Fix converting of Range<?> in Lists.
Original Pull Request #2707 Closes #2706 (cherry picked from commit 3330d65)
1 parent 026be26 commit d26d01b

File tree

7 files changed

+106
-34
lines changed

7 files changed

+106
-34
lines changed

src/main/java/org/springframework/data/elasticsearch/core/convert/AbstractRangePropertyValueConverter.java

+11-5
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,19 @@ public abstract class AbstractRangePropertyValueConverter<T> extends AbstractPro
3232
protected static final String LTE_FIELD = "lte";
3333
protected static final String GT_FIELD = "gt";
3434
protected static final String GTE_FIELD = "gte";
35+
private final Class<?> genericType;
3536

36-
public AbstractRangePropertyValueConverter(PersistentProperty<?> property) {
37+
/**
38+
* @param property the property this convertrer belongs to
39+
* @param genericType the generic type of the Range
40+
*/
41+
public AbstractRangePropertyValueConverter(PersistentProperty<?> property, Class<?> genericType) {
3742
super(property);
43+
this.genericType = genericType;
44+
}
45+
46+
public Class<?> getGenericType() {
47+
return genericType;
3848
}
3949

4050
@Override
@@ -117,10 +127,6 @@ public Object write(Object value) {
117127

118128
protected abstract String format(T value);
119129

120-
protected Class<?> getGenericType() {
121-
return getProperty().getTypeInformation().getTypeArguments().get(0).getType();
122-
}
123-
124130
protected abstract T parse(String value);
125131

126132
}

src/main/java/org/springframework/data/elasticsearch/core/convert/DateRangePropertyValueConverter.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ public class DateRangePropertyValueConverter extends AbstractRangePropertyValueC
3333
private final List<ElasticsearchDateConverter> dateConverters;
3434

3535
public DateRangePropertyValueConverter(PersistentProperty<?> property,
36-
List<ElasticsearchDateConverter> dateConverters) {
36+
Class<?> genericType, List<ElasticsearchDateConverter> dateConverters) {
3737

38-
super(property);
38+
super(property, genericType);
3939
this.dateConverters = dateConverters;
4040
}
4141

src/main/java/org/springframework/data/elasticsearch/core/convert/NumberRangePropertyValueConverter.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@
2323
*/
2424
public class NumberRangePropertyValueConverter extends AbstractRangePropertyValueConverter<Number> {
2525

26-
public NumberRangePropertyValueConverter(PersistentProperty<?> property) {
27-
super(property);
26+
/**
27+
* @param property the property this convertrer belongs to
28+
* @param genericType the generic type of the Range
29+
*/
30+
public NumberRangePropertyValueConverter(PersistentProperty<?> property, Class<?> genericType) {
31+
super(property, genericType);
2832
}
2933

3034
@Override

src/main/java/org/springframework/data/elasticsearch/core/convert/TemporalRangePropertyValueConverter.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public class TemporalRangePropertyValueConverter extends AbstractRangePropertyVa
3434
private final List<ElasticsearchDateConverter> dateConverters;
3535

3636
public TemporalRangePropertyValueConverter(PersistentProperty<?> property,
37-
List<ElasticsearchDateConverter> dateConverters) {
37+
Class<?> genericType, List<ElasticsearchDateConverter> dateConverters) {
3838

39-
super(property);
39+
super(property, genericType);
4040

4141
Assert.notEmpty(dateConverters, "dateConverters must not be empty.");
4242
this.dateConverters = dateConverters;

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

+19-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Arrays;
2121
import java.util.Date;
2222
import java.util.List;
23+
import java.util.function.Supplier;
2324

2425
import org.apache.commons.logging.Log;
2526
import org.apache.commons.logging.LogFactory;
@@ -56,6 +57,7 @@
5657
import org.springframework.data.mapping.model.Property;
5758
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
5859
import org.springframework.data.mapping.model.SimpleTypeHolder;
60+
import org.springframework.data.util.TypeInformation;
5961
import org.springframework.lang.Nullable;
6062
import org.springframework.util.StringUtils;
6163

@@ -168,6 +170,18 @@ private void initPropertyValueConverter() {
168170
return;
169171
}
170172

173+
Supplier<Class<?>> getGenericType = () -> {
174+
TypeInformation<?> typeInformation = getTypeInformation();
175+
176+
if (typeInformation.isCollectionLike()) {
177+
// we have a collection of Range<?>
178+
typeInformation = typeInformation.getComponentType();
179+
}
180+
181+
Class<?> genericType = typeInformation.getTypeArguments().get(0).getType();
182+
return genericType;
183+
};
184+
171185
switch (field.type()) {
172186
case Date:
173187
case Date_Nanos: {
@@ -197,11 +211,11 @@ private void initPropertyValueConverter() {
197211
return;
198212
}
199213

200-
Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
214+
var genericType = getGenericType.get();
201215
if (TemporalAccessor.class.isAssignableFrom(genericType)) {
202-
propertyValueConverter = new TemporalRangePropertyValueConverter(this, dateConverters);
216+
propertyValueConverter = new TemporalRangePropertyValueConverter(this, genericType, dateConverters);
203217
} else if (Date.class.isAssignableFrom(genericType)) {
204-
propertyValueConverter = new DateRangePropertyValueConverter(this, dateConverters);
218+
propertyValueConverter = new DateRangePropertyValueConverter(this, genericType, dateConverters);
205219
} else {
206220
LOGGER.warn(
207221
String.format("Unsupported generic type '{%s' for date range property '%s'.", genericType, getName()));
@@ -216,7 +230,7 @@ private void initPropertyValueConverter() {
216230
return;
217231
}
218232

219-
Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
233+
var genericType = getGenericType.get();
220234
if ((field.type() == FieldType.Integer_Range && !Integer.class.isAssignableFrom(genericType))
221235
|| (field.type() == FieldType.Float_Range && !Float.class.isAssignableFrom(genericType))
222236
|| (field.type() == FieldType.Long_Range && !Long.class.isAssignableFrom(genericType))
@@ -226,7 +240,7 @@ private void initPropertyValueConverter() {
226240
return;
227241
}
228242

229-
propertyValueConverter = new NumberRangePropertyValueConverter(this);
243+
propertyValueConverter = new NumberRangePropertyValueConverter(this, genericType);
230244
break;
231245
}
232246
case Ip_Range: {

src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java

+62-15
Original file line numberDiff line numberDiff line change
@@ -961,19 +961,57 @@ public InnerEntity(String prop1, String prop2) {
961961
@Nested
962962
class RangeTests {
963963

964-
static final String JSON = "{"
965-
+ "\"_class\":\"org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$RangeTests$RangeEntity\","
966-
+ "\"integerRange\":{\"gt\":\"1\",\"lt\":\"10\"}," //
967-
+ "\"floatRange\":{\"gte\":\"1.2\",\"lte\":\"2.5\"}," //
968-
+ "\"longRange\":{\"gt\":\"2\",\"lte\":\"5\"}," //
969-
+ "\"doubleRange\":{\"gte\":\"3.2\",\"lt\":\"7.4\"}," //
970-
+ "\"dateRange\":{\"gte\":\"1970-01-01T00:00:00.000Z\",\"lte\":\"1970-01-01T01:00:00.000Z\"}," //
971-
+ "\"localDateRange\":{\"gte\":\"2021-07-06\"}," //
972-
+ "\"localTimeRange\":{\"gte\":\"00:30:00.000\",\"lt\":\"02:30:00.000\"}," //
973-
+ "\"localDateTimeRange\":{\"gt\":\"2021-01-01T00:30:00.000\",\"lt\":\"2021-01-01T02:30:00.000\"}," //
974-
+ "\"offsetTimeRange\":{\"gte\":\"00:30:00.000+02:00\",\"lt\":\"02:30:00.000+02:00\"}," //
975-
+ "\"zonedDateTimeRange\":{\"gte\":\"2021-01-01T00:30:00.000+02:00\",\"lte\":\"2021-01-01T00:30:00.000+02:00\"}," //
976-
+ "\"nullRange\":null}";
964+
static final String JSON = """
965+
{
966+
"_class": "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$RangeTests$RangeEntity",
967+
"integerRange": {
968+
"gt": "1",
969+
"lt": "10"
970+
},
971+
"floatRange": {
972+
"gte": "1.2",
973+
"lte": "2.5"
974+
},
975+
"longRange": {
976+
"gt": "2",
977+
"lte": "5"
978+
},
979+
"doubleRange": {
980+
"gte": "3.2",
981+
"lt": "7.4"
982+
},
983+
"dateRange": {
984+
"gte": "1970-01-01T00:00:00.000Z",
985+
"lte": "1970-01-01T01:00:00.000Z"
986+
},
987+
"localDateRange": {
988+
"gte": "2021-07-06"
989+
},
990+
"localTimeRange": {
991+
"gte": "00:30:00.000",
992+
"lt": "02:30:00.000"
993+
},
994+
"localDateTimeRange": {
995+
"gt": "2021-01-01T00:30:00.000",
996+
"lt": "2021-01-01T02:30:00.000"
997+
},
998+
"offsetTimeRange": {
999+
"gte": "00:30:00.000+02:00",
1000+
"lt": "02:30:00.000+02:00"
1001+
},
1002+
"zonedDateTimeRange": {
1003+
"gte": "2021-01-01T00:30:00.000+02:00",
1004+
"lte": "2021-01-01T00:30:00.000+02:00"
1005+
},
1006+
"nullRange": null,
1007+
"integerRangeList": [
1008+
{
1009+
"gte": "2",
1010+
"lte": "5"
1011+
}
1012+
]
1013+
}
1014+
""";
9771015

9781016
@Test
9791017
public void shouldReadRanges() throws JSONException {
@@ -1004,6 +1042,7 @@ public void shouldReadRanges() throws JSONException {
10041042
assertThat(e.getZonedDateTimeRange()).isEqualTo(
10051043
Range.just(ZonedDateTime.of(LocalDate.of(2021, 1, 1), LocalTime.of(0, 30), ZoneOffset.ofHours(2))));
10061044
assertThat(e.getNullRange()).isNull();
1045+
assertThat(e.getIntegerRangeList()).containsExactly(Range.closed(2, 5));
10071046
});
10081047
}
10091048

@@ -1027,8 +1066,7 @@ public void shouldWriteRanges() throws JSONException {
10271066
entity.setZonedDateTimeRange(
10281067
Range.just(ZonedDateTime.of(LocalDate.of(2021, 1, 1), LocalTime.of(0, 30), ZoneOffset.ofHours(2))));
10291068
entity.setNullRange(null);
1030-
1031-
// when
1069+
entity.setIntegerRangeList(List.of(Range.closed(2, 5)));
10321070
Document document = mappingElasticsearchConverter.mapObject(entity);
10331071

10341072
// then
@@ -1053,6 +1091,8 @@ class RangeEntity {
10531091
@Field(type = FieldType.Date_Range) private Range<ZonedDateTime> zonedDateTimeRange;
10541092
@Field(type = FieldType.Date_Range, storeNullValue = true) private Range<ZonedDateTime> nullRange;
10551093

1094+
@Field(type = FieldType.Integer_Range) private List<Range<Integer>> integerRangeList;
1095+
10561096
public String getId() {
10571097
return id;
10581098
}
@@ -1149,6 +1189,13 @@ public void setNullRange(Range<ZonedDateTime> nullRange) {
11491189
this.nullRange = nullRange;
11501190
}
11511191

1192+
public List<Range<Integer>> getIntegerRangeList() {
1193+
return integerRangeList;
1194+
}
1195+
1196+
public void setIntegerRangeList(List<Range<Integer>> integerRangeList) {
1197+
this.integerRangeList = integerRangeList;
1198+
}
11521199
}
11531200
}
11541201

src/test/java/org/springframework/data/elasticsearch/core/convert/PropertyValueConvertersUnitTests.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,14 @@ static Stream<Arguments> propertyValueConverters() {
6363

6464
converters.add(new DatePropertyValueConverter(persistentProperty,
6565
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
66+
Class<?> genericType = Object.class;
6667
converters.add(new DateRangePropertyValueConverter(persistentProperty,
67-
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
68-
converters.add(new NumberRangePropertyValueConverter(persistentProperty));
68+
genericType, Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
69+
converters.add(new NumberRangePropertyValueConverter(persistentProperty, genericType));
6970
converters.add(new TemporalPropertyValueConverter(persistentProperty,
7071
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
7172
converters.add(new TemporalRangePropertyValueConverter(persistentProperty,
72-
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
73+
genericType, Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
7374

7475
return converters.stream().map(propertyValueConverter -> arguments(
7576
Named.of(propertyValueConverter.getClass().getSimpleName(), propertyValueConverter)));

0 commit comments

Comments
 (0)