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.
This commit is contained in:
Oliver Gierke
2013-11-06 23:06:53 +00:00
parent 7c0eee9e09
commit 506b6a2e85
2 changed files with 26 additions and 3 deletions

View File

@@ -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<ConvertiblePair>();
this.writingPairs = new HashSet<ConvertiblePair>();
this.readingPairs = new LinkedHashSet<ConvertiblePair>();
this.writingPairs = new LinkedHashSet<ConvertiblePair>();
this.customSimpleTypes = new HashSet<Class<?>>();
this.cache = new HashMap<Class<?>, HashMap<Class<?>, CacheValue>>();
this.converters = new ArrayList<Object>();
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);
}

View File

@@ -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<Format, String> {
INSTANCE;
@@ -206,4 +218,13 @@ public class CustomConversionsUnitTests {
return 0;
}
}
enum DateTimeToStringConverter implements Converter<DateTime, String> {
INSTANCE;
@Override
public String convert(DateTime source) {
return "";
}
}
}