DATACMNS-638, DATACMNS-643 - Support for JSR-310 and ThreeTen datetime types.
Extend AuditableBeanWrapper to allow access to the last modification date of a target object. Made AuditableBeanWrapperFactory an interface and renamed what’s been previously known under this name as DefaultAuditableBeanWrapperFactory. The components previously relying on a MappingContext to lookup a PersistentEntity now use PersistentEntities to be able to back a collection of MappingContexts behind that and also avoid unmanaged types to be added to the MappingContext. We now also register the JSR-310 and ThreeTen back-port converters with the ConversionService to be able to get and set auditing dates as these types.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2014 the original author or authors.
|
||||
* Copyright 2008-2015 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.
|
||||
@@ -18,10 +18,13 @@ package org.springframework.data.auditing;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.data.mapping.context.SampleMappingContext;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
|
||||
/**
|
||||
* Unit test for {@code AuditingHandler}.
|
||||
@@ -48,7 +51,7 @@ public class AuditingHandlerUnitTests {
|
||||
}
|
||||
|
||||
protected AuditingHandler getHandler() {
|
||||
return new AuditingHandler(new SampleMappingContext());
|
||||
return new AuditingHandler(new PersistentEntities(Collections.<MappingContext<?, ?>> emptySet()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2012-2015 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.
|
||||
@@ -18,17 +18,21 @@ package org.springframework.data.auditing;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.auditing.AuditableBeanWrapperFactory.AuditableInterfaceBeanWrapper;
|
||||
import org.springframework.data.auditing.AuditableBeanWrapperFactory.ReflectionAuditingBeanWrapper;
|
||||
import org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.AuditableInterfaceBeanWrapper;
|
||||
import org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.ReflectionAuditingBeanWrapper;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DefaultAuditableBeanWrapperFactory}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public class AuditableBeanWrapperFactoryUnitTests {
|
||||
public class DefaultAuditableBeanWrapperFactoryUnitTests {
|
||||
|
||||
AuditableBeanWrapperFactory factory = new AuditableBeanWrapperFactory();
|
||||
DefaultAuditableBeanWrapperFactory factory = new DefaultAuditableBeanWrapperFactory();
|
||||
|
||||
@Test
|
||||
public void returnsNullForNullSource() {
|
||||
@@ -55,4 +59,21 @@ public class AuditableBeanWrapperFactoryUnitTests {
|
||||
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(new Object());
|
||||
assertThat(wrapper, is(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-643
|
||||
*/
|
||||
@Test
|
||||
public void setsJsr310AndThreeTenBpTypes() {
|
||||
|
||||
Jsr310ThreeTenBpAuditedUser user = new Jsr310ThreeTenBpAuditedUser();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
|
||||
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(user);
|
||||
wrapper.setCreatedDate(calendar);
|
||||
wrapper.setLastModifiedDate(calendar);
|
||||
|
||||
assertThat(user.createdDate, is(notNullValue()));
|
||||
assertThat(user.lastModifiedDate, is(notNullValue()));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2014 the original author or authors.
|
||||
* Copyright 2008-2015 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.
|
||||
@@ -19,14 +19,15 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.mapping.context.SampleMappingContext;
|
||||
|
||||
/**
|
||||
@@ -47,7 +48,7 @@ public class IsNewAwareAuditingHandlerUnitTests extends AuditingHandlerUnitTests
|
||||
|
||||
@Override
|
||||
protected IsNewAwareAuditingHandler getHandler() {
|
||||
return new IsNewAwareAuditingHandler(mock(SampleMappingContext.class));
|
||||
return new IsNewAwareAuditingHandler(mock(PersistentEntities.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,8 +77,7 @@ public class IsNewAwareAuditingHandlerUnitTests extends AuditingHandlerUnitTests
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullMappingContext() {
|
||||
new IsNewAwareAuditingHandler(
|
||||
(MappingContext<? extends PersistentEntity<?, ?>, ? extends PersistentProperty<?>>) null);
|
||||
new IsNewAwareAuditingHandler((PersistentEntities) null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,20 @@ public class IsNewAwareAuditingHandlerUnitTests extends AuditingHandlerUnitTests
|
||||
*/
|
||||
@Test
|
||||
public void setsUpHandlerWithMappingContext() {
|
||||
new IsNewAwareAuditingHandler(new SampleMappingContext());
|
||||
new IsNewAwareAuditingHandler(new PersistentEntities(Collections.<MappingContext<?, ?>> emptySet()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-638
|
||||
*/
|
||||
@Test
|
||||
public void handlingNullIsANoOp() {
|
||||
|
||||
IsNewAwareAuditingHandler handler = getHandler();
|
||||
|
||||
handler.markAudited(null);
|
||||
handler.markCreated(null);
|
||||
handler.markModified(null);
|
||||
}
|
||||
|
||||
static class Domain {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2015 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
|
||||
*
|
||||
* http://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.auditing;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class Jsr310ThreeTenBpAuditedUser {
|
||||
|
||||
@CreatedDate LocalDateTime createdDate;
|
||||
@LastModifiedDate org.threeten.bp.LocalDateTime lastModifiedDate;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2015 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.
|
||||
@@ -19,14 +19,22 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.auditing.AuditableBeanWrapperFactory.AuditableInterfaceBeanWrapper;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.AuditableInterfaceBeanWrapper;
|
||||
import org.springframework.data.convert.Jsr310Converters.LocalDateTimeToDateConverter;
|
||||
import org.springframework.data.domain.Auditable;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.mapping.context.SampleMappingContext;
|
||||
|
||||
/**
|
||||
@@ -37,11 +45,17 @@ import org.springframework.data.mapping.context.SampleMappingContext;
|
||||
*/
|
||||
public class MappingAuditableBeanWrapperFactoryUnitTests {
|
||||
|
||||
AuditableBeanWrapperFactory factory;
|
||||
DefaultAuditableBeanWrapperFactory factory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
factory = new MappingAuditableBeanWrapperFactory(new SampleMappingContext());
|
||||
|
||||
SampleMappingContext context = new SampleMappingContext();
|
||||
context.setInitialEntitySet(Collections.singleton(Sample.class));
|
||||
context.afterPropertiesSet();
|
||||
|
||||
PersistentEntities entities = new PersistentEntities(Collections.singleton(context));
|
||||
factory = new MappingAuditableBeanWrapperFactory(entities);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,10 +118,83 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
|
||||
is(instanceOf(AuditableInterfaceBeanWrapper.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-638
|
||||
*/
|
||||
@Test
|
||||
public void returnsLastModificationCalendarAsCalendar() {
|
||||
|
||||
Date reference = new Date();
|
||||
|
||||
Calendar calendar = new GregorianCalendar();
|
||||
calendar.setTime(reference);
|
||||
|
||||
assertLastModificationDate(calendar, reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-638
|
||||
*/
|
||||
@Test
|
||||
public void returnsLastModificationDateTimeAsCalendar() {
|
||||
|
||||
DateTime reference = new DateTime();
|
||||
|
||||
assertLastModificationDate(reference, reference.toDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-638
|
||||
*/
|
||||
@Test
|
||||
public void returnsLastModificationDateAsCalendar() {
|
||||
|
||||
Date reference = new Date();
|
||||
|
||||
assertLastModificationDate(reference, reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-638, DATACMNS-43
|
||||
*/
|
||||
@Test
|
||||
public void returnsLastModificationJsr310DateTimeAsCalendar() {
|
||||
|
||||
LocalDateTime reference = LocalDateTime.now();
|
||||
|
||||
assertLastModificationDate(reference, LocalDateTimeToDateConverter.INSTANCE.convert(reference));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-638, DATACMNS-43
|
||||
*/
|
||||
@Test
|
||||
public void returnsLastModificationThreeTenBpDateTimeAsCalendar() {
|
||||
|
||||
org.threeten.bp.LocalDateTime reference = org.threeten.bp.LocalDateTime.now();
|
||||
|
||||
assertLastModificationDate(reference,
|
||||
org.springframework.data.convert.ThreeTenBackPortConverters.LocalDateTimeToDateConverter.INSTANCE
|
||||
.convert(reference));
|
||||
}
|
||||
|
||||
private final void assertLastModificationDate(Object source, Date expected) {
|
||||
|
||||
Calendar calendar = new GregorianCalendar();
|
||||
calendar.setTime(expected);
|
||||
|
||||
Sample sample = new Sample();
|
||||
sample.lastModifiedDate = source;
|
||||
|
||||
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(sample);
|
||||
assertThat(wrapper.getLastModifiedDate(), is(calendar));
|
||||
}
|
||||
|
||||
static class Sample {
|
||||
|
||||
@CreatedBy private Object createdBy;
|
||||
private @CreatedBy Object createdBy;
|
||||
private Object lastModifiedBy;
|
||||
private @LastModifiedDate Object lastModifiedDate;
|
||||
|
||||
@LastModifiedBy
|
||||
public Object getLastModifiedBy() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2012-2015 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.
|
||||
@@ -26,7 +26,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.auditing.AuditableBeanWrapperFactory.ReflectionAuditingBeanWrapper;
|
||||
import org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.ReflectionAuditingBeanWrapper;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ReflectionAuditingBeanWrapper}.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2015 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.
|
||||
@@ -18,18 +18,23 @@ package org.springframework.data.mapping.context;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
|
||||
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory.PropertyIsNullIsNewStrategy;
|
||||
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory.PropertyIsNullOrZeroNumberIsNewStrategy;
|
||||
import org.springframework.data.support.IsNewStrategy;
|
||||
import org.springframework.data.support.IsNewStrategyFactory;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MappingContextIsNewStrategyFactory}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingContextIsNewStrategyFactoryUnitTests {
|
||||
@@ -40,7 +45,10 @@ public class MappingContextIsNewStrategyFactoryUnitTests {
|
||||
public void setUp() {
|
||||
|
||||
SampleMappingContext context = new SampleMappingContext();
|
||||
factory = new MappingContextIsNewStrategyFactory(context);
|
||||
context.setInitialEntitySet(new HashSet<Class<?>>(Arrays.<Class<?>> asList(Entity.class, VersionedEntity.class)));
|
||||
context.afterPropertiesSet();
|
||||
|
||||
factory = new MappingContextIsNewStrategyFactory(new PersistentEntities(Collections.singleton(context)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -94,11 +102,9 @@ public class MappingContextIsNewStrategyFactoryUnitTests {
|
||||
@SuppressWarnings("serial")
|
||||
static class PersistableEntity implements Persistable<Long> {
|
||||
|
||||
@Version
|
||||
Long version;
|
||||
@Version Long version;
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
@Id Long id;
|
||||
|
||||
boolean isNew = true;
|
||||
|
||||
@@ -113,25 +119,20 @@ public class MappingContextIsNewStrategyFactoryUnitTests {
|
||||
|
||||
static class VersionedEntity {
|
||||
|
||||
@Version
|
||||
Long version;
|
||||
@Version Long version;
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
@Id Long id;
|
||||
}
|
||||
|
||||
static class PrimitveVersionedEntity {
|
||||
|
||||
@Version
|
||||
long version = 0;
|
||||
@Version long version = 0;
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
@Id Long id;
|
||||
}
|
||||
|
||||
static class Entity {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
@Id Long id;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user