Skip to content

Commit 09153ba

Browse files
committed
DATACMNS-1615 - Polishing.
Replace list creation with constant. Replace ConverterConfiguration.skipFor list with Predicate for flexible conditions. Fix typo. Simplify conditionals. Original pull request: #421.
1 parent dbcf9ae commit 09153ba

File tree

3 files changed

+59
-67
lines changed

3 files changed

+59
-67
lines changed

Diff for: src/main/java/org/springframework/data/convert/CustomConversions.java

+50-60
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import java.util.Set;
3535
import java.util.concurrent.ConcurrentHashMap;
3636
import java.util.function.Function;
37-
import java.util.function.Supplier;
37+
import java.util.function.Predicate;
3838
import java.util.stream.Collectors;
3939

4040
import org.springframework.core.GenericTypeResolver;
@@ -99,35 +99,24 @@ public class CustomConversions {
9999
private final Function<ConvertiblePair, Class<?>> getReadTarget = convertiblePair -> getCustomTarget(
100100
convertiblePair.getSourceType(), convertiblePair.getTargetType(), readingPairs);
101101

102-
private Function<ConvertiblePair, Class<?>> getWriteTarget = convertiblePair -> getCustomTarget(
102+
private final Function<ConvertiblePair, Class<?>> getWriteTarget = convertiblePair -> getCustomTarget(
103103
convertiblePair.getSourceType(), convertiblePair.getTargetType(), writingPairs);
104104

105-
private Function<ConvertiblePair, Class<?>> getRawWriteTarget = convertiblePair -> getCustomTarget(
105+
private final Function<ConvertiblePair, Class<?>> getRawWriteTarget = convertiblePair -> getCustomTarget(
106106
convertiblePair.getSourceType(), null, writingPairs);
107107

108-
/**
109-
* Deferred initialization allowing store implementations use a callback/consumer driven configuration of the actual
110-
* {@link CustomConversions}.
111-
*
112-
* @param converterConfiguration the {@link Supplier} providing a {@link ConverterConfiguration}.
113-
* @since 2.3
114-
*/
115-
protected CustomConversions(Supplier<ConverterConfiguration> converterConfiguration) {
116-
this(converterConfiguration.get());
117-
}
118-
119108
/**
120109
* @param converterConfiguration the {@link ConverterConfiguration} to apply.
121110
* @since 2.3
122111
*/
123-
protected CustomConversions(ConverterConfiguration converterConfiguration) {
112+
public CustomConversions(ConverterConfiguration converterConfiguration) {
124113

125114
this.converterConfiguration = converterConfiguration;
126115

127116
List<Object> registeredConverters = collectPotentialConverterRegistrations(
128117
converterConfiguration.getStoreConversions(), converterConfiguration.getUserConverters()).stream() //
129118
.filter(this::isSupportedConverter) //
130-
.filter(it -> !skip(it)) //
119+
.filter(this::shouldRegister) //
131120
.map(ConverterRegistrationIntent::getConverterRegistration) //
132121
.map(this::register) //
133122
.distinct() //
@@ -191,7 +180,7 @@ public void registerConvertersIn(ConverterRegistry conversionService) {
191180

192181
/**
193182
* Get all converters and add origin information
194-
*
183+
*
195184
* @param storeConversions
196185
* @param converters
197186
* @return
@@ -202,20 +191,23 @@ private List<ConverterRegistrationIntent> collectPotentialConverterRegistrations
202191

203192
List<ConverterRegistrationIntent> converterRegistrations = new ArrayList<>();
204193

205-
converterRegistrations.addAll(converters.stream() //
206-
.flatMap(it -> storeConversions.getRegistrationsFor(it).stream()) //
194+
converters.stream() //
195+
.map(storeConversions::getRegistrationsFor) //
196+
.flatMap(Streamable::stream) //
207197
.map(ConverterRegistrationIntent::userConverters) //
208-
.collect(Collectors.toList()));
198+
.forEach(converterRegistrations::add);
209199

210-
converterRegistrations.addAll(storeConversions.getStoreConverters().stream() //
211-
.flatMap(it -> storeConversions.getRegistrationsFor(it).stream()) //
200+
storeConversions.getStoreConverters().stream() //
201+
.map(storeConversions::getRegistrationsFor) //
202+
.flatMap(Streamable::stream) //
212203
.map(ConverterRegistrationIntent::storeConverters) //
213-
.collect(Collectors.toList()));
204+
.forEach(converterRegistrations::add);
214205

215-
converterRegistrations.addAll(DEFAULT_CONVERTERS.stream() //
216-
.flatMap(it -> storeConversions.getRegistrationsFor(it).stream()) //
206+
DEFAULT_CONVERTERS.stream() //
207+
.map(storeConversions::getRegistrationsFor) //
208+
.flatMap(Streamable::stream) //
217209
.map(ConverterRegistrationIntent::defaultConverters) //
218-
.collect(Collectors.toList()));
210+
.forEach(converterRegistrations::add);
219211

220212
return converterRegistrations;
221213
}
@@ -253,7 +245,7 @@ private void registerConverterIn(Object candidate, ConverterRegistry conversionS
253245

254246
/**
255247
* Registers the given {@link ConvertiblePair} as reading or writing pair depending on the type sides being basic
256-
* Mongo types.
248+
* types.
257249
*
258250
* @param converterRegistration
259251
*/
@@ -318,18 +310,17 @@ private boolean isSupportedConverter(ConverterRegistrationIntent registrationInt
318310

319311
/**
320312
* @param intent must not be {@literal null}.
321-
* @return {@literal true} if the given {@link ConverterRegistration} shall be skipped.
313+
* @return {@literal false} if the given {@link ConverterRegistration} shall be skipped.
322314
* @since 2.3
323315
*/
324-
private boolean skip(ConverterRegistrationIntent intent) {
325-
326-
return intent.isDefaultConveter()
327-
&& converterConfiguration.getSkipFor().contains(intent.getConverterRegistration().getConvertiblePair());
316+
private boolean shouldRegister(ConverterRegistrationIntent intent) {
317+
return !intent.isDefaultConverter()
318+
|| converterConfiguration.shouldRegister(intent.getConverterRegistration().getConvertiblePair());
328319
}
329320

330321
/**
331322
* Returns the target type to convert to in case we have a custom conversion registered to convert the given source
332-
* type into a Mongo native one.
323+
* type into a store native one.
333324
*
334325
* @param sourceType must not be {@literal null}
335326
* @return
@@ -344,9 +335,9 @@ public Optional<Class<?>> getCustomWriteTarget(Class<?> sourceType) {
344335
}
345336

346337
/**
347-
* Returns the target type we can read an inject of the given source type to. The returned type might
348-
* be a subclass of the given expected type though. If {@code requestedTargetType} is {@literal null} we will simply
349-
* return the first target type matching or {@literal null} if no conversion can be found.
338+
* Returns the target type we can read an inject of the given source type to. The returned type might be a subclass of
339+
* the given expected type though. If {@code requestedTargetType} is {@literal null} we will simply return the first
340+
* target type matching or {@literal null} if no conversion can be found.
350341
*
351342
* @param sourceType must not be {@literal null}
352343
* @param requestedTargetType must not be {@literal null}.
@@ -363,8 +354,8 @@ public Optional<Class<?>> getCustomWriteTarget(Class<?> sourceType, Class<?> req
363354
}
364355

365356
/**
366-
* Returns whether we have a custom conversion registered to read {@code sourceType} into a native type. The
367-
* returned type might be a subclass of the given expected type though.
357+
* Returns whether we have a custom conversion registered to read {@code sourceType} into a native type. The returned
358+
* type might be a subclass of the given expected type though.
368359
*
369360
* @param sourceType must not be {@literal null}
370361
* @return
@@ -377,8 +368,8 @@ public boolean hasCustomWriteTarget(Class<?> sourceType) {
377368
}
378369

379370
/**
380-
* Returns whether we have a custom conversion registered to read an object of the given source type
381-
* into an object of the given native target type.
371+
* Returns whether we have a custom conversion registered to read an object of the given source type into an object of
372+
* the given native target type.
382373
*
383374
* @param sourceType must not be {@literal null}.
384375
* @param targetType must not be {@literal null}.
@@ -393,8 +384,7 @@ public boolean hasCustomWriteTarget(Class<?> sourceType, Class<?> targetType) {
393384
}
394385

395386
/**
396-
* Returns whether we have a custom conversion registered to read the given source into the given target
397-
* type.
387+
* Returns whether we have a custom conversion registered to read the given source into the given target type.
398388
*
399389
* @param sourceType must not be {@literal null}
400390
* @param targetType must not be {@literal null}
@@ -409,8 +399,8 @@ public boolean hasCustomReadTarget(Class<?> sourceType, Class<?> targetType) {
409399
}
410400

411401
/**
412-
* Returns the actual target type for the given {@code sourceType} and {@code targetType}. Note that the
413-
* returned {@link Class} could be an assignable type to the given {@code targetType}.
402+
* Returns the actual target type for the given {@code sourceType} and {@code targetType}. Note that the returned
403+
* {@link Class} could be an assignable type to the given {@code targetType}.
414404
*
415405
* @param sourceType must not be {@literal null}.
416406
* @param targetType must not be {@literal null}.
@@ -422,8 +412,8 @@ private Class<?> getCustomReadTarget(Class<?> sourceType, Class<?> targetType) {
422412
}
423413

424414
/**
425-
* Inspects the given {@link ConvertiblePair ConvertiblePairs} for ones that have a source compatible type as source. Additionally
426-
* checks assignability of the target type if one is given.
415+
* Inspects the given {@link ConvertiblePair ConvertiblePairs} for ones that have a source compatible type as source.
416+
* Additionally checks assignability of the target type if one is given.
427417
*
428418
* @param sourceType must not be {@literal null}.
429419
* @param targetType can be {@literal null}.
@@ -461,7 +451,7 @@ private static boolean hasAssignableSourceType(ConvertiblePair pair, Class<?> so
461451
}
462452

463453
private static boolean requestedTargetTypeIsAssignable(@Nullable Class<?> requestedTargetType, Class<?> targetType) {
464-
return requestedTargetType == null ? true : targetType.isAssignableFrom(requestedTargetType);
454+
return requestedTargetType == null || targetType.isAssignableFrom(requestedTargetType);
465455
}
466456

467457
/**
@@ -607,7 +597,7 @@ public boolean isUserConverter() {
607597
return isConverterOfSource(ConverterOrigin.USER_DEFINED);
608598
}
609599

610-
public boolean isDefaultConveter() {
600+
public boolean isDefaultConverter() {
611601
return isConverterOfSource(ConverterOrigin.DEFAULT);
612602
}
613603

@@ -645,7 +635,7 @@ private static class ConverterRegistration {
645635
* @return
646636
*/
647637
public boolean isWriting() {
648-
return writing == true || (!reading && isSimpleTargetType());
638+
return writing || (!reading && isSimpleTargetType());
649639
}
650640

651641
/**
@@ -654,7 +644,7 @@ public boolean isWriting() {
654644
* @return
655645
*/
656646
public boolean isReading() {
657-
return reading == true || (!writing && isSimpleSourceType());
647+
return reading || (!writing && isSimpleSourceType());
658648
}
659649

660650
/**
@@ -667,7 +657,7 @@ public ConvertiblePair getConvertiblePair() {
667657
}
668658

669659
/**
670-
* Returns whether the source type is a Mongo simple one.
660+
* Returns whether the source type is a simple one.
671661
*
672662
* @return
673663
*/
@@ -676,7 +666,7 @@ public boolean isSimpleSourceType() {
676666
}
677667

678668
/**
679-
* Returns whether the target type is a Mongo simple one.
669+
* Returns whether the target type is a simple one.
680670
*
681671
* @return
682672
*/
@@ -811,15 +801,15 @@ private boolean isStoreSimpleType(Class<?> type) {
811801
/**
812802
* Value object holding the actual {@link StoreConversions} and custom {@link Converter converters} configured for
813803
* registration.
814-
*
804+
*
815805
* @author Christoph Strobl
816806
* @since 2.3
817807
*/
818808
protected static class ConverterConfiguration {
819809

820810
private final StoreConversions storeConversions;
821811
private final List<?> userConverters;
822-
private final Set<ConvertiblePair> skipFor;
812+
private final Predicate<ConvertiblePair> converterRegistrationFilter;
823813

824814
/**
825815
* Create a new ConverterConfiguration holding the given {@link StoreConversions} and user defined converters.
@@ -828,7 +818,7 @@ protected static class ConverterConfiguration {
828818
* @param userConverters must not be {@literal null} use {@link Collections#emptyList()} instead.
829819
*/
830820
public ConverterConfiguration(StoreConversions storeConversions, List<?> userConverters) {
831-
this(storeConversions, userConverters, Collections.emptySet());
821+
this(storeConversions, userConverters, it -> true);
832822
}
833823

834824
/**
@@ -840,14 +830,14 @@ public ConverterConfiguration(StoreConversions storeConversions, List<?> userCon
840830
*
841831
* @param storeConversions must not be {@literal null}.
842832
* @param userConverters must not be {@literal null} use {@link Collections#emptyList()} instead.
843-
* @param skipFor must not be {@literal null} use {@link Collections#emptyList()} instead.
833+
* @param converterRegistrationFilter must not be {@literal null}..
844834
*/
845835
public ConverterConfiguration(StoreConversions storeConversions, List<?> userConverters,
846-
Collection<ConvertiblePair> skipFor) {
836+
Predicate<ConvertiblePair> converterRegistrationFilter) {
847837

848838
this.storeConversions = storeConversions;
849839
this.userConverters = new ArrayList<>(userConverters);
850-
this.skipFor = new HashSet<>(skipFor);
840+
this.converterRegistrationFilter = converterRegistrationFilter;
851841
}
852842

853843
/**
@@ -867,8 +857,8 @@ List<?> getUserConverters() {
867857
/**
868858
* @return never {@literal null}.
869859
*/
870-
Set<ConvertiblePair> getSkipFor() {
871-
return skipFor;
860+
boolean shouldRegister(ConvertiblePair candidate) {
861+
return this.converterRegistrationFilter.test(candidate);
872862
}
873863
}
874864
}

Diff for: src/main/java/org/springframework/data/convert/Jsr310Converters.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public abstract class Jsr310Converters {
5353

5454
private static final boolean JAVA_8_IS_PRESENT = ClassUtils.isPresent("java.time.LocalDateTime",
5555
Jsr310Converters.class.getClassLoader());
56+
private static final List<Class<?>> CLASSES = Arrays.asList(LocalDateTime.class, LocalDate.class, LocalTime.class,
57+
Instant.class, ZoneId.class, Duration.class, Period.class);
5658

5759
/**
5860
* Returns the converters to be registered. Will only return converters in case we're running on Java 8.
@@ -95,8 +97,7 @@ public static boolean supports(Class<?> type) {
9597
return false;
9698
}
9799

98-
return Arrays.<Class<?>> asList(LocalDateTime.class, LocalDate.class, LocalTime.class, Instant.class)
99-
.contains(type);
100+
return CLASSES.contains(type);
100101
}
101102

102103
@ReadingConverter
@@ -296,7 +297,7 @@ public static enum StringToLocalDateConverter implements Converter<String, Local
296297

297298
INSTANCE;
298299

299-
/*
300+
/*
300301
* (non-Javadoc)
301302
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
302303
*/
@@ -312,7 +313,7 @@ public static enum StringToLocalDateTimeConverter implements Converter<String, L
312313

313314
INSTANCE;
314315

315-
/*
316+
/*
316317
* (non-Javadoc)
317318
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
318319
*/
@@ -328,7 +329,7 @@ public static enum StringToInstantConverter implements Converter<String, Instant
328329

329330
INSTANCE;
330331

331-
/*
332+
/*
332333
* (non-Javadoc)
333334
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
334335
*/

Diff for: src/test/java/org/springframework/data/convert/CustomConversionsUnitTests.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.Collections;
2626
import java.util.Date;
2727
import java.util.Locale;
28+
import java.util.function.Predicate;
2829

2930
import org.joda.time.DateTime;
3031
import org.junit.jupiter.api.Test;
@@ -235,7 +236,7 @@ public void skipsConverterBasedOnConfiguration() {
235236
ConverterRegistry registry = mock(ConverterRegistry.class);
236237

237238
ConverterConfiguration config = new ConverterConfiguration(StoreConversions.NONE, Collections.emptyList(),
238-
Collections.singleton(new ConvertiblePair(java.time.LocalDateTime.class, Date.class)));
239+
Predicate.<ConvertiblePair> isEqual(new ConvertiblePair(java.time.LocalDateTime.class, Date.class)).negate());
239240
new CustomConversions(config).registerConvertersIn(registry);
240241

241242
verify(registry, never()).addConverter(any(LocalDateTimeToDateConverter.class));
@@ -248,7 +249,7 @@ public void doesNotSkipUserConverterConverterEvenWhenConfigurationWouldNotAllowI
248249

249250
ConverterConfiguration config = new ConverterConfiguration(StoreConversions.NONE,
250251
Collections.singletonList(LocalDateTimeToDateConverter.INSTANCE),
251-
Collections.singleton(new ConvertiblePair(java.time.LocalDateTime.class, Date.class)));
252+
Predicate.<ConvertiblePair> isEqual(new ConvertiblePair(java.time.LocalDateTime.class, Date.class)).negate());
252253
new CustomConversions(config).registerConvertersIn(registry);
253254

254255
verify(registry).addConverter(any(LocalDateTimeToDateConverter.class));

0 commit comments

Comments
 (0)