Skip to content

Commit 139e098

Browse files
schauderodrotbohm
authored andcommitted
DATACMNS-1251 - Added methods returning Instant to Revision.
Revision and RevisionMetadata now have methods returning Instant instead of LocalDateTime. The existing methods returning LocalDateTime are now deprecated. Original pull request: #270.
1 parent 6675e33 commit 139e098

File tree

5 files changed

+156
-13
lines changed

5 files changed

+156
-13
lines changed

src/main/java/org/springframework/data/history/AnnotationRevisionMetadata.java

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
package org.springframework.data.history;
1717

1818
import java.lang.annotation.Annotation;
19+
import java.time.Instant;
1920
import java.time.LocalDateTime;
21+
import java.time.ZoneOffset;
22+
import java.time.temporal.TemporalAccessor;
2023
import java.util.Optional;
2124

2225
import org.springframework.data.util.AnnotationDetectionFieldCallback;
@@ -26,15 +29,17 @@
2629

2730
/**
2831
* A {@link RevisionMetadata} implementation that inspects the given object for fields with the configured annotations
29-
* and returns the field's values on calls to {@link #getRevisionDate()} and {@link #getRevisionNumber()}.
32+
* and returns the field's values on calls to {@link #getRevisionDate()}, {@link #getRevisionInstant()} and
33+
* {@link #getRevisionNumber()}.
3034
*
3135
* @author Oliver Gierke
36+
* @author Jens Schauder
3237
*/
3338
public class AnnotationRevisionMetadata<N extends Number & Comparable<N>> implements RevisionMetadata<N> {
3439

3540
private final Object entity;
3641
private final Lazy<Optional<N>> revisionNumber;
37-
private final Lazy<Optional<LocalDateTime>> revisionDate;
42+
private final Lazy<Optional<TemporalAccessor>> revisionDate;
3843

3944
/**
4045
* Creates a new {@link AnnotationRevisionMetadata} inspecting the given entity for the given annotations. If no
@@ -68,8 +73,44 @@ public Optional<N> getRevisionNumber() {
6873
* (non-Javadoc)
6974
* @see org.springframework.data.history.RevisionMetadata#getRevisionDate()
7075
*/
76+
@Deprecated
7177
public Optional<LocalDateTime> getRevisionDate() {
72-
return revisionDate.get();
78+
79+
return revisionDate.get().map(this::convertToLocalDateTime);
80+
}
81+
82+
/*
83+
* (non-Javadoc)
84+
* @see org.springframework.data.history.RevisionMetadata#getRevisionDate()
85+
*/
86+
public Optional<Instant> getRevisionInstant() {
87+
return revisionDate.get().map(this::convertToInstant);
88+
}
89+
90+
private LocalDateTime convertToLocalDateTime(TemporalAccessor temporalAccessor) {
91+
92+
if (temporalAccessor instanceof LocalDateTime) {
93+
return (LocalDateTime) temporalAccessor;
94+
}
95+
96+
if (temporalAccessor instanceof Instant) {
97+
return LocalDateTime.ofInstant((Instant) temporalAccessor, ZoneOffset.systemDefault());
98+
}
99+
100+
throw new IllegalArgumentException(String.format("Can't convert %s to LocalDateTime", temporalAccessor));
101+
}
102+
103+
private Instant convertToInstant(TemporalAccessor temporalAccessor) {
104+
105+
if (temporalAccessor instanceof Instant) {
106+
return (Instant) temporalAccessor;
107+
}
108+
109+
if (temporalAccessor instanceof LocalDateTime) {
110+
return ((LocalDateTime) temporalAccessor).atZone(ZoneOffset.systemDefault()).toInstant();
111+
}
112+
113+
throw new IllegalArgumentException(String.format("Can't convert %s to LocalDateTime", temporalAccessor));
73114
}
74115

75116
/*

src/main/java/org/springframework/data/history/Revision.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import lombok.RequiredArgsConstructor;
2323
import lombok.Value;
2424

25+
import java.time.Instant;
2526
import java.time.LocalDateTime;
2627
import java.util.Optional;
2728

@@ -33,6 +34,7 @@
3334
* @author Oliver Gierke
3435
* @author Philipp Huegelmeyer
3536
* @author Christoph Strobl
37+
* @author Jens Schauder
3638
*/
3739
@Value
3840
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@@ -80,21 +82,43 @@ public N getRequiredRevisionNumber() {
8082
/**
8183
* Returns the revision date of the revision.
8284
*
83-
* @return
85+
* @return Guaranteed to be not {@literal null}.
86+
* @deprecated Use {@link #getRevisionInstant()} instead.
8487
*/
88+
@Deprecated
8589
public Optional<LocalDateTime> getRevisionDate() {
8690
return metadata.getRevisionDate();
8791
}
8892

93+
/**
94+
* Returns the timestamp of the revision.
95+
*
96+
* @return Guaranteed to be not {@literal null}.
97+
*/
98+
public Optional<Instant> getRevisionInstant() {
99+
return metadata.getRevisionInstant();
100+
}
101+
89102
/**
90103
* Returns the revision date of the revision, immediately failing on absence.
91104
*
92105
* @return the revision date.
106+
* @deprecated Use {@link #getRequiredRevisionInstant()} instead.
93107
*/
108+
@Deprecated
94109
public LocalDateTime getRequiredRevisionDate() {
95110
return metadata.getRequiredRevisionDate();
96111
}
97112

113+
/**
114+
* Returns the timestamp of the revision, immediately failing on absence.
115+
*
116+
* @return the revision {@link Instant}. May be {@literal null}.
117+
*/
118+
public Instant getRequiredRevisionInstant() {
119+
return metadata.getRequiredRevisionInstant();
120+
}
121+
98122
/*
99123
* (non-Javadoc)
100124
* @see java.lang.Comparable#compareTo(java.lang.Object)

src/main/java/org/springframework/data/history/RevisionMetadata.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.history;
1717

18+
import java.time.Instant;
1819
import java.time.LocalDateTime;
1920
import java.util.Optional;
2021

@@ -23,6 +24,7 @@
2324
*
2425
* @author Philipp Huegelmeyer
2526
* @author Oliver Gierke
27+
* @author Jens Schauder
2628
*/
2729
public interface RevisionMetadata<N extends Number & Comparable<N>> {
2830

@@ -48,20 +50,43 @@ default N getRequiredRevisionNumber() {
4850
* Returns the date of the revision.
4951
*
5052
* @return will never be {@literal null}.
53+
* @deprecated use {@link #getRevisionInstant()} instead.
5154
*/
55+
@Deprecated
5256
Optional<LocalDateTime> getRevisionDate();
5357

58+
/**
59+
* Returns the timestamp of the revision.
60+
*
61+
* @return will never be {@literal null}.
62+
*/
63+
Optional<Instant> getRevisionInstant();
64+
5465
/**
5566
* Returns the revision date of the revision, immediately failing on absence.
5667
*
5768
* @return will never be {@literal null}.
58-
* @throw IllegalStateException if no revision date is available.
69+
* @throws IllegalStateException if no revision date is available.
70+
* @deprecated Use {@link #getRevisionInstant()} instead.
5971
*/
72+
@Deprecated
6073
default LocalDateTime getRequiredRevisionDate() {
6174
return getRevisionDate().orElseThrow(
6275
() -> new IllegalStateException(String.format("No revision date found on %s!", (Object) getDelegate())));
6376
}
6477

78+
79+
/**
80+
* Returns the timestamp of the revision, immediately failing on absence.
81+
*
82+
* @return will never be {@literal null}.
83+
* @throws IllegalStateException if no revision date is available.
84+
*/
85+
default Instant getRequiredRevisionInstant() {
86+
return getRevisionInstant().orElseThrow(
87+
() -> new IllegalStateException(String.format("No revision date found on %s!", (Object) getDelegate())));
88+
}
89+
6590
/**
6691
* Returns the underlying revision metadata which might provider more detailed implementation specific information.
6792
*

src/test/java/org/springframework/data/history/AnnotationRevisionMetadataUnitTests.java

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717

1818
import static org.assertj.core.api.Assertions.*;
1919

20+
import java.time.Instant;
2021
import java.time.LocalDateTime;
22+
import java.time.ZoneOffset;
2123

24+
import org.assertj.core.api.SoftAssertions;
2225
import org.junit.Test;
2326
import org.springframework.beans.factory.annotation.Autowired;
2427
import org.springframework.data.annotation.Reference;
@@ -27,9 +30,12 @@
2730
* Unit tests for {@link AnnotationRevisionMetadata}.
2831
*
2932
* @author Oliver Gierke
33+
* @author Jens Schauder
3034
*/
3135
public class AnnotationRevisionMetadataUnitTests {
3236

37+
SoftAssertions softly = new SoftAssertions();
38+
3339
@Test // DATACMNS-1173
3440
public void exposesNoInformationOnEmptyProbe() {
3541

@@ -40,10 +46,14 @@ public void exposesNoInformationOnEmptyProbe() {
4046
assertThat(metadata.getRevisionDate()).isEmpty();
4147

4248
assertThatExceptionOfType(IllegalStateException.class) //
43-
.isThrownBy(() -> metadata.getRequiredRevisionNumber());
49+
.isThrownBy(metadata::getRequiredRevisionNumber);
50+
51+
assertThatExceptionOfType(IllegalStateException.class) //
52+
.isThrownBy(metadata::getRequiredRevisionDate);
4453

4554
assertThatExceptionOfType(IllegalStateException.class) //
46-
.isThrownBy(() -> metadata.getRequiredRevisionDate());
55+
.isThrownBy(metadata::getRequiredRevisionInstant);
56+
4757
}
4858

4959
@Test // DATACMNS-1173
@@ -54,23 +64,49 @@ public void exposesRevisionNumber() {
5464

5565
RevisionMetadata<Long> metadata = getMetadata(sample);
5666

57-
assertThat(metadata.getRevisionNumber()).hasValue(1L);
58-
assertThat(metadata.getRequiredRevisionNumber()).isEqualTo(1L);
67+
softly.assertThat(metadata.getRevisionNumber()).hasValue(1L);
68+
softly.assertThat(metadata.getRequiredRevisionNumber()).isEqualTo(1L);
69+
70+
softly.assertAll();
5971
}
6072

6173
@Test // DATACMNS-1173
62-
public void exposesRevisionDate() {
74+
public void exposesRevisionDateAndInstantForLocalDateTime() {
6375

6476
Sample sample = new Sample();
6577
sample.revisionDate = LocalDateTime.now();
78+
Instant expectedInstant = sample.revisionDate.atZone(ZoneOffset.systemDefault()).toInstant();
6679

6780
RevisionMetadata<Long> metadata = getMetadata(sample);
6881

69-
assertThat(metadata.getRevisionDate()).hasValue(sample.revisionDate);
70-
assertThat(metadata.getRequiredRevisionDate()).isEqualTo(sample.revisionDate);
82+
softly.assertThat(metadata.getRevisionDate()).hasValue(sample.revisionDate);
83+
softly.assertThat(metadata.getRequiredRevisionDate()).isEqualTo(sample.revisionDate);
84+
85+
softly.assertThat(metadata.getRevisionInstant()).hasValue(expectedInstant);
86+
softly.assertThat(metadata.getRequiredRevisionInstant()).isEqualTo(expectedInstant);
87+
88+
softly.assertAll();
7189
}
7290

73-
private static RevisionMetadata<Long> getMetadata(Sample sample) {
91+
@Test // DATACMNS-1251
92+
public void exposesRevisionDateAndInstantForInstant() {
93+
94+
SampleWithInstant sample = new SampleWithInstant();
95+
sample.revisionInstant = Instant.now();
96+
LocalDateTime expectedLocalDateTime = LocalDateTime.ofInstant(sample.revisionInstant, ZoneOffset.systemDefault());
97+
98+
RevisionMetadata<Long> metadata = getMetadata(sample);
99+
100+
softly.assertThat(metadata.getRevisionDate()).hasValue(expectedLocalDateTime);
101+
softly.assertThat(metadata.getRequiredRevisionDate()).isEqualTo(expectedLocalDateTime);
102+
103+
softly.assertThat(metadata.getRevisionInstant()).hasValue(sample.revisionInstant);
104+
softly.assertThat(metadata.getRequiredRevisionInstant()).isEqualTo(sample.revisionInstant);
105+
106+
softly.assertAll();
107+
}
108+
109+
private static RevisionMetadata<Long> getMetadata(Object sample) {
74110
return new AnnotationRevisionMetadata<>(sample, Autowired.class, Reference.class);
75111
}
76112

@@ -79,4 +115,10 @@ static class Sample {
79115
@Autowired Long revisionNumber;
80116
@Reference LocalDateTime revisionDate;
81117
}
118+
119+
static class SampleWithInstant {
120+
121+
@Autowired Long revisionNumber;
122+
@Reference Instant revisionInstant;
123+
}
82124
}

src/test/java/org/springframework/data/history/RevisionUnitTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.assertj.core.api.Assertions.*;
1919
import static org.mockito.Mockito.*;
2020

21+
import java.time.Instant;
2122
import java.time.LocalDateTime;
2223
import java.util.List;
2324
import java.util.Optional;
@@ -33,6 +34,7 @@
3334
* Unit tests for {@link RevisionMetadata}.
3435
*
3536
* @author Oliver Gierke
37+
* @author Jens Schauder
3638
*/
3739
@RunWith(MockitoJUnitRunner.class)
3840
public class RevisionUnitTests {
@@ -72,6 +74,15 @@ public void returnsRevisionDate() {
7274
assertThat(Revision.of(firstMetadata, new Object()).getRevisionDate()).isEqualTo(reference);
7375
}
7476

77+
@Test // DATACMNS-1251
78+
public void returnsRevisionInstant() {
79+
80+
Optional<Instant> reference = Optional.of(Instant.now());
81+
when(firstMetadata.getRevisionInstant()).thenReturn(reference);
82+
83+
assertThat(Revision.of(firstMetadata, new Object()).getRevisionInstant()).isEqualTo(reference);
84+
}
85+
7586
@Test // DATACMNS-218
7687
public void returnsRevisionMetadata() {
7788
assertThat(Revision.of(firstMetadata, new Object()).getMetadata()).isEqualTo(firstMetadata);

0 commit comments

Comments
 (0)