diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java index d73d72576..ec173ae08 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java @@ -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 { 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. * diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceAssembler.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceAssembler.java index 1d6b0c389..cdaf984d4 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceAssembler.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceAssembler.java @@ -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 entity = repositories.getPersistentEntity(instance.getClass()); final List associationProjections = new ArrayList(); - final BeanWrapper 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 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); diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java index 11719ab05..50c7c4c5a 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java @@ -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 incomingWrapper = BeanWrapper.create(payload.getContent(), conversionService); + PersistentPropertyAccessor incomingWrapper = new ConvertingPropertyAccessor(payload.getPropertyAccessor(), + conversionService); incomingWrapper.setProperty(payload.getPersistentEntity().getIdProperty(), id); RepositoryInvoker invoker = resourceInformation.getInvoker(); diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java index 83745cd55..c219610dc 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java @@ -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 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 entry : ((Map) prop.propertyValue).entrySet()) { - BeanWrapper 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 itr = coll.iterator(); while (itr.hasNext()) { Object obj = itr.next(); - BeanWrapper 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 itr = m.keySet().iterator(); while (itr.hasNext()) { Object key = itr.next(); - BeanWrapper 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 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); } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java index 3fa3e7556..18803bd29 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java @@ -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 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) {