diff --git a/src/main/java/org/springframework/data/history/AnnotationRevisionMetadata.java b/src/main/java/org/springframework/data/history/AnnotationRevisionMetadata.java index ae89a77b6..ab30f27d6 100755 --- a/src/main/java/org/springframework/data/history/AnnotationRevisionMetadata.java +++ b/src/main/java/org/springframework/data/history/AnnotationRevisionMetadata.java @@ -16,7 +16,9 @@ package org.springframework.data.history; import java.lang.annotation.Annotation; +import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.Optional; import org.springframework.data.util.AnnotationDetectionFieldCallback; @@ -29,12 +31,13 @@ import org.springframework.util.ReflectionUtils; * and returns the field's values on calls to {@link #getRevisionDate()} and {@link #getRevisionNumber()}. * * @author Oliver Gierke + * @author Jens Schauder */ public class AnnotationRevisionMetadata> implements RevisionMetadata { private final Object entity; private final Lazy> revisionNumber; - private final Lazy> revisionDate; + private final Lazy> revisionDate; /** * Creates a new {@link AnnotationRevisionMetadata} inspecting the given entity for the given annotations. If no @@ -69,7 +72,7 @@ public class AnnotationRevisionMetadata> implem * @see org.springframework.data.history.RevisionMetadata#getRevisionDate() */ public Optional getRevisionDate() { - return revisionDate.get(); + return revisionDate.get().map(AnnotationRevisionMetadata::convertToLocalDateTime); } /* @@ -90,4 +93,30 @@ public class AnnotationRevisionMetadata> implem return Optional.ofNullable(callback.getValue(entity)); }); } + + private static LocalDateTime convertToLocalDateTime(Object timestamp) { + + if (timestamp instanceof LocalDateTime) { + return (LocalDateTime) timestamp; + } + + return LocalDateTime.ofInstant(convertToInstant(timestamp), ZoneOffset.systemDefault()); + } + + private static Instant convertToInstant(Object timestamp) { + + if (timestamp instanceof Instant) { + return (Instant) timestamp; + } + + if (timestamp instanceof LocalDateTime) { + return ((LocalDateTime) timestamp).atZone(ZoneOffset.systemDefault()).toInstant(); + } + + if (timestamp instanceof Long) { + return Instant.ofEpochMilli((Long) timestamp); + } + + throw new IllegalArgumentException(String.format("Can't convert %s to Instant!", timestamp)); + } } diff --git a/src/test/java/org/springframework/data/history/AnnotationRevisionMetadataUnitTests.java b/src/test/java/org/springframework/data/history/AnnotationRevisionMetadataUnitTests.java index 8f5f0531a..93cbb38f3 100644 --- a/src/test/java/org/springframework/data/history/AnnotationRevisionMetadataUnitTests.java +++ b/src/test/java/org/springframework/data/history/AnnotationRevisionMetadataUnitTests.java @@ -17,19 +17,25 @@ package org.springframework.data.history; import static org.assertj.core.api.Assertions.*; +import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneOffset; +import org.assertj.core.api.SoftAssertions; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.annotation.Reference; /** * Unit tests for {@link AnnotationRevisionMetadata}. - * + * * @author Oliver Gierke + * @author Jens Schauder */ public class AnnotationRevisionMetadataUnitTests { + SoftAssertions softly = new SoftAssertions(); + @Test // DATACMNS-1173 public void exposesNoInformationOnEmptyProbe() { @@ -70,7 +76,39 @@ public class AnnotationRevisionMetadataUnitTests { assertThat(metadata.getRequiredRevisionDate()).isEqualTo(sample.revisionDate); } - private static RevisionMetadata getMetadata(Sample sample) { + @Test // DATACMNS-1251 + public void exposesRevisionDateForInstant() { + + SampleWithInstant sample = new SampleWithInstant(); + sample.revisionInstant = Instant.now(); + LocalDateTime expectedLocalDateTime = LocalDateTime.ofInstant(sample.revisionInstant, ZoneOffset.systemDefault()); + + RevisionMetadata metadata = getMetadata(sample); + + softly.assertThat(metadata.getRevisionDate()).hasValue(expectedLocalDateTime); + softly.assertThat(metadata.getRequiredRevisionDate()).isEqualTo(expectedLocalDateTime); + + softly.assertAll(); + } + + @Test // DATACMNS-1290 + public void exposesRevisionDateForLong() { + + SampleWithLong sample = new SampleWithLong(); + sample.revisionLong = 4711L; + + Instant expectedInstant = Instant.ofEpochMilli(sample.revisionLong); + LocalDateTime expectedLocalDateTime = LocalDateTime.ofInstant(expectedInstant, ZoneOffset.systemDefault()); + + RevisionMetadata metadata = getMetadata(sample); + + softly.assertThat(metadata.getRevisionDate()).hasValue(expectedLocalDateTime); + softly.assertThat(metadata.getRequiredRevisionDate()).isEqualTo(expectedLocalDateTime); + + softly.assertAll(); + } + + private static RevisionMetadata getMetadata(Object sample) { return new AnnotationRevisionMetadata<>(sample, Autowired.class, Reference.class); } @@ -79,4 +117,16 @@ public class AnnotationRevisionMetadataUnitTests { @Autowired Long revisionNumber; @Reference LocalDateTime revisionDate; } + + static class SampleWithInstant { + + @Autowired Long revisionNumber; + @Reference Instant revisionInstant; + } + + static class SampleWithLong { + + @Autowired Long revisionNumber; + @Reference long revisionLong; + } }