EL simplification and config enhancements
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
package org.springframework.webflow.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.binding.convert.support.DefaultConversionService;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
|
||||
import org.springframework.webflow.expression.DefaultExpressionParserFactory;
|
||||
import org.springframework.webflow.mvc.MvcViewFactoryCreator;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -27,37 +32,67 @@ public class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanD
|
||||
|
||||
private static final String CONVERSION_SERVICE_PROPERTY = "conversionService";
|
||||
|
||||
protected Class getBeanClass(Element element) {
|
||||
return FlowBuilderServices.class;
|
||||
public static BeanDefinitionHolder registerDefaultBeanDefinition(ParserContext context) {
|
||||
FlowBuilderServicesBeanDefinitionParser parser = new FlowBuilderServicesBeanDefinitionParser();
|
||||
BeanDefinitionBuilder defaultBuilder = BeanDefinitionBuilder.genericBeanDefinition(FlowBuilderServices.class);
|
||||
defaultBuilder.addPropertyReference(CONVERSION_SERVICE_PROPERTY, parser.createBeanDefinitionForClass(
|
||||
DefaultConversionService.class, context).getBeanName());
|
||||
defaultBuilder.addPropertyReference(VIEW_FACTORY_CREATOR_PROPERTY, parser.createBeanDefinitionForClass(
|
||||
MvcViewFactoryCreator.class, context).getBeanName());
|
||||
defaultBuilder.addPropertyValue(EXPRESSION_PARSER_PROPERTY, DefaultExpressionParserFactory
|
||||
.getExpressionParser());
|
||||
BeanDefinitionHolder holder = new BeanDefinitionHolder(defaultBuilder.getBeanDefinition(),
|
||||
BeanDefinitionReaderUtils.generateBeanName(defaultBuilder.getBeanDefinition(), context.getRegistry()));
|
||||
parser.registerBeanDefinition(holder, context.getRegistry());
|
||||
return holder;
|
||||
}
|
||||
|
||||
protected void doParse(Element element, BeanDefinitionBuilder definitionBuilder) {
|
||||
parseExpressionParser(element, definitionBuilder);
|
||||
parseViewFactoryCreator(element, definitionBuilder);
|
||||
parseConversionService(element, definitionBuilder);
|
||||
protected void doParse(Element element, ParserContext context, BeanDefinitionBuilder builder) {
|
||||
parseExpressionParser(element, builder, context);
|
||||
parseViewFactoryCreator(element, builder, context);
|
||||
parseConversionService(element, builder, context);
|
||||
}
|
||||
|
||||
private void parseConversionService(Element element, BeanDefinitionBuilder definitionBuilder) {
|
||||
private void parseConversionService(Element element, BeanDefinitionBuilder definitionBuilder, ParserContext context) {
|
||||
String conversionService = element.getAttribute(CONVERSION_SERVICE_ATTRIBUTE);
|
||||
if (StringUtils.hasText(conversionService)) {
|
||||
definitionBuilder.addPropertyReference(CONVERSION_SERVICE_PROPERTY, conversionService);
|
||||
} else {
|
||||
definitionBuilder.addPropertyReference(CONVERSION_SERVICE_PROPERTY, createBeanDefinitionForClass(
|
||||
DefaultConversionService.class, context).getBeanName());
|
||||
}
|
||||
}
|
||||
|
||||
private void parseViewFactoryCreator(Element element, BeanDefinitionBuilder definitionBuilder) {
|
||||
private void parseViewFactoryCreator(Element element, BeanDefinitionBuilder definitionBuilder, ParserContext context) {
|
||||
String viewFactoryCreator = element.getAttribute(VIEW_FACTORY_CREATOR_ATTRIBUTE);
|
||||
if (StringUtils.hasText(viewFactoryCreator)) {
|
||||
definitionBuilder.addPropertyReference(VIEW_FACTORY_CREATOR_PROPERTY, viewFactoryCreator);
|
||||
} else {
|
||||
definitionBuilder.addPropertyValue(VIEW_FACTORY_CREATOR_PROPERTY, new MvcViewFactoryCreator());
|
||||
definitionBuilder.addPropertyReference(VIEW_FACTORY_CREATOR_PROPERTY, createBeanDefinitionForClass(
|
||||
MvcViewFactoryCreator.class, context).getBeanName());
|
||||
}
|
||||
}
|
||||
|
||||
private void parseExpressionParser(Element element, BeanDefinitionBuilder definitionBuilder) {
|
||||
private void parseExpressionParser(Element element, BeanDefinitionBuilder definitionBuilder, ParserContext context) {
|
||||
String expressionParser = element.getAttribute(EXPRESSION_PARSER_ATTRIBUTE);
|
||||
if (StringUtils.hasText(expressionParser)) {
|
||||
definitionBuilder.addPropertyReference(EXPRESSION_PARSER_PROPERTY, expressionParser);
|
||||
} else {
|
||||
definitionBuilder.addPropertyValue(EXPRESSION_PARSER_PROPERTY, DefaultExpressionParserFactory
|
||||
.getExpressionParser());
|
||||
}
|
||||
}
|
||||
|
||||
private BeanDefinitionHolder createBeanDefinitionForClass(Class clazz, ParserContext context) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
|
||||
BeanDefinitionHolder holder = new BeanDefinitionHolder(builder.getBeanDefinition(), BeanDefinitionReaderUtils
|
||||
.generateBeanName(builder.getBeanDefinition(), context.getRegistry()));
|
||||
registerBeanDefinition(holder, context.getRegistry());
|
||||
return holder;
|
||||
}
|
||||
|
||||
protected Class getBeanClass(Element element) {
|
||||
return FlowBuilderServices.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.Set;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -68,10 +69,13 @@ class FlowRegistryBeanDefinitionParser extends AbstractSingleBeanDefinitionParse
|
||||
return FlowRegistryFactoryBean.class;
|
||||
}
|
||||
|
||||
protected void doParse(Element element, BeanDefinitionBuilder definitionBuilder) {
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder definitionBuilder) {
|
||||
String flowBuilderServices = getFlowBuilderServicesAttribute(element);
|
||||
if (StringUtils.hasText(flowBuilderServices)) {
|
||||
definitionBuilder.addPropertyReference(FLOW_BUILDER_SERVICES_PROPERTY, flowBuilderServices);
|
||||
} else {
|
||||
definitionBuilder.addPropertyReference(FLOW_BUILDER_SERVICES_PROPERTY,
|
||||
FlowBuilderServicesBeanDefinitionParser.registerDefaultBeanDefinition(parserContext).getBeanName());
|
||||
}
|
||||
definitionBuilder.addPropertyValue(FLOW_LOCATIONS_PROPERTY, parseLocations(element));
|
||||
definitionBuilder.addPropertyValue(FLOW_BUILDERS_PROPERTY, parseFlowBuilders(element));
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.springframework.webflow.engine.builder.RefreshableFlowDefinitionHolde
|
||||
import org.springframework.webflow.engine.builder.support.FlowBuilderContextImpl;
|
||||
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
|
||||
import org.springframework.webflow.engine.builder.xml.XmlFlowBuilder;
|
||||
import org.springframework.webflow.mvc.MvcViewFactoryCreator;
|
||||
|
||||
/**
|
||||
* A factory for a flow definition registry. Is a Spring FactoryBean, for provision by the flow definition registry bean
|
||||
@@ -98,9 +97,6 @@ class FlowRegistryFactoryBean implements FactoryBean, ResourceLoaderAware, BeanF
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (flowBuilderServices == null) {
|
||||
initFlowBuilderServices();
|
||||
}
|
||||
flowResourceFactory = new FlowDefinitionResourceFactory(resourceLoader);
|
||||
flowRegistry = new FlowDefinitionRegistryImpl();
|
||||
registerFlowLocations();
|
||||
@@ -204,10 +200,4 @@ class FlowRegistryFactoryBean implements FactoryBean, ResourceLoaderAware, BeanF
|
||||
}
|
||||
}
|
||||
|
||||
private void initFlowBuilderServices() {
|
||||
flowBuilderServices = new FlowBuilderServices();
|
||||
flowBuilderServices.setResourceLoader(resourceLoader);
|
||||
flowBuilderServices.setBeanFactory(beanFactory);
|
||||
flowBuilderServices.setViewFactoryCreator(new MvcViewFactoryCreator());
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.support.DefaultConversionService;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
@@ -16,7 +15,6 @@ import org.springframework.webflow.engine.builder.FlowArtifactFactory;
|
||||
import org.springframework.webflow.engine.builder.FlowBuilderContext;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
import org.springframework.webflow.execution.Action;
|
||||
import org.springframework.webflow.expression.DefaultExpressionParserFactory;
|
||||
|
||||
/**
|
||||
* A simple holder for services needed by a flow builder. These services are typically exposed via a Flow Builder's
|
||||
@@ -47,13 +45,12 @@ public class FlowBuilderServices implements ResourceLoaderAware, BeanFactoryAwar
|
||||
/**
|
||||
* The conversion service for converting from one object type to another.
|
||||
*/
|
||||
private ConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
private ConversionService conversionService;
|
||||
/**
|
||||
* The parser for parsing expression strings into expression objects. The default is Web Flow's default expression
|
||||
* parser implementation.
|
||||
*/
|
||||
private ExpressionParser expressionParser = DefaultExpressionParserFactory.getExpressionParser();
|
||||
private ExpressionParser expressionParser;
|
||||
|
||||
/**
|
||||
* A resource loader that can load resources.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.springframework.webflow.expression.el;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELException;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.access.el.SpringBeanELResolver;
|
||||
@@ -17,36 +16,6 @@ public class SpringBeanWebFlowELResolver extends SpringBeanELResolver {
|
||||
|
||||
private static final BeanFactory EMPTY_BEAN_FACTORY = new StaticListableBeanFactory();
|
||||
|
||||
public Class getType(ELContext elContext, Object base, Object property) throws ELException {
|
||||
if (base != null && base instanceof RequestContext) {
|
||||
return super.getType(elContext, null, property);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getValue(ELContext elContext, Object base, Object property) throws ELException {
|
||||
if (base != null && base instanceof RequestContext) {
|
||||
return super.getValue(elContext, null, property);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReadOnly(ELContext elContext, Object base, Object property) throws ELException {
|
||||
if (base != null && base instanceof RequestContext) {
|
||||
return super.isReadOnly(elContext, null, property);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(ELContext elContext, Object base, Object property, Object value) throws ELException {
|
||||
if (base != null && base instanceof RequestContext) {
|
||||
super.setValue(elContext, null, property, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected BeanFactory getBeanFactory(ELContext elContext) {
|
||||
RequestContext rc = RequestContextHolder.getRequestContext();
|
||||
if (rc.getActiveFlow().getBeanFactory() != null) {
|
||||
|
||||
@@ -44,10 +44,11 @@ public class WebFlowELExpressionParser extends ELExpressionParser {
|
||||
public ELContext getELContext(Object target) {
|
||||
List customResolvers = new ArrayList();
|
||||
customResolvers.add(new RequestContextELResolver());
|
||||
customResolvers.add(new WebFlowImplicitObjectELResolver());
|
||||
customResolvers.add(new SpringBeanWebFlowELResolver());
|
||||
customResolvers.add(new ActionMethodELResolver());
|
||||
customResolvers.add(new ScopeSearchingELResolver());
|
||||
ELResolver resolver = new DefaultELResolver(target, customResolvers);
|
||||
ELResolver resolver = new DefaultELResolver(null, customResolvers);
|
||||
return new WebFlowELContext(resolver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.springframework.webflow.expression.el;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.el.BeanELResolver;
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.PropertyNotWritableException;
|
||||
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
public class WebFlowImplicitObjectELResolver extends ELResolver {
|
||||
|
||||
public Class getCommonPropertyType(ELContext context, Object base) {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public Iterator getFeatureDescriptors(ELContext context, Object base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Class getType(ELContext context, Object base, Object property) {
|
||||
if (base == null && RequestContextHolder.getRequestContext() == null && ImplicitVariable.matches(property)) {
|
||||
return ImplicitVariable.value(context, RequestContextHolder.getRequestContext(), property).getClass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getValue(ELContext context, Object base, Object property) {
|
||||
if (base == null && RequestContextHolder.getRequestContext() == null && ImplicitVariable.matches(property)) {
|
||||
return ImplicitVariable.value(context, RequestContextHolder.getRequestContext(), property);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isReadOnly(ELContext context, Object base, Object property) {
|
||||
if (base == null && RequestContextHolder.getRequestContext() == null && ImplicitVariable.matches(property)) {
|
||||
context.setPropertyResolved(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setValue(ELContext context, Object base, Object property, Object value) {
|
||||
if (base == null && RequestContextHolder.getRequestContext() == null && ImplicitVariable.matches(property)) {
|
||||
context.setPropertyResolved(true);
|
||||
throw new PropertyNotWritableException("The implicit flow variable " + property + " is not writable.");
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ImplicitVariable {
|
||||
private static final Set vars = new HashSet();
|
||||
|
||||
static {
|
||||
vars.add("requestScope");
|
||||
vars.add("flashScope");
|
||||
vars.add("flowScope");
|
||||
vars.add("conversationScope");
|
||||
vars.add("requestParameters");
|
||||
}
|
||||
|
||||
private static final BeanELResolver internalResolver = new BeanELResolver();
|
||||
|
||||
public static boolean matches(Object property) {
|
||||
return vars.contains(property);
|
||||
}
|
||||
|
||||
public static Object value(ELContext elContext, RequestContext requestContext, Object property) {
|
||||
return internalResolver.getValue(elContext, requestContext, property);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import java.util.HashSet;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.factory.support.StaticListableBeanFactory;
|
||||
import org.springframework.binding.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.webflow.definition.FlowDefinition;
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
|
||||
@@ -24,6 +25,9 @@ public class FlowRegistryFactoryBeanTests extends TestCase {
|
||||
FlowLocation location1 = new FlowLocation("flow1", "org/springframework/webflow/config/flow.xml", attributes);
|
||||
FlowLocation location2 = new FlowLocation("flow2", "org/springframework/webflow/config/flow.xml", attributes);
|
||||
FlowLocation[] flowLocations = new FlowLocation[] { location1, location2 };
|
||||
FlowBuilderServices builderServices = new FlowBuilderServices();
|
||||
builderServices.setConversionService(new DefaultConversionService());
|
||||
factoryBean.setFlowBuilderServices(builderServices);
|
||||
factoryBean.setFlowLocations(flowLocations);
|
||||
factoryBean.setResourceLoader(new DefaultResourceLoader());
|
||||
factoryBean.setBeanFactory(new StaticListableBeanFactory());
|
||||
@@ -42,6 +46,8 @@ public class FlowRegistryFactoryBeanTests extends TestCase {
|
||||
public void testGetFlowRegistryGeneratedFlowId() throws Exception {
|
||||
FlowLocation location1 = new FlowLocation(null, "org/springframework/webflow/config/flow.xml", null);
|
||||
FlowLocation[] flowLocations = new FlowLocation[] { location1 };
|
||||
FlowBuilderServices builderServices = new FlowBuilderServices();
|
||||
factoryBean.setFlowBuilderServices(builderServices);
|
||||
factoryBean.setFlowLocations(flowLocations);
|
||||
factoryBean.setResourceLoader(new DefaultResourceLoader());
|
||||
factoryBean.setBeanFactory(new StaticListableBeanFactory());
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
|
||||
|
||||
<web:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
|
||||
<web:flow-registry id="flowRegistry">
|
||||
<web:flow-location id="flow" path="org/springframework/webflow/config/flow.xml">
|
||||
<web:flow-definition-attributes>
|
||||
<web:attribute name="foo" value="bar" />
|
||||
@@ -26,6 +26,4 @@
|
||||
</web:flow-builder>
|
||||
</web:flow-registry>
|
||||
|
||||
<bean id="flowBuilderServices" class="org.springframework.webflow.engine.builder.support.FlowBuilderServices" />
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user