Skip to content

Commit b21bd79

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

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;
@@ -54,6 +55,7 @@
5455
import org.springframework.data.mapping.model.Property;
5556
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
5657
import org.springframework.data.mapping.model.SimpleTypeHolder;
58+
import org.springframework.data.util.TypeInformation;
5759
import org.springframework.lang.Nullable;
5860
import org.springframework.util.StringUtils;
5961

@@ -158,6 +160,18 @@ private void initPropertyValueConverter() {
158160
return;
159161
}
160162

163+
Supplier<Class<?>> getGenericType = () -> {
164+
TypeInformation<?> typeInformation = getTypeInformation();
165+
166+
if (typeInformation.isCollectionLike()) {
167+
// we have a collection of Range<?>
168+
typeInformation = typeInformation.getComponentType();
169+
}
170+
171+
Class<?> genericType = typeInformation.getTypeArguments().get(0).getType();
172+
return genericType;
173+
};
174+
161175
switch (field.type()) {
162176
case Date:
163177
case Date_Nanos: {
@@ -187,11 +201,11 @@ private void initPropertyValueConverter() {
187201
return;
188202
}
189203

190-
Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
204+
var genericType = getGenericType.get();
191205
if (TemporalAccessor.class.isAssignableFrom(genericType)) {
192-
propertyValueConverter = new TemporalRangePropertyValueConverter(this, dateConverters);
206+
propertyValueConverter = new TemporalRangePropertyValueConverter(this, genericType, dateConverters);
193207
} else if (Date.class.isAssignableFrom(genericType)) {
194-
propertyValueConverter = new DateRangePropertyValueConverter(this, dateConverters);
208+
propertyValueConverter = new DateRangePropertyValueConverter(this, genericType, dateConverters);
195209
} else {
196210
LOGGER.warn(
197211
String.format("Unsupported generic type '{%s' for date range property '%s'.", genericType, getName()));
@@ -206,7 +220,7 @@ private void initPropertyValueConverter() {
206220
return;
207221
}
208222

209-
Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
223+
var genericType = getGenericType.get();
210224
if ((field.type() == FieldType.Integer_Range && !Integer.class.isAssignableFrom(genericType))
211225
|| (field.type() == FieldType.Float_Range && !Float.class.isAssignableFrom(genericType))
212226
|| (field.type() == FieldType.Long_Range && !Long.class.isAssignableFrom(genericType))
@@ -216,7 +230,7 @@ private void initPropertyValueConverter() {
216230
return;
217231
}
218232

219-
propertyValueConverter = new NumberRangePropertyValueConverter(this);
233+
propertyValueConverter = new NumberRangePropertyValueConverter(this, genericType);
220234
break;
221235
}
222236
case Ip_Range: {

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

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

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

9771015
@Test
9781016
public void shouldReadRanges() throws JSONException {
@@ -1003,6 +1041,7 @@ public void shouldReadRanges() throws JSONException {
10031041
assertThat(e.getZonedDateTimeRange()).isEqualTo(
10041042
Range.just(ZonedDateTime.of(LocalDate.of(2021, 1, 1), LocalTime.of(0, 30), ZoneOffset.ofHours(2))));
10051043
assertThat(e.getNullRange()).isNull();
1044+
assertThat(e.getIntegerRangeList()).containsExactly(Range.closed(2, 5));
10061045
});
10071046
}
10081047

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

10331071
// then
@@ -1052,6 +1090,8 @@ class RangeEntity {
10521090
@Field(type = FieldType.Date_Range) private Range<ZonedDateTime> zonedDateTimeRange;
10531091
@Field(type = FieldType.Date_Range, storeNullValue = true) private Range<ZonedDateTime> nullRange;
10541092

1093+
@Field(type = FieldType.Integer_Range) private List<Range<Integer>> integerRangeList;
1094+
10551095
public String getId() {
10561096
return id;
10571097
}
@@ -1148,6 +1188,13 @@ public void setNullRange(Range<ZonedDateTime> nullRange) {
11481188
this.nullRange = nullRange;
11491189
}
11501190

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

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)