Browse Source

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.
pull/663/head
Christoph Strobl 10 years ago committed by Oliver Gierke
parent
commit
741a27edae
  1. 10
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java
  2. 55
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java

10
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.mapping.model.SimpleTypeHolder;
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter; 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.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.DBObjectToNamedMongoScriptCoverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToStringConverter; 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.StringToBigDecimalConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToURLConverter; 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 * Registers a conversion for the given converter. Inspects either generics of {@link Converter} and
* by a {@link GenericConverter}. * {@link ConverterFactory} or the {@link ConvertiblePair}s returned by a {@link GenericConverter}.
* *
* @param converter * @param converter
*/ */
@ -208,6 +208,10 @@ public class CustomConversions {
for (ConvertiblePair pair : genericConverter.getConvertibleTypes()) { for (ConvertiblePair pair : genericConverter.getConvertibleTypes()) {
register(new ConverterRegistration(pair, isReading, isWriting)); 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) { } else if (converter instanceof Converter) {
Class<?>[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class); Class<?>[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class);
register(new ConverterRegistration(arguments[0], arguments[1], isReading, isWriting)); register(new ConverterRegistration(arguments[0], arguments[1], isReading, isWriting));

55
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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.net.URL;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.Format; import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.UUID; import java.util.UUID;
@ -32,8 +34,10 @@ import org.joda.time.DateTime;
import org.junit.Test; import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.framework.ProxyFactory;
import org.springframework.core.convert.converter.Converter; 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.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService; import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
import org.threeten.bp.LocalDateTime; import org.threeten.bp.LocalDateTime;
@ -43,12 +47,11 @@ import com.mongodb.DBRef;
* Unit tests for {@link CustomConversions}. * Unit tests for {@link CustomConversions}.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @auhtor Christoph Strobl * @author Christoph Strobl
*/ */
public class CustomConversionsUnitTests { public class CustomConversionsUnitTests {
@Test @Test
@SuppressWarnings("unchecked")
public void findsBasicReadAndWriteConversions() { public void findsBasicReadAndWriteConversions() {
CustomConversions conversions = new CustomConversions(Arrays.asList(FormatToStringConverter.INSTANCE, CustomConversions conversions = new CustomConversions(Arrays.asList(FormatToStringConverter.INSTANCE,
@ -62,7 +65,6 @@ public class CustomConversionsUnitTests {
} }
@Test @Test
@SuppressWarnings("unchecked")
public void considersSubtypesCorrectly() { public void considersSubtypesCorrectly() {
CustomConversions conversions = new CustomConversions(Arrays.asList(NumberToStringConverter.INSTANCE, CustomConversions conversions = new CustomConversions(Arrays.asList(NumberToStringConverter.INSTANCE,
@ -132,6 +134,7 @@ public class CustomConversionsUnitTests {
*/ */
@Test @Test
public void doesNotConsiderTypeSimpleIfOnlyReadConverterIsRegistered() { public void doesNotConsiderTypeSimpleIfOnlyReadConverterIsRegistered() {
CustomConversions conversions = new CustomConversions(Arrays.asList(StringToFormatConverter.INSTANCE)); CustomConversions conversions = new CustomConversions(Arrays.asList(StringToFormatConverter.INSTANCE));
assertThat(conversions.isSimpleType(Format.class), is(false)); assertThat(conversions.isSimpleType(Format.class), is(false));
} }
@ -257,6 +260,17 @@ public class CustomConversionsUnitTests {
assertThat(customConversions.hasCustomWriteTarget(LocalDateTime.class), is(true)); 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) { private static Class<?> createProxyTypeFor(Class<?> type) {
ProxyFactory factory = new ProxyFactory(); ProxyFactory factory = new ProxyFactory();
@ -331,4 +345,37 @@ public class CustomConversionsUnitTests {
} }
} }
@WritingConverter
static class FormatConverterFactory implements ConverterFactory<String, Format> {
@Override
public <T extends Format> Converter<String, T> getConverter(Class<T> targetType) {
return new StringToFormat<T>(targetType);
}
private static final class StringToFormat<T extends Format> implements Converter<String, T> {
private final Class<T> targetType;
public StringToFormat(Class<T> 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);
}
}
}
}
} }

Loading…
Cancel
Save