IN PROGRESS - issue SWF-720: Multiple checkboxes to Collection mapping
http://jira.springframework.org/browse/SWF-720
This commit is contained in:
@@ -39,4 +39,12 @@ public interface ConversionService {
|
||||
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
|
||||
throws ConversionExecutorNotFoundException;
|
||||
|
||||
/**
|
||||
* Lookup a class by its fully qualified name or alias. As an example, for Long.class the fully qualified class name
|
||||
* is <code>java.lang.Long</code> and the alias is <code>long</code>.
|
||||
* @param name the fully qualified class name or alias
|
||||
* @return the class
|
||||
*/
|
||||
public Class getClassByName(String name);
|
||||
|
||||
}
|
||||
@@ -15,6 +15,10 @@
|
||||
*/
|
||||
package org.springframework.binding.convert.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.converters.StringToBigDecimal;
|
||||
import org.springframework.binding.convert.converters.StringToBigInteger;
|
||||
@@ -29,6 +33,7 @@ import org.springframework.binding.convert.converters.StringToInteger;
|
||||
import org.springframework.binding.convert.converters.StringToLabeledEnum;
|
||||
import org.springframework.binding.convert.converters.StringToLong;
|
||||
import org.springframework.binding.convert.converters.StringToShort;
|
||||
import org.springframework.core.enums.LabeledEnum;
|
||||
|
||||
/**
|
||||
* Default, local implementation of a conversion service. Will automatically register <i>from string</i> converters for
|
||||
@@ -48,6 +53,7 @@ public class DefaultConversionService extends GenericConversionService {
|
||||
*/
|
||||
public DefaultConversionService() {
|
||||
addDefaultConverters();
|
||||
addDefaultAliases();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,6 +75,23 @@ public class DefaultConversionService extends GenericConversionService {
|
||||
addConverter(new StringToDate());
|
||||
}
|
||||
|
||||
protected void addDefaultAliases() {
|
||||
addAlias("byte", Byte.class);
|
||||
addAlias("boolean", Boolean.class);
|
||||
addAlias("character", Character.class);
|
||||
addAlias("short", Short.class);
|
||||
addAlias("integer", Integer.class);
|
||||
addAlias("long", Long.class);
|
||||
addAlias("float", Float.class);
|
||||
addAlias("double", Double.class);
|
||||
addAlias("bigInteger", BigInteger.class);
|
||||
addAlias("bigDecimal", BigDecimal.class);
|
||||
addAlias("class", Class.class);
|
||||
addAlias("labeledEnum", LabeledEnum.class);
|
||||
addAlias("date", Date.class);
|
||||
addAlias("string", String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared {@link DefaultConversionService} instance.
|
||||
*/
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.binding.convert.converters.ObjectToArray;
|
||||
import org.springframework.binding.convert.converters.ReverseConverter;
|
||||
import org.springframework.binding.convert.converters.TwoWayConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Base implementation of a conversion service. Initially empty, e.g. no converters are registered by default.
|
||||
@@ -47,6 +48,11 @@ public class GenericConversionService implements ConversionService {
|
||||
*/
|
||||
private final Map sourceClassConverters = new HashMap();
|
||||
|
||||
/**
|
||||
* Indexes classes by well-known aliases.
|
||||
*/
|
||||
private final Map aliasMap = new HashMap();
|
||||
|
||||
/**
|
||||
* An optional parent conversion service.
|
||||
*/
|
||||
@@ -89,6 +95,13 @@ public class GenericConversionService implements ConversionService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an alias for given target type.
|
||||
*/
|
||||
public void addAlias(String alias, Class targetType) {
|
||||
aliasMap.put(alias, targetType);
|
||||
}
|
||||
|
||||
private Map getSourceMap(Class sourceClass) {
|
||||
Map sourceMap = (Map) sourceClassConverters.get(sourceClass);
|
||||
if (sourceMap == null) {
|
||||
@@ -147,6 +160,26 @@ public class GenericConversionService implements ConversionService {
|
||||
}
|
||||
}
|
||||
|
||||
public Class getClassByName(String name) throws IllegalArgumentException {
|
||||
Class clazz = (Class) aliasMap.get(name);
|
||||
if (clazz != null) {
|
||||
return clazz;
|
||||
} else {
|
||||
if (parent != null) {
|
||||
return parent.getClassByName(name);
|
||||
} else {
|
||||
try {
|
||||
return ClassUtils.forName(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
IllegalArgumentException iae = new IllegalArgumentException(
|
||||
"No Class alias or instance found with name '" + name + "' in this ConversionService");
|
||||
iae.initCause(e);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// subclassing support
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,8 @@ e.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package org.springframework.faces.model.converter;
|
||||
|
||||
import javax.faces.model.DataModel;
|
||||
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.service.DefaultConversionService;
|
||||
import org.springframework.faces.model.OneSelectionTrackingListDataModel;
|
||||
@@ -35,5 +37,6 @@ public class FacesConversionService extends DefaultConversionService {
|
||||
|
||||
protected void addFacesConverters() {
|
||||
addConverter(new DataModelConverter());
|
||||
addAlias("dataModel", DataModel.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,24 +71,13 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
|
||||
|
||||
public static class TestConversionService implements ConversionService {
|
||||
|
||||
public Class getClassByAlias(String alias) throws ConversionExecutionException {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
|
||||
throws ConversionExecutionException {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
public ConversionExecutor getConversionExecutorByTargetAlias(Class sourceClass, String targetAlias)
|
||||
throws ConversionExecutionException {
|
||||
public Class getClassByName(String name) throws ConversionExecutionException {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass)
|
||||
throws ConversionExecutionException {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ class FlowExecutorFactoryBean implements FactoryBean, ApplicationContextAware, I
|
||||
}
|
||||
}
|
||||
|
||||
private Class fromStringToClass(String type) {
|
||||
return (Class) conversionService.getConversionExecutor(String.class, Class.class).execute(type);
|
||||
private Class fromStringToClass(String name) {
|
||||
return conversionService.getClassByName(name);
|
||||
}
|
||||
}
|
||||
@@ -237,8 +237,7 @@ class FlowRegistryFactoryBean implements FactoryBean, InitializingBean {
|
||||
}
|
||||
|
||||
private Class fromStringToClass(String type) {
|
||||
return (Class) flowBuilderServices.getConversionService().getConversionExecutor(String.class, Class.class)
|
||||
.execute(type);
|
||||
return flowBuilderServices.getConversionService().getClassByName(type);
|
||||
}
|
||||
|
||||
private FlowDefinition buildFlowDefinition(FlowBuilderInfo builderInfo) {
|
||||
|
||||
@@ -375,7 +375,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
}
|
||||
|
||||
private FlowVariable parseFlowVariable(VarModel var) {
|
||||
Class clazz = (Class) fromStringTo(Class.class).execute(var.getClassName());
|
||||
Class clazz = toClass(var.getClassName());
|
||||
VariableValueFactory valueFactory = new BeanFactoryVariableValueFactory(clazz, getFlow()
|
||||
.getApplicationContext().getAutowireCapableBeanFactory());
|
||||
return new FlowVariable(var.getName(), valueFactory);
|
||||
@@ -499,7 +499,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
|
||||
private void parseAndSetMappingConversionExecutor(AbstractMappingModel mappingModel, DefaultMapping mapping) {
|
||||
if (StringUtils.hasText(mappingModel.getType())) {
|
||||
Class type = (Class) fromStringTo(Class.class).execute(mappingModel.getType());
|
||||
Class type = toClass(mappingModel.getType());
|
||||
ConversionExecutor typeConverter = new RuntimeBindingConversionExecutor(type, getLocalContext()
|
||||
.getConversionService());
|
||||
mapping.setTypeConverter(typeConverter);
|
||||
@@ -624,7 +624,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
}
|
||||
|
||||
private ViewVariable parseViewVariable(VarModel var) {
|
||||
Class clazz = (Class) fromStringTo(Class.class).execute(var.getClassName());
|
||||
Class clazz = toClass(var.getClassName());
|
||||
VariableValueFactory valueFactory = new BeanFactoryVariableValueFactory(clazz, getFlow()
|
||||
.getApplicationContext().getAutowireCapableBeanFactory());
|
||||
return new ViewVariable(var.getName(), valueFactory);
|
||||
@@ -718,7 +718,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
|
||||
private FlowExecutionExceptionHandler parseTransitionExecutingExceptionHandler(TransitionModel transition) {
|
||||
TransitionExecutingFlowExecutionExceptionHandler handler = new TransitionExecutingFlowExecutionExceptionHandler();
|
||||
Class exceptionClass = (Class) fromStringTo(Class.class).execute(transition.getOnException());
|
||||
Class exceptionClass = toClass(transition.getOnException());
|
||||
TargetStateResolver targetStateResolver = (TargetStateResolver) fromStringTo(TargetStateResolver.class)
|
||||
.execute(transition.getTo());
|
||||
handler.add(exceptionClass, targetStateResolver);
|
||||
@@ -820,7 +820,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
new FluentParserContext().evaluate(RequestContext.class));
|
||||
Class expectedResultType = null;
|
||||
if (StringUtils.hasText(evaluate.getResultType())) {
|
||||
expectedResultType = (Class) fromStringTo(Class.class).execute(evaluate.getResultType());
|
||||
expectedResultType = toClass(evaluate.getResultType());
|
||||
}
|
||||
return new ActionResultExposer(resultExpression, expectedResultType, getLocalContext()
|
||||
.getConversionService());
|
||||
@@ -849,7 +849,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
new FluentParserContext().evaluate(RequestContext.class));
|
||||
Class expectedType = null;
|
||||
if (StringUtils.hasText(set.getType())) {
|
||||
expectedType = (Class) fromStringTo(Class.class).execute(set.getType());
|
||||
expectedType = toClass(set.getType());
|
||||
}
|
||||
return new SetAction(nameExpression, valueExpression, expectedType, getLocalContext().getConversionService());
|
||||
}
|
||||
@@ -874,7 +874,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
|
||||
private Object parseAttributeValueIfNecessary(AttributeModel attribute, String stringValue) {
|
||||
if (StringUtils.hasText(attribute.getType())) {
|
||||
Class targetClass = (Class) fromStringTo(Class.class).execute(attribute.getType());
|
||||
Class targetClass = toClass(attribute.getType());
|
||||
return fromStringTo(targetClass).execute(stringValue);
|
||||
} else {
|
||||
return stringValue;
|
||||
@@ -909,6 +909,10 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
return getLocalContext().getConversionService().getConversionExecutor(String.class, targetType);
|
||||
}
|
||||
|
||||
private Class toClass(String name) {
|
||||
return getLocalContext().getConversionService().getClassByName(name);
|
||||
}
|
||||
|
||||
private static class FlowRelativeResourceLoader implements ResourceLoader {
|
||||
private Resource resource;
|
||||
|
||||
|
||||
@@ -123,6 +123,11 @@ public class FlowBuilderContextImpl implements FlowBuilderContext {
|
||||
throws ConversionExecutionException {
|
||||
return getFlowBuilderServices().getConversionService().getConversionExecutor(sourceClass, targetClass);
|
||||
}
|
||||
|
||||
public Class getClassByName(String name) {
|
||||
return getFlowBuilderServices().getConversionService().getClassByName(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,22 +54,12 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
|
||||
|
||||
public static class TestConversionService implements ConversionService {
|
||||
|
||||
public Class getClassByAlias(String alias) throws ConversionExecutionException {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
|
||||
throws ConversionExecutionException {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
public ConversionExecutor getConversionExecutorByTargetAlias(Class sourceClass, String targetAlias)
|
||||
throws ConversionExecutionException {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass)
|
||||
throws ConversionExecutionException {
|
||||
public Class getClassByName(String alias) throws ConversionExecutionException {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user