DATACMNS-596 - Introduced PersistentPropertyAccessor.

To be able to customize the lookup of bean properties by persistent store we now expose a getPropertyAccessor(Object entity) method on PersistentEntity. It returns a PersistentPropertyAccessor which is basically an interface with a simplified API of BeanWrapper.

Reduced the plain BeanWrapper to not perform any type conversion to be able to drop the ConversionService dependency. To compensate for that we introduced a ConvertingPropertyAccessor that takes a ConversionService and delegates to a standard PersistentPropertyAccessor and applies conversions if necessary.

Refactored client APIs to use the PersistentPropertyAccessor instead of referring to BeanWrapper directly. Deprecated BeanWrapper.create(…) for removal in RC1.
This commit is contained in:
Oliver Gierke
2014-11-18 12:27:46 +01:00
parent 93dbc26969
commit 6a849bc8ef
10 changed files with 422 additions and 75 deletions

View File

@@ -26,6 +26,7 @@ import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.domain.Auditable;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.BeanWrapper;
import org.springframework.util.Assert;
@@ -82,7 +83,8 @@ class MappingAuditableBeanWrapperFactory extends AuditableBeanWrapperFactory {
metadataCache.put(type, metadata);
}
return metadata.isAuditable() ? new MappingMetadataAuditableBeanWrapper(source, metadata) : null;
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(source);
return metadata.isAuditable() ? new MappingMetadataAuditableBeanWrapper(accessor, metadata) : null;
}
/**
@@ -132,7 +134,7 @@ class MappingAuditableBeanWrapperFactory extends AuditableBeanWrapperFactory {
*/
static class MappingMetadataAuditableBeanWrapper extends DateConvertingAuditableBeanWrapper {
private final BeanWrapper<Object> wrapper;
private final PersistentPropertyAccessor accessor;
private final MappingAuditingMetadata metadata;
/**
@@ -142,12 +144,12 @@ class MappingAuditableBeanWrapperFactory extends AuditableBeanWrapperFactory {
* @param target must not be {@literal null}.
* @param metadata must not be {@literal null}.
*/
public MappingMetadataAuditableBeanWrapper(Object target, MappingAuditingMetadata metadata) {
public MappingMetadataAuditableBeanWrapper(PersistentPropertyAccessor accessor, MappingAuditingMetadata metadata) {
Assert.notNull(target, "Target object must not be null!");
Assert.notNull(accessor, "Target object must not be null!");
Assert.notNull(metadata, "Auditing metadata must not be null!");
this.wrapper = BeanWrapper.create(target, null);
this.accessor = accessor;
this.metadata = metadata;
}
@@ -159,7 +161,7 @@ class MappingAuditableBeanWrapperFactory extends AuditableBeanWrapperFactory {
public void setCreatedBy(Object value) {
if (metadata.createdByProperty != null) {
this.wrapper.setProperty(metadata.createdByProperty, value);
this.accessor.setProperty(metadata.createdByProperty, value);
}
}
@@ -173,7 +175,7 @@ class MappingAuditableBeanWrapperFactory extends AuditableBeanWrapperFactory {
PersistentProperty<?> property = metadata.createdDateProperty;
if (property != null) {
this.wrapper.setProperty(property, getDateValueToSet(value, property.getType(), property));
this.accessor.setProperty(property, getDateValueToSet(value, property.getType(), property));
}
}
@@ -185,7 +187,7 @@ class MappingAuditableBeanWrapperFactory extends AuditableBeanWrapperFactory {
public void setLastModifiedBy(Object value) {
if (metadata.lastModifiedByProperty != null) {
this.wrapper.setProperty(metadata.lastModifiedByProperty, value);
this.accessor.setProperty(metadata.lastModifiedByProperty, value);
}
}
@@ -199,7 +201,7 @@ class MappingAuditableBeanWrapperFactory extends AuditableBeanWrapperFactory {
PersistentProperty<?> property = metadata.lastModifiedDateProperty;
if (property != null) {
this.wrapper.setProperty(property, getDateValueToSet(value, property.getType(), property));
this.accessor.setProperty(property, getDateValueToSet(value, property.getType(), property));
}
}
}