From 506b6a2e85dd312f2a9cef5eb2e2e06141791a83 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 d4ac002fb..4d42cb8df 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; @@ -171,6 +172,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; @@ -206,4 +218,13 @@ public class CustomConversionsUnitTests { return 0; } } + + enum DateTimeToStringConverter implements Converter { + INSTANCE; + + @Override + public String convert(DateTime source) { + return ""; + } + } }