diff --git a/src/main/java/org/springframework/data/auditing/AuditableBeanWrapper.java b/src/main/java/org/springframework/data/auditing/AuditableBeanWrapper.java index c086f1ef3..6cd77895a 100644 --- a/src/main/java/org/springframework/data/auditing/AuditableBeanWrapper.java +++ b/src/main/java/org/springframework/data/auditing/AuditableBeanWrapper.java @@ -31,21 +31,21 @@ public interface AuditableBeanWrapper { * * @param value */ - Optional setCreatedBy(Optional value); + Object setCreatedBy(Object value); /** * Set the date the object was created. * * @param value */ - Optional setCreatedDate(Optional value); + TemporalAccessor setCreatedDate(TemporalAccessor value); /** * Set the last modifier of the object. * * @param value */ - Optional setLastModifiedBy(Optional value); + Object setLastModifiedBy(Object value); /** * Returns the date of the last modification date of the backing bean. @@ -60,5 +60,5 @@ public interface AuditableBeanWrapper { * * @param value */ - Optional setLastModifiedDate(Optional value); + TemporalAccessor setLastModifiedDate(TemporalAccessor value); } diff --git a/src/main/java/org/springframework/data/auditing/AuditingHandler.java b/src/main/java/org/springframework/data/auditing/AuditingHandler.java index 8acebbcf8..cdb69f919 100644 --- a/src/main/java/org/springframework/data/auditing/AuditingHandler.java +++ b/src/main/java/org/springframework/data/auditing/AuditingHandler.java @@ -157,11 +157,14 @@ public class AuditingHandler implements InitializingBean { Optional auditor = touchAuditor(it, isNew); Optional now = dateTimeForNow ? touchDate(it, isNew) : Optional.empty(); - Object defaultedNow = now.map(Object::toString).orElse("not set"); - Object defaultedAuditor = auditor.map(Object::toString).orElse("unknown"); + if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Touched {} - Last modification at {} by {}", - new Object[] { target, defaultedNow, defaultedAuditor }); + Object defaultedNow = now.map(Object::toString).orElse("not set"); + Object defaultedAuditor = auditor.map(Object::toString).orElse("unknown"); + + LOGGER.debug("Touched {} - Last modification at {} by {}", + new Object[] { target, defaultedNow, defaultedAuditor }); + } }); } @@ -177,14 +180,10 @@ public class AuditingHandler implements InitializingBean { Optional auditor = it.getCurrentAuditor(); - if (isNew) { - wrapper.setCreatedBy(auditor); - if (!modifyOnCreation) { - return auditor; - } - } + auditor.filter(__ -> isNew).ifPresent(foo -> wrapper.setCreatedBy(foo)); + auditor.filter(__ -> !isNew || modifyOnCreation).ifPresent(foo -> wrapper.setLastModifiedBy(foo)); - return wrapper.setLastModifiedBy(auditor); + return auditor; }); } @@ -199,14 +198,10 @@ public class AuditingHandler implements InitializingBean { Optional now = dateTimeProvider.getNow(); - if (isNew) { - wrapper.setCreatedDate(now); - if (!modifyOnCreation) { - return now; - } - } + now.filter(__ -> isNew).ifPresent(it -> wrapper.setCreatedDate(it)); + now.filter(__ -> !isNew || modifyOnCreation).ifPresent(it -> wrapper.setLastModifiedDate(it)); - return wrapper.setLastModifiedDate(now); + return now; } /* diff --git a/src/main/java/org/springframework/data/auditing/DefaultAuditableBeanWrapperFactory.java b/src/main/java/org/springframework/data/auditing/DefaultAuditableBeanWrapperFactory.java index 922815b72..44c69d8e7 100644 --- a/src/main/java/org/springframework/data/auditing/DefaultAuditableBeanWrapperFactory.java +++ b/src/main/java/org/springframework/data/auditing/DefaultAuditableBeanWrapperFactory.java @@ -94,10 +94,9 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedBy(java.util.Optional) */ @Override - public Optional setCreatedBy(Optional value) { + public Object setCreatedBy(Object value) { auditable.setCreatedBy(value); - return value; } @@ -106,9 +105,10 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedDate(java.util.Optional) */ @Override - public Optional setCreatedDate(Optional value) { + public TemporalAccessor setCreatedDate(TemporalAccessor value) { - auditable.setCreatedDate(getAsTemporalAccessor(value, type)); + auditable.setCreatedDate( + getAsTemporalAccessor(Optional.of(value), type).orElseThrow(() -> new IllegalStateException())); return value; } @@ -118,7 +118,8 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @see org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.AuditableInterfaceBeanWrapper#setLastModifiedBy(java.util.Optional) */ @Override - public Optional setLastModifiedBy(Optional value) { + public Object setLastModifiedBy(Object value) { + auditable.setLastModifiedBy(value); return value; @@ -138,9 +139,10 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedDate(java.util.Optional) */ @Override - public Optional setLastModifiedDate(Optional value) { + public TemporalAccessor setLastModifiedDate(TemporalAccessor value) { - auditable.setLastModifiedDate(getAsTemporalAccessor(value, type)); + auditable.setLastModifiedDate( + getAsTemporalAccessor(Optional.of(value), type).orElseThrow(() -> new IllegalStateException())); return value; } @@ -179,33 +181,30 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @param source must not be {@literal null}. * @return */ - protected Optional getDateValueToSet(Optional value, Class targetType, Object source) { + protected Object getDateValueToSet(TemporalAccessor value, Class targetType, Object source) { - return value.map(it -> { + if (TemporalAccessor.class.equals(targetType)) { + return value; + } - if (TemporalAccessor.class.equals(targetType)) { - return it; + if (conversionService.canConvert(value.getClass(), targetType)) { + return conversionService.convert(value, targetType); + } + + if (conversionService.canConvert(Date.class, targetType)) { + + if (!conversionService.canConvert(value.getClass(), Date.class)) { + throw new IllegalArgumentException( + String.format("Cannot convert date type for member %s! From %s to java.util.Date to %s.", source, + value.getClass(), targetType)); } - if (conversionService.canConvert(it.getClass(), targetType)) { - return conversionService.convert(it, targetType); - } + Date date = conversionService.convert(value, Date.class); + return conversionService.convert(date, targetType); + } - if (conversionService.canConvert(Date.class, targetType)) { - - if (!conversionService.canConvert(it.getClass(), Date.class)) { - throw new IllegalArgumentException( - String.format("Cannot convert date type for member %s! From %s to java.util.Date to %s.", source, - it.getClass(), targetType)); - } - - Date date = conversionService.convert(it, Date.class); - return conversionService.convert(date, targetType); - } - - throw new IllegalArgumentException(String.format("Invalid date type for member %s! Supported types are %s.", - source, AnnotationAuditingMetadata.SUPPORTED_DATE_TYPES)); - }); + throw new IllegalArgumentException(String.format("Invalid date type for member %s! Supported types are %s.", + source, AnnotationAuditingMetadata.SUPPORTED_DATE_TYPES)); } /** @@ -215,8 +214,8 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @return */ @SuppressWarnings("unchecked") - protected Optional getAsTemporalAccessor(Optional source, Class target) { - + protected Optional getAsTemporalAccessor(Optional source, + Class target) { return source.map(it -> target.isInstance(it) ? (T) it : conversionService.convert(it, target)); } } @@ -249,7 +248,7 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedBy(java.util.Optional) */ @Override - public Optional setCreatedBy(Optional value) { + public Object setCreatedBy(Object value) { return setField(metadata.getCreatedByField(), value); } @@ -258,7 +257,8 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedDate(java.util.Optional) */ @Override - public Optional setCreatedDate(Optional value) { + public TemporalAccessor setCreatedDate(TemporalAccessor value) { + return setDateField(metadata.getCreatedDateField(), value); } @@ -267,7 +267,7 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedBy(java.util.Optional) */ @Override - public Optional setLastModifiedBy(Optional value) { + public Object setLastModifiedBy(Object value) { return setField(metadata.getLastModifiedByField(), value); } @@ -291,7 +291,7 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedDate(java.util.Optional) */ @Override - public Optional setLastModifiedDate(Optional value) { + public TemporalAccessor setLastModifiedDate(TemporalAccessor value) { return setDateField(metadata.getLastModifiedDateField(), value); } @@ -301,10 +301,9 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @param field * @param value */ - private Optional setField(Optional field, Optional value) { + private T setField(Optional field, T value) { - field.ifPresent(it -> ReflectionUtils.setField(it, target, - Optional.class.isAssignableFrom(it.getType()) ? value : value.orElse(null))); + field.ifPresent(it -> ReflectionUtils.setField(it, target, value)); return value; } @@ -315,13 +314,9 @@ class DefaultAuditableBeanWrapperFactory implements AuditableBeanWrapperFactory * @param field * @param value */ - private Optional setDateField(Optional field, Optional value) { + private TemporalAccessor setDateField(Optional field, TemporalAccessor value) { - field.ifPresent(it -> { - Optional toSet = getDateValueToSet(value, it.getType(), it); - ReflectionUtils.setField(it, target, - Optional.class.isAssignableFrom(it.getType()) ? toSet : toSet.orElse(null)); - }); + field.ifPresent(it -> ReflectionUtils.setField(it, target, getDateValueToSet(value, it.getType(), it))); return value; } diff --git a/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java b/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java index 1c10e47b6..d302fc681 100644 --- a/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java +++ b/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java @@ -15,6 +15,7 @@ */ package org.springframework.data.auditing; +import java.time.LocalDateTime; import java.time.temporal.TemporalAccessor; import java.util.HashMap; import java.util.Map; @@ -158,9 +159,9 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap * @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedBy(java.util.Optional) */ @Override - public Optional setCreatedBy(Optional value) { + public Object setCreatedBy(Object value) { - metadata.createdByProperty.ifPresent(it -> this.accessor.setProperty(it, value)); + metadata.createdByProperty.ifPresent(it -> this.accessor.setProperty(it, Optional.of(value))); return value; } @@ -170,12 +171,8 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap * @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedDate(java.util.Optional) */ @Override - public Optional setCreatedDate(Optional value) { - - metadata.createdDateProperty - .ifPresent(it -> this.accessor.setProperty(it, getDateValueToSet(value, it.getType(), it))); - - return value; + public TemporalAccessor setCreatedDate(TemporalAccessor value) { + return setDateProperty(metadata.createdDateProperty, value); } /* @@ -183,11 +180,8 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap * @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedBy(java.util.Optional) */ @Override - public Optional setLastModifiedBy(Optional value) { - - metadata.lastModifiedByProperty.ifPresent(it -> this.accessor.setProperty(it, value)); - - return value; + public Object setLastModifiedBy(Object value) { + return setProperty(metadata.lastModifiedByProperty, value); } /* @@ -196,8 +190,8 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap */ @Override public Optional getLastModifiedDate() { - return getAsTemporalAccessor(metadata.lastModifiedDateProperty.map(accessor::getProperty), - TemporalAccessor.class); + return getAsTemporalAccessor(metadata.lastModifiedDateProperty.flatMap(accessor::getProperty), + LocalDateTime.class); } /* @@ -205,10 +199,22 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap * @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedDate(java.util.Optional) */ @Override - public Optional setLastModifiedDate(Optional value) { + public TemporalAccessor setLastModifiedDate(TemporalAccessor value) { + return setDateProperty(metadata.lastModifiedDateProperty, value); + } - metadata.lastModifiedDateProperty - .ifPresent(it -> this.accessor.setProperty(it, getDateValueToSet(value, it.getType(), it))); + private > T setProperty(Optional

property, T value) { + + property.ifPresent(it -> this.accessor.setProperty(it, Optional.of(value))); + + return value; + } + + private

> TemporalAccessor setDateProperty(Optional

property, + TemporalAccessor value) { + + property.ifPresent( + it -> this.accessor.setProperty(it, Optional.of(getDateValueToSet(value, it.getType(), accessor.getBean())))); return value; } diff --git a/src/main/java/org/springframework/data/domain/Auditable.java b/src/main/java/org/springframework/data/domain/Auditable.java index 04aae732a..5d7bc9848 100644 --- a/src/main/java/org/springframework/data/domain/Auditable.java +++ b/src/main/java/org/springframework/data/domain/Auditable.java @@ -41,7 +41,7 @@ public interface Auditable createdBy); + void setCreatedBy(U createdBy); /** * Returns the creation date of the entity. @@ -55,7 +55,7 @@ public interface Auditable creationDate); + void setCreatedDate(T creationDate); /** * Returns the user who modified the entity lastly. @@ -69,7 +69,7 @@ public interface Auditable lastModifiedBy); + void setLastModifiedBy(U lastModifiedBy); /** * Returns the date of the last modification. @@ -83,5 +83,5 @@ public interface Auditable lastModifiedDate); + void setLastModifiedDate(T lastModifiedDate); } diff --git a/src/test/java/org/springframework/data/auditing/AuditedUser.java b/src/test/java/org/springframework/data/auditing/AuditedUser.java index 0382e7f04..cef8cd880 100644 --- a/src/test/java/org/springframework/data/auditing/AuditedUser.java +++ b/src/test/java/org/springframework/data/auditing/AuditedUser.java @@ -48,31 +48,31 @@ class AuditedUser implements Auditable { return Optional.ofNullable(createdBy); } - public void setCreatedBy(Optional createdBy) { - this.createdBy = createdBy.orElse(null); + public void setCreatedBy(AuditedUser createdBy) { + this.createdBy = createdBy; } public Optional getCreatedDate() { return Optional.ofNullable(createdDate); } - public void setCreatedDate(Optional creationDate) { - this.createdDate = creationDate.orElse(null); + public void setCreatedDate(LocalDateTime creationDate) { + this.createdDate = creationDate; } public Optional getLastModifiedBy() { return Optional.ofNullable(modifiedBy); } - public void setLastModifiedBy(Optional lastModifiedBy) { - this.modifiedBy = lastModifiedBy.orElse(null); + public void setLastModifiedBy(AuditedUser lastModifiedBy) { + this.modifiedBy = lastModifiedBy; } public Optional getLastModifiedDate() { return Optional.ofNullable(modifiedDate); } - public void setLastModifiedDate(Optional lastModifiedDate) { - this.modifiedDate = lastModifiedDate.orElse(null); + public void setLastModifiedDate(LocalDateTime lastModifiedDate) { + this.modifiedDate = lastModifiedDate; } } diff --git a/src/test/java/org/springframework/data/auditing/DefaultAuditableBeanWrapperFactoryUnitTests.java b/src/test/java/org/springframework/data/auditing/DefaultAuditableBeanWrapperFactoryUnitTests.java index 717dc113c..6430248ab 100755 --- a/src/test/java/org/springframework/data/auditing/DefaultAuditableBeanWrapperFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/auditing/DefaultAuditableBeanWrapperFactoryUnitTests.java @@ -70,13 +70,12 @@ public class DefaultAuditableBeanWrapperFactoryUnitTests { assertThat(wrapper).hasValueSatisfying(it -> { - it.setCreatedDate(Optional.of(instant)); - it.setLastModifiedDate(Optional.of(instant)); + it.setCreatedDate(instant); + it.setLastModifiedDate(instant); assertThat(user.createdDate).isNotNull(); assertThat(user.lastModifiedDate).isNotNull(); }); - } @Test(expected = IllegalArgumentException.class) // DATACMNS-867 @@ -87,6 +86,6 @@ public class DefaultAuditableBeanWrapperFactoryUnitTests { Optional wrapper = factory.getBeanWrapperFor(user); - assertThat(wrapper).hasValueSatisfying(it -> it.setLastModifiedDate(Optional.of(zonedDateTime))); + assertThat(wrapper).hasValueSatisfying(it -> it.setLastModifiedDate(zonedDateTime)); } } diff --git a/src/test/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactoryUnitTests.java b/src/test/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactoryUnitTests.java index 91448cb44..69dec3a07 100755 --- a/src/test/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactoryUnitTests.java @@ -96,7 +96,7 @@ public class MappingAuditableBeanWrapperFactoryUnitTests { Optional wrapper = factory.getBeanWrapperFor(Optional.of(sample)); - assertThat(wrapper).hasValueSatisfying(it -> it.setLastModifiedDate(Optional.of(Instant.now()))); + assertThat(wrapper).hasValueSatisfying(it -> it.setLastModifiedDate(Instant.now())); } @Test // DATACMNS-365 @@ -107,7 +107,8 @@ public class MappingAuditableBeanWrapperFactoryUnitTests { @Test // DATACMNS-365 public void returnsAuditableWrapperForAuditable() { - assertThat(factory.getBeanWrapperFor(Optional.of(mock(ExtendingAuditable.class)))).hasValueSatisfying(it -> assertThat(it).isInstanceOf(AuditableInterfaceBeanWrapper.class)); + assertThat(factory.getBeanWrapperFor(Optional.of(mock(ExtendingAuditable.class)))) + .hasValueSatisfying(it -> assertThat(it).isInstanceOf(AuditableInterfaceBeanWrapper.class)); } @Test // DATACMNS-638 diff --git a/src/test/java/org/springframework/data/auditing/ReflectionAuditingBeanWrapperUnitTests.java b/src/test/java/org/springframework/data/auditing/ReflectionAuditingBeanWrapperUnitTests.java index efdcd589d..6345a3d60 100755 --- a/src/test/java/org/springframework/data/auditing/ReflectionAuditingBeanWrapperUnitTests.java +++ b/src/test/java/org/springframework/data/auditing/ReflectionAuditingBeanWrapperUnitTests.java @@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.*; import java.time.LocalDateTime; import java.time.ZoneOffset; -import java.util.Optional; import org.joda.time.DateTime; import org.junit.Before; @@ -53,14 +52,14 @@ public class ReflectionAuditingBeanWrapperUnitTests { @Test public void setsDateTimeFieldCorrectly() { - wrapper.setCreatedDate(Optional.of(time)); + wrapper.setCreatedDate(time); assertThat(user.createdDate).isEqualTo(new DateTime(LocalDateTimeToDateConverter.INSTANCE.convert(time))); } @Test public void setsDateFieldCorrectly() { - wrapper.setLastModifiedDate(Optional.of(time)); + wrapper.setLastModifiedDate(time); assertThat(user.lastModifiedDate).isEqualTo(LocalDateTimeToDateConverter.INSTANCE.convert(time)); } @@ -77,10 +76,10 @@ public class ReflectionAuditingBeanWrapperUnitTests { Sample sample = new Sample(); AuditableBeanWrapper wrapper = new ReflectionAuditingBeanWrapper(sample); - wrapper.setCreatedDate(Optional.of(time)); + wrapper.setCreatedDate(time); assertThat(sample.createdDate).isEqualTo(time.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli()); - wrapper.setLastModifiedDate(Optional.of(time)); + wrapper.setLastModifiedDate(time); assertThat(sample.modifiedDate).isEqualTo(time.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli()); } @@ -89,10 +88,10 @@ public class ReflectionAuditingBeanWrapperUnitTests { Object object = new Object(); - wrapper.setCreatedBy(Optional.of(object)); + wrapper.setCreatedBy(object); assertThat(user.createdBy).isEqualTo(object); - wrapper.setLastModifiedBy(Optional.of(object)); + wrapper.setLastModifiedBy(object); assertThat(user.lastModifiedBy).isEqualTo(object); } }