DATAMONGO-402 - Adapt new entity instantiation API.
Adapt to the entity instantiation API refactored to be able to cope with non-static member classes.
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
<org.springframework.version.30>3.0.7.RELEASE</org.springframework.version.30>
|
||||
<org.springframework.version.40>4.0.0.RELEASE</org.springframework.version.40>
|
||||
<org.springframework.version.range>[${org.springframework.version.30}, ${org.springframework.version.40})</org.springframework.version.range>
|
||||
<data.commons.version>1.3.0.M1</data.commons.version>
|
||||
<data.commons.version>1.3.0.BUILD-SNAPSHOT</data.commons.version>
|
||||
<aspectj.version>1.6.11.RELEASE</aspectj.version>
|
||||
</properties>
|
||||
|
||||
@@ -245,8 +245,8 @@
|
||||
</pluginRepositories>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-milestone</id>
|
||||
<url>http://repo.springsource.org/libs-milestone</url>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<url>http://repo.springsource.org/libs-snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<reporting>
|
||||
|
||||
@@ -169,8 +169,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return read(ClassTypeInformation.from(clazz), dbo);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <S extends Object> S read(TypeInformation<S> type, DBObject dbo) {
|
||||
return read(type, dbo, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <S extends Object> S read(TypeInformation<S> type, DBObject dbo, Object parent) {
|
||||
|
||||
if (null == dbo) {
|
||||
return null;
|
||||
@@ -188,11 +192,11 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
}
|
||||
|
||||
if (typeToUse.isCollectionLike() && dbo instanceof BasicDBList) {
|
||||
return (S) readCollectionOrArray(typeToUse, (BasicDBList) dbo);
|
||||
return (S) readCollectionOrArray(typeToUse, (BasicDBList) dbo, parent);
|
||||
}
|
||||
|
||||
if (typeToUse.isMap()) {
|
||||
return (S) readMap(typeToUse, dbo);
|
||||
return (S) readMap(typeToUse, dbo, parent);
|
||||
}
|
||||
|
||||
// Retrieve persistent entity info
|
||||
@@ -202,29 +206,30 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
throw new MappingException("No mapping metadata found for " + rawType.getName());
|
||||
}
|
||||
|
||||
return read(persistentEntity, dbo);
|
||||
return read(persistentEntity, dbo, parent);
|
||||
}
|
||||
|
||||
private ParameterValueProvider<MongoPersistentProperty> getParameterProvider(MongoPersistentEntity<?> entity,
|
||||
DBObject source, DefaultSpELExpressionEvaluator evaluator) {
|
||||
DBObject source, DefaultSpELExpressionEvaluator evaluator, Object parent) {
|
||||
|
||||
MongoDbPropertyValueProvider provider = new MongoDbPropertyValueProvider(source, evaluator);
|
||||
MongoDbPropertyValueProvider provider = new MongoDbPropertyValueProvider(source, evaluator, parent);
|
||||
PersistentEntityParameterValueProvider<MongoPersistentProperty> parameterProvider = new PersistentEntityParameterValueProvider<MongoPersistentProperty>(
|
||||
entity, provider);
|
||||
entity, provider, parent);
|
||||
parameterProvider.setSpELEvaluator(evaluator);
|
||||
|
||||
return parameterProvider;
|
||||
}
|
||||
|
||||
private <S extends Object> S read(final MongoPersistentEntity<S> entity, final DBObject dbo) {
|
||||
private <S extends Object> S read(final MongoPersistentEntity<S> entity, final DBObject dbo, Object parent) {
|
||||
|
||||
final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(dbo, spELContext);
|
||||
|
||||
ParameterValueProvider<MongoPersistentProperty> provider = getParameterProvider(entity, dbo, evaluator);
|
||||
ParameterValueProvider<MongoPersistentProperty> provider = getParameterProvider(entity, dbo, evaluator, parent);
|
||||
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
|
||||
S instance = instantiator.createInstance(entity, provider);
|
||||
|
||||
final BeanWrapper<MongoPersistentEntity<S>, S> wrapper = BeanWrapper.create(instance, conversionService);
|
||||
final S result = wrapper.getBean();
|
||||
|
||||
// Set properties not already set in the constructor
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
@@ -237,7 +242,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return;
|
||||
}
|
||||
|
||||
Object obj = getValueInternal(prop, dbo, evaluator);
|
||||
Object obj = getValueInternal(prop, dbo, evaluator, result);
|
||||
wrapper.setProperty(prop, obj, useFieldAccessOnly);
|
||||
}
|
||||
});
|
||||
@@ -246,7 +251,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
entity.doWithAssociations(new AssociationHandler<MongoPersistentProperty>() {
|
||||
public void doWithAssociation(Association<MongoPersistentProperty> association) {
|
||||
MongoPersistentProperty inverseProp = association.getInverse();
|
||||
Object obj = getValueInternal(inverseProp, dbo, evaluator);
|
||||
Object obj = getValueInternal(inverseProp, dbo, evaluator, result);
|
||||
try {
|
||||
wrapper.setProperty(inverseProp, obj);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -257,7 +262,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
}
|
||||
});
|
||||
|
||||
return wrapper.getBean();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -677,9 +682,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return new DBRef(db, collection, idMapper.convertId(id));
|
||||
}
|
||||
|
||||
protected Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, SpELExpressionEvaluator eval) {
|
||||
protected Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, SpELExpressionEvaluator eval,
|
||||
Object parent) {
|
||||
|
||||
MongoDbPropertyValueProvider provider = new MongoDbPropertyValueProvider(dbo, spELContext);
|
||||
MongoDbPropertyValueProvider provider = new MongoDbPropertyValueProvider(dbo, spELContext, parent);
|
||||
return provider.getPropertyValue(prop);
|
||||
}
|
||||
|
||||
@@ -691,7 +697,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
* @return the converted {@link Collections}, will never be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Collection<?> readCollectionOrArray(TypeInformation<?> targetType, BasicDBList sourceValue) {
|
||||
private Collection<?> readCollectionOrArray(TypeInformation<?> targetType, BasicDBList sourceValue, Object parent) {
|
||||
|
||||
Assert.notNull(targetType);
|
||||
|
||||
@@ -704,9 +710,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
for (int i = 0; i < sourceValue.size(); i++) {
|
||||
Object dbObjItem = sourceValue.get(i);
|
||||
if (dbObjItem instanceof DBRef) {
|
||||
items.add(read(targetType.getComponentType(), ((DBRef) dbObjItem).fetch()));
|
||||
items.add(read(targetType.getComponentType(), ((DBRef) dbObjItem).fetch(), parent));
|
||||
} else if (dbObjItem instanceof DBObject) {
|
||||
items.add(read(targetType.getComponentType(), (DBObject) dbObjItem));
|
||||
items.add(read(targetType.getComponentType(), (DBObject) dbObjItem, parent));
|
||||
} else {
|
||||
TypeInformation<?> componentType = targetType.getComponentType();
|
||||
items.add(getPotentiallyConvertedSimpleRead(dbObjItem, componentType == null ? null : componentType.getType()));
|
||||
@@ -724,7 +730,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<Object, Object> readMap(TypeInformation<?> type, DBObject dbObject) {
|
||||
protected Map<Object, Object> readMap(TypeInformation<?> type, DBObject dbObject, Object parent) {
|
||||
|
||||
Assert.notNull(dbObject);
|
||||
|
||||
@@ -749,7 +755,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
TypeInformation<?> valueType = type.getMapValueType();
|
||||
|
||||
if (value instanceof DBObject) {
|
||||
map.put(key, read(valueType, (DBObject) value));
|
||||
map.put(key, read(valueType, (DBObject) value, parent));
|
||||
} else {
|
||||
Class<?> valueClass = valueType == null ? null : valueType.getType();
|
||||
map.put(key, getPotentiallyConvertedSimpleRead(value, valueClass));
|
||||
@@ -874,18 +880,20 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
private final DBObject source;
|
||||
private final SpELExpressionEvaluator evaluator;
|
||||
private final Object parent;
|
||||
|
||||
public MongoDbPropertyValueProvider(DBObject source, SpELContext factory) {
|
||||
this(source, new DefaultSpELExpressionEvaluator(source, factory));
|
||||
public MongoDbPropertyValueProvider(DBObject source, SpELContext factory, Object parent) {
|
||||
this(source, new DefaultSpELExpressionEvaluator(source, factory), parent);
|
||||
}
|
||||
|
||||
public MongoDbPropertyValueProvider(DBObject source, DefaultSpELExpressionEvaluator evaluator) {
|
||||
public MongoDbPropertyValueProvider(DBObject source, DefaultSpELExpressionEvaluator evaluator, Object parent) {
|
||||
|
||||
Assert.notNull(source);
|
||||
Assert.notNull(evaluator);
|
||||
|
||||
this.source = source;
|
||||
this.evaluator = evaluator;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -906,11 +914,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
if (conversions.hasCustomReadTarget(value.getClass(), type.getType())) {
|
||||
return (T) conversionService.convert(value, type.getType());
|
||||
} else if (value instanceof DBRef) {
|
||||
return (T) read(type, ((DBRef) value).fetch());
|
||||
return (T) read(type, ((DBRef) value).fetch(), parent);
|
||||
} else if (value instanceof BasicDBList) {
|
||||
return (T) getPotentiallyConvertedSimpleRead(readCollectionOrArray(type, (BasicDBList) value), type.getType());
|
||||
return (T) getPotentiallyConvertedSimpleRead(readCollectionOrArray(type, (BasicDBList) value, parent),
|
||||
type.getType());
|
||||
} else if (value instanceof DBObject) {
|
||||
return (T) read(type, (DBObject) value);
|
||||
return (T) read(type, (DBObject) value, parent);
|
||||
} else {
|
||||
return (T) getPotentiallyConvertedSimpleRead(value, type.getType());
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.PersonPojoStringId;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
@@ -1016,6 +1017,34 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(readResult.iterator().next(), is(Map.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-402
|
||||
*/
|
||||
@Test
|
||||
public void readsMemberClassCorrectly() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject("inner", new BasicDBObject("value", "FOO!"));
|
||||
|
||||
Outer outer = converter.read(Outer.class, dbObject);
|
||||
assertThat(outer.inner, is(notNullValue()));
|
||||
assertThat(outer.inner.value, is("FOO!"));
|
||||
assertSyntheticFieldValueOf(outer.inner, outer);
|
||||
}
|
||||
|
||||
private static void assertSyntheticFieldValueOf(Object target, Object expected) {
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
try {
|
||||
assertThat(ReflectionTestUtils.getField(target, "this$" + i), is(expected));
|
||||
return;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Suppress and try next
|
||||
}
|
||||
}
|
||||
|
||||
fail(String.format("Didn't find synthetic field on %s!", target));
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
@@ -1147,6 +1176,15 @@ public class MappingMongoConverterUnitTests {
|
||||
Object value;
|
||||
}
|
||||
|
||||
static class Outer {
|
||||
|
||||
class Inner {
|
||||
String value;
|
||||
}
|
||||
|
||||
Inner inner;
|
||||
}
|
||||
|
||||
private class LocalDateToDateConverter implements Converter<LocalDate, Date> {
|
||||
|
||||
public Date convert(LocalDate source) {
|
||||
|
||||
Reference in New Issue
Block a user