DATACMNS-1322 - Generified PersistentPropertyAccessor API.
PersistentPropertyAccessor is now generic to be able to retain the type information about the object it was created for and the return type of ….getBean(). Adapted client APIs.
This commit is contained in:
@@ -285,7 +285,7 @@ public interface PersistentEntity<T, P extends PersistentProperty<P>> extends It
|
||||
* @return new {@link PersistentPropertyAccessor}.
|
||||
* @since 1.10
|
||||
*/
|
||||
PersistentPropertyAccessor getPropertyAccessor(Object bean);
|
||||
<B> PersistentPropertyAccessor<B> getPropertyAccessor(B bean);
|
||||
|
||||
/**
|
||||
* Returns the {@link IdentifierAccessor} for the given bean.
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.springframework.util.Assert;
|
||||
* @see PersistentEntity#getPropertyAccessor(Object)
|
||||
* @see ConvertingPropertyAccessor
|
||||
*/
|
||||
public interface PersistentPropertyAccessor {
|
||||
public interface PersistentPropertyAccessor<T> {
|
||||
|
||||
/**
|
||||
* Sets the given {@link PersistentProperty} to the given value. Will do type conversion if a
|
||||
@@ -71,7 +71,7 @@ public interface PersistentPropertyAccessor {
|
||||
getBean().getClass().getName()));
|
||||
}
|
||||
|
||||
PersistentPropertyAccessor accessor = parent == getBean() //
|
||||
PersistentPropertyAccessor<?> accessor = parent == getBean() //
|
||||
? this //
|
||||
: leafProperty.getOwner().getPropertyAccessor(parent);
|
||||
|
||||
@@ -126,7 +126,7 @@ public interface PersistentPropertyAccessor {
|
||||
}
|
||||
|
||||
PersistentEntity<?, ? extends PersistentProperty<?>> entity = property.getOwner();
|
||||
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(current);
|
||||
PersistentPropertyAccessor<Object> accessor = entity.getPropertyAccessor(current);
|
||||
|
||||
current = accessor.getProperty(property);
|
||||
}
|
||||
@@ -140,5 +140,5 @@ public interface PersistentPropertyAccessor {
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
Object getBean();
|
||||
T getBean();
|
||||
}
|
||||
|
||||
@@ -461,7 +461,7 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
|
||||
* @see org.springframework.data.mapping.PersistentEntity#getPropertyAccessor(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public PersistentPropertyAccessor getPropertyAccessor(Object bean) {
|
||||
public <B> PersistentPropertyAccessor<B> getPropertyAccessor(B bean) {
|
||||
|
||||
verifyBeanType(bean);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class BeanWrapper<T> implements PersistentPropertyAccessor {
|
||||
class BeanWrapper<T> implements PersistentPropertyAccessor<T> {
|
||||
|
||||
private T bean;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ enum BeanWrapperPropertyAccessorFactory implements PersistentPropertyAccessorFac
|
||||
* @see org.springframework.data.mapping.model.PersistentPropertyAccessorFactory#getPropertyAccessor(org.springframework.data.mapping.PersistentEntity, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public PersistentPropertyAccessor getPropertyAccessor(PersistentEntity<?, ?> entity, Object bean) {
|
||||
public <T> PersistentPropertyAccessor<T> getPropertyAccessor(PersistentEntity<?, ?> entity, T bean) {
|
||||
return new BeanWrapper<>(bean);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
|
||||
private final ThreadLocal<Object[]> argumentCache = ThreadLocal.withInitial(() -> new Object[1]);
|
||||
|
||||
private volatile Map<PersistentEntity<?, ?>, Constructor<?>> constructorMap = new HashMap<>(32);
|
||||
private volatile Map<TypeInformation<?>, Class<PersistentPropertyAccessor>> propertyAccessorClasses = new HashMap<>(
|
||||
private volatile Map<TypeInformation<?>, Class<PersistentPropertyAccessor<?>>> propertyAccessorClasses = new HashMap<>(
|
||||
32);
|
||||
|
||||
/*
|
||||
@@ -91,13 +91,13 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
|
||||
* @see org.springframework.data.mapping.model.PersistentPropertyAccessorFactory#getPropertyAccessor(org.springframework.data.mapping.PersistentEntity, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public PersistentPropertyAccessor getPropertyAccessor(PersistentEntity<?, ?> entity, Object bean) {
|
||||
public <T> PersistentPropertyAccessor<T> getPropertyAccessor(PersistentEntity<?, ?> entity, T bean) {
|
||||
|
||||
Constructor<?> constructor = constructorMap.get(entity);
|
||||
|
||||
if (constructor == null) {
|
||||
|
||||
Class<PersistentPropertyAccessor> accessorClass = potentiallyCreateAndRegisterPersistentPropertyAccessorClass(
|
||||
Class<PersistentPropertyAccessor<?>> accessorClass = potentiallyCreateAndRegisterPersistentPropertyAccessorClass(
|
||||
entity);
|
||||
constructor = accessorClass.getConstructors()[0];
|
||||
|
||||
@@ -110,7 +110,7 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
|
||||
args[0] = bean;
|
||||
|
||||
try {
|
||||
return (PersistentPropertyAccessor) constructor.newInstance(args);
|
||||
return (PersistentPropertyAccessor<T>) constructor.newInstance(args);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(String.format("Cannot create persistent property accessor for %s", entity), e);
|
||||
} finally {
|
||||
@@ -177,11 +177,11 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
|
||||
/**
|
||||
* @param entity must not be {@literal null}.
|
||||
*/
|
||||
private synchronized Class<PersistentPropertyAccessor> potentiallyCreateAndRegisterPersistentPropertyAccessorClass(
|
||||
private synchronized Class<PersistentPropertyAccessor<?>> potentiallyCreateAndRegisterPersistentPropertyAccessorClass(
|
||||
PersistentEntity<?, ?> entity) {
|
||||
|
||||
Map<TypeInformation<?>, Class<PersistentPropertyAccessor>> map = this.propertyAccessorClasses;
|
||||
Class<PersistentPropertyAccessor> propertyAccessorClass = map.get(entity.getTypeInformation());
|
||||
Map<TypeInformation<?>, Class<PersistentPropertyAccessor<?>>> map = this.propertyAccessorClasses;
|
||||
Class<PersistentPropertyAccessor<?>> propertyAccessorClass = map.get(entity.getTypeInformation());
|
||||
|
||||
if (propertyAccessorClass != null) {
|
||||
return propertyAccessorClass;
|
||||
@@ -198,10 +198,10 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<PersistentPropertyAccessor> createAccessorClass(PersistentEntity<?, ?> entity) {
|
||||
private Class<PersistentPropertyAccessor<?>> createAccessorClass(PersistentEntity<?, ?> entity) {
|
||||
|
||||
try {
|
||||
return (Class<PersistentPropertyAccessor>) PropertyAccessorClassGenerator.generateCustomAccessorClass(entity);
|
||||
return (Class<PersistentPropertyAccessor<?>>) PropertyAccessorClassGenerator.generateCustomAccessorClass(entity);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ import org.springframework.util.Assert;
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
|
||||
public class ConvertingPropertyAccessor<T> implements PersistentPropertyAccessor<T> {
|
||||
|
||||
private final PersistentPropertyAccessor accessor;
|
||||
private final PersistentPropertyAccessor<T> accessor;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @param conversionService must not be {@literal null}.
|
||||
*/
|
||||
public ConvertingPropertyAccessor(PersistentPropertyAccessor accessor, ConversionService conversionService) {
|
||||
public ConvertingPropertyAccessor(PersistentPropertyAccessor<T> accessor, ConversionService conversionService) {
|
||||
|
||||
Assert.notNull(accessor, "PersistentPropertyAccessor must not be null!");
|
||||
Assert.notNull(conversionService, "ConversionService must not be null!");
|
||||
@@ -78,7 +78,7 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
public <T> T getProperty(PersistentProperty<?> property, Class<T> targetType) {
|
||||
public <S> S getProperty(PersistentProperty<?> property, Class<S> targetType) {
|
||||
|
||||
Assert.notNull(property, "PersistentProperty must not be null!");
|
||||
Assert.notNull(targetType, "Target type must not be null!");
|
||||
@@ -91,7 +91,7 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
|
||||
* @see org.springframework.data.mapping.PersistentPropertyAccessor#getBean()
|
||||
*/
|
||||
@Override
|
||||
public Object getBean() {
|
||||
public T getBean() {
|
||||
return accessor.getBean();
|
||||
}
|
||||
|
||||
@@ -105,8 +105,8 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T convertIfNecessary(@Nullable Object source, Class<T> type) {
|
||||
return (T) (source == null ? null
|
||||
private <S> S convertIfNecessary(@Nullable Object source, Class<S> type) {
|
||||
return (S) (source == null ? null
|
||||
: type.isAssignableFrom(source.getClass()) ? source : conversionService.convert(source, type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class IdPropertyIdentifierAccessor extends TargetAwareIdentifierAccessor {
|
||||
|
||||
private final PersistentPropertyAccessor accessor;
|
||||
private final PersistentPropertyAccessor<?> accessor;
|
||||
private final PersistentProperty<?> idProperty;
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,7 @@ public interface PersistentPropertyAccessorFactory {
|
||||
* @param bean must not be {@literal null}.
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
PersistentPropertyAccessor getPropertyAccessor(PersistentEntity<?, ?> entity, Object bean);
|
||||
<T> PersistentPropertyAccessor<T> getPropertyAccessor(PersistentEntity<?, ?> entity, T bean);
|
||||
|
||||
/**
|
||||
* Returns whether given {@link PersistentEntity} is supported by this {@link PersistentPropertyAccessorFactory}.
|
||||
|
||||
Reference in New Issue
Block a user