DATACMNS-266 - Use new common Maven build infrastructure.
Simplified project setup to be a single module build again. Using Spring Data Build parent POM to simplify project setup. See https://github.com/SpringSource/spring-data-build#spring-data-build-infrastructure
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
package org.springframework.data.auditing;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.data.util.ReflectionUtils.AnnotationFieldFilter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Inspects the given {@link Class} for fields annotated by {@link CreatedBy}, {@link CreatedDate},
|
||||
* {@link LastModifiedBy} , and {@link LastModifiedDate}. Only one field per annotation is stored.
|
||||
*
|
||||
* @author Ranie Jade Ramiso
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
class AnnotationAuditingMetadata {
|
||||
|
||||
private static final AnnotationFieldFilter CREATED_BY_FILTER = new AnnotationFieldFilter(CreatedBy.class);
|
||||
private static final AnnotationFieldFilter CREATED_DATE_FILTER = new AnnotationFieldFilter(CreatedDate.class);
|
||||
private static final AnnotationFieldFilter LAST_MODIFIED_BY_FILTER = new AnnotationFieldFilter(LastModifiedBy.class);
|
||||
private static final AnnotationFieldFilter LAST_MODIFIED_DATE_FILTER = new AnnotationFieldFilter(
|
||||
LastModifiedDate.class);
|
||||
|
||||
private static final Map<Class<?>, AnnotationAuditingMetadata> METADATA_CACHE = new ConcurrentHashMap<Class<?>, AnnotationAuditingMetadata>();
|
||||
|
||||
static final List<Class<?>> SUPPORTED_DATE_TYPES;
|
||||
|
||||
static {
|
||||
|
||||
List<Class<?>> types = new ArrayList<Class<?>>(4);
|
||||
types.add(DateTime.class);
|
||||
types.add(Date.class);
|
||||
types.add(Long.class);
|
||||
types.add(long.class);
|
||||
|
||||
SUPPORTED_DATE_TYPES = Collections.unmodifiableList(types);
|
||||
}
|
||||
|
||||
private final Field createdByField;
|
||||
private final Field createdDateField;
|
||||
private final Field lastModifiedByField;
|
||||
private final Field lastModifiedDateField;
|
||||
|
||||
private AnnotationAuditingMetadata(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, "Given type must not be null!");
|
||||
|
||||
this.createdByField = ReflectionUtils.findField(type, CREATED_BY_FILTER);
|
||||
this.createdDateField = ReflectionUtils.findField(type, CREATED_DATE_FILTER);
|
||||
this.lastModifiedByField = ReflectionUtils.findField(type, LAST_MODIFIED_BY_FILTER);
|
||||
this.lastModifiedDateField = ReflectionUtils.findField(type, LAST_MODIFIED_DATE_FILTER);
|
||||
|
||||
assertValidDateFieldType(createdDateField);
|
||||
assertValidDateFieldType(lastModifiedDateField);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given field has a type that is a supported date type.
|
||||
*
|
||||
* @param field
|
||||
*/
|
||||
private void assertValidDateFieldType(Field field) {
|
||||
|
||||
if (field == null || SUPPORTED_DATE_TYPES.contains(field.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format(
|
||||
"Found created/modified date field with type %s but only %s are supported!", field.getType(),
|
||||
SUPPORTED_DATE_TYPES));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link AnnotationAuditingMetadata} for the given {@link Class}.
|
||||
*
|
||||
* @param type the type to inspect, must not be {@literal null}.
|
||||
*/
|
||||
public static AnnotationAuditingMetadata getMetadata(Class<?> type) {
|
||||
|
||||
if (METADATA_CACHE.containsKey(type)) {
|
||||
return METADATA_CACHE.get(type);
|
||||
}
|
||||
|
||||
AnnotationAuditingMetadata metadata = new AnnotationAuditingMetadata(type);
|
||||
METADATA_CACHE.put(type, metadata);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the {@link Class} represented in this instance is auditable or not.
|
||||
*/
|
||||
public boolean isAuditable() {
|
||||
if (createdByField == null && createdDateField == null && lastModifiedByField == null
|
||||
&& lastModifiedDateField == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field annotated by {@link CreatedBy}, or {@literal null}.
|
||||
*/
|
||||
public Field getCreatedByField() {
|
||||
return createdByField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field annotated by {@link CreatedDate}, or {@literal null}.
|
||||
*/
|
||||
public Field getCreatedDateField() {
|
||||
return createdDateField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field annotated by {@link LastModifiedBy}, or {@literal null}.
|
||||
*/
|
||||
public Field getLastModifiedByField() {
|
||||
return lastModifiedByField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field annotated by {@link LastModifiedDate}, or {@literal null}.
|
||||
*/
|
||||
public Field getLastModifiedDateField() {
|
||||
return lastModifiedDateField;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012 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 org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Interface to abstract the ways setting the auditing information can be implemented.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface AuditableBeanWrapper {
|
||||
|
||||
/**
|
||||
* Set the creator of the object.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setCreatedBy(Object value);
|
||||
|
||||
/**
|
||||
* Set the date the object was created.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setCreatedDate(DateTime value);
|
||||
|
||||
/**
|
||||
* Set the last modifier of the object.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setLastModifiedBy(Object value);
|
||||
|
||||
/**
|
||||
* Set the last modification date.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setLastModifiedDate(DateTime value);
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright 2012 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.lang.reflect.Field;
|
||||
import java.util.Date;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.data.domain.Auditable;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A factory class to {@link AuditableBeanWrapper} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
class AuditableBeanWrapperFactory {
|
||||
|
||||
/**
|
||||
* Returns an {@link AuditableBeanWrapper} if the given object is capable of being equipped with auditing information.
|
||||
*
|
||||
* @param source the auditing candidate.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public AuditableBeanWrapper getBeanWrapperFor(Object source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (source instanceof Auditable) {
|
||||
return new AuditableInterfaceBeanWrapper((Auditable<Object, ?>) source);
|
||||
}
|
||||
|
||||
AnnotationAuditingMetadata metadata = AnnotationAuditingMetadata.getMetadata(source.getClass());
|
||||
|
||||
if (metadata.isAuditable()) {
|
||||
return new ReflectionAuditingBeanWrapper(source);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@link AuditableBeanWrapper} that works with objects implementing
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static class AuditableInterfaceBeanWrapper implements AuditableBeanWrapper {
|
||||
|
||||
private final Auditable<Object, ?> auditable;
|
||||
|
||||
public AuditableInterfaceBeanWrapper(Auditable<Object, ?> auditable) {
|
||||
this.auditable = auditable;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedBy(java.lang.Object)
|
||||
*/
|
||||
public void setCreatedBy(Object value) {
|
||||
auditable.setCreatedBy(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedDate(org.joda.time.DateTime)
|
||||
*/
|
||||
public void setCreatedDate(DateTime value) {
|
||||
auditable.setCreatedDate(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedBy(java.lang.Object)
|
||||
*/
|
||||
public void setLastModifiedBy(Object value) {
|
||||
auditable.setLastModifiedBy(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedDate(org.joda.time.DateTime)
|
||||
*/
|
||||
public void setLastModifiedDate(DateTime value) {
|
||||
auditable.setLastModifiedDate(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@link AuditableBeanWrapper} implementation that sets values on the target object using refelction.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static class ReflectionAuditingBeanWrapper implements AuditableBeanWrapper {
|
||||
|
||||
private final AnnotationAuditingMetadata metadata;
|
||||
private final Object target;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ReflectionAuditingBeanWrapper} to set auditing data on the given target object.
|
||||
*
|
||||
* @param target must not be {@literal null}.
|
||||
*/
|
||||
public ReflectionAuditingBeanWrapper(Object target) {
|
||||
|
||||
Assert.notNull(target, "Target object must not be null!");
|
||||
|
||||
this.metadata = AnnotationAuditingMetadata.getMetadata(target.getClass());
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedBy(java.lang.Object)
|
||||
*/
|
||||
public void setCreatedBy(Object value) {
|
||||
setField(metadata.getCreatedByField(), value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedDate(org.joda.time.DateTime)
|
||||
*/
|
||||
public void setCreatedDate(DateTime value) {
|
||||
setDateField(metadata.getCreatedDateField(), value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedBy(java.lang.Object)
|
||||
*/
|
||||
public void setLastModifiedBy(Object value) {
|
||||
setField(metadata.getLastModifiedByField(), value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedDate(org.joda.time.DateTime)
|
||||
*/
|
||||
public void setLastModifiedDate(DateTime value) {
|
||||
setDateField(metadata.getLastModifiedDateField(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given field to the given value if the field is not {@literal null}.
|
||||
*
|
||||
* @param field
|
||||
* @param value
|
||||
*/
|
||||
private void setField(Field field, Object value) {
|
||||
|
||||
if (field != null) {
|
||||
ReflectionUtils.setField(field, target, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given field to the given value if the field is not {@literal null}.
|
||||
*
|
||||
* @param field
|
||||
* @param value
|
||||
*/
|
||||
private void setDateField(Field field, DateTime value) {
|
||||
|
||||
if (field == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReflectionUtils.setField(field, target, getDateValueToSet(value, field));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link DateTime} in a type compatible to the given field.
|
||||
*
|
||||
* @param value
|
||||
* @param field must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private Object getDateValueToSet(DateTime value, Field field) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Class<?> targetType = field.getType();
|
||||
|
||||
if (DateTime.class.equals(targetType)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (Date.class.equals(targetType)) {
|
||||
return value.toDate();
|
||||
}
|
||||
|
||||
if (Long.class.equals(targetType) || long.class.equals(targetType)) {
|
||||
return value.getMillis();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Invalid date type for field %s! Supported types are %s.",
|
||||
field, AnnotationAuditingMetadata.SUPPORTED_DATE_TYPES));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2012 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 org.joda.time.DateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.domain.Auditable;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Auditing handler to mark entity objects created and modified.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public class AuditingHandler<T> implements InitializingBean {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AuditingHandler.class);
|
||||
|
||||
private final AuditableBeanWrapperFactory factory = new AuditableBeanWrapperFactory();
|
||||
private DateTimeProvider dateTimeProvider = CurrentDateTimeProvider.INSTANCE;
|
||||
private AuditorAware<T> auditorAware;
|
||||
private boolean dateTimeForNow = true;
|
||||
private boolean modifyOnCreation = true;
|
||||
|
||||
/**
|
||||
* Setter to inject a {@code AuditorAware} component to retrieve the current auditor.
|
||||
*
|
||||
* @param auditorAware the auditorAware to set
|
||||
*/
|
||||
public void setAuditorAware(final AuditorAware<T> auditorAware) {
|
||||
|
||||
Assert.notNull(auditorAware);
|
||||
this.auditorAware = auditorAware;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter do determine if {@link Auditable#setCreatedDate(DateTime)} and
|
||||
* {@link Auditable#setLastModifiedDate(DateTime)} shall be filled with the current Java time. Defaults to
|
||||
* {@code true}. One might set this to {@code false} to use database features to set entity time.
|
||||
*
|
||||
* @param dateTimeForNow the dateTimeForNow to set
|
||||
*/
|
||||
public void setDateTimeForNow(boolean dateTimeForNow) {
|
||||
this.dateTimeForNow = dateTimeForNow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this to false if you want to treat entity creation as modification and thus set the current date as
|
||||
* modification date, too. Defaults to {@code true}.
|
||||
*
|
||||
* @param modifyOnCreation if modification information shall be set on creation, too
|
||||
*/
|
||||
public void setModifyOnCreation(boolean modifyOnCreation) {
|
||||
this.modifyOnCreation = modifyOnCreation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link DateTimeProvider} to be used to determine the dates to be set.
|
||||
*
|
||||
* @param dateTimeProvider
|
||||
*/
|
||||
public void setDateTimeProvider(DateTimeProvider dateTimeProvider) {
|
||||
this.dateTimeProvider = dateTimeProvider == null ? CurrentDateTimeProvider.INSTANCE : dateTimeProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given object as created.
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
public void markCreated(Object source) {
|
||||
touch(source, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given object as modified.
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
public void markModified(Object source) {
|
||||
touch(source, false);
|
||||
}
|
||||
|
||||
private void touch(Object target, boolean isNew) {
|
||||
|
||||
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(target);
|
||||
|
||||
if (wrapper == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
T auditor = touchAuditor(wrapper, isNew);
|
||||
DateTime now = dateTimeForNow ? touchDate(wrapper, isNew) : null;
|
||||
|
||||
Object defaultedNow = now == null ? "not set" : now;
|
||||
Object defaultedAuditor = auditor == null ? "unknown" : auditor;
|
||||
|
||||
LOGGER.debug("Touched {} - Last modification at {} by {}", new Object[] { target, defaultedNow, defaultedAuditor });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets modifying and creating auditioner. Creating auditioner is only set on new auditables.
|
||||
*
|
||||
* @param auditable
|
||||
* @return
|
||||
*/
|
||||
private T touchAuditor(AuditableBeanWrapper wrapper, boolean isNew) {
|
||||
|
||||
if (null == auditorAware) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T auditor = auditorAware.getCurrentAuditor();
|
||||
|
||||
if (isNew) {
|
||||
wrapper.setCreatedBy(auditor);
|
||||
if (!modifyOnCreation) {
|
||||
return auditor;
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.setLastModifiedBy(auditor);
|
||||
return auditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Touches the auditable regarding modification and creation date. Creation date is only set on new auditables.
|
||||
*
|
||||
* @param wrapper
|
||||
* @return
|
||||
*/
|
||||
private DateTime touchDate(AuditableBeanWrapper wrapper, boolean isNew) {
|
||||
|
||||
DateTime now = dateTimeProvider.getDateTime();
|
||||
|
||||
if (isNew) {
|
||||
wrapper.setCreatedDate(now);
|
||||
if (!modifyOnCreation) {
|
||||
return now;
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.setLastModifiedDate(now);
|
||||
return now;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
if (auditorAware == null) {
|
||||
LOGGER.debug("No AuditorAware set! Auditing will not be applied!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 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 org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Default {@link DateTimeProvider} simply creating new {@link DateTime} instances for each method call.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public enum CurrentDateTimeProvider implements DateTimeProvider {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.domain.support.DateTimeProvider#getDateTime()
|
||||
*/
|
||||
public DateTime getDateTime() {
|
||||
return new DateTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2012 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 org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* SPI to calculate the {@link DateTime} instance to be used when auditing.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface DateTimeProvider {
|
||||
|
||||
/**
|
||||
* Returns the {@link DateTime} to be used as modification date.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
DateTime getDateTime();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012 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 org.springframework.data.support.IsNewStrategy;
|
||||
import org.springframework.data.support.IsNewStrategyFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link AuditingHandler} extension that uses an {@link IsNewStrategyFactory} to expose a generic
|
||||
* {@link #markAudited(Object)} method that will route calls to {@link #markCreated(Object)} or
|
||||
* {@link #markModified(Object)} based on the {@link IsNewStrategy} determined from the factory.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public class IsNewAwareAuditingHandler<T> extends AuditingHandler<T> {
|
||||
|
||||
private final IsNewStrategyFactory isNewStrategyFactory;
|
||||
|
||||
/**
|
||||
* Creates a new {@link IsNewAwareAuditingHandler} using the given {@link IsNewStrategyFactory}.
|
||||
*
|
||||
* @param isNewStrategyFactory must not be {@literal null}.
|
||||
*/
|
||||
public IsNewAwareAuditingHandler(IsNewStrategyFactory isNewStrategyFactory) {
|
||||
|
||||
Assert.notNull(isNewStrategyFactory, "IsNewStrategy must not be null!");
|
||||
this.isNewStrategyFactory = isNewStrategyFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given object created or modified based on the {@link IsNewStrategy} returned by the
|
||||
* {@link IsNewStrategyFactory} configured. Will rout the calls to {@link #markCreated(Object)} and
|
||||
* {@link #markModified(Object)} accordingly.
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
public void markAudited(Object object) {
|
||||
|
||||
if (object == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
IsNewStrategy strategy = isNewStrategyFactory.getIsNewStrategy(object.getClass());
|
||||
|
||||
if (strategy.isNew(object)) {
|
||||
markCreated(object);
|
||||
} else {
|
||||
markModified(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user