DATACMNS-1109 - Reinstantiate support for all date/time APIs in auditing.

Re-enabled test cases for handling of different date/time APIs in auditing. Tweaked the lookup of the last modified value to try to convert to LocalDateTime as well in case it's a subtype of the type requested. In combination with two newly introduced converters for local date type times in JodaTime and ThreeTenBP, this allows us to still convert legacy JodaTime and ThreeTenBP types to be used as well.
This commit is contained in:
Oliver Gierke
2017-07-12 18:58:00 +02:00
parent d4b79ea8f2
commit 6a6d995eab
6 changed files with 94 additions and 31 deletions

View File

@@ -19,10 +19,12 @@ import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.Optional;
import java.util.stream.Stream;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.ConversionService;
@@ -216,7 +218,23 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory
@SuppressWarnings("unchecked")
protected <T extends TemporalAccessor> Optional<T> getAsTemporalAccessor(Optional<? extends Object> source,
Class<? extends T> target) {
return source.map(it -> target.isInstance(it) ? (T) it : conversionService.convert(it, target));
return source.map(it -> {
if (target.isInstance(it)) {
return (T) it;
}
Class<?> typeToConvertTo = Stream.of(target, LocalDateTime.class)//
.filter(type -> target.isAssignableFrom(type))//
.filter(type -> conversionService.canConvert(it.getClass(), type))//
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(
String.format("Invalid date type for member %s! Supported types are %s.", source,
AnnotationAuditingMetadata.SUPPORTED_DATE_TYPES)));
return (T) conversionService.convert(it, typeToConvertTo);
});
}
}

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.data.auditing;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.HashMap;
import java.util.Map;
@@ -191,7 +190,8 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
*/
@Override
public Optional<TemporalAccessor> getLastModifiedDate() {
return getAsTemporalAccessor(metadata.lastModifiedDateProperty.map(accessor::getProperty), LocalDateTime.class);
return getAsTemporalAccessor(metadata.lastModifiedDateProperty.map(accessor::getProperty),
TemporalAccessor.class);
}
/*

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.convert;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -35,7 +36,6 @@ import org.springframework.util.ClassUtils;
* @author Christoph Strobl
* @author Jens Schauder
*/
@SuppressWarnings("deprecation")
public abstract class JodaTimeConverters {
private static final boolean JODA_TIME_IS_PRESENT = ClassUtils.isPresent("org.joda.time.LocalDate", null);
@@ -63,9 +63,21 @@ public abstract class JodaTimeConverters {
converters.add(LocalDateTimeToJodaLocalDateTime.INSTANCE);
converters.add(LocalDateTimeToJodaDateTime.INSTANCE);
converters.add(LocalDateTimeToJsr310Converter.INSTANCE);
return converters;
}
public enum LocalDateTimeToJsr310Converter implements Converter<LocalDateTime, java.time.LocalDateTime> {
INSTANCE;
@Override
public java.time.LocalDateTime convert(LocalDateTime source) {
return source == null ? null : java.time.LocalDateTime.ofInstant(source.toDate().toInstant(), ZoneId.of("UTC"));
}
}
public enum LocalDateToDateConverter implements Converter<LocalDate, Date> {
INSTANCE;

View File

@@ -71,6 +71,7 @@ public abstract class ThreeTenBackPortConverters {
converters.add(InstantToDateConverter.INSTANCE);
converters.add(ZoneIdToStringConverter.INSTANCE);
converters.add(StringToZoneIdConverter.INSTANCE);
converters.add(LocalDateTimeToJsr310LocalDateTimeConverter.INSTANCE);
return converters;
}
@@ -85,6 +86,24 @@ public abstract class ThreeTenBackPortConverters {
.contains(type);
}
public static enum LocalDateTimeToJsr310LocalDateTimeConverter
implements Converter<LocalDateTime, java.time.LocalDateTime> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public java.time.LocalDateTime convert(LocalDateTime source) {
Date date = toDate(source.atZone(ZoneId.systemDefault()).toInstant());
return source == null ? null : Jsr310Converters.DateToLocalDateTimeConverter.INSTANCE.convert(date);
}
}
public static enum DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {
INSTANCE;