builder fixes

This commit is contained in:
Keith Donald
2007-10-29 23:50:21 +00:00
parent 1eb453ac9a
commit cdcc23d346
6 changed files with 59 additions and 63 deletions

View File

@@ -17,12 +17,14 @@ package org.springframework.webflow.core.expression;
import java.util.Map;
import ognl.ObjectPropertyAccessor;
import ognl.OgnlException;
import ognl.PropertyAccessor;
import org.springframework.binding.collection.MapAdaptable;
import org.springframework.binding.expression.ognl.OgnlExpressionParser;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.execution.RequestContext;
/**
* An extension of {@link OgnlExpressionParser} that registers web flow specific property accessors.
@@ -35,6 +37,7 @@ class WebFlowOgnlExpressionParser extends OgnlExpressionParser {
* Creates a webflow-specific ognl expression parser.
*/
public WebFlowOgnlExpressionParser() {
addPropertyAccessor(RequestContext.class, new RequestContextPropertyAccessor(new ObjectPropertyAccessor()));
addPropertyAccessor(MapAdaptable.class, new MapAdaptablePropertyAccessor());
addPropertyAccessor(MutableAttributeMap.class, new MutableAttributeMapPropertyAccessor());
}
@@ -65,4 +68,33 @@ class WebFlowOgnlExpressionParser extends OgnlExpressionParser {
((MutableAttributeMap) target).put((String) name, value);
}
}
private static class RequestContextPropertyAccessor implements PropertyAccessor {
private PropertyAccessor delegate;
public RequestContextPropertyAccessor(PropertyAccessor delegate) {
this.delegate = delegate;
}
public Object getProperty(Map context, Object target, Object name) throws OgnlException {
String property = name.toString();
RequestContext requestContext = (RequestContext) target;
if (requestContext.getRequestScope().contains(property)) {
return requestContext.getRequestScope().get(property);
} else if (requestContext.getFlashScope().contains(property)) {
return requestContext.getFlashScope().get(property);
} else if (requestContext.getFlowScope().contains(property)) {
return requestContext.getFlowScope().get(property);
} else if (requestContext.getConversationScope().contains(property)) {
return requestContext.getConversationScope().get(property);
} else {
return delegate.getProperty(context, target, name);
}
}
public void setProperty(Map context, Object target, Object name, Object value) throws OgnlException {
delegate.setProperty(context, target, name, value);
}
}
}

View File

@@ -71,13 +71,11 @@ class TextToTargetStateResolver extends AbstractConverter {
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
String targetStateId = (String) source;
ExpressionParser parser = flowBuilderContext.getExpressionParser();
if (parser.isEvalExpressionString(targetStateId)) {
Expression expression = parser.parseExpression(targetStateId, RequestContext.class, String.class, null);
return new DefaultTargetStateResolver(expression);
} else if (targetStateId.startsWith(BEAN_PREFIX)) {
if (targetStateId.startsWith(BEAN_PREFIX)) {
return flowBuilderContext.getBeanFactory().getBean(targetStateId.substring(BEAN_PREFIX.length()));
} else {
return new DefaultTargetStateResolver(targetStateId);
Expression expression = parser.parseExpression(targetStateId, RequestContext.class, String.class, null);
return new DefaultTargetStateResolver(expression);
}
}
}

View File

@@ -78,6 +78,7 @@ class TextToTransitionCriteria extends AbstractConverter {
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
// TODO - add separate transition 'event' and 'condition' attributes
String encodedCriteria = (String) source;
ExpressionParser parser = flowBuilderContext.getExpressionParser();
if (!StringUtils.hasText(encodedCriteria)

View File

@@ -51,7 +51,6 @@ import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.context.support.ServletContextResource;
import org.springframework.webflow.action.ActionResultExposer;
import org.springframework.webflow.action.EvaluateAction;
import org.springframework.webflow.action.ExternalRedirectAction;
@@ -603,8 +602,7 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
String encodedViewName = encodedView.substring(REDIRECT_PREFIX.length());
Expression viewName = getExpressionParser().parseExpression(encodedViewName, RequestContext.class,
String.class, null);
Expression viewResource = new ViewResourceExpression(viewName, getLocalContext().getResourceLoader());
ViewFactory viewFactory = getLocalContext().getViewFactoryCreator().createViewFactory(viewResource,
ViewFactory viewFactory = getLocalContext().getViewFactoryCreator().createViewFactory(viewName,
getLocalContext().getResourceLoader());
return new ViewInfo(viewFactory, Boolean.TRUE);
} else if (encodedView.startsWith(EXTERNAL_REDIRECT_PREFIX)) {
@@ -624,8 +622,7 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
} else {
Expression viewName = getExpressionParser().parseExpression(encodedView, RequestContext.class,
String.class, null);
Expression viewResource = new ViewResourceExpression(viewName, getLocalContext().getResourceLoader());
ViewFactory viewFactory = getLocalContext().getViewFactoryCreator().createViewFactory(viewResource,
ViewFactory viewFactory = getLocalContext().getViewFactoryCreator().createViewFactory(viewName,
getLocalContext().getResourceLoader());
return new ViewInfo(viewFactory, null);
}
@@ -650,8 +647,7 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
} else {
Expression viewName = getExpressionParser().parseExpression(encodedView, RequestContext.class,
String.class, null);
Expression viewResource = new ViewResourceExpression(viewName, getLocalContext().getResourceLoader());
return getLocalContext().getViewFactoryCreator().createFinalResponseAction(viewResource,
return getLocalContext().getViewFactoryCreator().createFinalResponseAction(viewName,
getLocalContext().getResourceLoader());
}
}
@@ -774,9 +770,8 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
ExpressionParser parser = getLocalContext().getExpressionParser();
while (it.hasNext()) {
Element argumentElement = (Element) it.next();
String expressionString = parser.parseEvalExpressionString(argumentElement
.getAttribute(EXPRESSION_ATTRIBUTE));
Expression name = parser.parseExpression(expressionString, RequestContext.class, Object.class, null);
Expression name = parser.parseExpression(argumentElement.getAttribute(EXPRESSION_ATTRIBUTE),
RequestContext.class, Object.class, null);
Class type = null;
if (argumentElement.hasAttribute(PARAMETER_TYPE_ATTRIBUTE)) {
type = (Class) fromStringTo(Class.class)
@@ -807,10 +802,8 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
}
private Action parseEvaluateAction(Element element) {
String expressionString = getExpressionParser().parseEvalExpressionString(
element.getAttribute(EXPRESSION_ATTRIBUTE));
Expression expression = getExpressionParser().parseExpression(expressionString, RequestContext.class,
Object.class, null);
Expression expression = getExpressionParser().parseExpression(element.getAttribute(EXPRESSION_ATTRIBUTE),
RequestContext.class, Object.class, null);
return new EvaluateAction(expression, parseEvaluationResultExposer(element));
}
@@ -900,9 +893,8 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
}
private Transition parseThen(Element element) {
String expressionString = getExpressionParser().parseEvalExpressionString(element.getAttribute(TEST_ATTRIBUTE));
Expression expression = getExpressionParser().parseExpression(expressionString, RequestContext.class,
Boolean.class, null);
Expression expression = getExpressionParser().parseExpression(element.getAttribute(TEST_ATTRIBUTE),
RequestContext.class, Boolean.class, null);
TransitionCriteria matchingCriteria = new BooleanExpressionTransitionCriteria(expression);
TargetStateResolver targetStateResolver = (TargetStateResolver) fromStringTo(TargetStateResolver.class)
.execute(element.getAttribute(THEN_ATTRIBUTE));
@@ -959,16 +951,15 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
List mappingElements = DomUtils.getChildElementsByTagName(element, MAPPING_ELEMENT);
for (Iterator it = mappingElements.iterator(); it.hasNext();) {
Element mappingElement = (Element) it.next();
Expression source = parser.parseExpression(parser.parseEvalExpressionString(mappingElement
.getAttribute(SOURCE_ATTRIBUTE)), sourceClass, Object.class, null);
Expression source = parser.parseExpression(mappingElement.getAttribute(SOURCE_ATTRIBUTE), sourceClass,
Object.class, null);
Expression target = null;
if (StringUtils.hasText(mappingElement.getAttribute(TARGET_ATTRIBUTE))) {
target = parser.parseExpression(parser.parseEvalExpressionString(mappingElement
.getAttribute(TARGET_ATTRIBUTE)), targetClass, Object.class, null);
target = parser.parseExpression(mappingElement.getAttribute(TARGET_ATTRIBUTE), targetClass,
Object.class, null);
} else if (StringUtils.hasText(mappingElement.getAttribute(TARGET_COLLECTION_ATTRIBUTE))) {
target = new CollectionAddingExpression(parser.parseExpression(parser
.parseEvalExpressionString(mappingElement.getAttribute(TARGET_COLLECTION_ATTRIBUTE)),
targetClass, Object.class, null));
target = new CollectionAddingExpression(parser.parseExpression(mappingElement
.getAttribute(TARGET_COLLECTION_ATTRIBUTE), targetClass, Object.class, null));
}
if (getRequired(mappingElement, false)) {
mapper.addMapping(new RequiredMapping(source, target, parseTypeConverter(mappingElement)));
@@ -982,9 +973,8 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
ExpressionParser parser = getLocalContext().getExpressionParser();
for (Iterator it = elements.iterator(); it.hasNext();) {
Element element = (Element) it.next();
String expressionString = parser.parseEvalExpressionString(element.getAttribute(NAME_ATTRIBUTE));
Expression attributeExpression = parser.parseExpression(expressionString, MutableAttributeMap.class,
Object.class, null);
Expression attributeExpression = parser.parseExpression(element.getAttribute(NAME_ATTRIBUTE),
MutableAttributeMap.class, Object.class, null);
Expression scopedAttributeExpression = new ScopedAttributeExpression(attributeExpression, parseScope(
element, ScopeType.FLOW));
if (getRequired(element, false)) {
@@ -999,9 +989,8 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
ExpressionParser parser = getLocalContext().getExpressionParser();
for (Iterator it = elements.iterator(); it.hasNext();) {
Element element = (Element) it.next();
String expressionString = parser.parseEvalExpressionString(element.getAttribute(NAME_ATTRIBUTE));
Expression attributeExpression = parser.parseExpression(expressionString, MutableAttributeMap.class,
Object.class, null);
Expression attributeExpression = parser.parseExpression(element.getAttribute(NAME_ATTRIBUTE),
MutableAttributeMap.class, Object.class, null);
Expression scopedAttributeExpression = new ScopedAttributeExpression(attributeExpression, parseScope(
element, ScopeType.FLOW));
if (getRequired(element, false)) {
@@ -1135,30 +1124,6 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
}
}
private static class ViewResourceExpression implements Expression {
private Expression viewLocation;
private ResourceLoader viewResourceLoader;
public ViewResourceExpression(Expression viewLocation, ResourceLoader viewResourceLoader) {
this.viewLocation = viewLocation;
this.viewResourceLoader = viewResourceLoader;
}
public Object getValue(Object target) throws EvaluationException {
String location = (String) viewLocation.getValue(target);
Resource resource = viewResourceLoader.getResource(location);
if (resource instanceof ServletContextResource) {
return ((ServletContextResource) resource).getPath();
} else {
throw new IllegalArgumentException("Unsupported resource " + resource);
}
}
public void setValue(Object target, Object value) throws EvaluationException {
throw new UnsupportedOperationException("Set value not supported");
}
}
private static class FlowRelativeResourceLoader implements ResourceLoader {
private Resource resource;

View File

@@ -65,7 +65,7 @@ public class EndStateTests extends TestCase {
EndState state = new EndState(flow, "end");
DefaultAttributeMapper mapper = new DefaultAttributeMapper();
MappingBuilder builder = new MappingBuilder(DefaultExpressionParserFactory.getExpressionParser());
Mapping mapping = builder.source("flowScope.x").target("y").value();
Mapping mapping = builder.source("${flowScope.x}").target("${y}").value();
mapper.addMapping(mapping);
state.setOutputMapper(mapper);
MockRequestControlContext context = new MockRequestControlContext(flow);

View File

@@ -196,7 +196,7 @@ public class FlowTests extends TestCase {
public void testStartWithMapper() {
DefaultAttributeMapper attributeMapper = new DefaultAttributeMapper();
MappingBuilder mapping = new MappingBuilder(DefaultExpressionParserFactory.getExpressionParser());
attributeMapper.addMapping(mapping.source("attr").target("flowScope.attr").value());
attributeMapper.addMapping(mapping.source("${attr}").target("${flowScope.attr}").value());
flow.setInputMapper(attributeMapper);
MockRequestControlContext context = new MockRequestControlContext(flow);
LocalAttributeMap sessionInput = new LocalAttributeMap();
@@ -208,7 +208,7 @@ public class FlowTests extends TestCase {
public void testStartWithMapperButNoInput() {
DefaultAttributeMapper attributeMapper = new DefaultAttributeMapper();
MappingBuilder mapping = new MappingBuilder(DefaultExpressionParserFactory.getExpressionParser());
attributeMapper.addMapping(mapping.source("attr").target("flowScope.attr").value());
attributeMapper.addMapping(mapping.source("${attr}").target("${flowScope.attr}").value());
flow.setInputMapper(attributeMapper);
MockRequestControlContext context = new MockRequestControlContext(flow);
LocalAttributeMap sessionInput = new LocalAttributeMap();
@@ -294,7 +294,7 @@ public class FlowTests extends TestCase {
public void testEndWithOutputMapper() {
DefaultAttributeMapper attributeMapper = new DefaultAttributeMapper();
MappingBuilder mapping = new MappingBuilder(DefaultExpressionParserFactory.getExpressionParser());
attributeMapper.addMapping(mapping.source("flowScope.attr").target("attr").value());
attributeMapper.addMapping(mapping.source("${flowScope.attr}").target("${attr}").value());
flow.setOutputMapper(attributeMapper);
MockRequestControlContext context = new MockRequestControlContext(flow);
context.getFlowScope().put("attr", "foo");