mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-05-31 09:12:11 +00:00
DATAES-792 - Add java.util.Date to the supported types for Field annotation date times.
Original PR: #432
This commit is contained in:
parent
f6a37f4601
commit
e49f140233
@ -17,7 +17,9 @@ package org.springframework.data.elasticsearch.core.convert;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.elasticsearch.common.time.DateFormatter;
|
||||
@ -73,9 +75,25 @@ final public class ElasticsearchDateConverter {
|
||||
* @return the formatted object
|
||||
*/
|
||||
public String format(TemporalAccessor accessor) {
|
||||
|
||||
Assert.notNull(accessor, "accessor must not be null");
|
||||
|
||||
return dateFormatter.format(accessor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given {@link TemporalAccessor} int a String
|
||||
*
|
||||
* @param date must not be {@literal null}
|
||||
* @return the formatted object
|
||||
*/
|
||||
public String format(Date date) {
|
||||
|
||||
Assert.notNull(date, "accessor must not be null");
|
||||
|
||||
return dateFormatter.format(Instant.ofEpochMilli(date.getTime()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a String into an object
|
||||
*
|
||||
@ -96,4 +114,14 @@ final public class ElasticsearchDateConverter {
|
||||
throw new ConversionException("could not create object of class " + type.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a String into a Date.
|
||||
*
|
||||
* @param input the String to parse, must not be {@literal null}.
|
||||
* @return the new created object
|
||||
*/
|
||||
public Date parse(String input) {
|
||||
return new Date(Instant.from(dateFormatter.parse(input)).toEpochMilli());
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.core.mapping;
|
||||
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
@ -95,11 +96,14 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
/**
|
||||
* Initializes an {@link ElasticsearchPersistentPropertyConverter} if this property is annotated as a Field with type
|
||||
* {@link FieldType#Date}, has a {@link DateFormat} set and if the type of the property is one of the Java8 temporal
|
||||
* classes.
|
||||
* classes or java.util.Date.
|
||||
*/
|
||||
private void initDateConverter() {
|
||||
Field field = findAnnotation(Field.class);
|
||||
if (field != null && field.type() == FieldType.Date && TemporalAccessor.class.isAssignableFrom(getType())) {
|
||||
boolean isTemporalAccessor = TemporalAccessor.class.isAssignableFrom(getType());
|
||||
boolean isDate = Date.class.isAssignableFrom(getType());
|
||||
|
||||
if (field != null && field.type() == FieldType.Date && (isTemporalAccessor || isDate)) {
|
||||
DateFormat dateFormat = field.format();
|
||||
|
||||
ElasticsearchDateConverter converter = null;
|
||||
@ -119,13 +123,21 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
propertyConverter = new ElasticsearchPersistentPropertyConverter() {
|
||||
@Override
|
||||
public String write(Object property) {
|
||||
return dateConverter.format((TemporalAccessor) property);
|
||||
if (isTemporalAccessor) {
|
||||
return dateConverter.format((TemporalAccessor) property);
|
||||
} else { // must be Date
|
||||
return dateConverter.format((Date) property);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object read(String s) {
|
||||
return dateConverter.parse(s, (Class<? extends TemporalAccessor>) getType());
|
||||
if (isTemporalAccessor) {
|
||||
return dateConverter.parse(s, (Class<? extends TemporalAccessor>) getType());
|
||||
} else { // must be date
|
||||
return dateConverter.parse(s);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package org.springframework.data.elasticsearch.core.convert;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
@ -14,7 +16,7 @@ import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
*/
|
||||
class ElasticsearchDateConverterTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@ParameterizedTest // DATAES-716
|
||||
@EnumSource(DateFormat.class)
|
||||
void shouldCreateConvertersForAllKnownFormats(DateFormat dateFormat) {
|
||||
|
||||
@ -28,8 +30,8 @@ class ElasticsearchDateConverterTests {
|
||||
assertThat(converter).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldConvertToString() {
|
||||
@Test // DATAES-716
|
||||
void shouldConvertTemporalAccessorToString() {
|
||||
LocalDate localDate = LocalDate.of(2019, 12, 27);
|
||||
ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date);
|
||||
|
||||
@ -38,8 +40,8 @@ class ElasticsearchDateConverterTests {
|
||||
assertThat(formatted).isEqualTo("20191227");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldParseFromString() {
|
||||
@Test // DATAES-716
|
||||
void shouldParseTemporalAccessorFromString() {
|
||||
LocalDate localDate = LocalDate.of(2019, 12, 27);
|
||||
ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date);
|
||||
|
||||
@ -47,4 +49,24 @@ class ElasticsearchDateConverterTests {
|
||||
|
||||
assertThat(parsed).isEqualTo(localDate);
|
||||
}
|
||||
|
||||
@Test // DATAES-792
|
||||
void shouldConvertLegacyDateToString() {
|
||||
Date date = new GregorianCalendar(2020, 3, 19, 21, 44).getTime();
|
||||
ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date_time);
|
||||
|
||||
String formatted = converter.format(date);
|
||||
|
||||
assertThat(formatted).isEqualTo("20200419T194400.000Z");
|
||||
}
|
||||
|
||||
@Test // DATAES-792
|
||||
void shouldParseLegacyDateFromString() {
|
||||
Date date = new GregorianCalendar(2020, 3, 19, 21, 44).getTime();
|
||||
ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date_time);
|
||||
|
||||
Date parsed = converter.parse("20200419T194400.000Z");
|
||||
|
||||
assertThat(parsed).isEqualTo(date);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
@ -69,25 +70,25 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
assertThat(persistentProperty.getFieldName()).isEqualTo("by-value");
|
||||
}
|
||||
|
||||
@Test
|
||||
// DATAES-716
|
||||
@Test // DATAES-716, DATAES-792
|
||||
void shouldSetPropertyConverters() {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("date");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isFalse();
|
||||
|
||||
persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyConverter()).isNotNull();
|
||||
|
||||
persistentProperty = persistentEntity.getRequiredPersistentProperty("localDateTime");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyConverter()).isNotNull();
|
||||
|
||||
persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyConverter()).isNotNull();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
// DATAES-716
|
||||
@Test // DATAES-716
|
||||
void shouldConvertFromLocalDate() {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
@ -98,8 +99,7 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
assertThat(converted).isEqualTo("27.12.2019");
|
||||
}
|
||||
|
||||
@Test
|
||||
// DATAES-716
|
||||
@Test // DATAES-716
|
||||
void shouldConvertToLocalDate() {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
@ -110,6 +110,28 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
assertThat(converted).isEqualTo(LocalDate.of(2019, 12, 27));
|
||||
}
|
||||
|
||||
@Test // DATAES_792
|
||||
void shouldConvertFromLegacyDate() {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate");
|
||||
Date legacyDate = new GregorianCalendar(2020, 3, 19, 21, 44).getTime();
|
||||
|
||||
String converted = persistentProperty.getPropertyConverter().write(legacyDate);
|
||||
|
||||
assertThat(converted).isEqualTo("20200419T194400.000Z");
|
||||
}
|
||||
|
||||
@Test // DATES-792
|
||||
void shouldConvertToLegacyDate() {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate");
|
||||
|
||||
Object converted = persistentProperty.getPropertyConverter().read("20200419T194400.000Z");
|
||||
|
||||
assertThat(converted).isInstanceOf(Date.class);
|
||||
assertThat(converted).isEqualTo(new GregorianCalendar(2020, 3, 19, 21, 44).getTime());
|
||||
}
|
||||
|
||||
static class InvalidScoreProperty {
|
||||
@Nullable @Score String scoreProperty;
|
||||
}
|
||||
@ -123,8 +145,8 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
}
|
||||
|
||||
static class DatesProperty {
|
||||
@Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date) Date date;
|
||||
@Nullable @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.uuuu") LocalDate localDate;
|
||||
@Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime;
|
||||
@Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) Date legacyDate;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user