From e1daf36ed82407f680e7b7c4777e0bc3daf593f8 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Fri, 22 Jul 2011 17:52:48 +0200 Subject: [PATCH] DATADOC-209 - MappingMongoConverter handles collections of enums correctly now. --- .../core/convert/MappingMongoConverter.java | 51 ++++++++++++++++--- .../MappingMongoConverterUnitTests.java | 37 ++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index 2fa85870b..77b247005 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -535,7 +535,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App Class elementType = element.getClass(); if (conversions.isSimpleType(elementType)) { - dbList.add(element); + dbList.add(getPotentiallyConvertedSimpleWrite(element)); } else if (element instanceof Collection || elementType.isArray()) { dbList.add(createCollectionDBObject(componentType, asCollection(element))); } else { @@ -601,16 +601,55 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * @param dbObject */ private void writeSimpleInternal(String key, Object value, DBObject dbObject) { + dbObject.put(key, getPotentiallyConvertedSimpleWrite(value)); + } + /** + * Checks whether we have a custom conversion registered for the given value into an arbitrary simple Mongo type. + * Returns the converted value if so. If not, we perform special enum handling or simply return the value as is. + * + * @param value + * @return + */ + private Object getPotentiallyConvertedSimpleWrite(Object value) { + + if (value == null) { + return null; + } + Class customTarget = conversions.getCustomWriteTarget(value.getClass(), null); - Object valueToSet = null; if (customTarget != null) { - valueToSet = conversionService.convert(value, customTarget); + return conversionService.convert(value, customTarget); } else { - valueToSet = value.getClass().isEnum() ? ((Enum) value).name() : value; + return value.getClass().isEnum() ? ((Enum) value).name() : value; } - dbObject.put(key, valueToSet); + } + + /** + * Checks whether we have a custom conversion for the given simple object. Converts the given value if so, applies + * {@link Enum} handling or returns the value as is. + * + * @param value + * @param target must not be {@literal null}. + * @return + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + private Object getPotentiallyConvertedSimpleRead(Object value, Class target) { + + if (value == null) { + return null; + } + + if (conversions.hasCustomReadTarget(value.getClass(), target)) { + return conversionService.convert(value, target); + } + + if (target.isEnum()) { + return Enum.valueOf((Class) target, value.toString()); + } + + return value; } protected DBRef createDBRef(Object target, org.springframework.data.mongodb.core.mapping.DBRef dbref) { @@ -686,7 +725,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } else if (dbObjItem instanceof DBObject) { items.add(read(prop.getComponentType(), (DBObject) dbObjItem)); } else { - items.add(dbObjItem); + items.add(getPotentiallyConvertedSimpleRead(dbObjItem, prop.getComponentType())); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index c38b4c37d..ab0f601e2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -196,6 +196,25 @@ public class MappingMongoConverterUnitTests { assertThat(result.get("sampleEnum").toString(), is("FIRST")); } + /** + * @see DATADOC-209 + */ + @Test + public void writesEnumCollectionCorrectly() { + + ClassWithEnumProperty value = new ClassWithEnumProperty(); + value.enums = Arrays.asList(SampleEnum.FIRST); + + DBObject result = new BasicDBObject(); + converter.write(value, result); + + assertThat(result.get("enums"), is(BasicDBList.class)); + + BasicDBList enums = (BasicDBList) result.get("enums"); + assertThat(enums.size(), is(1)); + assertThat((String) enums.get(0), is("FIRST")); + } + /** * @see DATADOC-136 */ @@ -207,6 +226,23 @@ public class MappingMongoConverterUnitTests { assertThat(result.sampleEnum, is(SampleEnum.FIRST)); } + /** + * @see DATADOC-209 + */ + @Test + public void readsEnumCollectionsCorrectly() { + + BasicDBList enums = new BasicDBList(); + enums.add("FIRST"); + DBObject dbObject = new BasicDBObject("enums", enums); + + ClassWithEnumProperty result = converter.read(ClassWithEnumProperty.class, dbObject); + + assertThat(result.enums, is(List.class)); + assertThat(result.enums.size(), is(1)); + assertThat(result.enums, hasItem(SampleEnum.FIRST)); + } + /** * @see DATADOC-144 */ @@ -415,6 +451,7 @@ public class MappingMongoConverterUnitTests { class ClassWithEnumProperty { SampleEnum sampleEnum; + List enums; } enum SampleEnum {