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.
This commit is contained in:
committed by
Oliver Gierke
parent
6675e33233
commit
139e098e85
@@ -16,7 +16,10 @@
|
||||
package org.springframework.data.history;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.util.AnnotationDetectionFieldCallback;
|
||||
@@ -26,15 +29,17 @@ import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* A {@link RevisionMetadata} implementation that inspects the given object for fields with the configured annotations
|
||||
* and returns the field's values on calls to {@link #getRevisionDate()} and {@link #getRevisionNumber()}.
|
||||
* and returns the field's values on calls to {@link #getRevisionDate()}, {@link #getRevisionInstant()} and
|
||||
* {@link #getRevisionNumber()}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
public class AnnotationRevisionMetadata<N extends Number & Comparable<N>> implements RevisionMetadata<N> {
|
||||
|
||||
private final Object entity;
|
||||
private final Lazy<Optional<N>> revisionNumber;
|
||||
private final Lazy<Optional<LocalDateTime>> revisionDate;
|
||||
private final Lazy<Optional<TemporalAccessor>> revisionDate;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AnnotationRevisionMetadata} inspecting the given entity for the given annotations. If no
|
||||
@@ -68,8 +73,44 @@ public class AnnotationRevisionMetadata<N extends Number & Comparable<N>> implem
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.history.RevisionMetadata#getRevisionDate()
|
||||
*/
|
||||
@Deprecated
|
||||
public Optional<LocalDateTime> getRevisionDate() {
|
||||
return revisionDate.get();
|
||||
|
||||
return revisionDate.get().map(this::convertToLocalDateTime);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.history.RevisionMetadata#getRevisionDate()
|
||||
*/
|
||||
public Optional<Instant> getRevisionInstant() {
|
||||
return revisionDate.get().map(this::convertToInstant);
|
||||
}
|
||||
|
||||
private LocalDateTime convertToLocalDateTime(TemporalAccessor temporalAccessor) {
|
||||
|
||||
if (temporalAccessor instanceof LocalDateTime) {
|
||||
return (LocalDateTime) temporalAccessor;
|
||||
}
|
||||
|
||||
if (temporalAccessor instanceof Instant) {
|
||||
return LocalDateTime.ofInstant((Instant) temporalAccessor, ZoneOffset.systemDefault());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Can't convert %s to LocalDateTime", temporalAccessor));
|
||||
}
|
||||
|
||||
private Instant convertToInstant(TemporalAccessor temporalAccessor) {
|
||||
|
||||
if (temporalAccessor instanceof Instant) {
|
||||
return (Instant) temporalAccessor;
|
||||
}
|
||||
|
||||
if (temporalAccessor instanceof LocalDateTime) {
|
||||
return ((LocalDateTime) temporalAccessor).atZone(ZoneOffset.systemDefault()).toInstant();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Can't convert %s to LocalDateTime", temporalAccessor));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,6 +22,7 @@ import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -33,6 +34,7 @@ import org.springframework.lang.Nullable;
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Huegelmeyer
|
||||
* @author Christoph Strobl
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
@Value
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@@ -80,21 +82,43 @@ public final class Revision<N extends Number & Comparable<N>, T> implements Comp
|
||||
/**
|
||||
* Returns the revision date of the revision.
|
||||
*
|
||||
* @return
|
||||
* @return Guaranteed to be not {@literal null}.
|
||||
* @deprecated Use {@link #getRevisionInstant()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public Optional<LocalDateTime> getRevisionDate() {
|
||||
return metadata.getRevisionDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timestamp of the revision.
|
||||
*
|
||||
* @return Guaranteed to be not {@literal null}.
|
||||
*/
|
||||
public Optional<Instant> getRevisionInstant() {
|
||||
return metadata.getRevisionInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the revision date of the revision, immediately failing on absence.
|
||||
*
|
||||
* @return the revision date.
|
||||
* @deprecated Use {@link #getRequiredRevisionInstant()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public LocalDateTime getRequiredRevisionDate() {
|
||||
return metadata.getRequiredRevisionDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timestamp of the revision, immediately failing on absence.
|
||||
*
|
||||
* @return the revision {@link Instant}. May be {@literal null}.
|
||||
*/
|
||||
public Instant getRequiredRevisionInstant() {
|
||||
return metadata.getRequiredRevisionInstant();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.history;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -23,6 +24,7 @@ import java.util.Optional;
|
||||
*
|
||||
* @author Philipp Huegelmeyer
|
||||
* @author Oliver Gierke
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
public interface RevisionMetadata<N extends Number & Comparable<N>> {
|
||||
|
||||
@@ -48,20 +50,43 @@ public interface RevisionMetadata<N extends Number & Comparable<N>> {
|
||||
* Returns the date of the revision.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
* @deprecated use {@link #getRevisionInstant()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
Optional<LocalDateTime> getRevisionDate();
|
||||
|
||||
/**
|
||||
* Returns the timestamp of the revision.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
Optional<Instant> getRevisionInstant();
|
||||
|
||||
/**
|
||||
* Returns the revision date of the revision, immediately failing on absence.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
* @throw IllegalStateException if no revision date is available.
|
||||
* @throws IllegalStateException if no revision date is available.
|
||||
* @deprecated Use {@link #getRevisionInstant()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default LocalDateTime getRequiredRevisionDate() {
|
||||
return getRevisionDate().orElseThrow(
|
||||
() -> new IllegalStateException(String.format("No revision date found on %s!", (Object) getDelegate())));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the timestamp of the revision, immediately failing on absence.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
* @throws IllegalStateException if no revision date is available.
|
||||
*/
|
||||
default Instant getRequiredRevisionInstant() {
|
||||
return getRevisionInstant().orElseThrow(
|
||||
() -> new IllegalStateException(String.format("No revision date found on %s!", (Object) getDelegate())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying revision metadata which might provider more detailed implementation specific information.
|
||||
*
|
||||
|
||||
@@ -17,8 +17,11 @@ 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;
|
||||
@@ -27,9 +30,12 @@ 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() {
|
||||
|
||||
@@ -40,10 +46,14 @@ public class AnnotationRevisionMetadataUnitTests {
|
||||
assertThat(metadata.getRevisionDate()).isEmpty();
|
||||
|
||||
assertThatExceptionOfType(IllegalStateException.class) //
|
||||
.isThrownBy(() -> metadata.getRequiredRevisionNumber());
|
||||
.isThrownBy(metadata::getRequiredRevisionNumber);
|
||||
|
||||
assertThatExceptionOfType(IllegalStateException.class) //
|
||||
.isThrownBy(() -> metadata.getRequiredRevisionDate());
|
||||
.isThrownBy(metadata::getRequiredRevisionDate);
|
||||
|
||||
assertThatExceptionOfType(IllegalStateException.class) //
|
||||
.isThrownBy(metadata::getRequiredRevisionInstant);
|
||||
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1173
|
||||
@@ -54,23 +64,49 @@ public class AnnotationRevisionMetadataUnitTests {
|
||||
|
||||
RevisionMetadata<Long> metadata = getMetadata(sample);
|
||||
|
||||
assertThat(metadata.getRevisionNumber()).hasValue(1L);
|
||||
assertThat(metadata.getRequiredRevisionNumber()).isEqualTo(1L);
|
||||
softly.assertThat(metadata.getRevisionNumber()).hasValue(1L);
|
||||
softly.assertThat(metadata.getRequiredRevisionNumber()).isEqualTo(1L);
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1173
|
||||
public void exposesRevisionDate() {
|
||||
public void exposesRevisionDateAndInstantForLocalDateTime() {
|
||||
|
||||
Sample sample = new Sample();
|
||||
sample.revisionDate = LocalDateTime.now();
|
||||
Instant expectedInstant = sample.revisionDate.atZone(ZoneOffset.systemDefault()).toInstant();
|
||||
|
||||
RevisionMetadata<Long> metadata = getMetadata(sample);
|
||||
|
||||
assertThat(metadata.getRevisionDate()).hasValue(sample.revisionDate);
|
||||
assertThat(metadata.getRequiredRevisionDate()).isEqualTo(sample.revisionDate);
|
||||
softly.assertThat(metadata.getRevisionDate()).hasValue(sample.revisionDate);
|
||||
softly.assertThat(metadata.getRequiredRevisionDate()).isEqualTo(sample.revisionDate);
|
||||
|
||||
softly.assertThat(metadata.getRevisionInstant()).hasValue(expectedInstant);
|
||||
softly.assertThat(metadata.getRequiredRevisionInstant()).isEqualTo(expectedInstant);
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
private static RevisionMetadata<Long> getMetadata(Sample sample) {
|
||||
@Test // DATACMNS-1251
|
||||
public void exposesRevisionDateAndInstantForInstant() {
|
||||
|
||||
SampleWithInstant sample = new SampleWithInstant();
|
||||
sample.revisionInstant = Instant.now();
|
||||
LocalDateTime expectedLocalDateTime = LocalDateTime.ofInstant(sample.revisionInstant, ZoneOffset.systemDefault());
|
||||
|
||||
RevisionMetadata<Long> metadata = getMetadata(sample);
|
||||
|
||||
softly.assertThat(metadata.getRevisionDate()).hasValue(expectedLocalDateTime);
|
||||
softly.assertThat(metadata.getRequiredRevisionDate()).isEqualTo(expectedLocalDateTime);
|
||||
|
||||
softly.assertThat(metadata.getRevisionInstant()).hasValue(sample.revisionInstant);
|
||||
softly.assertThat(metadata.getRequiredRevisionInstant()).isEqualTo(sample.revisionInstant);
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
private static RevisionMetadata<Long> getMetadata(Object sample) {
|
||||
return new AnnotationRevisionMetadata<>(sample, Autowired.class, Reference.class);
|
||||
}
|
||||
|
||||
@@ -79,4 +115,10 @@ public class AnnotationRevisionMetadataUnitTests {
|
||||
@Autowired Long revisionNumber;
|
||||
@Reference LocalDateTime revisionDate;
|
||||
}
|
||||
|
||||
static class SampleWithInstant {
|
||||
|
||||
@Autowired Long revisionNumber;
|
||||
@Reference Instant revisionInstant;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.history;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -33,6 +34,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
* Unit tests for {@link RevisionMetadata}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RevisionUnitTests {
|
||||
@@ -72,6 +74,15 @@ public class RevisionUnitTests {
|
||||
assertThat(Revision.of(firstMetadata, new Object()).getRevisionDate()).isEqualTo(reference);
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1251
|
||||
public void returnsRevisionInstant() {
|
||||
|
||||
Optional<Instant> reference = Optional.of(Instant.now());
|
||||
when(firstMetadata.getRevisionInstant()).thenReturn(reference);
|
||||
|
||||
assertThat(Revision.of(firstMetadata, new Object()).getRevisionInstant()).isEqualTo(reference);
|
||||
}
|
||||
|
||||
@Test // DATACMNS-218
|
||||
public void returnsRevisionMetadata() {
|
||||
assertThat(Revision.of(firstMetadata, new Object()).getMetadata()).isEqualTo(firstMetadata);
|
||||
|
||||
Reference in New Issue
Block a user