SpEL performs String->String type conversion even within concatenated String
Issue: SPR-11215
This commit is contained in:
parent
63d300ac86
commit
67abeb4722
|
|
@ -23,10 +23,8 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.tests.sample.beans.TestBean;
|
|
||||||
import org.springframework.beans.factory.ObjectFactory;
|
import org.springframework.beans.factory.ObjectFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
@ -38,13 +36,18 @@ import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.tests.Assume;
|
|
||||||
import org.springframework.tests.TestGroup;
|
|
||||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
|
import org.springframework.core.convert.converter.Converter;
|
||||||
|
import org.springframework.core.convert.support.GenericConversionService;
|
||||||
|
import org.springframework.tests.Assume;
|
||||||
|
import org.springframework.tests.TestGroup;
|
||||||
|
import org.springframework.tests.sample.beans.TestBean;
|
||||||
import org.springframework.util.SerializationTestUtils;
|
import org.springframework.util.SerializationTestUtils;
|
||||||
import org.springframework.util.StopWatch;
|
import org.springframework.util.StopWatch;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
|
@ -190,10 +193,18 @@ public class ApplicationContextExpressionTests {
|
||||||
public void prototypeCreationReevaluatesExpressions() {
|
public void prototypeCreationReevaluatesExpressions() {
|
||||||
GenericApplicationContext ac = new GenericApplicationContext();
|
GenericApplicationContext ac = new GenericApplicationContext();
|
||||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
|
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
|
||||||
|
GenericConversionService cs = new GenericConversionService();
|
||||||
|
cs.addConverter(String.class, String.class, new Converter<String, String>() {
|
||||||
|
@Override
|
||||||
|
public String convert(String source) {
|
||||||
|
return source.trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ac.getBeanFactory().registerSingleton(GenericApplicationContext.CONVERSION_SERVICE_BEAN_NAME, cs);
|
||||||
RootBeanDefinition rbd = new RootBeanDefinition(PrototypeTestBean.class);
|
RootBeanDefinition rbd = new RootBeanDefinition(PrototypeTestBean.class);
|
||||||
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||||
rbd.getPropertyValues().add("country", "#{systemProperties.country}");
|
rbd.getPropertyValues().add("country", "#{systemProperties.country}");
|
||||||
rbd.getPropertyValues().add("country2", new TypedStringValue("#{systemProperties.country}"));
|
rbd.getPropertyValues().add("country2", new TypedStringValue("-#{systemProperties.country}-"));
|
||||||
ac.registerBeanDefinition("test", rbd);
|
ac.registerBeanDefinition("test", rbd);
|
||||||
ac.refresh();
|
ac.refresh();
|
||||||
|
|
||||||
|
|
@ -203,14 +214,14 @@ public class ApplicationContextExpressionTests {
|
||||||
PrototypeTestBean tb = (PrototypeTestBean) ac.getBean("test");
|
PrototypeTestBean tb = (PrototypeTestBean) ac.getBean("test");
|
||||||
assertEquals("juergen1", tb.getName());
|
assertEquals("juergen1", tb.getName());
|
||||||
assertEquals("UK1", tb.getCountry());
|
assertEquals("UK1", tb.getCountry());
|
||||||
assertEquals("UK1", tb.getCountry2());
|
assertEquals("-UK1-", tb.getCountry2());
|
||||||
|
|
||||||
System.getProperties().put("name", "juergen2");
|
System.getProperties().put("name", "juergen2");
|
||||||
System.getProperties().put("country", " UK2 ");
|
System.getProperties().put("country", " UK2 ");
|
||||||
tb = (PrototypeTestBean) ac.getBean("test");
|
tb = (PrototypeTestBean) ac.getBean("test");
|
||||||
assertEquals("juergen2", tb.getName());
|
assertEquals("juergen2", tb.getName());
|
||||||
assertEquals("UK2", tb.getCountry());
|
assertEquals("UK2", tb.getCountry());
|
||||||
assertEquals("UK2", tb.getCountry2());
|
assertEquals("-UK2-", tb.getCountry2());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
System.getProperties().remove("name");
|
System.getProperties().remove("name");
|
||||||
|
|
|
||||||
|
|
@ -63,11 +63,15 @@ public abstract class ExpressionUtils {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T convertTypedValue(EvaluationContext context, TypedValue typedValue, Class<T> targetType) {
|
public static <T> T convertTypedValue(EvaluationContext context, TypedValue typedValue, Class<T> targetType) {
|
||||||
Object value = typedValue.getValue();
|
Object value = typedValue.getValue();
|
||||||
if ((targetType == null) || (value != null && ClassUtils.isAssignableValue(targetType, value))) {
|
if (targetType == null) {
|
||||||
return (T) value;
|
return (T) value;
|
||||||
}
|
}
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
return (T) context.getTypeConverter().convertValue(value, typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(targetType));
|
return (T) context.getTypeConverter().convertValue(
|
||||||
|
value, typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(targetType));
|
||||||
|
}
|
||||||
|
if (ClassUtils.isAssignableValue(targetType, value)) {
|
||||||
|
return (T) value;
|
||||||
}
|
}
|
||||||
throw new EvaluationException("Cannot convert value '" + value + "' to type '" + targetType.getName() + "'");
|
throw new EvaluationException("Cannot convert value '" + value + "' to type '" + targetType.getName() + "'");
|
||||||
}
|
}
|
||||||
|
|
@ -100,8 +104,8 @@ public abstract class ExpressionUtils {
|
||||||
* Attempt to convert a typed value to a long using the supplied type converter.
|
* Attempt to convert a typed value to a long using the supplied type converter.
|
||||||
*/
|
*/
|
||||||
public static long toLong(TypeConverter typeConverter, TypedValue typedValue) {
|
public static long toLong(TypeConverter typeConverter, TypedValue typedValue) {
|
||||||
return (Long) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor
|
return (Long) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(),
|
||||||
.valueOf(Long.class));
|
TypeDescriptor.valueOf(Long.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -116,24 +120,24 @@ public abstract class ExpressionUtils {
|
||||||
* Attempt to convert a typed value to a short using the supplied type converter.
|
* Attempt to convert a typed value to a short using the supplied type converter.
|
||||||
*/
|
*/
|
||||||
public static short toShort(TypeConverter typeConverter, TypedValue typedValue) {
|
public static short toShort(TypeConverter typeConverter, TypedValue typedValue) {
|
||||||
return (Short) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor
|
return (Short) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(),
|
||||||
.valueOf(Short.class));
|
TypeDescriptor.valueOf(Short.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to convert a typed value to a float using the supplied type converter.
|
* Attempt to convert a typed value to a float using the supplied type converter.
|
||||||
*/
|
*/
|
||||||
public static float toFloat(TypeConverter typeConverter, TypedValue typedValue) {
|
public static float toFloat(TypeConverter typeConverter, TypedValue typedValue) {
|
||||||
return (Float) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor
|
return (Float) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(),
|
||||||
.valueOf(Float.class));
|
TypeDescriptor.valueOf(Float.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to convert a typed value to a byte using the supplied type converter.
|
* Attempt to convert a typed value to a byte using the supplied type converter.
|
||||||
*/
|
*/
|
||||||
public static byte toByte(TypeConverter typeConverter, TypedValue typedValue) {
|
public static byte toByte(TypeConverter typeConverter, TypedValue typedValue) {
|
||||||
return (Byte) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor
|
return (Byte) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(),
|
||||||
.valueOf(Byte.class));
|
TypeDescriptor.valueOf(Byte.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue