Skip to content

Commit 3436c63

Browse files
committed
DAATCMNS-1034 - Improvements to new ConverterBuilder API.
Made nested API interfaces public so that they can actually be used. CustomConversions now considers ConverterAware and treats them appropriately for ConvertiblePair registration as well as during the registration in the ConversionService. Tweaked parameter types in CustomConversions to rather accept a Collection<?> for the converters (previously List<?>). Also, registerConverterIn(…) now takes a ConverterRegistry over a GenericConversionService. Polished Javadoc and non-null assertions.
1 parent e9438ed commit 3436c63

File tree

3 files changed

+76
-30
lines changed

3 files changed

+76
-30
lines changed

src/main/java/org/springframework/data/convert/ConverterBuilder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static <S, T> WritingConverterBuilder<S, T> writing(Class<S> source, Class<T> ta
8787
* @author Oliver Gierke
8888
* @since 2.0
8989
*/
90-
interface WritingConverterAware {
90+
public interface WritingConverterAware {
9191

9292
/**
9393
* Returns the writing converter already created.
@@ -103,7 +103,7 @@ interface WritingConverterAware {
103103
* @author Oliver Gierke
104104
* @since 2.0
105105
*/
106-
interface ReadingConverterAware {
106+
public interface ReadingConverterAware {
107107

108108
/**
109109
* Returns the reading converter already created.
@@ -119,7 +119,7 @@ interface ReadingConverterAware {
119119
* @author Oliver Gierke
120120
* @since 2.0
121121
*/
122-
interface ReadingConverterBuilder<T, S> extends ConverterBuilder, ReadingConverterAware {
122+
public interface ReadingConverterBuilder<T, S> extends ConverterBuilder, ReadingConverterAware {
123123

124124
/**
125125
* Creates a new {@link ConverterAware} by registering the given {@link Function} to add a write converter.
@@ -136,7 +136,7 @@ interface ReadingConverterBuilder<T, S> extends ConverterBuilder, ReadingConvert
136136
* @author Oliver Gierke
137137
* @since 2.0
138138
*/
139-
interface WritingConverterBuilder<S, T> extends ConverterBuilder, WritingConverterAware {
139+
public interface WritingConverterBuilder<S, T> extends ConverterBuilder, WritingConverterAware {
140140

141141
/**
142142
* Creates a new {@link ConverterAware} by registering the given {@link Function} to add a write converter.
@@ -153,5 +153,5 @@ interface WritingConverterBuilder<S, T> extends ConverterBuilder, WritingConvert
153153
* @author Oliver Gierke
154154
* @since 2.0
155155
*/
156-
interface ConverterAware extends ConverterBuilder, ReadingConverterAware, WritingConverterAware {}
156+
public interface ConverterAware extends ConverterBuilder, ReadingConverterAware, WritingConverterAware {}
157157
}

src/main/java/org/springframework/data/convert/CustomConversions.java

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737
import org.springframework.core.GenericTypeResolver;
3838
import org.springframework.core.convert.converter.Converter;
3939
import org.springframework.core.convert.converter.ConverterFactory;
40+
import org.springframework.core.convert.converter.ConverterRegistry;
4041
import org.springframework.core.convert.converter.GenericConverter;
4142
import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair;
4243
import org.springframework.core.convert.support.GenericConversionService;
44+
import org.springframework.data.convert.ConverterBuilder.ConverterAware;
4345
import org.springframework.data.mapping.model.SimpleTypeHolder;
4446
import org.springframework.data.util.Optionals;
4547
import org.springframework.data.util.Streamable;
@@ -90,10 +92,12 @@ public class CustomConversions {
9092
/**
9193
* Creates a new {@link CustomConversions} instance registering the given converters.
9294
*
93-
* @param converters
95+
* @param storeConversions must not be {@literal null}.
96+
* @param converters must not be {@literal null}.
9497
*/
95-
public CustomConversions(StoreConversions storeConversions, List<?> converters) {
98+
public CustomConversions(StoreConversions storeConversions, Collection<?> converters) {
9699

100+
Assert.notNull(storeConversions, "StoreConversions must not be null!");
97101
Assert.notNull(converters, "List of converters must not be null!");
98102

99103
this.readingPairs = new LinkedHashSet<>();
@@ -149,33 +153,46 @@ public boolean isSimpleType(Class<?> type) {
149153
*
150154
* @param conversionService
151155
*/
152-
public void registerConvertersIn(GenericConversionService conversionService) {
156+
public void registerConvertersIn(ConverterRegistry conversionService) {
153157

154158
Assert.notNull(conversionService, "ConversionService must not be null!");
155159

156-
converters.forEach(it -> {
160+
converters.forEach(it -> registerConverterIn(it, conversionService));
161+
}
157162

158-
boolean added = false;
163+
/**
164+
* Registers the given converter in the given {@link GenericConversionService}.
165+
*
166+
* @param candidate must not be {@literal null}.
167+
* @param conversionService must not be {@literal null}.
168+
*/
169+
private void registerConverterIn(Object candidate, ConverterRegistry conversionService) {
159170

160-
if (it instanceof Converter) {
161-
conversionService.addConverter(Converter.class.cast(it));
162-
added = true;
163-
}
171+
boolean added = false;
164172

165-
if (it instanceof ConverterFactory) {
166-
conversionService.addConverterFactory(ConverterFactory.class.cast(it));
167-
added = true;
168-
}
173+
if (candidate instanceof Converter) {
174+
conversionService.addConverter(Converter.class.cast(candidate));
175+
added = true;
176+
}
169177

170-
if (it instanceof GenericConverter) {
171-
conversionService.addConverter(GenericConverter.class.cast(it));
172-
added = true;
173-
}
178+
if (candidate instanceof ConverterFactory) {
179+
conversionService.addConverterFactory(ConverterFactory.class.cast(candidate));
180+
added = true;
181+
}
174182

175-
if (!added) {
176-
throw new IllegalArgumentException(String.format(NOT_A_CONVERTER, it));
177-
}
178-
});
183+
if (candidate instanceof GenericConverter) {
184+
conversionService.addConverter(GenericConverter.class.cast(candidate));
185+
added = true;
186+
}
187+
188+
if (candidate instanceof ConverterAware) {
189+
ConverterAware.class.cast(candidate).getConverters().forEach(it -> registerConverterIn(it, conversionService));
190+
added = true;
191+
}
192+
193+
if (!added) {
194+
throw new IllegalArgumentException(String.format(NOT_A_CONVERTER, candidate));
195+
}
179196
}
180197

181198
/**
@@ -460,10 +477,15 @@ public Streamable<ConverterRegistration> getRegistrationsFor(Object converter) {
460477
boolean isWriting = type.isAnnotationPresent(WritingConverter.class);
461478
boolean isReading = type.isAnnotationPresent(ReadingConverter.class);
462479

463-
if (converter instanceof GenericConverter) {
480+
if (converter instanceof ConverterAware) {
481+
482+
return Streamable.of(() -> ConverterAware.class.cast(converter).getConverters().stream()//
483+
.flatMap(it -> getRegistrationsFor(it).stream()));
484+
485+
} else if (converter instanceof GenericConverter) {
464486

465-
GenericConverter genericConverter = (GenericConverter) converter;
466-
return Streamable.of(genericConverter.getConvertibleTypes()).map(it -> register(it, isReading, isWriting));
487+
return Streamable.of(GenericConverter.class.cast(converter).getConvertibleTypes())//
488+
.map(it -> register(it, isReading, isWriting));
467489

468490
} else if (converter instanceof ConverterFactory) {
469491

@@ -474,7 +496,7 @@ public Streamable<ConverterRegistration> getRegistrationsFor(Object converter) {
474496
return getRegistrationFor(converter, Converter.class, isReading, isWriting);
475497

476498
} else {
477-
throw new IllegalArgumentException("Unsupported converter type!");
499+
throw new IllegalArgumentException(String.format("Unsupported converter type %s!", converter));
478500
}
479501
}
480502

src/test/java/org/springframework/data/convert/CustomConversionsUnitTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@
3232
import org.springframework.aop.framework.ProxyFactory;
3333
import org.springframework.core.convert.converter.Converter;
3434
import org.springframework.core.convert.converter.ConverterFactory;
35+
import org.springframework.core.convert.support.ConfigurableConversionService;
3536
import org.springframework.core.convert.support.DefaultConversionService;
3637
import org.springframework.core.convert.support.GenericConversionService;
38+
import org.springframework.data.convert.ConverterBuilder.ConverterAware;
3739
import org.springframework.data.convert.CustomConversions.StoreConversions;
3840
import org.threeten.bp.LocalDateTime;
3941

@@ -158,6 +160,24 @@ public void registersConverterFactoryCorrectly() {
158160
assertThat(customConversions.getCustomWriteTarget(String.class, SimpleDateFormat.class)).isPresent();
159161
}
160162

163+
@Test // DATACMNS-1034
164+
public void registersConverterFromConverterAware() {
165+
166+
ConverterAware converters = ConverterBuilder.reading(Left.class, Right.class, left -> new Right())
167+
.andWriting(right -> new Left());
168+
169+
CustomConversions conversions = new CustomConversions(StoreConversions.NONE, Collections.singletonList(converters));
170+
171+
assertThat(conversions.hasCustomWriteTarget(Right.class)).isTrue();
172+
assertThat(conversions.hasCustomReadTarget(Left.class, Right.class)).isTrue();
173+
174+
ConfigurableConversionService conversionService = new GenericConversionService();
175+
conversions.registerConvertersIn(conversionService);
176+
177+
assertThat(conversionService.canConvert(Left.class, Right.class)).isTrue();
178+
assertThat(conversionService.canConvert(Right.class, Left.class)).isTrue();
179+
}
180+
161181
private static Class<?> createProxyTypeFor(Class<?> type) {
162182

163183
ProxyFactory factory = new ProxyFactory();
@@ -274,4 +294,8 @@ public T convert(String source) {
274294
}
275295
}
276296
}
297+
298+
static class Left {}
299+
300+
static class Right {}
277301
}

0 commit comments

Comments
 (0)