activated DefaultConversionService in EL, linking convert and EL
This commit is contained in:
parent
8b52b7eeef
commit
1d22b9fb88
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2004-2009 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.core.convert.converter;
|
||||
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts from any JDK-standard Number implementation to a Character and back.
|
||||
*
|
||||
* Support Number classes including Byte, Short, Integer, Float, Double, Long, BigInteger, BigDecimal. This class
|
||||
* delegates to {@link NumberUtils#convertNumberToTargetClass(Number, Class)} to perform the conversion.
|
||||
*
|
||||
* @see java.lang.Byte
|
||||
* @see java.lang.Short
|
||||
* @see java.lang.Integer
|
||||
* @see java.lang.Long
|
||||
* @see java.math.BigInteger
|
||||
* @see java.lang.Float
|
||||
* @see java.lang.Double
|
||||
* @see java.math.BigDecimal
|
||||
* @see NumberUtils
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class NumberToCharacter implements SuperTwoWayConverter<Number, Character> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <RT extends Character> RT convert(Number source, Class<RT> targetClass) {
|
||||
return (RT) Character.valueOf((char) source.shortValue());
|
||||
}
|
||||
|
||||
public <RS extends Number> RS convertBack(Character target, Class<RS> sourceClass) {
|
||||
return NumberUtils.convertNumberToTargetClass((short) target.charValue(), sourceClass);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.springframework.core.convert.converter;
|
||||
|
||||
import org.springframework.core.convert.service.DefaultConversionService;
|
||||
|
||||
/**
|
||||
* Simply calls {@link Object#toString()} to convert any object to a string.
|
||||
* Used by the {@link DefaultConversionService} as a fallback if there are no other explicit to string converters registered.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class ObjectToString implements SuperConverter<Object, String> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <RT extends String> RT convert(Object source, Class<RT> targetClass) {
|
||||
return (RT) source.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -20,7 +20,9 @@ import java.math.BigInteger;
|
|||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.core.convert.converter.NumberToCharacter;
|
||||
import org.springframework.core.convert.converter.NumberToNumber;
|
||||
import org.springframework.core.convert.converter.ObjectToString;
|
||||
import org.springframework.core.convert.converter.StringToBigDecimal;
|
||||
import org.springframework.core.convert.converter.StringToBigInteger;
|
||||
import org.springframework.core.convert.converter.StringToBoolean;
|
||||
|
@ -67,6 +69,8 @@ public class DefaultConversionService extends GenericConversionService {
|
|||
addConverter(new StringToLocale());
|
||||
addConverter(new StringToEnum());
|
||||
addConverter(new NumberToNumber());
|
||||
addConverter(new NumberToCharacter());
|
||||
addConverter(new ObjectToString());
|
||||
}
|
||||
|
||||
protected void addDefaultAliases() {
|
||||
|
|
|
@ -193,21 +193,21 @@ public class GenericConversionService implements ConversionService {
|
|||
if (sourceType.isCollection()) {
|
||||
return new CollectionToArray(sourceType, targetType, this);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Object to Array conversion not yet supported");
|
||||
throw new ConversionExecutorNotFoundException(sourceType, targetType, "Object to Array conversion not yet supported");
|
||||
}
|
||||
}
|
||||
if (sourceType.isCollection()) {
|
||||
if (targetType.isCollection()) {
|
||||
return new CollectionToCollection(sourceType, targetType, this);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Object to Collection conversion not yet supported");
|
||||
throw new ConversionExecutorNotFoundException(sourceType, targetType, "Object to Collection conversion not yet supported");
|
||||
}
|
||||
}
|
||||
if (sourceType.isMap()) {
|
||||
if (targetType.isMap()) {
|
||||
return new MapToMap(sourceType, targetType, this);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Object to Map conversion not yet supported");
|
||||
throw new ConversionExecutorNotFoundException(sourceType, targetType, "Object to Map conversion not yet supported");
|
||||
}
|
||||
}
|
||||
Converter converter = findRegisteredConverter(sourceClass, targetType.getType());
|
||||
|
|
|
@ -8,7 +8,9 @@ import java.math.BigInteger;
|
|||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.converter.NumberToCharacter;
|
||||
import org.springframework.core.convert.converter.NumberToNumber;
|
||||
import org.springframework.core.convert.converter.ObjectToString;
|
||||
import org.springframework.core.convert.converter.StringToBigDecimal;
|
||||
import org.springframework.core.convert.converter.StringToBigInteger;
|
||||
import org.springframework.core.convert.converter.StringToBoolean;
|
||||
|
@ -154,6 +156,19 @@ public class DefaultConverterTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumberToCharacter() {
|
||||
NumberToCharacter n = new NumberToCharacter();
|
||||
assertEquals(Character.valueOf('A'), n.convert(Integer.valueOf(65), Character.class));
|
||||
assertEquals(Integer.valueOf(65), n.convertBack(Character.valueOf('A'), Integer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObjectToString() {
|
||||
ObjectToString o = new ObjectToString();
|
||||
assertEquals("3", o.convert(3, String.class));
|
||||
}
|
||||
|
||||
public static class CustomNumber extends Number {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
|
||||
package org.springframework.expression.spel.support;
|
||||
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConversionExecutorNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.service.DefaultConversionService;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.TypeConverter;
|
||||
import org.springframework.expression.spel.SpelException;
|
||||
import org.springframework.expression.spel.SpelMessages;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
|
@ -40,84 +40,25 @@ public class StandardTypeConverter implements TypeConverter {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T convertValue(Object value, Class<T> targetType) throws EvaluationException {
|
||||
// For activation when conversion service available - this replaces the rest of the method (probably...)
|
||||
// return (T)convertValue(value,TypeDescriptor.valueOf(targetType));
|
||||
if (ClassUtils.isAssignableValue(targetType, value)) {
|
||||
return (T) value;
|
||||
}
|
||||
if (String.class.equals(targetType)) {
|
||||
return (T) (value != null ? value.toString() : null);
|
||||
}
|
||||
Class actualTargetType = ClassUtils.resolvePrimitiveIfNecessary(targetType);
|
||||
if (Number.class.isAssignableFrom(actualTargetType)) {
|
||||
try {
|
||||
if (value instanceof String) {
|
||||
return (T) NumberUtils.parseNumber(value.toString(), (Class<Number>) actualTargetType);
|
||||
}
|
||||
else if (value instanceof Number) {
|
||||
return (T) NumberUtils.convertNumberToTargetClass((Number) value, (Class<Number>) actualTargetType);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new SpelException(SpelMessages.PROBLEM_DURING_TYPE_CONVERSION, ex.getMessage());
|
||||
}
|
||||
}
|
||||
if (Character.class.equals(actualTargetType)) {
|
||||
if (value instanceof String) {
|
||||
String str = (String) value;
|
||||
if (str.length() == 1) {
|
||||
return (T) new Character(str.charAt(0));
|
||||
}
|
||||
}
|
||||
else if (value instanceof Number) {
|
||||
return (T) new Character((char) ((Number) value).shortValue());
|
||||
}
|
||||
}
|
||||
if (Boolean.class.equals(actualTargetType) && value instanceof String) {
|
||||
String str = (String) value;
|
||||
if ("true".equalsIgnoreCase(str)) {
|
||||
return (T) Boolean.TRUE;
|
||||
}
|
||||
else if ("false".equalsIgnoreCase(str)) {
|
||||
return (T) Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
throw new SpelException(SpelMessages.TYPE_CONVERSION_ERROR, value.getClass(), targetType);
|
||||
return (T) convertValue(value,TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convertValue(Object value, TypeDescriptor typeDescriptor) throws EvaluationException {
|
||||
// For activation when conversion service available - this replaces the rest of the method (probably...)
|
||||
// try {
|
||||
// return conversionService.executeConversion(value, typeDescriptor);
|
||||
// } catch (ConversionExecutorNotFoundException cenfe) {
|
||||
// throw new SpelException(cenfe, SpelMessages.TYPE_CONVERSION_ERROR, value.getClass(), typeDescriptor.asString());
|
||||
// } catch (ConversionException ce) {
|
||||
// throw new SpelException(ce, SpelMessages.TYPE_CONVERSION_ERROR, value.getClass(), typeDescriptor.asString());
|
||||
// }
|
||||
return convertValue(value,typeDescriptor.getType());
|
||||
try {
|
||||
return conversionService.executeConversion(value, typeDescriptor);
|
||||
} catch (ConversionExecutorNotFoundException cenfe) {
|
||||
throw new SpelException(cenfe, SpelMessages.TYPE_CONVERSION_ERROR, value.getClass(), typeDescriptor.asString());
|
||||
} catch (ConversionException ce) {
|
||||
throw new SpelException(ce, SpelMessages.TYPE_CONVERSION_ERROR, value.getClass(), typeDescriptor.asString());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
|
||||
// For activation when conversion service available - this replaces the rest of the method (probably...)
|
||||
// return canConvert(sourceType,TypeDescriptor.valueOf(targetType));
|
||||
if (ClassUtils.isAssignable(targetType, sourceType) || String.class.equals(targetType)) {
|
||||
return true;
|
||||
}
|
||||
Class actualTargetType = ClassUtils.resolvePrimitiveIfNecessary(targetType);
|
||||
return (((Number.class.isAssignableFrom(actualTargetType) || Character.class.equals(actualTargetType)) &&
|
||||
(String.class.equals(sourceType) || Number.class.isAssignableFrom(sourceType))) ||
|
||||
(Boolean.class.equals(actualTargetType) && String.class.equals(sourceType)));
|
||||
return canConvert(sourceType, TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
public boolean canConvert(Class<?> sourceType, TypeDescriptor typeDescriptor) {
|
||||
// For activation when conversion service available - this replaces the rest of the method (probably...)
|
||||
// try {
|
||||
// return conversionService.getConversionExecutor(sourceType, typeDescriptor)!=null;
|
||||
// } catch (ConversionExecutorNotFoundException cenfe) {
|
||||
// return false;
|
||||
// }
|
||||
return canConvert(sourceType,typeDescriptor.getType());
|
||||
public boolean canConvert(Class<?> sourceType, TypeDescriptor targetType) {
|
||||
return conversionService.canConvert(sourceType, targetType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public class LiteralTests extends ExpressionTestCase {
|
|||
// ask for the result to be made into an Integer
|
||||
evaluateAndAskForReturnType("0x20 * 2L", 64, Integer.class);
|
||||
// ask for the result to be made into an Integer knowing that it will not fit
|
||||
evaluateAndCheckError("0x1220 * 0xffffffffL", Integer.class, SpelMessages.PROBLEM_DURING_TYPE_CONVERSION, -1);
|
||||
evaluateAndCheckError("0x1220 * 0xffffffffL", Integer.class, SpelMessages.TYPE_CONVERSION_ERROR, -1);
|
||||
}
|
||||
|
||||
public void testSignedIntLiterals() {
|
||||
|
|
Loading…
Reference in New Issue