committed by
Jens Schauder
parent
f417c4ca13
commit
582319a5fe
14
pom.xml
14
pom.xml
@@ -99,20 +99,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${jodatime}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.threeten</groupId>
|
||||
<artifactId>threetenbp</artifactId>
|
||||
<version>${threetenbp}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Project Reactor -->
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[[auditing.basics]]
|
||||
== Basics
|
||||
Spring Data provides sophisticated support to transparently keep track of who created or changed an entity and when the change happened. To benefit from that functionality, you have to equip your entity classes with auditing metadata that can be defined either using annotations or by implementing an interface.
|
||||
Spring Data provides sophisticated support to transparently keep track of who created or changed an entity and when the change happened.To benefit from that functionality, you have to equip your entity classes with auditing metadata that can be defined either using annotations or by implementing an interface.
|
||||
Additionally, auditing has to be enabled either through Annotation configuration or XML configuration to register the required infrastructure components.
|
||||
Please refer to the store-specific section for configuration samples.
|
||||
|
||||
@@ -18,7 +18,7 @@ We provide `@CreatedBy` and `@LastModifiedBy` to capture the user who created or
|
||||
|
||||
.An audited entity
|
||||
====
|
||||
[source, java]
|
||||
[source,java]
|
||||
----
|
||||
class Customer {
|
||||
|
||||
@@ -33,13 +33,14 @@ class Customer {
|
||||
----
|
||||
====
|
||||
|
||||
As you can see, the annotations can be applied selectively, depending on which information you want to capture. The annotations capturing when changes were made can be used on properties of type Joda-Time, `DateTime`, legacy Java `Date` and `Calendar`, JDK8 date and time types, and `long` or `Long`.
|
||||
As you can see, the annotations can be applied selectively, depending on which information you want to capture.
|
||||
The annotations, indicating to capture when changes are made, can be used on properties of type JDK8 date and time types, `long`, `Long`, and legacy Java `Date` and `Calendar`.
|
||||
|
||||
Auditing metadata does not necessarily need to live in the root level entity but can be added to an embedded one (depending on the actual store in use), as shown in the snipped below.
|
||||
Auditing metadata does not necessarily need to live in the root level entity but can be added to an embedded one (depending on the actual store in use), as shown in the snippet below.
|
||||
|
||||
.Audit metadata in embedded entity
|
||||
====
|
||||
[source, java]
|
||||
[source,java]
|
||||
----
|
||||
class Customer {
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ Converters are subject to explicit registration as instances are not picked up f
|
||||
`CustomConversions` ships with a pre-defined set of converter registrations:
|
||||
|
||||
* JSR-310 Converters for conversion between `java.time`, `java.util.Date` and `String` types.
|
||||
* Deprecated: Joda Time Converters for conversion between `org.joda.time`, JSR-310, and `java.util.Date`.
|
||||
* Deprecated: ThreeTenBackport Converters for conversion between `org.joda.time`, JSR-310, and `java.util.Date`.
|
||||
|
||||
NOTE: Default converters for local temporal types (e.g. `LocalDateTime` to `java.util.Date`) rely on system-default timezone settings to convert between those types. You can override the default converter, by registering your own converter.
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.convert.Jsr310Converters;
|
||||
import org.springframework.data.convert.ThreeTenBackPortConverters;
|
||||
import org.springframework.data.util.Optionals;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.data.util.ReflectionUtils.AnnotationFieldFilter;
|
||||
@@ -54,16 +53,11 @@ final class AnnotationAuditingMetadata {
|
||||
|
||||
private static final Map<Class<?>, AnnotationAuditingMetadata> metadataCache = new ConcurrentHashMap<>();
|
||||
|
||||
public static final boolean IS_JDK_8 = org.springframework.util.ClassUtils.isPresent("java.time.Clock",
|
||||
AnnotationAuditingMetadata.class.getClassLoader());
|
||||
|
||||
static final List<String> SUPPORTED_DATE_TYPES;
|
||||
|
||||
static {
|
||||
|
||||
List<String> types = new ArrayList<>(5);
|
||||
types.add("org.joda.time.DateTime");
|
||||
types.add("org.joda.time.LocalDateTime");
|
||||
types.add(Date.class.getName());
|
||||
types.add(Long.class.getName());
|
||||
types.add(long.class.getName());
|
||||
@@ -109,7 +103,7 @@ final class AnnotationAuditingMetadata {
|
||||
|
||||
Class<?> type = it.getType();
|
||||
|
||||
if (Jsr310Converters.supports(type) || ThreeTenBackPortConverters.supports(type)) {
|
||||
if (Jsr310Converters.supports(type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.convert.JodaTimeConverters;
|
||||
import org.springframework.data.convert.Jsr310Converters;
|
||||
import org.springframework.data.convert.ThreeTenBackPortConverters;
|
||||
import org.springframework.data.domain.Auditable;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
@@ -50,9 +48,7 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory
|
||||
|
||||
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
|
||||
|
||||
JodaTimeConverters.getConvertersToRegister().forEach(conversionService::addConverter);
|
||||
Jsr310Converters.getConvertersToRegister().forEach(conversionService::addConverter);
|
||||
ThreeTenBackPortConverters.getConvertersToRegister().forEach(conversionService::addConverter);
|
||||
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
@@ -79,9 +79,7 @@ public class CustomConversions {
|
||||
|
||||
List<Object> defaults = new ArrayList<>();
|
||||
|
||||
defaults.addAll(JodaTimeConverters.getConvertersToRegister());
|
||||
defaults.addAll(Jsr310Converters.getConvertersToRegister());
|
||||
defaults.addAll(ThreeTenBackPortConverters.getConvertersToRegister());
|
||||
defaults.addAll(JMoleculesConverters.getConvertersToRegister());
|
||||
|
||||
DEFAULT_CONVERTERS = Collections.unmodifiableList(defaults);
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Helper class to register JodaTime specific {@link Converter} implementations in case the library is present on the
|
||||
* classpath.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Jens Schauder
|
||||
* @author Mark Paluch
|
||||
* @deprecated since 2.3, use JSR-310 types as replacement for Joda-Time.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class JodaTimeConverters {
|
||||
|
||||
private static final boolean JODA_TIME_IS_PRESENT = ClassUtils.isPresent("org.joda.time.LocalDate", null);
|
||||
|
||||
/**
|
||||
* Returns the converters to be registered. Will only return converters in case JodaTime is present on the class.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Collection<Converter<?, ?>> getConvertersToRegister() {
|
||||
|
||||
if (!JODA_TIME_IS_PRESENT) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
List<Converter<?, ?>> converters = new ArrayList<>();
|
||||
converters.add(LocalDateToDateConverter.INSTANCE);
|
||||
converters.add(LocalDateTimeToDateConverter.INSTANCE);
|
||||
converters.add(DateTimeToDateConverter.INSTANCE);
|
||||
|
||||
converters.add(DateToLocalDateConverter.INSTANCE);
|
||||
converters.add(DateToLocalDateTimeConverter.INSTANCE);
|
||||
converters.add(DateToDateTimeConverter.INSTANCE);
|
||||
|
||||
converters.add(LocalDateTimeToJodaLocalDateTime.INSTANCE);
|
||||
converters.add(LocalDateTimeToJodaDateTime.INSTANCE);
|
||||
|
||||
converters.add(InstantToJodaLocalDateTime.INSTANCE);
|
||||
converters.add(JodaLocalDateTimeToInstant.INSTANCE);
|
||||
|
||||
converters.add(LocalDateTimeToJsr310Converter.INSTANCE);
|
||||
|
||||
return converters;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum LocalDateTimeToJsr310Converter implements Converter<LocalDateTime, java.time.LocalDateTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public java.time.LocalDateTime convert(LocalDateTime source) {
|
||||
return java.time.LocalDateTime.ofInstant(source.toDate().toInstant(), ZoneId.systemDefault());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum LocalDateToDateConverter implements Converter<LocalDate, Date> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Date convert(LocalDate source) {
|
||||
return source.toDate();
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Date convert(LocalDateTime source) {
|
||||
return source.toDate();
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum DateTimeToDateConverter implements Converter<DateTime, Date> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Date convert(DateTime source) {
|
||||
return source.toDate();
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum DateToLocalDateConverter implements Converter<Date, LocalDate> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public LocalDate convert(Date source) {
|
||||
return new LocalDate(source.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public LocalDateTime convert(Date source) {
|
||||
return new LocalDateTime(source.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum DateToDateTimeConverter implements Converter<Date, DateTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DateTime convert(Date source) {
|
||||
return new DateTime(source.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
@ReadingConverter
|
||||
@Deprecated
|
||||
public enum LocalDateTimeToJodaLocalDateTime implements Converter<java.time.LocalDateTime, LocalDateTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public LocalDateTime convert(java.time.LocalDateTime source) {
|
||||
return LocalDateTime.fromDateFields(Jsr310Converters.LocalDateTimeToDateConverter.INSTANCE.convert(source));
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum InstantToJodaLocalDateTime implements Converter<java.time.Instant, LocalDateTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public LocalDateTime convert(java.time.Instant source) {
|
||||
return LocalDateTime.fromDateFields(new Date(source.toEpochMilli()));
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum JodaLocalDateTimeToInstant implements Converter<LocalDateTime, Instant> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Instant convert(LocalDateTime source) {
|
||||
return Instant.ofEpochMilli(source.toDateTime().getMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum LocalDateTimeToJodaDateTime implements Converter<java.time.LocalDateTime, DateTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DateTime convert(java.time.LocalDateTime source) {
|
||||
return new DateTime(Jsr310Converters.LocalDateTimeToDateConverter.INSTANCE.convert(source));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,266 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import static org.threeten.bp.DateTimeUtils.*;
|
||||
import static org.threeten.bp.Instant.*;
|
||||
import static org.threeten.bp.LocalDateTime.*;
|
||||
import static org.threeten.bp.ZoneId.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import org.threeten.bp.Instant;
|
||||
import org.threeten.bp.LocalDate;
|
||||
import org.threeten.bp.LocalDateTime;
|
||||
import org.threeten.bp.LocalTime;
|
||||
import org.threeten.bp.ZoneId;
|
||||
import org.threeten.bp.ZoneOffset;
|
||||
|
||||
/**
|
||||
* Helper class to register {@link Converter} implementations for the ThreeTen Backport project in case it's present on
|
||||
* the classpath.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Jens Schauder
|
||||
* @author Mark Paluch
|
||||
* @see <a href="https://www.threeten.org/threetenbp">https://www.threeten.org/threetenbp</a>
|
||||
* @since 1.10
|
||||
* @deprecated since 2.3, use JSR-310 types as replacement for ThreeTenBackport.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class ThreeTenBackPortConverters {
|
||||
|
||||
private static final boolean THREE_TEN_BACK_PORT_IS_PRESENT = ClassUtils.isPresent("org.threeten.bp.LocalDateTime",
|
||||
ThreeTenBackPortConverters.class.getClassLoader());
|
||||
private static final Collection<Class<?>> SUPPORTED_TYPES;
|
||||
|
||||
static {
|
||||
|
||||
SUPPORTED_TYPES = THREE_TEN_BACK_PORT_IS_PRESENT //
|
||||
? Arrays.asList(LocalDateTime.class, LocalDate.class, LocalTime.class, Instant.class, java.time.Instant.class)
|
||||
: Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the converters to be registered. Will only return converters in case we're running on Java 8.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Collection<Converter<?, ?>> getConvertersToRegister() {
|
||||
|
||||
if (!THREE_TEN_BACK_PORT_IS_PRESENT) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
List<Converter<?, ?>> converters = new ArrayList<>();
|
||||
converters.add(DateToLocalDateTimeConverter.INSTANCE);
|
||||
converters.add(LocalDateTimeToDateConverter.INSTANCE);
|
||||
converters.add(DateToLocalDateConverter.INSTANCE);
|
||||
converters.add(LocalDateToDateConverter.INSTANCE);
|
||||
converters.add(DateToLocalTimeConverter.INSTANCE);
|
||||
converters.add(LocalTimeToDateConverter.INSTANCE);
|
||||
converters.add(DateToInstantConverter.INSTANCE);
|
||||
converters.add(InstantToDateConverter.INSTANCE);
|
||||
converters.add(ZoneIdToStringConverter.INSTANCE);
|
||||
converters.add(StringToZoneIdConverter.INSTANCE);
|
||||
converters.add(LocalDateTimeToJsr310LocalDateTimeConverter.INSTANCE);
|
||||
converters.add(LocalDateTimeToJavaTimeInstantConverter.INSTANCE);
|
||||
converters.add(JavaTimeInstantToLocalDateTimeConverter.INSTANCE);
|
||||
|
||||
return converters;
|
||||
}
|
||||
|
||||
public static boolean supports(Class<?> type) {
|
||||
return SUPPORTED_TYPES.contains(type);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum LocalDateTimeToJsr310LocalDateTimeConverter
|
||||
implements Converter<LocalDateTime, java.time.LocalDateTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public java.time.LocalDateTime convert(LocalDateTime source) {
|
||||
|
||||
Date date = toDate(source.atZone(ZoneId.systemDefault()).toInstant());
|
||||
|
||||
return Jsr310Converters.DateToLocalDateTimeConverter.INSTANCE.convert(date);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public LocalDateTime convert(Date source) {
|
||||
return ofInstant(toInstant(source), systemDefault());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Date convert(LocalDateTime source) {
|
||||
return toDate(source.atZone(systemDefault()).toInstant());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum DateToLocalDateConverter implements Converter<Date, LocalDate> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public LocalDate convert(Date source) {
|
||||
return ofInstant(ofEpochMilli(source.getTime()), systemDefault()).toLocalDate();
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum LocalDateToDateConverter implements Converter<LocalDate, Date> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Date convert(LocalDate source) {
|
||||
return toDate(source.atStartOfDay(systemDefault()).toInstant());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum DateToLocalTimeConverter implements Converter<Date, LocalTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public LocalTime convert(Date source) {
|
||||
return ofInstant(ofEpochMilli(source.getTime()), systemDefault()).toLocalTime();
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum LocalTimeToDateConverter implements Converter<LocalTime, Date> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Date convert(LocalTime source) {
|
||||
return toDate(source.atDate(LocalDate.now()).atZone(systemDefault()).toInstant());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum DateToInstantConverter implements Converter<Date, Instant> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Instant convert(Date source) {
|
||||
return toInstant(source);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum InstantToDateConverter implements Converter<Instant, Date> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Date convert(Instant source) {
|
||||
return toDate(source.atZone(systemDefault()).toInstant());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum LocalDateTimeToJavaTimeInstantConverter implements Converter<LocalDateTime, java.time.Instant> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public java.time.Instant convert(LocalDateTime source) {
|
||||
return java.time.Instant.ofEpochMilli(source.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static enum JavaTimeInstantToLocalDateTimeConverter implements Converter<java.time.Instant, LocalDateTime> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public LocalDateTime convert(java.time.Instant source) {
|
||||
return LocalDateTime.ofInstant(Instant.ofEpochMilli(source.toEpochMilli()), ZoneOffset.systemDefault());
|
||||
}
|
||||
}
|
||||
|
||||
@WritingConverter
|
||||
@Deprecated
|
||||
public static enum ZoneIdToStringConverter implements Converter<ZoneId, String> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String convert(ZoneId source) {
|
||||
return source.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ReadingConverter
|
||||
@Deprecated
|
||||
public static enum StringToZoneIdConverter implements Converter<String, ZoneId> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ZoneId convert(String source) {
|
||||
return ZoneId.of(source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.auditing;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
@@ -35,7 +35,7 @@ class AnnotatedUser {
|
||||
Object createdBy;
|
||||
|
||||
@CreatedDate
|
||||
DateTime createdDate;
|
||||
LocalDateTime createdDate;
|
||||
|
||||
@LastModifiedBy
|
||||
Object lastModifiedBy;
|
||||
|
||||
@@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Optional;
|
||||
@@ -69,12 +68,12 @@ class DefaultAuditableBeanWrapperFactoryUnitTests {
|
||||
}
|
||||
|
||||
@Test // DATACMNS-643
|
||||
void setsJsr310AndThreeTenBpTypes() {
|
||||
void setsJsr310Types() {
|
||||
|
||||
Jsr310ThreeTenBpAuditedUser user = new Jsr310ThreeTenBpAuditedUser();
|
||||
Jsr310AuditedUser user = new Jsr310AuditedUser();
|
||||
Instant instant = Instant.now();
|
||||
|
||||
Optional<AuditableBeanWrapper<Jsr310ThreeTenBpAuditedUser>> wrapper = factory.getBeanWrapperFor(user);
|
||||
Optional<AuditableBeanWrapper<Jsr310AuditedUser>> wrapper = factory.getBeanWrapperFor(user);
|
||||
|
||||
assertThat(wrapper).hasValueSatisfying(it -> {
|
||||
|
||||
@@ -86,20 +85,6 @@ class DefaultAuditableBeanWrapperFactoryUnitTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATACMNS-867
|
||||
void errorsWhenUnableToConvertDateViaIntermediateJavaUtilDateConversion() {
|
||||
|
||||
Jsr310ThreeTenBpAuditedUser user = new Jsr310ThreeTenBpAuditedUser();
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.now();
|
||||
|
||||
Optional<AuditableBeanWrapper<Jsr310ThreeTenBpAuditedUser>> wrapper = factory.getBeanWrapperFor(user);
|
||||
|
||||
assertThat(wrapper).isNotEmpty();
|
||||
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> wrapper.ifPresent(it -> it.setLastModifiedDate(zonedDateTime)));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1259
|
||||
void lastModifiedDateAsLongIsAvailableViaWrapper() {
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ import org.springframework.data.annotation.LastModifiedDate;
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class Jsr310ThreeTenBpAuditedUser {
|
||||
class Jsr310AuditedUser {
|
||||
|
||||
@CreatedDate LocalDateTime createdDate;
|
||||
@LastModifiedDate org.threeten.bp.LocalDateTime lastModifiedDate;
|
||||
@LastModifiedDate LocalDateTime lastModifiedDate;
|
||||
}
|
||||
@@ -40,9 +40,7 @@ import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.AuditableInterfaceBeanWrapper;
|
||||
import org.springframework.data.convert.JodaTimeConverters;
|
||||
import org.springframework.data.convert.Jsr310Converters;
|
||||
import org.springframework.data.convert.ThreeTenBackPortConverters;
|
||||
import org.springframework.data.domain.Auditable;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.mapping.context.SampleMappingContext;
|
||||
@@ -132,15 +130,6 @@ class MappingAuditableBeanWrapperFactoryUnitTests {
|
||||
Jsr310Converters.DateToLocalDateTimeConverter.INSTANCE.convert(reference));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-638
|
||||
void returnsLastModificationDateTimeAsCalendar() {
|
||||
|
||||
org.joda.time.LocalDateTime reference = new org.joda.time.LocalDateTime();
|
||||
|
||||
assertLastModificationDate(reference,
|
||||
JodaTimeConverters.LocalDateTimeToJsr310Converter.INSTANCE.convert(reference));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-638
|
||||
void returnsLastModificationDateAsCalendar() {
|
||||
|
||||
@@ -158,15 +147,6 @@ class MappingAuditableBeanWrapperFactoryUnitTests {
|
||||
assertLastModificationDate(reference, reference);
|
||||
}
|
||||
|
||||
@Test // DATACMNS-638, DATACMNS-43
|
||||
void returnsLastModificationThreeTenBpDateTimeAsCalendar() {
|
||||
|
||||
org.threeten.bp.LocalDateTime reference = org.threeten.bp.LocalDateTime.now();
|
||||
|
||||
assertLastModificationDate(reference,
|
||||
ThreeTenBackPortConverters.LocalDateTimeToJsr310LocalDateTimeConverter.INSTANCE.convert(reference));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1109
|
||||
void exposesInstantAsModificationDate() {
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
@@ -55,7 +54,7 @@ class ReflectionAuditingBeanWrapperUnitTests {
|
||||
void setsDateTimeFieldCorrectly() {
|
||||
|
||||
wrapper.setCreatedDate(time);
|
||||
assertThat(user.createdDate).isEqualTo(new DateTime(LocalDateTimeToDateConverter.INSTANCE.convert(time)));
|
||||
assertThat(user.createdDate).isEqualTo(time);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.function.Predicate;
|
||||
|
||||
import org.jmolecules.ddd.types.Association;
|
||||
import org.jmolecules.ddd.types.Identifier;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
@@ -43,12 +42,9 @@ import org.springframework.data.convert.ConverterBuilder.ConverterAware;
|
||||
import org.springframework.data.convert.CustomConversions.ConverterConfiguration;
|
||||
import org.springframework.data.convert.CustomConversions.StoreConversions;
|
||||
import org.springframework.data.convert.Jsr310Converters.LocalDateTimeToDateConverter;
|
||||
import org.springframework.data.convert.ThreeTenBackPortConverters.LocalDateTimeToJavaTimeInstantConverter;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
|
||||
import org.threeten.bp.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link CustomConversions}.
|
||||
*
|
||||
@@ -131,25 +127,6 @@ class CustomConversionsUnitTests {
|
||||
assertThat(conversions.hasCustomWriteTarget(String.class, Integer.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-795, DATACMNS-1035
|
||||
void favorsCustomConverterForIndeterminedTargetType() {
|
||||
|
||||
CustomConversions conversions = new CustomConversions(StoreConversions.NONE,
|
||||
Arrays.asList(DateTimeToStringConverter.INSTANCE));
|
||||
assertThat(conversions.getCustomWriteTarget(DateTime.class)).hasValue(String.class);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-881, DATACMNS-1035
|
||||
void customConverterOverridesDefault() {
|
||||
|
||||
CustomConversions conversions = new CustomConversions(StoreConversions.NONE,
|
||||
Arrays.asList(CustomDateTimeConverter.INSTANCE));
|
||||
GenericConversionService conversionService = new DefaultConversionService();
|
||||
conversions.registerConvertersIn(conversionService);
|
||||
|
||||
assertThat(conversionService.convert(new DateTime(), Date.class)).isEqualTo(new Date(0));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1001, DATACMNS-1035
|
||||
void shouldSelectPropertCustomWriteTargetForCglibProxiedType() {
|
||||
|
||||
@@ -174,14 +151,6 @@ class CustomConversionsUnitTests {
|
||||
assertThat(customConversions.hasCustomWriteTarget(java.time.LocalDateTime.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1131, DATACMNS-1035
|
||||
void registersConvertersForThreeTenBackPort() {
|
||||
|
||||
CustomConversions customConversions = new CustomConversions(StoreConversions.NONE, Collections.emptyList());
|
||||
|
||||
assertThat(customConversions.hasCustomWriteTarget(LocalDateTime.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1302, DATACMNS-1035
|
||||
void registersConverterFactoryCorrectly() {
|
||||
|
||||
@@ -220,7 +189,7 @@ class CustomConversionsUnitTests {
|
||||
new CustomConversions(StoreConversions.of(DATE_EXCLUDING_SIMPLE_TYPE_HOLDER), Collections.emptyList())
|
||||
.registerConvertersIn(registry);
|
||||
|
||||
verify(registry, never()).addConverter(any(LocalDateTimeToJavaTimeInstantConverter.class));
|
||||
verify(registry, never()).addConverter(any(Jsr310Converters.LocalDateTimeToInstantConverter.class));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1665
|
||||
@@ -244,9 +213,10 @@ class CustomConversionsUnitTests {
|
||||
ConverterRegistry registry = mock(ConverterRegistry.class);
|
||||
|
||||
new CustomConversions(StoreConversions.of(DATE_EXCLUDING_SIMPLE_TYPE_HOLDER),
|
||||
Collections.singletonList(LocalDateTimeToJavaTimeInstantConverter.INSTANCE)).registerConvertersIn(registry);
|
||||
Collections.singletonList(Jsr310Converters.LocalDateTimeToInstantConverter.INSTANCE))
|
||||
.registerConvertersIn(registry);
|
||||
|
||||
verify(registry).addConverter(any(LocalDateTimeToJavaTimeInstantConverter.class));
|
||||
verify(registry).addConverter(any(Jsr310Converters.LocalDateTimeToInstantConverter.class));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1615
|
||||
@@ -346,26 +316,6 @@ class CustomConversionsUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
enum DateTimeToStringConverter implements Converter<DateTime, String> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public String convert(DateTime source) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
enum CustomDateTimeConverter implements Converter<DateTime, Date> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Date convert(DateTime source) {
|
||||
return new Date(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ReadingConverter
|
||||
enum CustomTypeToStringConverter implements Converter<CustomType, String> {
|
||||
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.threeten.bp.DateTimeUtils.*;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.threeten.bp.Instant;
|
||||
import org.threeten.bp.LocalDate;
|
||||
import org.threeten.bp.LocalDateTime;
|
||||
import org.threeten.bp.LocalTime;
|
||||
import org.threeten.bp.ZoneId;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ThreeTenBackPortConverters}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.10
|
||||
*/
|
||||
class ThreeTenBackPortConvertersUnitTests {
|
||||
|
||||
static final Date NOW = new Date();
|
||||
static final ConversionService CONVERSION_SERVICE;
|
||||
|
||||
static {
|
||||
|
||||
GenericConversionService conversionService = new GenericConversionService();
|
||||
|
||||
for (Converter<?, ?> converter : ThreeTenBackPortConverters.getConvertersToRegister()) {
|
||||
conversionService.addConverter(converter);
|
||||
}
|
||||
|
||||
CONVERSION_SERVICE = conversionService;
|
||||
}
|
||||
|
||||
@Test // DATACMNS-606
|
||||
void convertsDateToLocalDateTime() {
|
||||
assertThat(CONVERSION_SERVICE.convert(NOW, LocalDateTime.class).toString())
|
||||
.isEqualTo(format(NOW, "yyyy-MM-dd'T'HH:mm:ss.SSS"));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-606
|
||||
void convertsLocalDateTimeToDate() {
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
assertThat(format(CONVERSION_SERVICE.convert(now, Date.class), "yyyy-MM-dd'T'HH:mm:ss.SSS"))
|
||||
.isEqualTo(now.toString());
|
||||
}
|
||||
|
||||
@Test // DATACMNS-606
|
||||
void convertsDateToLocalDate() {
|
||||
assertThat(CONVERSION_SERVICE.convert(NOW, LocalDate.class).toString()).isEqualTo(format(NOW, "yyyy-MM-dd"));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-606
|
||||
void convertsLocalDateToDate() {
|
||||
|
||||
LocalDate now = LocalDate.now();
|
||||
assertThat(format(CONVERSION_SERVICE.convert(now, Date.class), "yyyy-MM-dd")).isEqualTo(now.toString());
|
||||
}
|
||||
|
||||
@Test // DATACMNS-606
|
||||
void convertsDateToLocalTime() {
|
||||
assertThat(CONVERSION_SERVICE.convert(NOW, LocalTime.class).toString()).isEqualTo(format(NOW, "HH:mm:ss.SSS"));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-606
|
||||
void convertsLocalTimeToDate() {
|
||||
|
||||
LocalTime now = LocalTime.now();
|
||||
assertThat(format(CONVERSION_SERVICE.convert(now, Date.class), "HH:mm:ss.SSS")).isEqualTo(now.toString());
|
||||
}
|
||||
|
||||
@Test // DATACMNS-623
|
||||
void convertsDateToInstant() {
|
||||
|
||||
Date now = new Date();
|
||||
assertThat(CONVERSION_SERVICE.convert(now, Instant.class)).isEqualTo(toInstant(now));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-623
|
||||
void convertsInstantToDate() {
|
||||
|
||||
Date now = new Date();
|
||||
assertThat(CONVERSION_SERVICE.convert(toInstant(now), Date.class)).isEqualTo(now);
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertsZoneIdToStringAndBack() {
|
||||
|
||||
Map<String, ZoneId> ids = new HashMap<>();
|
||||
ids.put("Europe/Berlin", ZoneId.of("Europe/Berlin"));
|
||||
ids.put("+06:00", ZoneId.of("+06:00"));
|
||||
|
||||
for (Entry<String, ZoneId> entry : ids.entrySet()) {
|
||||
assertThat(CONVERSION_SERVICE.convert(entry.getValue(), String.class)).isEqualTo(entry.getKey());
|
||||
assertThat(CONVERSION_SERVICE.convert(entry.getKey(), ZoneId.class)).isEqualTo(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private static String format(Date date, String format) {
|
||||
return new SimpleDateFormat(format).format(date);
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,8 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assumptions.*;
|
||||
import static org.springframework.test.util.ReflectionTestUtils.*;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -185,19 +181,6 @@ class QuerydslPredicateBuilderUnitTests {
|
||||
assertThat(constant.getConstant()).isEqualTo("rivers,two");
|
||||
}
|
||||
|
||||
@Test // DATACMNS-734
|
||||
void bindsDateCorrectly() throws ParseException {
|
||||
|
||||
DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd");
|
||||
String date = format.print(new DateTime());
|
||||
|
||||
values.add("dateOfBirth", format.print(new DateTime()));
|
||||
|
||||
Predicate predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS);
|
||||
|
||||
assertThat(predicate).isEqualTo(QUser.user.dateOfBirth.eq(format.parseDateTime(date).toDate()));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-883
|
||||
void automaticallyInsertsAnyStepInCollectionReference() {
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class MapDataBinderUnitTests {
|
||||
Date reference = new Date();
|
||||
|
||||
MutablePropertyValues values = new MutablePropertyValues();
|
||||
values.add("foo.date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(reference));
|
||||
values.add("foo.date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX").format(reference));
|
||||
|
||||
Map<String, Object> nested = new HashMap<>();
|
||||
nested.put("date", reference);
|
||||
|
||||
Reference in New Issue
Block a user