DATAREST-415 - Moved to PersistentPropertyAccessor API.
We now use the PersistentPropertyAccessor provided by the PersistentEntity to lookup property values to benefit from store-specific customizations. Code that relies on value conversion by using a ConversionService now explicitly uses a ConvertingPropertyAccessor. Related tickets: DATACMNS-596.
This commit is contained in:
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.Resources;
|
||||
@@ -75,6 +76,15 @@ public class PersistentEntityResource extends Resource<Object> {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PersistentPropertyAccessor} for the underlying content bean.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public PersistentPropertyAccessor getPropertyAccessor() {
|
||||
return entity.getPropertyAccessor(getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resources that are supposed to be rendered in the {@code _embedded} clause.
|
||||
*
|
||||
|
||||
@@ -22,8 +22,8 @@ import java.util.List;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.mapping.SimpleAssociationHandler;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.rest.core.mapping.ResourceMappings;
|
||||
import org.springframework.data.rest.core.mapping.ResourceMetadata;
|
||||
@@ -121,7 +121,7 @@ public class PersistentEntityResourceAssembler implements ResourceAssembler<Obje
|
||||
PersistentEntity<?, ?> entity = repositories.getPersistentEntity(instance.getClass());
|
||||
|
||||
final List<EmbeddedWrapper> associationProjections = new ArrayList<EmbeddedWrapper>();
|
||||
final BeanWrapper<Object> wrapper = BeanWrapper.create(instance, null);
|
||||
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(instance);
|
||||
final AssociationLinks associationLinks = new AssociationLinks(mappings);
|
||||
final ResourceMetadata metadata = mappings.getMappingFor(instance.getClass());
|
||||
|
||||
@@ -144,7 +144,7 @@ public class PersistentEntityResourceAssembler implements ResourceAssembler<Obje
|
||||
return;
|
||||
}
|
||||
|
||||
Object value = wrapper.getProperty(association.getInverse());
|
||||
Object value = accessor.getProperty(association.getInverse());
|
||||
|
||||
if (value == null) {
|
||||
return;
|
||||
@@ -197,8 +197,8 @@ public class PersistentEntityResourceAssembler implements ResourceAssembler<Obje
|
||||
instanceType));
|
||||
}
|
||||
|
||||
BeanWrapper<Object> wrapper = BeanWrapper.create(instance, null);
|
||||
Object id = wrapper.getProperty(entity.getIdProperty());
|
||||
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(instance);
|
||||
Object id = accessor.getProperty(entity.getIdProperty());
|
||||
|
||||
Link resourceLink = entityLinks.linkToSingleResource(entity.getType(), id);
|
||||
return new Link(resourceLink.getHref(), Link.REL_SELF);
|
||||
|
||||
@@ -29,7 +29,8 @@ import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
|
||||
import org.springframework.data.repository.invoker.RepositoryInvoker;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
|
||||
@@ -314,7 +315,8 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
|
||||
resourceInformation.verifySupportedMethod(HttpMethod.PUT, ResourceType.ITEM);
|
||||
|
||||
// Force ID on unmarshalled object
|
||||
BeanWrapper<Object> incomingWrapper = BeanWrapper.create(payload.getContent(), conversionService);
|
||||
PersistentPropertyAccessor incomingWrapper = new ConvertingPropertyAccessor(payload.getPropertyAccessor(),
|
||||
conversionService);
|
||||
incomingWrapper.setProperty(payload.getPersistentEntity().getIdProperty(), id);
|
||||
|
||||
RepositoryInvoker invoker = resourceInformation.getInvoker();
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.repository.invoker.RepositoryInvoker;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.rest.core.event.AfterLinkDeleteEvent;
|
||||
@@ -175,11 +175,11 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
} else if (prop.property.isMap()) {
|
||||
throw new HttpRequestMethodNotSupportedException("DELETE");
|
||||
} else {
|
||||
prop.wrapper.setProperty(prop.property, null);
|
||||
prop.accessor.setProperty(prop.property, null);
|
||||
}
|
||||
|
||||
publisher.publishEvent(new BeforeLinkDeleteEvent(prop.wrapper.getBean(), prop.propertyValue));
|
||||
Object result = repoMethodInvoker.invokeSave(prop.wrapper.getBean());
|
||||
publisher.publishEvent(new BeforeLinkDeleteEvent(prop.accessor.getBean(), prop.propertyValue));
|
||||
Object result = repoMethodInvoker.invokeSave(prop.accessor.getBean());
|
||||
publisher.publishEvent(new AfterLinkDeleteEvent(result, prop.propertyValue));
|
||||
|
||||
return null;
|
||||
@@ -209,8 +209,8 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
if (prop.property.isCollectionLike()) {
|
||||
for (Object obj : (Iterable<?>) prop.propertyValue) {
|
||||
|
||||
BeanWrapper<Object> propValWrapper = BeanWrapper.create(obj, null);
|
||||
String sId = propValWrapper.getProperty(prop.entity.getIdProperty()).toString();
|
||||
PersistentPropertyAccessor accessor = prop.entity.getPropertyAccessor(obj);
|
||||
String sId = accessor.getProperty(prop.entity.getIdProperty()).toString();
|
||||
|
||||
if (propertyId.equals(sId)) {
|
||||
|
||||
@@ -222,8 +222,8 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
} else if (prop.property.isMap()) {
|
||||
for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) prop.propertyValue).entrySet()) {
|
||||
|
||||
BeanWrapper<Object> propValWrapper = BeanWrapper.create(entry.getValue(), null);
|
||||
String sId = propValWrapper.getProperty(prop.entity.getIdProperty()).toString();
|
||||
PersistentPropertyAccessor accessor = prop.entity.getPropertyAccessor(entry.getValue());
|
||||
String sId = accessor.getProperty(prop.entity.getIdProperty()).toString();
|
||||
|
||||
if (propertyId.equals(sId)) {
|
||||
|
||||
@@ -325,7 +325,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
coll.add(propVal);
|
||||
}
|
||||
|
||||
prop.wrapper.setProperty(prop.property, coll);
|
||||
prop.accessor.setProperty(prop.property, coll);
|
||||
|
||||
} else if (prop.property.isMap()) {
|
||||
|
||||
@@ -342,7 +342,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
m.put(l.getRel(), propVal);
|
||||
}
|
||||
|
||||
prop.wrapper.setProperty(prop.property, m);
|
||||
prop.accessor.setProperty(prop.property, m);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -357,11 +357,11 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
}
|
||||
|
||||
Object propVal = loadPropertyValue(prop.propertyType, incoming.getLinks().get(0));
|
||||
prop.wrapper.setProperty(prop.property, propVal);
|
||||
prop.accessor.setProperty(prop.property, propVal);
|
||||
}
|
||||
|
||||
publisher.publishEvent(new BeforeLinkSaveEvent(prop.wrapper.getBean(), prop.propertyValue));
|
||||
Object result = invoker.invokeSave(prop.wrapper.getBean());
|
||||
publisher.publishEvent(new BeforeLinkSaveEvent(prop.accessor.getBean(), prop.propertyValue));
|
||||
Object result = invoker.invokeSave(prop.accessor.getBean());
|
||||
publisher.publishEvent(new AfterLinkSaveEvent(result, prop.propertyValue));
|
||||
|
||||
return null;
|
||||
@@ -400,8 +400,9 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
Iterator<Object> itr = coll.iterator();
|
||||
while (itr.hasNext()) {
|
||||
Object obj = itr.next();
|
||||
BeanWrapper<Object> propValWrapper = BeanWrapper.create(obj, null);
|
||||
String s = propValWrapper.getProperty(prop.entity.getIdProperty()).toString();
|
||||
|
||||
PersistentPropertyAccessor accessor = prop.entity.getPropertyAccessor(obj);
|
||||
String s = accessor.getProperty(prop.entity.getIdProperty()).toString();
|
||||
if (propertyId.equals(s)) {
|
||||
itr.remove();
|
||||
}
|
||||
@@ -411,18 +412,18 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
Iterator<Object> itr = m.keySet().iterator();
|
||||
while (itr.hasNext()) {
|
||||
Object key = itr.next();
|
||||
BeanWrapper<Object> propValWrapper = BeanWrapper.create(m.get(key), null);
|
||||
String s = propValWrapper.getProperty(prop.entity.getIdProperty()).toString();
|
||||
PersistentPropertyAccessor accessor = prop.entity.getPropertyAccessor(m.get(key));
|
||||
String s = accessor.getProperty(prop.entity.getIdProperty()).toString();
|
||||
if (propertyId.equals(s)) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
prop.wrapper.setProperty(prop.property, null);
|
||||
prop.accessor.setProperty(prop.property, null);
|
||||
}
|
||||
|
||||
publisher.publishEvent(new BeforeLinkDeleteEvent(prop.wrapper.getBean(), prop.propertyValue));
|
||||
Object result = invoker.invokeSave(prop.wrapper.getBean());
|
||||
publisher.publishEvent(new BeforeLinkDeleteEvent(prop.accessor.getBean(), prop.propertyValue));
|
||||
Object result = invoker.invokeSave(prop.accessor.getBean());
|
||||
publisher.publishEvent(new AfterLinkDeleteEvent(result, prop.propertyValue));
|
||||
|
||||
return null;
|
||||
@@ -456,15 +457,17 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
PersistentProperty<?> prop = repoRequest.getPersistentEntity().getPersistentProperty(propertyPath);
|
||||
PersistentEntity<?, ?> persistentEntity = repoRequest.getPersistentEntity();
|
||||
PersistentProperty<?> prop = persistentEntity.getPersistentProperty(propertyPath);
|
||||
|
||||
if (null == prop) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
BeanWrapper<Object> wrapper = BeanWrapper.create(domainObj, null);
|
||||
Object propVal = wrapper.getProperty(prop);
|
||||
PersistentPropertyAccessor accessor = persistentEntity.getPropertyAccessor(domainObj);
|
||||
Object propVal = accessor.getProperty(prop);
|
||||
|
||||
return handler.apply(new ReferencedProperty(prop, propVal, wrapper));
|
||||
return handler.apply(new ReferencedProperty(prop, propVal, accessor));
|
||||
}
|
||||
|
||||
private class ReferencedProperty {
|
||||
@@ -473,13 +476,13 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
final PersistentProperty<?> property;
|
||||
final Class<?> propertyType;
|
||||
final Object propertyValue;
|
||||
final BeanWrapper<?> wrapper;
|
||||
final PersistentPropertyAccessor accessor;
|
||||
|
||||
private ReferencedProperty(PersistentProperty<?> property, Object propertyValue, BeanWrapper<?> wrapper) {
|
||||
private ReferencedProperty(PersistentProperty<?> property, Object propertyValue, PersistentPropertyAccessor wrapper) {
|
||||
|
||||
this.property = property;
|
||||
this.propertyValue = propertyValue;
|
||||
this.wrapper = wrapper;
|
||||
this.accessor = wrapper;
|
||||
this.propertyType = property.getActualType();
|
||||
this.entity = repositories.getPersistentEntity(propertyType);
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.rest.core.mapping.ResourceMappings;
|
||||
import org.springframework.data.rest.webmvc.mapping.AssociationLinks;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
@@ -118,8 +118,9 @@ public class DomainObjectReader {
|
||||
continue;
|
||||
}
|
||||
|
||||
BeanWrapper<T> wrapper = BeanWrapper.create(existingObject, null);
|
||||
Object nested = wrapper.getProperty(property);
|
||||
PersistentEntity<?, ?> entity = entities.getPersistentEntity(existingObject.getClass());
|
||||
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(existingObject);
|
||||
Object nested = accessor.getProperty(property);
|
||||
|
||||
if (nested != null) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user