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