From 899afe1fe70e1c138e3debf0adcc7356c68f86ce Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 6 Nov 2013 23:06:53 +0000 Subject: [PATCH] DATAMONGO-795 - More predictable behavior in CustomConversions. The target type lookup previously was unpredictable in cases two converters were registered for the same source type. We now use LinkedHashMaps to register the converters and also make sure that we prefer manually registered converters over the default ones. Related pull request: #96. --- .../core/convert/CustomConversions.java | 8 ++++--- .../convert/CustomConversionsUnitTests.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java index 2d9646ffd..3c8704636 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -86,12 +87,13 @@ public class CustomConversions { Assert.notNull(converters); - this.readingPairs = new HashSet(); - this.writingPairs = new HashSet(); + this.readingPairs = new LinkedHashSet(); + this.writingPairs = new LinkedHashSet(); this.customSimpleTypes = new HashSet>(); this.cache = new HashMap, HashMap, CacheValue>>(); this.converters = new ArrayList(); + this.converters.addAll(converters); this.converters.add(CustomToStringConverter.INSTANCE); this.converters.add(BigDecimalToStringConverter.INSTANCE); this.converters.add(StringToBigDecimalConverter.INSTANCE); @@ -101,7 +103,6 @@ public class CustomConversions { this.converters.add(StringToURLConverter.INSTANCE); this.converters.add(DBObjectToStringConverter.INSTANCE); this.converters.addAll(JodaTimeConverters.getConvertersToRegister()); - this.converters.addAll(converters); for (Object c : this.converters) { registerConversion(c); @@ -239,6 +240,7 @@ public class CustomConversions { * @return */ public Class getCustomWriteTarget(Class source, Class expectedTargetType) { + Assert.notNull(source); return getCustomTarget(source, expectedTargetType, writingPairs); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java index 9fae44fe6..af4bc2304 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java @@ -12,6 +12,7 @@ import java.util.UUID; import org.bson.types.Binary; import org.bson.types.ObjectId; +import org.joda.time.DateTime; import org.junit.Test; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.support.DefaultConversionService; @@ -172,6 +173,17 @@ public class CustomConversionsUnitTests { assertThat(conversions.hasCustomReadTarget(String.class, URL.class), is(true)); } + /** + * @see DATAMONGO-795 + */ + @Test + @SuppressWarnings("rawtypes") + public void favorsCustomConverterForIndeterminedTargetType() { + + CustomConversions conversions = new CustomConversions(Arrays.asList(DateTimeToStringConverter.INSTANCE)); + assertThat(conversions.getCustomWriteTarget(DateTime.class, null), is(equalTo((Class) String.class))); + } + enum FormatToStringConverter implements Converter { INSTANCE; @@ -207,4 +219,13 @@ public class CustomConversionsUnitTests { return 0; } } + + enum DateTimeToStringConverter implements Converter { + INSTANCE; + + @Override + public String convert(DateTime source) { + return ""; + } + } }