Add @Ignored repro test for SPR-7538
This commit is contained in:
parent
aa54518e2e
commit
99f7142e3f
|
|
@ -0,0 +1,91 @@
|
|||
package org.springframework.expression.spel.support;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.SimpleTypeConverter;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.expression.TypeConverter;
|
||||
|
||||
/**
|
||||
* Copied from Spring Integration for purposes of reproducing
|
||||
* {@link Spr7538Tests}.
|
||||
*/
|
||||
class BeanFactoryTypeConverter implements TypeConverter, BeanFactoryAware {
|
||||
|
||||
private SimpleTypeConverter delegate = new SimpleTypeConverter();
|
||||
|
||||
private static ConversionService defaultConversionService;
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
public BeanFactoryTypeConverter() {
|
||||
synchronized (this) {
|
||||
if (defaultConversionService == null) {
|
||||
defaultConversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
}
|
||||
}
|
||||
this.conversionService = defaultConversionService;
|
||||
}
|
||||
|
||||
public BeanFactoryTypeConverter(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public void setConversionService(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
if (beanFactory instanceof ConfigurableBeanFactory) {
|
||||
Object typeConverter = ((ConfigurableBeanFactory) beanFactory).getTypeConverter();
|
||||
if (typeConverter instanceof SimpleTypeConverter) {
|
||||
delegate = (SimpleTypeConverter) typeConverter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
|
||||
if (conversionService.canConvert(sourceType, targetType)) {
|
||||
return true;
|
||||
}
|
||||
if (!String.class.isAssignableFrom(sourceType) && !String.class.isAssignableFrom(targetType)) {
|
||||
// PropertyEditor cannot convert non-Strings
|
||||
return false;
|
||||
}
|
||||
if (!String.class.isAssignableFrom(sourceType)) {
|
||||
return delegate.findCustomEditor(sourceType, null) != null || delegate.getDefaultEditor(sourceType) != null;
|
||||
}
|
||||
return delegate.findCustomEditor(targetType, null) != null || delegate.getDefaultEditor(targetType) != null;
|
||||
}
|
||||
|
||||
public boolean canConvert(TypeDescriptor sourceTypeDescriptor, TypeDescriptor targetTypeDescriptor) {
|
||||
if (conversionService.canConvert(sourceTypeDescriptor, targetTypeDescriptor)) {
|
||||
return true;
|
||||
}
|
||||
// TODO: what does this mean? This method is not used in SpEL so probably ignorable?
|
||||
Class<?> sourceType = sourceTypeDescriptor.getObjectType();
|
||||
Class<?> targetType = targetTypeDescriptor.getObjectType();
|
||||
return canConvert(sourceType, targetType);
|
||||
}
|
||||
|
||||
public Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
if (targetType.getType() == Void.class || targetType.getType() == Void.TYPE) {
|
||||
return null;
|
||||
}
|
||||
if (conversionService.canConvert(sourceType, targetType)) {
|
||||
return conversionService.convert(value, sourceType, targetType);
|
||||
}
|
||||
if (!String.class.isAssignableFrom(sourceType.getType())) {
|
||||
PropertyEditor editor = delegate.findCustomEditor(sourceType.getType(), null);
|
||||
editor.setValue(value);
|
||||
return editor.getAsText();
|
||||
}
|
||||
return delegate.convertIfNecessary(value, targetType.getType());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package org.springframework.expression.spel.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.MethodExecutor;
|
||||
|
||||
public class Spr7538Tests {
|
||||
|
||||
@Ignore @Test
|
||||
public void repro() throws Exception {
|
||||
AlwaysTrueReleaseStrategy target = new AlwaysTrueReleaseStrategy();
|
||||
BeanFactoryTypeConverter converter = new BeanFactoryTypeConverter();
|
||||
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setTypeConverter(converter);
|
||||
|
||||
List<Foo> arguments = new ArrayList<Foo>();
|
||||
|
||||
// !!!! With the below line commented you'll get NPE. Uncomment and everything is OK!
|
||||
//arguments.add(new Foo());
|
||||
|
||||
List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>();
|
||||
Method method = AlwaysTrueReleaseStrategy.class.getMethod("checkCompleteness", List.class);
|
||||
paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, 0)));
|
||||
|
||||
|
||||
List<TypeDescriptor> argumentTypes = new ArrayList<TypeDescriptor>();
|
||||
argumentTypes.add(TypeDescriptor.forObject(arguments));
|
||||
ReflectiveMethodResolver resolver = new ReflectiveMethodResolver();
|
||||
MethodExecutor executor = resolver.resolve(context, target, "checkCompleteness", argumentTypes);
|
||||
|
||||
Object result = executor.execute(context, target, arguments);
|
||||
System.out.println("Result: " + result);
|
||||
}
|
||||
|
||||
public static class AlwaysTrueReleaseStrategy {
|
||||
public boolean checkCompleteness(List<Foo> messages) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Foo{}
|
||||
}
|
||||
Loading…
Reference in New Issue