From 8f2ced8adab9514c590ad797f41d8a530e0c76ec Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 18 Mar 2014 09:16:21 +0100 Subject: [PATCH] DATAMONGO-881 - Allow custom conversions to override default conversions. User provided converters are now registered *after* the default converters to make sure they enjoy precedence over the default ones. This is achieved by inverting the order of converters after the conversions have been registered. This is necessary as the registration order for convertible pairs is different from the one of the converters. For the pairs, earlier registered instances take precedence, while for the actual converter instances, instances registered later trump ones registered before. --- .../core/convert/CustomConversions.java | 31 ++++++++++++------- .../convert/CustomConversionsUnitTests.java | 24 ++++++++++++++ 2 files changed, 43 insertions(+), 12 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 7a38306b3..93304cd8b 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 @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.convert; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -93,22 +94,28 @@ public class CustomConversions { this.customSimpleTypes = new HashSet>(); this.customReadTargetTypes = new ConcurrentHashMap(); - this.converters = new ArrayList(); - this.converters.addAll(converters); - this.converters.add(CustomToStringConverter.INSTANCE); - this.converters.add(BigDecimalToStringConverter.INSTANCE); - this.converters.add(StringToBigDecimalConverter.INSTANCE); - this.converters.add(BigIntegerToStringConverter.INSTANCE); - this.converters.add(StringToBigIntegerConverter.INSTANCE); - this.converters.add(URLToStringConverter.INSTANCE); - this.converters.add(StringToURLConverter.INSTANCE); - this.converters.add(DBObjectToStringConverter.INSTANCE); - this.converters.addAll(JodaTimeConverters.getConvertersToRegister()); + List toRegister = new ArrayList(); - for (Object c : this.converters) { + toRegister.addAll(converters); + toRegister.add(CustomToStringConverter.INSTANCE); + toRegister.add(BigDecimalToStringConverter.INSTANCE); + toRegister.add(StringToBigDecimalConverter.INSTANCE); + toRegister.add(BigIntegerToStringConverter.INSTANCE); + toRegister.add(StringToBigIntegerConverter.INSTANCE); + toRegister.add(URLToStringConverter.INSTANCE); + toRegister.add(StringToURLConverter.INSTANCE); + toRegister.add(DBObjectToStringConverter.INSTANCE); + toRegister.addAll(JodaTimeConverters.getConvertersToRegister()); + + // Add user provided converters to make sure they can override the defaults + + for (Object c : toRegister) { registerConversion(c); } + Collections.reverse(toRegister); + + this.converters = Collections.unmodifiableList(toRegister); this.simpleTypeHolder = new SimpleTypeHolder(customSimpleTypes, MongoSimpleTypes.HOLDER); } 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 4d42cb8df..e75094444 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 @@ -7,6 +7,7 @@ import java.net.URL; import java.text.DateFormat; import java.text.Format; import java.util.Arrays; +import java.util.Date; import java.util.Locale; import java.util.UUID; @@ -183,6 +184,19 @@ public class CustomConversionsUnitTests { assertThat(conversions.getCustomWriteTarget(DateTime.class, null), is(equalTo((Class) String.class))); } + /** + * @see DATAMONGO-881 + */ + @Test + public void customConverterOverridesDefault() { + + CustomConversions conversions = new CustomConversions(Arrays.asList(CustomDateTimeConverter.INSTANCE)); + GenericConversionService conversionService = new DefaultConversionService(); + conversions.registerConvertersIn(conversionService); + + assertThat(conversionService.convert(new DateTime(), Date.class), is(new Date(0))); + } + enum FormatToStringConverter implements Converter { INSTANCE; @@ -227,4 +241,14 @@ public class CustomConversionsUnitTests { return ""; } } + + enum CustomDateTimeConverter implements Converter { + + INSTANCE; + + @Override + public Date convert(DateTime source) { + return new Date(0); + } + } }