ognl type conversion adaption
This commit is contained in:
@@ -26,12 +26,21 @@ package org.springframework.binding.convert;
|
||||
public interface ConversionService {
|
||||
|
||||
/**
|
||||
* Return the default conversion executor capable of converting source objects of the specified
|
||||
* <code>sourceClass</code> to instances of the <code>targetClass</code>.
|
||||
* Execute a conversion of the source to the specified target class.
|
||||
* @param source the source to convert from (may be null)
|
||||
* @param targetClass the target class to convert to
|
||||
* @return the converted object
|
||||
* @throws ConversionException if an exception occurred during the conversion process
|
||||
*/
|
||||
public Object executeConversion(Object source, Class targetClass) throws ConversionException;
|
||||
|
||||
/**
|
||||
* Return the conversion executor capable of converting source objects of the specified <code>sourceClass</code>
|
||||
* to instances of the <code>targetClass</code>.
|
||||
* <p>
|
||||
* The returned ConversionExecutor is thread-safe and may safely be cached for use in client code.
|
||||
* @param sourceClass the source class to convert from
|
||||
* @param targetClass the target class to convert to
|
||||
* @param sourceClass the source class to convert from (required)
|
||||
* @param targetClass the target class to convert to (required)
|
||||
* @return the executor that can execute instance type conversion, never null
|
||||
* @throws ConversionExecutorNotFoundException when no suitable conversion executor could be found
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.binding.convert.ConversionException;
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.convert.ConversionExecutorNotFoundException;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
@@ -163,6 +164,15 @@ public class GenericConversionService implements ConversionService {
|
||||
}
|
||||
}
|
||||
|
||||
public Object executeConversion(Object source, Class targetClass) throws ConversionException {
|
||||
if (source != null) {
|
||||
ConversionExecutor conversionExecutor = getConversionExecutor(source.getClass(), targetClass);
|
||||
return conversionExecutor.execute(source);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Class getClassForAlias(String name) throws IllegalArgumentException {
|
||||
Class clazz = (Class) aliasMap.get(name);
|
||||
if (clazz != null) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.beans.propertyeditors.PropertiesEditor;
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.service.DefaultConversionService;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ParserContext;
|
||||
import org.springframework.binding.expression.ParserException;
|
||||
@@ -31,13 +32,13 @@ import org.springframework.binding.expression.support.AbstractExpressionParser;
|
||||
*/
|
||||
public class BeanWrapperExpressionParser extends AbstractExpressionParser {
|
||||
|
||||
private ConversionService conversionService;
|
||||
private ConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
/**
|
||||
* The conversion service to use to obtain {@link ConversionExecutor conversion executors} that will be adapted to
|
||||
* {@link PropertiesEditor property editors} for use during a
|
||||
* {@link BeanWrapperImpl#setPropertyValue(String, Object) set value} call.
|
||||
* @return the conversion service
|
||||
* {@link BeanWrapperImpl#setPropertyValue(String, Object) set value} call. The default if not specified is an
|
||||
* instance of {@link DefaultConversionService}.
|
||||
*/
|
||||
public ConversionService getConversionService() {
|
||||
return conversionService;
|
||||
|
||||
@@ -44,15 +44,12 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class ELExpressionParser implements ExpressionParser {
|
||||
|
||||
/**
|
||||
* The ExpressionFactory for constructing EL expressions
|
||||
*/
|
||||
private ExpressionFactory expressionFactory;
|
||||
|
||||
private ConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
private Map contextFactories = new HashMap();
|
||||
|
||||
private ConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
/**
|
||||
* Creates a new EL expression parser for standalone usage.
|
||||
*/
|
||||
@@ -60,6 +57,22 @@ public class ELExpressionParser implements ExpressionParser {
|
||||
init(expressionFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* The conversion service to use to perform type conversions as needed by the Unified EL system. If not specified,
|
||||
* the default is an instance of {@link DefaultConversionService}.
|
||||
*/
|
||||
public ConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the conversion service to use to perform type conversions as needed by the Unified EL system.
|
||||
* @param conversionService the conversion service to use
|
||||
*/
|
||||
public void setConversionService(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the ELContextFactory for expressions that evaluate the given class of context object.
|
||||
* @param contextType the expression context class
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.binding.expression.ognl;
|
||||
|
||||
import java.lang.reflect.Member;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -23,10 +24,12 @@ import java.util.Map;
|
||||
import ognl.NoSuchPropertyException;
|
||||
import ognl.Ognl;
|
||||
import ognl.OgnlException;
|
||||
import ognl.TypeConverter;
|
||||
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.InvalidPropertyException;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.PropertyNotFoundException;
|
||||
@@ -46,14 +49,18 @@ class OgnlExpression implements Expression {
|
||||
|
||||
private String expressionString;
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
/**
|
||||
* Creates a new OGNL expression.
|
||||
*/
|
||||
public OgnlExpression(Object expression, Map variableExpressions, Class expectedResultType, String expressionString) {
|
||||
public OgnlExpression(Object expression, Map variableExpressions, Class expectedResultType,
|
||||
String expressionString, ConversionService conversionService) {
|
||||
this.expression = expression;
|
||||
this.variableExpressions = variableExpressions;
|
||||
this.expectedResultType = expectedResultType;
|
||||
this.expressionString = expressionString;
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
@@ -84,7 +91,7 @@ class OgnlExpression implements Expression {
|
||||
public void setValue(Object context, Object value) {
|
||||
try {
|
||||
Map evaluationContext = Ognl.addDefaultContext(context, getVariables(context));
|
||||
// TODO set TypeConverter here to invoke our ConversionService
|
||||
Ognl.setTypeConverter(evaluationContext, createTypeConverter());
|
||||
Ognl.setValue(expression, evaluationContext, context, value);
|
||||
} catch (NoSuchPropertyException e) {
|
||||
throw new PropertyNotFoundException(context.getClass(), getExpressionString(), e);
|
||||
@@ -95,6 +102,15 @@ class OgnlExpression implements Expression {
|
||||
}
|
||||
}
|
||||
|
||||
private TypeConverter createTypeConverter() {
|
||||
return new TypeConverter() {
|
||||
public Object convertValue(Map context, Object target, Member member, String propertyName, Object value,
|
||||
Class toType) {
|
||||
return conversionService.executeConversion(value, toType);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Class getValueType(Object context) {
|
||||
try {
|
||||
// OGNL has no native way to get this information
|
||||
|
||||
@@ -20,6 +20,8 @@ import ognl.OgnlException;
|
||||
import ognl.OgnlRuntime;
|
||||
import ognl.PropertyAccessor;
|
||||
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.service.DefaultConversionService;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ParserContext;
|
||||
import org.springframework.binding.expression.ParserException;
|
||||
@@ -32,6 +34,24 @@ import org.springframework.binding.expression.support.AbstractExpressionParser;
|
||||
*/
|
||||
public class OgnlExpressionParser extends AbstractExpressionParser {
|
||||
|
||||
private ConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
/**
|
||||
* The conversion service to use to perform type conversions as needed by the OGNL system. If not specified, the
|
||||
* default is an instance of {@link DefaultConversionService}.
|
||||
*/
|
||||
public ConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the conversion service to use to perform type conversions as needed by the OGNL system.
|
||||
* @param conversionService the conversion service to use
|
||||
*/
|
||||
public void setConversionService(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a property access strategy for the given class.
|
||||
* @param clazz the class that contains properties needing access
|
||||
@@ -44,7 +64,8 @@ public class OgnlExpressionParser extends AbstractExpressionParser {
|
||||
protected Expression doParseExpression(String expressionString, ParserContext context) throws ParserException {
|
||||
try {
|
||||
return new OgnlExpression(Ognl.parseExpression(expressionString), parseVariableExpressions(context
|
||||
.getExpressionVariables()), context.getExpectedEvaluationResultType(), expressionString);
|
||||
.getExpressionVariables()), context.getExpectedEvaluationResultType(), expressionString,
|
||||
conversionService);
|
||||
} catch (OgnlException e) {
|
||||
throw new ParserException(expressionString, e);
|
||||
}
|
||||
|
||||
@@ -40,23 +40,6 @@ public class DefaultMapper implements Mapper {
|
||||
|
||||
private List mappings = new ArrayList();
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
/**
|
||||
* Returns the conversion service to use to perform type conversions as needed by mapping operations. May be null.
|
||||
*/
|
||||
public ConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the conversion service to use to perform type conversions as needed by mapping operations. Optional.
|
||||
* @param conversionService the conversion service;
|
||||
*/
|
||||
public void setConversionService(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mapping to this mapper.
|
||||
* @param mapping the mapping to add (required)
|
||||
@@ -80,7 +63,7 @@ public class DefaultMapper implements Mapper {
|
||||
logger.debug("Beginning mapping between source [" + source.getClass().getName() + "] and target ["
|
||||
+ target.getClass().getName() + "]");
|
||||
}
|
||||
DefaultMappingContext context = new DefaultMappingContext(source, target, conversionService);
|
||||
DefaultMappingContext context = new DefaultMappingContext(source, target);
|
||||
Iterator it = mappings.iterator();
|
||||
while (it.hasNext()) {
|
||||
DefaultMapping mapping = (DefaultMapping) it.next();
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.List;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.binding.convert.ConversionExecutionException;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.mapping.Mapping;
|
||||
import org.springframework.binding.mapping.MappingResult;
|
||||
@@ -48,12 +47,9 @@ public class DefaultMappingContext {
|
||||
|
||||
private List mappingResults;
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
public DefaultMappingContext(Object source, Object target, ConversionService conversionService) {
|
||||
public DefaultMappingContext(Object source, Object target) {
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
this.conversionService = conversionService;
|
||||
this.mappingResults = new ArrayList();
|
||||
}
|
||||
|
||||
@@ -71,14 +67,6 @@ public class DefaultMappingContext {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the conversion service that can be used to perform type conversions during the mapping process. May be
|
||||
* null if no externally managed conversion service is provided.
|
||||
*/
|
||||
public ConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current mapping.
|
||||
* @return the current mapping
|
||||
|
||||
Reference in New Issue
Block a user