From 96e4b7ed37b702a1c534216a95d5bb0055b1e27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Basl=C3=A9?= Date: Thu, 23 Jul 2015 09:56:32 +0200 Subject: [PATCH] DATACOUCH-149 - Switched to PersistentPropertyAccessor API. Replaces all references to BeanWrapper with usage of PersistentPropertyAccessor API. MappingCouchbaseEntityInformation now extends PersistentEntityInformation to get rid of obsolete code implemented by the superclass. --- .../couchbase/core/CouchbaseTemplate.java | 20 ++++--- .../convert/MappingCouchbaseConverter.java | 33 +++++++----- .../MappingCouchbaseEntityInformation.java | 54 +++---------------- 3 files changed, 42 insertions(+), 65 deletions(-) diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java index 53c8b175..3ba4b357 100644 --- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java +++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java @@ -65,8 +65,9 @@ import org.springframework.data.couchbase.core.mapping.event.BeforeConvertEvent; import org.springframework.data.couchbase.core.mapping.event.BeforeDeleteEvent; import org.springframework.data.couchbase.core.mapping.event.BeforeSaveEvent; import org.springframework.data.couchbase.core.mapping.event.CouchbaseMappingEvent; +import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.BeanWrapper; +import org.springframework.data.mapping.model.ConvertingPropertyAccessor; /** * @author Michael Nitschinger @@ -452,10 +453,10 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP final String operationDesc = failOnExist ? "Insert" : failOnMissing ? "Update" : "Upsert"; - final BeanWrapper beanWrapper = BeanWrapper.create(objectToPersist, converter.getConversionService()); + final ConvertingPropertyAccessor accessor = getPropertyAccessor(objectToPersist); final CouchbasePersistentEntity persistentEntity = mappingContext.getPersistentEntity(objectToPersist.getClass()); final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty(); - final Long version = versionProperty != null ? beanWrapper.getProperty(versionProperty, Long.class) : null; + final Long version = versionProperty != null ? accessor.getProperty(versionProperty, Long.class) : null; maybeEmitEvent(new BeforeConvertEvent(objectToPersist)); final CouchbaseDocument converted = new CouchbaseDocument(); @@ -480,7 +481,7 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP if (persistentEntity.hasVersionProperty() && storedDoc != null && storedDoc.cas() != 0) { //inject new cas into the bean - beanWrapper.setProperty(versionProperty, storedDoc.cas()); + accessor.setProperty(versionProperty, storedDoc.cas()); return true; } return false; @@ -537,15 +538,22 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP final CouchbaseDocument converted = new CouchbaseDocument(id); Object readEntity = converter.read(entityClass, (CouchbaseDocument) decodeAndUnwrap(data, converted)); - final BeanWrapper beanWrapper = BeanWrapper.create(readEntity, converter.getConversionService()); + final ConvertingPropertyAccessor accessor = getPropertyAccessor(readEntity); CouchbasePersistentEntity persistentEntity = mappingContext.getPersistentEntity(readEntity.getClass()); if (persistentEntity.hasVersionProperty()) { - beanWrapper.setProperty(persistentEntity.getVersionProperty(), data.cas()); + accessor.setProperty(persistentEntity.getVersionProperty(), data.cas()); } return (T) readEntity; } + private final ConvertingPropertyAccessor getPropertyAccessor(Object source) { + CouchbasePersistentEntity entity = mappingContext.getPersistentEntity(source.getClass()); + PersistentPropertyAccessor accessor = entity.getPropertyAccessor(source); + + return new ConvertingPropertyAccessor(accessor, converter.getConversionService()); + } + private void checkN1ql() { if (!getCouchbaseClusterInfo().checkAvailable(CouchbaseFeature.N1QL)) { throw new UnsupportedCouchbaseFeatureException("Detected usage of N1QL in template, which is unsupported on this cluster", diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java b/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java index a5e33171..c2837ee0 100644 --- a/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java +++ b/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java @@ -35,10 +35,11 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.AssociationHandler; +import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PreferredConstructor.Parameter; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.BeanWrapper; +import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.ParameterValueProvider; @@ -201,9 +202,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter getParameterProvider(entity, source, evaluator, parent); EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity); - R instance = instantiator.createInstance(entity, provider); - final BeanWrapper wrapper = BeanWrapper.create(instance, conversionService); - final R result = wrapper.getBean(); + final R instance = instantiator.createInstance(entity, provider); + final ConvertingPropertyAccessor accessor = getPropertyAccessor(instance); entity.doWithProperties(new PropertyHandler() { @Override @@ -211,8 +211,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter if (!doesPropertyExistInSource(prop) || entity.isConstructorArgument(prop)) { return; } - Object obj = prop.isIdProperty() ? source.getId() : getValueInternal(prop, source, result); - wrapper.setProperty(prop, obj); + Object obj = prop.isIdProperty() ? source.getId() : getValueInternal(prop, source, instance); + accessor.setProperty(prop, obj); } private boolean doesPropertyExistInSource(final CouchbasePersistentProperty property) { @@ -224,12 +224,12 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter @Override public void doWithAssociation(final Association association) { CouchbasePersistentProperty inverseProp = association.getInverse(); - Object obj = getValueInternal(inverseProp, source, result); - wrapper.setProperty(inverseProp, obj); + Object obj = getValueInternal(inverseProp, source, instance); + accessor.setProperty(inverseProp, obj); } }); - return result; + return instance; } /** @@ -421,12 +421,12 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter throw new MappingException("No mapping metadata found for entity of type " + source.getClass().getName()); } - final BeanWrapper wrapper = BeanWrapper.create(source, conversionService); + final ConvertingPropertyAccessor accessor = getPropertyAccessor(source); final CouchbasePersistentProperty idProperty = entity.getIdProperty(); final CouchbasePersistentProperty versionProperty = entity.getVersionProperty(); if (idProperty != null && target.getId() == null) { - String id = wrapper.getProperty(idProperty, String.class); + String id = accessor.getProperty(idProperty, String.class); target.setId(id); } target.setExpiration(entity.getExpiry()); @@ -438,7 +438,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter return; } - Object propertyObj = wrapper.getProperty(prop, prop.getType()); + Object propertyObj = accessor.getProperty(prop, prop.getType()); if (null != propertyObj) { if (!conversions.isSimpleType(propertyObj.getClass())) { writePropertyInternal(propertyObj, target, prop); @@ -454,7 +454,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter public void doWithAssociation(final Association association) { CouchbasePersistentProperty inverseProp = association.getInverse(); Class type = inverseProp.getType(); - Object propertyObj = wrapper.getProperty(inverseProp, type); + Object propertyObj = accessor.getProperty(inverseProp, type); if (null != propertyObj) { writePropertyInternal(propertyObj, target, inverseProp); } @@ -732,6 +732,13 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter } } + private ConvertingPropertyAccessor getPropertyAccessor(Object source) { + CouchbasePersistentEntity entity = mappingContext.getPersistentEntity(source.getClass()); + PersistentPropertyAccessor accessor = entity.getPropertyAccessor(source); + + return new ConvertingPropertyAccessor(accessor, conversionService); + } + /** * A property value provider for Couchbase documents. */ diff --git a/src/main/java/org/springframework/data/couchbase/repository/support/MappingCouchbaseEntityInformation.java b/src/main/java/org/springframework/data/couchbase/repository/support/MappingCouchbaseEntityInformation.java index c05cc67d..1e1a93c5 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/support/MappingCouchbaseEntityInformation.java +++ b/src/main/java/org/springframework/data/couchbase/repository/support/MappingCouchbaseEntityInformation.java @@ -16,66 +16,28 @@ package org.springframework.data.couchbase.repository.support; -import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity; -import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty; -import org.springframework.data.couchbase.repository.query.CouchbaseEntityInformation; -import org.springframework.data.mapping.model.BeanWrapper; -import org.springframework.data.repository.core.support.AbstractEntityInformation; - import java.io.Serializable; +import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity; +import org.springframework.data.couchbase.repository.query.CouchbaseEntityInformation; +import org.springframework.data.repository.core.support.PersistentEntityInformation; + /** * Entity Information container. * * @author Michael Nitschinger + * @author Oliver Grieke */ public class MappingCouchbaseEntityInformation - extends AbstractEntityInformation + extends PersistentEntityInformation implements CouchbaseEntityInformation { /** - * Contains the entity metadata. - */ - private final CouchbasePersistentEntity entityMetadata; - - /** - * Create a new Infomration container. + * Create a new Information container. * * @param entity the entity of the container. */ public MappingCouchbaseEntityInformation(final CouchbasePersistentEntity entity) { - super(entity.getType()); - entityMetadata = entity; - } - - /** - * Returns the ID of the entity. - * - * @param entity the entity from where to extract the ID from. - * @return the id of the entity. - */ - @Override - public ID getId(T entity) { - CouchbasePersistentProperty idProperty = entityMetadata.getIdProperty(); - - if (idProperty == null) { - return null; - } - - try { - return (ID) BeanWrapper.create(entity, null).getProperty(idProperty); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Returns the ID type. - * - * @return the ID type. - */ - @Override - public Class getIdType() { - return (Class) entityMetadata.getIdProperty().getType(); + super(entity); } }