From 9890ac2aa5c954e2354ce4e08890dfc016872ccf Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 9 Nov 2015 10:56:38 +0100 Subject: [PATCH] DATAMONGO-1302 - Allow ConverterFactory to be registered in CustomConversions. We now allow registration of ConverterFactory within CustomConversions by inspecting the generic type arguments for determining the conversion source and target types. Original pull request: #330. --- .../core/convert/CustomConversions.java | 10 +++- .../convert/CustomConversionsUnitTests.java | 55 +++++++++++++++++-- 2 files changed, 58 insertions(+), 7 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 5b8eea9ab..d782492f5 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 @@ -44,9 +44,9 @@ import org.springframework.data.convert.WritingConverter; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter; -import org.springframework.data.mongodb.core.convert.MongoConverters.NamedMongoScriptToDBObjectConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToNamedMongoScriptCoverter; import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToStringConverter; +import org.springframework.data.mongodb.core.convert.MongoConverters.NamedMongoScriptToDBObjectConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToURLConverter; @@ -192,8 +192,8 @@ public class CustomConversions { } /** - * Registers a conversion for the given converter. Inspects either generics or the {@link ConvertiblePair}s returned - * by a {@link GenericConverter}. + * Registers a conversion for the given converter. Inspects either generics of {@link Converter} and + * {@link ConverterFactory} or the {@link ConvertiblePair}s returned by a {@link GenericConverter}. * * @param converter */ @@ -208,6 +208,10 @@ public class CustomConversions { for (ConvertiblePair pair : genericConverter.getConvertibleTypes()) { register(new ConverterRegistration(pair, isReading, isWriting)); } + } else if (converter instanceof ConverterFactory) { + + Class[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), ConverterFactory.class); + register(new ConverterRegistration(arguments[0], arguments[1], isReading, isWriting)); } else if (converter instanceof Converter) { Class[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class); register(new ConverterRegistration(arguments[0], arguments[1], isReading, isWriting)); 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 7589ca0f7..924b30bce 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 @@ -1,5 +1,5 @@ /* - * Copyright 2011-2014 the original author or authors. + * Copyright 2011-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,9 @@ import static org.junit.Assert.*; import java.net.URL; import java.text.DateFormat; import java.text.Format; +import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.Locale; import java.util.UUID; @@ -32,8 +34,10 @@ import org.joda.time.DateTime; import org.junit.Test; import org.springframework.aop.framework.ProxyFactory; import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.data.convert.WritingConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter; import org.threeten.bp.LocalDateTime; @@ -43,12 +47,11 @@ import com.mongodb.DBRef; * Unit tests for {@link CustomConversions}. * * @author Oliver Gierke - * @auhtor Christoph Strobl + * @author Christoph Strobl */ public class CustomConversionsUnitTests { @Test - @SuppressWarnings("unchecked") public void findsBasicReadAndWriteConversions() { CustomConversions conversions = new CustomConversions(Arrays.asList(FormatToStringConverter.INSTANCE, @@ -62,7 +65,6 @@ public class CustomConversionsUnitTests { } @Test - @SuppressWarnings("unchecked") public void considersSubtypesCorrectly() { CustomConversions conversions = new CustomConversions(Arrays.asList(NumberToStringConverter.INSTANCE, @@ -132,6 +134,7 @@ public class CustomConversionsUnitTests { */ @Test public void doesNotConsiderTypeSimpleIfOnlyReadConverterIsRegistered() { + CustomConversions conversions = new CustomConversions(Arrays.asList(StringToFormatConverter.INSTANCE)); assertThat(conversions.isSimpleType(Format.class), is(false)); } @@ -257,6 +260,17 @@ public class CustomConversionsUnitTests { assertThat(customConversions.hasCustomWriteTarget(LocalDateTime.class), is(true)); } + /** + * @see DATAMONGO-1302 + */ + @Test + public void registersConverterFactoryCorrectly() { + + CustomConversions customConversions = new CustomConversions(Collections.singletonList(new FormatConverterFactory())); + + assertThat(customConversions.getCustomWriteTarget(String.class, SimpleDateFormat.class), notNullValue()); + } + private static Class createProxyTypeFor(Class type) { ProxyFactory factory = new ProxyFactory(); @@ -331,4 +345,37 @@ public class CustomConversionsUnitTests { } } + + @WritingConverter + static class FormatConverterFactory implements ConverterFactory { + + @Override + public Converter getConverter(Class targetType) { + return new StringToFormat(targetType); + } + + private static final class StringToFormat implements Converter { + + private final Class targetType; + + public StringToFormat(Class targetType) { + this.targetType = targetType; + } + + @Override + public T convert(String source) { + + if (source.length() == 0) { + return null; + } + + try { + return targetType.newInstance(); + } catch (Exception e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + } + } + + } }