Skip to content

Fix converting of Range<?> in Lists. #2707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,19 @@ public abstract class AbstractRangePropertyValueConverter<T> extends AbstractPro
protected static final String LTE_FIELD = "lte";
protected static final String GT_FIELD = "gt";
protected static final String GTE_FIELD = "gte";
private final Class<?> genericType;

public AbstractRangePropertyValueConverter(PersistentProperty<?> property) {
/**
* @param property the property this convertrer belongs to
* @param genericType the generic type of the Range
*/
public AbstractRangePropertyValueConverter(PersistentProperty<?> property, Class<?> genericType) {
super(property);
this.genericType = genericType;
}

public Class<?> getGenericType() {
return genericType;
}

@Override
Expand Down Expand Up @@ -117,10 +127,6 @@ public Object write(Object value) {

protected abstract String format(T value);

protected Class<?> getGenericType() {
return getProperty().getTypeInformation().getTypeArguments().get(0).getType();
}

protected abstract T parse(String value);

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public class DateRangePropertyValueConverter extends AbstractRangePropertyValueC
private final List<ElasticsearchDateConverter> dateConverters;

public DateRangePropertyValueConverter(PersistentProperty<?> property,
List<ElasticsearchDateConverter> dateConverters) {
Class<?> genericType, List<ElasticsearchDateConverter> dateConverters) {

super(property);
super(property, genericType);
this.dateConverters = dateConverters;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
*/
public class NumberRangePropertyValueConverter extends AbstractRangePropertyValueConverter<Number> {

public NumberRangePropertyValueConverter(PersistentProperty<?> property) {
super(property);
/**
* @param property the property this convertrer belongs to
* @param genericType the generic type of the Range
*/
public NumberRangePropertyValueConverter(PersistentProperty<?> property, Class<?> genericType) {
super(property, genericType);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ public class TemporalRangePropertyValueConverter extends AbstractRangePropertyVa
private final List<ElasticsearchDateConverter> dateConverters;

public TemporalRangePropertyValueConverter(PersistentProperty<?> property,
List<ElasticsearchDateConverter> dateConverters) {
Class<?> genericType, List<ElasticsearchDateConverter> dateConverters) {

super(property);
super(property, genericType);

Assert.notEmpty(dateConverters, "dateConverters must not be empty.");
this.dateConverters = dateConverters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.function.Supplier;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand Down Expand Up @@ -56,6 +57,7 @@
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;

Expand Down Expand Up @@ -168,6 +170,18 @@ private void initPropertyValueConverter() {
return;
}

Supplier<Class<?>> getGenericType = () -> {
TypeInformation<?> typeInformation = getTypeInformation();

if (typeInformation.isCollectionLike()) {
// we have a collection of Range<?>
typeInformation = typeInformation.getComponentType();
}

Class<?> genericType = typeInformation.getTypeArguments().get(0).getType();
return genericType;
};

switch (field.type()) {
case Date:
case Date_Nanos: {
Expand Down Expand Up @@ -197,11 +211,11 @@ private void initPropertyValueConverter() {
return;
}

Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
var genericType = getGenericType.get();
if (TemporalAccessor.class.isAssignableFrom(genericType)) {
propertyValueConverter = new TemporalRangePropertyValueConverter(this, dateConverters);
propertyValueConverter = new TemporalRangePropertyValueConverter(this, genericType, dateConverters);
} else if (Date.class.isAssignableFrom(genericType)) {
propertyValueConverter = new DateRangePropertyValueConverter(this, dateConverters);
propertyValueConverter = new DateRangePropertyValueConverter(this, genericType, dateConverters);
} else {
LOGGER.warn(
String.format("Unsupported generic type '{%s' for date range property '%s'.", genericType, getName()));
Expand All @@ -216,7 +230,7 @@ private void initPropertyValueConverter() {
return;
}

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

propertyValueConverter = new NumberRangePropertyValueConverter(this);
propertyValueConverter = new NumberRangePropertyValueConverter(this, genericType);
break;
}
case Ip_Range: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,13 @@ class RangeTests {
"gte": "2021-01-01T00:30:00.000+02:00",
"lte": "2021-01-01T00:30:00.000+02:00"
},
"nullRange": null
"nullRange": null,
"integerRangeList": [
{
"gte": "2",
"lte": "5"
}
]
}
""";

Expand Down Expand Up @@ -1020,6 +1026,7 @@ public void shouldReadRanges() throws JSONException {
assertThat(e.getZonedDateTimeRange()).isEqualTo(
Range.just(ZonedDateTime.of(LocalDate.of(2021, 1, 1), LocalTime.of(0, 30), ZoneOffset.ofHours(2))));
assertThat(e.getNullRange()).isNull();
assertThat(e.getIntegerRangeList()).containsExactly(Range.closed(2, 5));
});
}

Expand All @@ -1042,7 +1049,7 @@ public void shouldWriteRanges() throws JSONException {
entity.setZonedDateTimeRange(
Range.just(ZonedDateTime.of(LocalDate.of(2021, 1, 1), LocalTime.of(0, 30), ZoneOffset.ofHours(2))));
entity.setNullRange(null);

entity.setIntegerRangeList(List.of(Range.closed(2, 5)));
Document document = mappingElasticsearchConverter.mapObject(entity);

assertThat(document).isEqualTo(source);
Expand All @@ -1066,6 +1073,8 @@ class RangeEntity {
@Field(type = FieldType.Date_Range) private Range<ZonedDateTime> zonedDateTimeRange;
@Field(type = FieldType.Date_Range, storeNullValue = true) private Range<ZonedDateTime> nullRange;

@Field(type = FieldType.Integer_Range) private List<Range<Integer>> integerRangeList;

public String getId() {
return id;
}
Expand Down Expand Up @@ -1162,6 +1171,13 @@ public void setNullRange(Range<ZonedDateTime> nullRange) {
this.nullRange = nullRange;
}

public List<Range<Integer>> getIntegerRangeList() {
return integerRangeList;
}

public void setIntegerRangeList(List<Range<Integer>> integerRangeList) {
this.integerRangeList = integerRangeList;
}
}
}

Expand Down Expand Up @@ -2055,7 +2071,8 @@ void shouldReadEntityWithDottedFieldName() {
void shouldMapPropertyPathToFieldNames() {

var propertyPath = "level1Entries.level2Entries.keyWord";
ElasticsearchPersistentEntity<?> persistentEntity = mappingElasticsearchConverter.getMappingContext().getPersistentEntity(NestedEntity.class);
ElasticsearchPersistentEntity<?> persistentEntity = mappingElasticsearchConverter.getMappingContext()
.getPersistentEntity(NestedEntity.class);
var mappedNames = mappingElasticsearchConverter.updateFieldNames(propertyPath, persistentEntity);

assertThat(mappedNames).isEqualTo("level-one.level-two.key-word");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,14 @@ static Stream<Arguments> propertyValueConverters() {

converters.add(new DatePropertyValueConverter(persistentProperty,
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
Class<?> genericType = Object.class;
converters.add(new DateRangePropertyValueConverter(persistentProperty,
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
converters.add(new NumberRangePropertyValueConverter(persistentProperty));
genericType, Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
converters.add(new NumberRangePropertyValueConverter(persistentProperty, genericType));
converters.add(new TemporalPropertyValueConverter(persistentProperty,
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
converters.add(new TemporalRangePropertyValueConverter(persistentProperty,
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
genericType, Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));

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