Fix package tangle in binder

Update the `BinderConversionService` so that it no longer references
classes from `org.springframework.boot.context.properties.bind`.

See gh-10592
This commit is contained in:
Phillip Webb 2017-10-11 10:10:32 -07:00
parent 1bd44d89d6
commit f48550aa44
6 changed files with 51 additions and 48 deletions

View File

@ -227,10 +227,8 @@ public class Binder {
}
private <T> T convert(Object value, Bindable<T> target) {
if (value == null) {
return null;
}
return this.conversionService.convert(value, target);
return ResolvableTypeDescriptor.forBindable(target)
.convert(this.conversionService, value);
}
private <T> Object bindObject(ConfigurationPropertyName name, Bindable<T> target,
@ -287,7 +285,7 @@ public class Binder {
context.setConfigurationProperty(property);
Object result = property.getValue();
result = this.placeholdersResolver.resolvePlaceholders(result);
result = this.conversionService.convert(result, target);
result = convert(result, target);
return result;
}

View File

@ -122,11 +122,10 @@ abstract class IndexedElementsBinder<T> extends AggregateBinder<T> {
}
}
@SuppressWarnings("unchecked")
private <C> C convert(Object value, ResolvableType type) {
value = getContext().getPlaceholdersResolver().resolvePlaceholders(value);
BinderConversionService conversionService = getContext().getConversionService();
return (C) conversionService.convert(value, type);
return ResolvableTypeDescriptor.forType(type).convert(conversionService, value);
}
/**

View File

@ -20,7 +20,6 @@ import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import org.springframework.boot.context.properties.bind.convert.BinderConversionService;
import org.springframework.boot.context.properties.source.ConfigurationProperty;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName.Form;
@ -102,8 +101,7 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
for (ConfigurationPropertyName name : (IterableConfigurationPropertySource) source) {
Bindable<?> valueBindable = getValueBindable(name);
ConfigurationPropertyName entryName = getEntryName(source, name);
Object key = getContext().getConversionService()
.convert(getKeyName(entryName), this.keyType);
Object key = convert(getKeyName(entryName), this.keyType);
map.computeIfAbsent(key,
(k) -> this.elementBinder.bind(entryName, valueBindable));
}
@ -159,9 +157,17 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
}
Object value = property.getValue();
value = getContext().getPlaceholdersResolver().resolvePlaceholders(value);
BinderConversionService conversionService = getContext()
.getConversionService();
return conversionService.canConvert(value, this.valueType);
return canConvert(value, this.valueType);
}
private boolean canConvert(Object source, ResolvableType targetType) {
return ResolvableTypeDescriptor.forType(targetType)
.canConvert(getContext().getConversionService(), source);
}
private Object convert(Object source, ResolvableType targetType) {
return ResolvableTypeDescriptor.forType(targetType)
.convert(getContext().getConversionService(), source);
}
private String getKeyName(ConfigurationPropertyName name) {

View File

@ -14,12 +14,13 @@
* limitations under the License.
*/
package org.springframework.boot.context.properties.bind.convert;
package org.springframework.boot.context.properties.bind;
import java.lang.annotation.Annotation;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
/**
@ -35,12 +36,40 @@ final class ResolvableTypeDescriptor extends TypeDescriptor {
super(resolvableType, null, annotations);
}
/**
* Determine if the specified source object can be converted to this type.
* @param conversionService the backing conversion service
* @param source the source to check
* @return {@code true} if conversion can be performed
*/
public boolean canConvert(ConversionService conversionService, Object source) {
TypeDescriptor sourceType = TypeDescriptor.forObject(source);
return conversionService.canConvert(sourceType, this);
}
/**
* Convert the given source object into this type.
* @param conversionService the source conversion service
* @param value the value to convert
* @param <T> the target type
* @return the converted value
* @throws ConversionException if a conversion exception occurred
*/
@SuppressWarnings("unchecked")
public <T> T convert(ConversionService conversionService, Object value) {
if (value == null) {
return null;
}
TypeDescriptor sourceType = TypeDescriptor.forObject(value);
return (T) conversionService.convert(value, sourceType, this);
}
/**
* Create a {@link TypeDescriptor} for the specified {@link Bindable}.
* @param bindable the bindable
* @return the type descriptor
*/
public static TypeDescriptor forBindable(Bindable<?> bindable) {
public static ResolvableTypeDescriptor forBindable(Bindable<?> bindable) {
return forType(bindable.getType(), bindable.getAnnotations());
}
@ -50,7 +79,8 @@ final class ResolvableTypeDescriptor extends TypeDescriptor {
* @param annotations the annotations to include
* @return the type descriptor
*/
public static TypeDescriptor forType(ResolvableType type, Annotation... annotations) {
public static ResolvableTypeDescriptor forType(ResolvableType type,
Annotation... annotations) {
return new ResolvableTypeDescriptor(type, annotations);
}

View File

@ -18,9 +18,7 @@ package org.springframework.boot.context.properties.bind.convert;
import java.util.function.Function;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.ConverterNotFoundException;
@ -54,19 +52,6 @@ public class BinderConversionService implements ConversionService {
this.additionalConversionService = createAdditionalConversionService();
}
/**
* Return {@code true} if the given source object can be converted to the
* {@code targetType}.
* @param source the source object
* @param targetType the target type to convert to (required)
* @return {@code true} if a conversion can be performed, {@code false} if not
* @throws IllegalArgumentException if {@code targetType} is {@code null}
*/
public boolean canConvert(Object source, ResolvableType targetType) {
TypeDescriptor sourceType = TypeDescriptor.forObject(source);
return canConvert(sourceType, ResolvableTypeDescriptor.forType(targetType));
}
@Override
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
return (this.conversionService != null
@ -81,20 +66,6 @@ public class BinderConversionService implements ConversionService {
|| this.additionalConversionService.canConvert(sourceType, targetType);
}
@SuppressWarnings("unchecked")
public <T> T convert(Object value, ResolvableType type) {
TypeDescriptor sourceType = TypeDescriptor.forObject(value);
TypeDescriptor targetType = ResolvableTypeDescriptor.forType(type);
return (T) convert(value, sourceType, targetType);
}
@SuppressWarnings("unchecked")
public <T> T convert(Object value, Bindable<T> bindable) {
TypeDescriptor sourceType = TypeDescriptor.forObject(value);
TypeDescriptor targetType = ResolvableTypeDescriptor.forBindable(bindable);
return (T) convert(value, sourceType, targetType);
}
@Override
public <T> T convert(Object source, Class<T> targetType) {
return callConversionService((c) -> c.convert(source, targetType));

View File

@ -14,14 +14,13 @@
* limitations under the License.
*/
package org.springframework.boot.context.properties.bind.convert;
package org.springframework.boot.context.properties.bind;
import java.lang.annotation.Annotation;
import java.util.List;
import org.junit.Test;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.TypeDescriptor;