Review and polish pull request #132
Content:
- Rename Conditional{Conversion=>Converter}
- Add @since tags where appropriate
- Update Apache date headers to read 2002-2012 (not just 2012)
- Correct minor Javadoc typo
Style:
- Polish line breaks / whitespace
- Use wildcard static imports where appropriate
Issue: SPR-9566, SPR-9692, SPR-9928, SPR-9927
This commit is contained in:
@@ -63,6 +63,7 @@ public interface ConversionService {
|
||||
* @param targetType context about the target type to convert to (required)
|
||||
* @return true if conversion can be bypassed
|
||||
* @throws IllegalArgumentException if targetType is null
|
||||
* @since 3.2
|
||||
*/
|
||||
boolean canBypassConvert(Class<?> sourceType, Class<?> targetType);
|
||||
|
||||
@@ -74,6 +75,7 @@ public interface ConversionService {
|
||||
* @param targetType context about the target type to convert to (required)
|
||||
* @return true if conversion can be bypassed
|
||||
* @throws IllegalArgumentException if targetType is null
|
||||
* @since 3.2
|
||||
*/
|
||||
boolean canBypassConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
|
||||
|
||||
|
||||
@@ -257,6 +257,7 @@ public class TypeDescriptor {
|
||||
* @param superType the super type to cast to (can be {@code null}
|
||||
* @return a new TypeDescriptor for the up-cast type
|
||||
* @throws IllegalArgumentException if this type is not assignable to the super-type
|
||||
* @since 3.2
|
||||
*/
|
||||
public TypeDescriptor upcast(Class<?> superType) {
|
||||
if (superType == null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -33,18 +33,18 @@ import org.springframework.core.convert.TypeDescriptor;
|
||||
* implementation might return {@code true} if the target Account class defines a
|
||||
* {@code public static findAccount(String)} method.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Phillip Webb
|
||||
* @author Keith Donald
|
||||
* @since 3.2
|
||||
* @see Converter
|
||||
* @see GenericConverter
|
||||
* @see ConverterFactory
|
||||
* @see ConditionalGenericConverter
|
||||
*/
|
||||
public interface ConditionalConversion {
|
||||
public interface ConditionalConverter {
|
||||
|
||||
/**
|
||||
* Should the converter from {@code sourceType} to {@code targetType} currently under
|
||||
* Should the conversion from {@code sourceType} to {@code targetType} currently under
|
||||
* consideration be selected?
|
||||
*
|
||||
* @param sourceType the type descriptor of the field we are converting from
|
||||
@@ -18,19 +18,18 @@ package org.springframework.core.convert.converter;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link GenericConverter} that may conditionally execute based on attributes of the
|
||||
* {@code source} and {@code target} {@link TypeDescriptor}. See
|
||||
* {@link ConditionalConversion} for details.
|
||||
* {@link ConditionalConverter} for details.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Phillip Webb
|
||||
* @since 3.0
|
||||
* @see GenericConverter
|
||||
* @see ConditionalConversion
|
||||
* @see ConditionalConverter
|
||||
*/
|
||||
public interface ConditionalGenericConverter extends GenericConverter,
|
||||
ConditionalConversion {
|
||||
ConditionalConverter {
|
||||
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ package org.springframework.core.convert.converter;
|
||||
* A converter converts a source object of type S to a target of type T.
|
||||
* Implementations of this interface are thread-safe and can be shared.
|
||||
*
|
||||
* <p>Implementations may additionally implement {@link ConditionalConversion}.
|
||||
* <p>Implementations may additionally implement {@link ConditionalConverter}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see ConditionalConversion
|
||||
* @see ConditionalConverter
|
||||
* @param <S> The source type
|
||||
* @param <T> The target type
|
||||
*/
|
||||
|
||||
@@ -19,11 +19,11 @@ package org.springframework.core.convert.converter;
|
||||
/**
|
||||
* A factory for "ranged" converters that can convert objects from S to subtypes of R.
|
||||
*
|
||||
* <p>Implementations may additionally implement {@link ConditionalConversion}.
|
||||
* <p>Implementations may additionally implement {@link ConditionalConverter}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see ConditionalConversion
|
||||
* @see ConditionalConverter
|
||||
* @param <S> The source type converters created by this factory can convert from
|
||||
* @param <R> The target range (or base) type converters created by this factory can convert to;
|
||||
* for example {@link Number} for a set of number subtypes.
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.Set;
|
||||
* <p>This interface should generally not be used when the simpler {@link Converter} or
|
||||
* {@link ConverterFactory} interfaces are sufficient.
|
||||
*
|
||||
* <p>Implementations may additionally implement {@link ConditionalConversion}.
|
||||
* <p>Implementations may additionally implement {@link ConditionalConverter}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
@@ -42,7 +42,7 @@ import java.util.Set;
|
||||
* @see TypeDescriptor
|
||||
* @see Converter
|
||||
* @see ConverterFactory
|
||||
* @see ConditionalConversion
|
||||
* @see ConditionalConverter
|
||||
*/
|
||||
public interface GenericConverter {
|
||||
|
||||
@@ -50,7 +50,7 @@ public interface GenericConverter {
|
||||
* Return the source and target types which this converter can convert between. Each
|
||||
* entry is a convertible source-to-target type pair.
|
||||
* <p>
|
||||
* For {@link ConditionalConversion conditional} converters this method may return
|
||||
* For {@link ConditionalConverter conditional} converters this method may return
|
||||
* {@code null} to indicate all source-to-target pairs should be considered. *
|
||||
*/
|
||||
Set<ConvertiblePair> getConvertibleTypes();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -18,10 +18,9 @@ package org.springframework.core.convert.support;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.ConditionalConversion;
|
||||
import org.springframework.core.convert.converter.ConditionalConverter;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Calls {@link Enum#name()} to convert a source Enum to a String. This converter will
|
||||
@@ -30,7 +29,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Phillip Webb
|
||||
* @since 3.0
|
||||
*/
|
||||
final class EnumToStringConverter implements Converter<Enum<?>, String>, ConditionalConversion {
|
||||
final class EnumToStringConverter implements Converter<Enum<?>, String>, ConditionalConverter {
|
||||
|
||||
private final ConversionService conversionService;
|
||||
|
||||
@@ -40,8 +39,7 @@ final class EnumToStringConverter implements Converter<Enum<?>, String>, Conditi
|
||||
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
for (Class<?> interfaceType : ClassUtils.getAllInterfacesForClass(sourceType.getType())) {
|
||||
if (conversionService.canConvert(TypeDescriptor.valueOf(interfaceType),
|
||||
targetType)) {
|
||||
if (conversionService.canConvert(TypeDescriptor.valueOf(interfaceType), targetType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.ConditionalConversion;
|
||||
import org.springframework.core.convert.converter.ConditionalConverter;
|
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterFactory;
|
||||
@@ -81,8 +81,8 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
|
||||
public void addConverter(Converter<?, ?> converter) {
|
||||
GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converter, Converter.class);
|
||||
Assert.notNull(typeInfo, "Unable to the determine sourceType <S> and targetType <T> which " +
|
||||
"your Converter<S, T> converts between; declare these generic types.");
|
||||
Assert.notNull(typeInfo, "Unable to the determine sourceType <S> and targetType " +
|
||||
"<T> which your Converter<S, T> converts between; declare these generic types.");
|
||||
addConverter(new ConverterAdapter(typeInfo, converter));
|
||||
}
|
||||
|
||||
@@ -99,8 +99,9 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
public void addConverterFactory(ConverterFactory<?, ?> converterFactory) {
|
||||
GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converterFactory, ConverterFactory.class);
|
||||
if (typeInfo == null) {
|
||||
throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetRangeType R which " +
|
||||
"your ConverterFactory<S, R> converts between; declare these generic types.");
|
||||
throw new IllegalArgumentException("Unable to the determine sourceType <S> and " +
|
||||
"targetRangeType R which your ConverterFactory<S, R> converts between; " +
|
||||
"declare these generic types.");
|
||||
}
|
||||
addConverter(new ConverterFactoryAdapter(typeInfo, converterFactory));
|
||||
}
|
||||
@@ -114,7 +115,9 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
|
||||
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
|
||||
Assert.notNull(targetType, "The targetType to convert to cannot be null");
|
||||
return canConvert(sourceType != null ? TypeDescriptor.valueOf(sourceType) : null, TypeDescriptor.valueOf(targetType));
|
||||
return canConvert(sourceType != null ?
|
||||
TypeDescriptor.valueOf(sourceType) : null,
|
||||
TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
@@ -128,8 +131,9 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
|
||||
public boolean canBypassConvert(Class<?> sourceType, Class<?> targetType) {
|
||||
Assert.notNull(targetType, "The targetType to convert to cannot be null");
|
||||
return canBypassConvert(sourceType != null ? TypeDescriptor.valueOf(sourceType)
|
||||
: null, TypeDescriptor.valueOf(targetType));
|
||||
return canBypassConvert(sourceType != null ?
|
||||
TypeDescriptor.valueOf(sourceType) : null,
|
||||
TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
public boolean canBypassConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
@@ -166,8 +170,11 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience operation for converting a source object to the specified targetType, where the targetType is a descriptor that provides additional conversion context.
|
||||
* Simply delegates to {@link #convert(Object, TypeDescriptor, TypeDescriptor)} and encapsulates the construction of the sourceType descriptor using {@link TypeDescriptor#forObject(Object)}.
|
||||
* Convenience operation for converting a source object to the specified targetType,
|
||||
* where the targetType is a descriptor that provides additional conversion context.
|
||||
* Simply delegates to {@link #convert(Object, TypeDescriptor, TypeDescriptor)} and
|
||||
* encapsulates the construction of the sourceType descriptor using
|
||||
* {@link TypeDescriptor#forObject(Object)}.
|
||||
* @param source the source object
|
||||
* @param targetType the target type
|
||||
* @return the converted value
|
||||
@@ -206,7 +213,8 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
* Subclasses may override.
|
||||
* @param sourceType the source type to convert from
|
||||
* @param targetType the target type to convert to
|
||||
* @return the generic converter that will perform the conversion, or {@code null} if no suitable converter was found
|
||||
* @return the generic converter that will perform the conversion, or {@code null} if
|
||||
* no suitable converter was found
|
||||
* @see #getDefaultConverter(TypeDescriptor, TypeDescriptor)
|
||||
*/
|
||||
protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
@@ -305,9 +313,8 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
if(!this.typeInfo.getTargetType().equals(targetType.getObjectType())) {
|
||||
return false;
|
||||
}
|
||||
if (this.converter instanceof ConditionalConversion) {
|
||||
return ((ConditionalConversion) this.converter).matches(sourceType,
|
||||
targetType);
|
||||
if (this.converter instanceof ConditionalConverter) {
|
||||
return ((ConditionalConverter) this.converter).matches(sourceType, targetType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -320,8 +327,9 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.typeInfo.getSourceType().getName() + " -> " + this.typeInfo.getTargetType().getName() +
|
||||
" : " + this.converter.toString();
|
||||
return this.typeInfo.getSourceType().getName() + " -> " +
|
||||
this.typeInfo.getTargetType().getName() + " : " +
|
||||
this.converter.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,14 +357,13 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
boolean matches = true;
|
||||
if (this.converterFactory instanceof ConditionalConversion) {
|
||||
matches = ((ConditionalConversion) this.converterFactory).matches(
|
||||
sourceType, targetType);
|
||||
if (this.converterFactory instanceof ConditionalConverter) {
|
||||
matches = ((ConditionalConverter) this.converterFactory).matches(sourceType, targetType);
|
||||
}
|
||||
if(matches) {
|
||||
Converter<?, ?> converter = converterFactory.getConverter(targetType.getType());
|
||||
if(converter instanceof ConditionalConversion) {
|
||||
matches = ((ConditionalConversion) converter).matches(sourceType, targetType);
|
||||
Converter<?, ?> converter = this.converterFactory.getConverter(targetType.getType());
|
||||
if(converter instanceof ConditionalConverter) {
|
||||
matches = ((ConditionalConverter) converter).matches(sourceType, targetType);
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
@@ -370,8 +377,9 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.typeInfo.getSourceType().getName() + " -> " + this.typeInfo.getTargetType().getName() +
|
||||
" : " + this.converterFactory.toString();
|
||||
return this.typeInfo.getSourceType().getName() + " -> " +
|
||||
this.typeInfo.getTargetType().getName() + " : " +
|
||||
this.converterFactory.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,7 +445,7 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
public void add(GenericConverter converter) {
|
||||
Set<ConvertiblePair> convertibleTypes = converter.getConvertibleTypes();
|
||||
if (convertibleTypes == null) {
|
||||
Assert.state(converter instanceof ConditionalConversion,
|
||||
Assert.state(converter instanceof ConditionalConverter,
|
||||
"Only conditional converters may return null convertible types");
|
||||
globalConverters.add(converter);
|
||||
} else {
|
||||
@@ -476,7 +484,8 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
List<TypeDescriptor> targetCandidates = getTypeHierarchy(targetType);
|
||||
for (TypeDescriptor sourceCandidate : sourceCandidates) {
|
||||
for (TypeDescriptor targetCandidate : targetCandidates) {
|
||||
GenericConverter converter = getRegisteredConverter(sourceType, targetType, sourceCandidate, targetCandidate);
|
||||
GenericConverter converter = getRegisteredConverter(
|
||||
sourceType, targetType, sourceCandidate, targetCandidate);
|
||||
if(converter != null) {
|
||||
return converter;
|
||||
}
|
||||
@@ -499,9 +508,8 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
|
||||
// Check ConditionalGenericConverter that match all types
|
||||
for (GenericConverter globalConverter : this.globalConverters) {
|
||||
if (((ConditionalConversion)globalConverter).matches(
|
||||
sourceCandidate,
|
||||
targetCandidate)) {
|
||||
if (((ConditionalConverter)globalConverter).matches(
|
||||
sourceCandidate, targetCandidate)) {
|
||||
return globalConverter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.ConditionalConversion;
|
||||
import org.springframework.core.convert.converter.ConditionalConverter;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterFactory;
|
||||
import org.springframework.util.NumberUtils;
|
||||
@@ -41,7 +41,7 @@ import org.springframework.util.NumberUtils;
|
||||
* @see NumberUtils
|
||||
*/
|
||||
final class NumberToNumberConverterFactory implements ConverterFactory<Number, Number>,
|
||||
ConditionalConversion {
|
||||
ConditionalConverter {
|
||||
|
||||
public <T extends Number> Converter<Number, T> getConverter(Class<T> targetType) {
|
||||
return new NumberToNumber<T>(targetType);
|
||||
|
||||
@@ -16,13 +16,6 @@
|
||||
|
||||
package org.springframework.core.convert;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -37,6 +30,8 @@ import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
* @author Andy Clement
|
||||
|
||||
@@ -16,15 +16,6 @@
|
||||
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.SystemColor;
|
||||
import java.util.ArrayList;
|
||||
@@ -42,10 +33,11 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.ConditionalConversion;
|
||||
import org.springframework.core.convert.converter.ConditionalConverter;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterFactory;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
@@ -54,6 +46,8 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
@@ -751,7 +745,7 @@ public class GenericConversionServiceTests {
|
||||
}
|
||||
|
||||
private static class MyConditionalConverter implements Converter<String, Color>,
|
||||
ConditionalConversion {
|
||||
ConditionalConverter {
|
||||
|
||||
private int matchAttempts = 0;
|
||||
|
||||
@@ -770,7 +764,7 @@ public class GenericConversionServiceTests {
|
||||
}
|
||||
|
||||
private static class MyConditionalGenericConverter implements GenericConverter,
|
||||
ConditionalConversion {
|
||||
ConditionalConverter {
|
||||
|
||||
private Set<TypeDescriptor> sourceTypes = new LinkedHashSet<TypeDescriptor>();
|
||||
|
||||
@@ -794,7 +788,7 @@ public class GenericConversionServiceTests {
|
||||
}
|
||||
|
||||
private static class MyConditionalConverterFactory implements
|
||||
ConverterFactory<String, Color>, ConditionalConversion {
|
||||
ConverterFactory<String, Color>, ConditionalConverter {
|
||||
|
||||
private MyConditionalConverter converter = new MyConditionalConverter();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user