cleanup
removed some overloaded bean: prefix support for view=, on=, and to=
This commit is contained in:
@@ -35,8 +35,7 @@ public class EvaluationException extends NestedRuntimeException {
|
||||
* @param cause the underlying cause of this exception
|
||||
*/
|
||||
public EvaluationException(EvaluationAttempt evaluationAttempt, Throwable cause) {
|
||||
super("Expression " + evaluationAttempt
|
||||
+ " failed - make sure the expression is evaluatable in the context provided", cause);
|
||||
super(evaluationAttempt + " failed - make sure the expression is evaluatable in the context provided", cause);
|
||||
this.evaluationAttempt = evaluationAttempt;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import javax.el.ValueExpression;
|
||||
import org.springframework.binding.expression.EvaluationAttempt;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.SetValueAttempt;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -50,7 +51,7 @@ public class ELExpression implements Expression {
|
||||
try {
|
||||
valueExpression.setValue(ctx, value);
|
||||
if (!ctx.isPropertyResolved()) {
|
||||
throw new EvaluationException(new EvaluationAttempt(this, context), null);
|
||||
throw new EvaluationException(new SetValueAttempt(this, context, value), null);
|
||||
}
|
||||
} catch (ELException ex) {
|
||||
throw new EvaluationException(new EvaluationAttempt(this, context), ex);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/spring-binding"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/spring-webflow"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/global/commons-logging.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/ognl.jar"/>
|
||||
@@ -25,7 +27,5 @@
|
||||
<classpathentry kind="lib" path="lib/test/shale-test.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/servlet-api.jar"/>
|
||||
<classpathentry kind="lib" path="lib/test/spring-test.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/spring-webflow.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/spring-binding.jar"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
||||
@@ -50,14 +50,14 @@ public class JsfViewFactory implements ViewFactory {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JsfViewFactory.class);
|
||||
|
||||
private final Expression viewExpr;
|
||||
private final Expression viewIdExpression;
|
||||
|
||||
private final ResourceLoader resourceLoader;
|
||||
|
||||
private final Lifecycle lifecycle;
|
||||
|
||||
public JsfViewFactory(Expression viewExpr, ResourceLoader resourceLoader, Lifecycle lifecycle) {
|
||||
this.viewExpr = viewExpr;
|
||||
public JsfViewFactory(Expression viewIdExpression, ResourceLoader resourceLoader, Lifecycle lifecycle) {
|
||||
this.viewIdExpression = viewIdExpression;
|
||||
this.resourceLoader = resourceLoader;
|
||||
this.lifecycle = lifecycle;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ public class JsfViewFactory implements ViewFactory {
|
||||
}
|
||||
|
||||
private String resolveViewName(RequestContext context) {
|
||||
String viewId = (String) viewExpr.getValue(context);
|
||||
String viewId = (String) viewIdExpression.getValue(context);
|
||||
if (viewId.startsWith("/")) {
|
||||
return viewId;
|
||||
} else {
|
||||
|
||||
@@ -22,7 +22,6 @@ import javax.faces.lifecycle.LifecycleFactory;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
import org.springframework.webflow.execution.Action;
|
||||
import org.springframework.webflow.execution.ViewFactory;
|
||||
|
||||
/**
|
||||
@@ -36,12 +35,12 @@ public class JsfViewFactoryCreator implements ViewFactoryCreator {
|
||||
|
||||
private Lifecycle lifecycle;
|
||||
|
||||
public Action createFinalResponseAction(Expression viewName, ResourceLoader resourceLoader) {
|
||||
return new JsfFinalResponseAction(new JsfViewFactory(viewName, resourceLoader, getLifecycle()));
|
||||
public ViewFactory createViewFactory(Expression viewIdExpression, ResourceLoader resourceLoader) {
|
||||
return new JsfViewFactory(viewIdExpression, resourceLoader, getLifecycle());
|
||||
}
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewName, ResourceLoader resourceLoader) {
|
||||
return new JsfViewFactory(viewName, resourceLoader, getLifecycle());
|
||||
public String getViewIdByConvention(String viewStateId) {
|
||||
return viewStateId + FACELETS_EXTENSION;
|
||||
}
|
||||
|
||||
private Lifecycle createFlowFacesLifecycle() {
|
||||
@@ -58,8 +57,4 @@ public class JsfViewFactoryCreator implements ViewFactoryCreator {
|
||||
return lifecycle;
|
||||
}
|
||||
|
||||
public String createViewIdByConvention(String viewStateId) {
|
||||
return viewStateId + FACELETS_EXTENSION;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/spring-binding"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/test/aopalliance.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/antlr.jar"/>
|
||||
@@ -36,7 +37,6 @@
|
||||
<classpathentry kind="lib" path="lib/buildtime/servlet-api.jar"/>
|
||||
<classpathentry kind="lib" path="lib/test/spring-aop.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/spring-beans.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/spring-binding.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/spring-context.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/spring-core.jar"/>
|
||||
<classpathentry kind="lib" path="lib/test/spring-jdbc.jar"/>
|
||||
|
||||
@@ -29,16 +29,16 @@ public interface ViewFactoryCreator {
|
||||
/**
|
||||
* Create a view factory capable of creating {@link View} objects that can render the view template with the
|
||||
* provided identifier.
|
||||
* @param viewId an expression that resolves the id of the view template
|
||||
* @param viewIdExpression an expression that resolves the id of the view template
|
||||
* @param viewResourceLoader an optional resource loader to use to load the view template from an input stream
|
||||
* @return the view factory
|
||||
*/
|
||||
public ViewFactory createViewFactory(Expression viewId, ResourceLoader viewResourceLoader);
|
||||
public ViewFactory createViewFactory(Expression viewIdExpression, ResourceLoader viewResourceLoader);
|
||||
|
||||
/**
|
||||
* Create the default id of the view to render in the provided view state by convention.
|
||||
* Get the default id of the view to render in the provided view state by convention.
|
||||
* @param viewStateId the view state id
|
||||
* @return the default view id
|
||||
*/
|
||||
public String createViewIdByConvention(String viewStateId);
|
||||
public String getViewIdByConvention(String viewStateId);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.springframework.binding.convert.support.AbstractConverter;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.binding.expression.support.ParserContextImpl;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.engine.TargetStateResolver;
|
||||
import org.springframework.webflow.engine.builder.FlowBuilderContext;
|
||||
import org.springframework.webflow.engine.support.DefaultTargetStateResolver;
|
||||
@@ -33,9 +34,8 @@ import org.springframework.webflow.execution.RequestContext;
|
||||
* <ul>
|
||||
* <li>"stateId" - will result in a TargetStateResolver that always resolves the same state. </li>
|
||||
* <li>"${stateIdExpression} - will result in a TargetStateResolver that resolves the target state by evaluating an
|
||||
* expression against the request context.</li>
|
||||
* <li>"bean:<id>" - will result in usage of a custom TargetStateResolver bean implementation configured in an
|
||||
* external context.</li>
|
||||
* expression against the request context. The resolved value can be a target state identifier or a custom
|
||||
* TargetStateResolver to delegate to.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Keith Donald
|
||||
@@ -43,11 +43,6 @@ import org.springframework.webflow.execution.RequestContext;
|
||||
*/
|
||||
class TextToTargetStateResolver extends AbstractConverter {
|
||||
|
||||
/**
|
||||
* Prefix used when the user wants to use a custom TargetStateResolver implementation managed by a factory.
|
||||
*/
|
||||
private static final String BEAN_PREFIX = "bean:";
|
||||
|
||||
/**
|
||||
* Context for flow builder services.
|
||||
*/
|
||||
@@ -71,16 +66,13 @@ class TextToTargetStateResolver extends AbstractConverter {
|
||||
|
||||
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
|
||||
String targetStateId = (String) source;
|
||||
if (targetStateId == null) {
|
||||
if (!StringUtils.hasText(targetStateId)) {
|
||||
return null;
|
||||
}
|
||||
ExpressionParser parser = flowBuilderContext.getExpressionParser();
|
||||
if (targetStateId.startsWith(BEAN_PREFIX)) {
|
||||
return flowBuilderContext.getBeanFactory().getBean(targetStateId.substring(BEAN_PREFIX.length()));
|
||||
} else {
|
||||
Expression expression = parser.parseExpression(targetStateId, new ParserContextImpl().template().eval(
|
||||
RequestContext.class).expect(String.class));
|
||||
return new DefaultTargetStateResolver(expression);
|
||||
}
|
||||
Expression expression = parser.parseExpression(targetStateId, new ParserContextImpl().template().eval(
|
||||
RequestContext.class).expect(String.class));
|
||||
return new DefaultTargetStateResolver(expression);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.engine.TransitionCriteria;
|
||||
import org.springframework.webflow.engine.WildcardTransitionCriteria;
|
||||
import org.springframework.webflow.engine.builder.FlowBuilderContext;
|
||||
import org.springframework.webflow.engine.support.BooleanExpressionTransitionCriteria;
|
||||
import org.springframework.webflow.engine.support.DefaultTransitionCriteria;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
/**
|
||||
@@ -39,9 +39,8 @@ import org.springframework.webflow.execution.RequestContext;
|
||||
* </li>
|
||||
* <li>"eventId" - will result in a TransitionCriteria object that matches given event id ({@link org.springframework.webflow.engine.support.EventIdTransitionCriteria})
|
||||
* </li>
|
||||
* <li>"${...}" - will result in a TransitionCriteria object that evaluates given condition, expressed as an expression ({@link org.springframework.webflow.engine.support.BooleanExpressionTransitionCriteria})
|
||||
* <li>"${...}" - will result in a TransitionCriteria object that evaluates given condition, expressed as an expression ({@link org.springframework.webflow.engine.support.DefaultTransitionCriteria})
|
||||
* </li>
|
||||
* <li>"bean:<id>" - will result in usage of a custom TransitionCriteria bean implementation.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see org.springframework.webflow.engine.TransitionCriteria
|
||||
@@ -51,11 +50,6 @@ import org.springframework.webflow.execution.RequestContext;
|
||||
*/
|
||||
class TextToTransitionCriteria extends AbstractConverter {
|
||||
|
||||
/**
|
||||
* Prefix used when the user wants to use a custom TransitionCriteria implementation managed by a bean factory.
|
||||
*/
|
||||
private static final String BEAN_PREFIX = "bean:";
|
||||
|
||||
/**
|
||||
* Context for flow builder services.
|
||||
*/
|
||||
@@ -83,9 +77,6 @@ class TextToTransitionCriteria extends AbstractConverter {
|
||||
if (!StringUtils.hasText(encodedCriteria)
|
||||
|| WildcardTransitionCriteria.WILDCARD_EVENT_ID.equals(encodedCriteria)) {
|
||||
return WildcardTransitionCriteria.INSTANCE;
|
||||
} else if (encodedCriteria.startsWith(BEAN_PREFIX)) {
|
||||
return flowBuilderContext.getBeanFactory().getBean(encodedCriteria.substring(BEAN_PREFIX.length()),
|
||||
TransitionCriteria.class);
|
||||
} else {
|
||||
return createBooleanExpressionTransitionCriteria(encodedCriteria, parser);
|
||||
}
|
||||
@@ -103,6 +94,6 @@ class TextToTransitionCriteria extends AbstractConverter {
|
||||
ExpressionParser parser) throws ConversionException {
|
||||
Expression expression = parser.parseExpression(encodedCriteria, new ParserContextImpl().template().eval(
|
||||
RequestContext.class).variable(new ExpressionVariable("result", "lastEvent.id")));
|
||||
return new BooleanExpressionTransitionCriteria(expression);
|
||||
return new DefaultTransitionCriteria(expression);
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ import org.springframework.webflow.engine.builder.FlowBuilderException;
|
||||
import org.springframework.webflow.engine.builder.support.AbstractFlowBuilder;
|
||||
import org.springframework.webflow.engine.builder.support.ActionExecutingViewFactory;
|
||||
import org.springframework.webflow.engine.support.BeanFactoryVariableValueFactory;
|
||||
import org.springframework.webflow.engine.support.BooleanExpressionTransitionCriteria;
|
||||
import org.springframework.webflow.engine.support.DefaultTransitionCriteria;
|
||||
import org.springframework.webflow.engine.support.GenericSubflowAttributeMapper;
|
||||
import org.springframework.webflow.engine.support.TransitionCriteriaChain;
|
||||
import org.springframework.webflow.engine.support.TransitionExecutingFlowExecutionExceptionHandler;
|
||||
@@ -593,7 +593,7 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
|
||||
if (endState) {
|
||||
return null;
|
||||
} else {
|
||||
encodedView = getLocalContext().getViewFactoryCreator().createViewIdByConvention(parseId(element));
|
||||
encodedView = getLocalContext().getViewFactoryCreator().getViewIdByConvention(parseId(element));
|
||||
Expression viewName = getExpressionParser().parseExpression(encodedView,
|
||||
new ParserContextImpl().template().eval(RequestContext.class).expect(String.class));
|
||||
return getLocalContext().getViewFactoryCreator().createViewFactory(viewName,
|
||||
@@ -609,13 +609,10 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
|
||||
Expression expression = getExpressionParser().parseExpression(flowRedirect,
|
||||
new ParserContextImpl().template().eval(RequestContext.class).expect(String.class));
|
||||
return new ActionExecutingViewFactory(new FlowDefinitionRedirectAction(expression));
|
||||
} else if (encodedView.startsWith("bean:")) {
|
||||
return (ViewFactory) getLocalContext().getBeanFactory().getBean(encodedView.substring("bean:".length()),
|
||||
ViewFactory.class);
|
||||
} else {
|
||||
Expression viewName = getExpressionParser().parseExpression(encodedView,
|
||||
Expression viewId = getExpressionParser().parseExpression(encodedView,
|
||||
new ParserContextImpl().template().eval(RequestContext.class).expect(String.class));
|
||||
return getLocalContext().getViewFactoryCreator().createViewFactory(viewName,
|
||||
return getLocalContext().getViewFactoryCreator().createViewFactory(viewId,
|
||||
getLocalContext().getResourceLoader());
|
||||
}
|
||||
}
|
||||
@@ -782,7 +779,7 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
|
||||
private Transition parseThen(Element element) {
|
||||
Expression expression = getExpressionParser().parseExpression(element.getAttribute("test"),
|
||||
new ParserContextImpl().eval(RequestContext.class).expect(Boolean.class));
|
||||
TransitionCriteria matchingCriteria = new BooleanExpressionTransitionCriteria(expression);
|
||||
TransitionCriteria matchingCriteria = new DefaultTransitionCriteria(expression);
|
||||
TargetStateResolver targetStateResolver = (TargetStateResolver) fromStringTo(TargetStateResolver.class)
|
||||
.execute(element.getAttribute("then"));
|
||||
return getFlowArtifactFactory().createTransition(targetStateResolver, matchingCriteria, null, null);
|
||||
|
||||
@@ -768,10 +768,6 @@ Sophisticated transitional expressions are also supported when enclosed in a del
|
||||
<pre>
|
||||
<transition on="#{event == 'submit' &;amp;& flowScope.attribute == 'foo'}" to="state"/>
|
||||
</pre>
|
||||
For exotic usage scenarios, custom TransitionCriteria beans can be plugged in as follows:
|
||||
<pre>
|
||||
<transition on="bean:myCustomCriteriaBean" to="state"/>
|
||||
</pre>
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -794,8 +790,7 @@ Superclasses of the configured exception class match by default. Use this attri
|
||||
<![CDATA[
|
||||
The target state to transition to.
|
||||
<br>
|
||||
The value of this attribute may be a static state identifier (e.g. to="displayForm") or a dynamic eval expression (e.g. to="#{flowScope.previousViewState}").
|
||||
For exotic usage scenarios, custom target state resolver beans can also be plugged in (e.g. to="bean:myCustomTargetStateResolver").
|
||||
The value of this attribute may be a static state identifier (e.g. to="displayForm") or a dynamic expression (e.g. to="${flowScope.previousViewState}").
|
||||
If no value is specified, this transition acts as a simple event handler and will not change the state of the flow.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
@@ -905,11 +900,6 @@ Use the flowRedirect: prefix to redirect to another flow:
|
||||
<pre>
|
||||
flowRedirect:myOtherFlow?someData=#{flowScope.data}
|
||||
</pre>
|
||||
For exotic usages, use the bean: prefix to plug in a custom ViewFactory bean you define.
|
||||
<pre>
|
||||
bean:myCustomViewFactory
|
||||
</pre>
|
||||
<br>
|
||||
When this attribute is not specified, the view to render will be determined by convention.
|
||||
The default convention is to treat the id of this view state as the view identifier.
|
||||
]]>
|
||||
@@ -1241,9 +1231,9 @@ Use the flowRedirect: prefix to redirect to another flow:
|
||||
<pre>
|
||||
flowRedirect:myOtherFlow?someData=#{flowScope.data}
|
||||
</pre>
|
||||
For exotic usages, use the bean: prefix to plug in a custom ViewFactory bean you define:
|
||||
For exotic usages, you may plug in a custom ViewFactory bean you define:
|
||||
<pre>
|
||||
bean:myCustomViewFactory
|
||||
#{myCustomViewFactory}
|
||||
</pre>
|
||||
<br>
|
||||
When this attribute is not specified, no final response will be issued. In this case,
|
||||
|
||||
@@ -35,11 +35,11 @@ public class DefaultTargetStateResolver implements TargetStateResolver {
|
||||
/**
|
||||
* The expression for the target state identifier.
|
||||
*/
|
||||
private Expression targetStateIdExpression;
|
||||
private Expression targetStateExpression;
|
||||
|
||||
/**
|
||||
* Creates a new target state resolver that always returns the same target state id.
|
||||
* @param targetStateId the id of the target state
|
||||
* @param targetStateId a static target target state
|
||||
*/
|
||||
public DefaultTargetStateResolver(String targetStateId) {
|
||||
this(new StaticExpression(targetStateId));
|
||||
@@ -47,23 +47,23 @@ public class DefaultTargetStateResolver implements TargetStateResolver {
|
||||
|
||||
/**
|
||||
* Creates a new target state resolver.
|
||||
* @param targetStateIdExpression the target state id expression
|
||||
* @param targetStateExpression the target state expression
|
||||
*/
|
||||
public DefaultTargetStateResolver(Expression targetStateIdExpression) {
|
||||
Assert.notNull(targetStateIdExpression, "The target state id expression is required");
|
||||
this.targetStateIdExpression = targetStateIdExpression;
|
||||
public DefaultTargetStateResolver(Expression targetStateExpression) {
|
||||
Assert.notNull(targetStateExpression, "The target state expression is required");
|
||||
this.targetStateExpression = targetStateExpression;
|
||||
}
|
||||
|
||||
public State resolveTargetState(Transition transition, State sourceState, RequestContext context) {
|
||||
String stateId = String.valueOf(targetStateIdExpression.getValue(context));
|
||||
if (stateId != null) {
|
||||
return ((Flow) context.getActiveFlow()).getStateInstance(stateId);
|
||||
String targetStateId = (String) targetStateExpression.getValue(context);
|
||||
if (targetStateId != null) {
|
||||
return ((Flow) context.getActiveFlow()).getStateInstance(targetStateId);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return targetStateIdExpression.toString();
|
||||
return targetStateExpression.toString();
|
||||
}
|
||||
}
|
||||
@@ -22,39 +22,41 @@ import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
/**
|
||||
* Transition criteria that tests the value of an expression. The expression is used to express a condition that guards
|
||||
* transition execution in a web flow. Expressions will be evaluated agains the request context and should return a
|
||||
* boolean result.
|
||||
* transition execution in a web flow. Expressions will be evaluated against the request context. Boolean, string, and
|
||||
* custom TransitonCriteria evaluation results are supported.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Erwin Vervaet
|
||||
*/
|
||||
public class BooleanExpressionTransitionCriteria implements TransitionCriteria {
|
||||
public class DefaultTransitionCriteria implements TransitionCriteria {
|
||||
|
||||
/**
|
||||
* The expression evaluator to use.
|
||||
*/
|
||||
private Expression booleanExpression;
|
||||
private Expression expression;
|
||||
|
||||
/**
|
||||
* Create a new expression based transition criteria object.
|
||||
* @param booleanExpression the expression evaluator testing the criteria, this expression should be a condition
|
||||
* that returns a Boolean value
|
||||
* @param expression the expression evaluator testing the criteria
|
||||
*/
|
||||
public BooleanExpressionTransitionCriteria(Expression booleanExpression) {
|
||||
Assert.notNull(booleanExpression, "The expression to test is required");
|
||||
this.booleanExpression = booleanExpression;
|
||||
public DefaultTransitionCriteria(Expression expression) {
|
||||
Assert.notNull(expression, "The transition criteria expression to test is required");
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public boolean test(RequestContext context) {
|
||||
Object result = booleanExpression.getValue(context);
|
||||
if (result instanceof Boolean) {
|
||||
Object result = expression.getValue(context);
|
||||
if (result == null) {
|
||||
return false;
|
||||
} else if (result instanceof Boolean) {
|
||||
return ((Boolean) result).booleanValue();
|
||||
} else {
|
||||
return context.getLastEvent().getId().equals(String.valueOf(result));
|
||||
String eventId = String.valueOf(result);
|
||||
return context.getLastEvent().getId().equals(eventId);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return booleanExpression.toString();
|
||||
return expression.toString();
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,8 @@ public class SpringBeanWebFlowELResolver extends SpringBeanELResolver {
|
||||
protected BeanFactory getBeanFactory(ELContext elContext) {
|
||||
RequestContext rc = RequestContextHolder.getRequestContext();
|
||||
if (rc != null && rc.getActiveFlow().getBeanFactory() != null) {
|
||||
return rc.getActiveFlow().getBeanFactory();
|
||||
BeanFactory factory = rc.getActiveFlow().getBeanFactory();
|
||||
return factory;
|
||||
} else {
|
||||
return EMPTY_BEAN_FACTORY;
|
||||
}
|
||||
|
||||
@@ -19,10 +19,8 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.view.InternalResourceView;
|
||||
import org.springframework.web.servlet.view.JstlView;
|
||||
import org.springframework.webflow.action.ViewFactoryActionAdapter;
|
||||
import org.springframework.webflow.core.collection.ParameterMap;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
import org.springframework.webflow.execution.Action;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.View;
|
||||
@@ -43,6 +41,7 @@ import org.springframework.webflow.execution.ViewFactory;
|
||||
public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationContextAware {
|
||||
|
||||
private static final boolean jstlPresent = ClassUtils.isPresent("javax.servlet.jsp.jstl.fmt.LocalizationContext");
|
||||
|
||||
private static final boolean springSecurityPresent = ClassUtils
|
||||
.isPresent("org.springframework.security.context.SecurityContextHolder");
|
||||
|
||||
@@ -50,23 +49,6 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public Action createRenderViewAction(Expression viewId, ResourceLoader viewResourceLoader) {
|
||||
return new ViewFactoryActionAdapter(createViewFactory(viewId, viewResourceLoader));
|
||||
}
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewId, ResourceLoader viewResourceLoader) {
|
||||
if (viewResolvers != null) {
|
||||
return new ViewResolvingMvcViewFactory(viewId, viewResolvers);
|
||||
} else {
|
||||
return new InternalFlowResourceMvcViewFactory(viewId, applicationContext, viewResourceLoader);
|
||||
}
|
||||
}
|
||||
|
||||
public String createViewIdByConvention(String viewStateId) {
|
||||
// TODO - make configurable
|
||||
return viewStateId + ".jsp";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the view resolvers that will be used to resolve views selected by flows. If multiple resolvers are to be
|
||||
* used, the resolvers should be ordered in the manner they should be applied.
|
||||
@@ -80,27 +62,40 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
this.applicationContext = context;
|
||||
}
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewIdExpression, ResourceLoader viewResourceLoader) {
|
||||
if (viewResolvers != null) {
|
||||
return new ViewResolvingMvcViewFactory(viewIdExpression, viewResolvers);
|
||||
} else {
|
||||
return new InternalFlowResourceMvcViewFactory(viewIdExpression, applicationContext, viewResourceLoader);
|
||||
}
|
||||
}
|
||||
|
||||
public String getViewIdByConvention(String viewStateId) {
|
||||
// TODO - make configurable
|
||||
return viewStateId + ".jsp";
|
||||
}
|
||||
|
||||
/**
|
||||
* View factory implementation that creates a Spring-MVC Internal Resource view to render a flow-relative view
|
||||
* resource such as a JSP or Velocity template.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
static class InternalFlowResourceMvcViewFactory implements ViewFactory {
|
||||
private Expression viewExpression;
|
||||
private Expression viewIdExpression;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
public InternalFlowResourceMvcViewFactory(Expression viewExpression, ApplicationContext context,
|
||||
public InternalFlowResourceMvcViewFactory(Expression viewIdExpression, ApplicationContext context,
|
||||
ResourceLoader resourceLoader) {
|
||||
this.viewExpression = viewExpression;
|
||||
this.viewIdExpression = viewIdExpression;
|
||||
this.applicationContext = context;
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
public View getView(RequestContext context) {
|
||||
String viewId = (String) viewExpression.getValue(context);
|
||||
String viewId = (String) viewIdExpression.getValue(context);
|
||||
if (viewId.startsWith("/")) {
|
||||
return getViewInternal(viewId, context);
|
||||
} else {
|
||||
@@ -133,17 +128,17 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
* @author Keith Donald
|
||||
*/
|
||||
private static class ViewResolvingMvcViewFactory implements ViewFactory {
|
||||
private Expression viewId;
|
||||
private Expression viewIdExpression;
|
||||
|
||||
private List viewResolvers;
|
||||
|
||||
public ViewResolvingMvcViewFactory(Expression viewId, List viewResolvers) {
|
||||
this.viewId = viewId;
|
||||
public ViewResolvingMvcViewFactory(Expression viewIdExpression, List viewResolvers) {
|
||||
this.viewIdExpression = viewIdExpression;
|
||||
this.viewResolvers = viewResolvers;
|
||||
}
|
||||
|
||||
public View getView(RequestContext context) {
|
||||
String view = (String) viewId.getValue(context);
|
||||
String view = (String) viewIdExpression.getValue(context);
|
||||
return new MvcView(resolveView(view), context);
|
||||
}
|
||||
|
||||
@@ -190,7 +185,7 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
Map model = new HashMap();
|
||||
model.putAll(context.getConversationScope().union(context.getFlowScope()).union(context.getFlashScope())
|
||||
.union(context.getRequestScope()).asMap());
|
||||
model.put("flowExecutionRequestContext", context);
|
||||
model.put("flowRequestContext", context);
|
||||
model.put("flowExecutionKey", context.getFlowExecutionContext().getKey().toString());
|
||||
model.put("flowExecutionUrl", context.getFlowExecutionUrl());
|
||||
if (springSecurityPresent && !model.containsKey("currentUser")) {
|
||||
|
||||
@@ -121,12 +121,18 @@ public class MockFlowExecutionContext implements FlowExecutionContext {
|
||||
return outcome;
|
||||
}
|
||||
|
||||
// convenience mock accessors
|
||||
|
||||
public Flow getDefinitionInternal() {
|
||||
return (Flow) getDefinition();
|
||||
}
|
||||
|
||||
// mutators
|
||||
|
||||
/**
|
||||
* Sets the top-level flow definition.
|
||||
*/
|
||||
public void setFlow(Flow rootFlow) {
|
||||
public void setFlow(FlowDefinition rootFlow) {
|
||||
this.flow = rootFlow;
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ public class MockRequestContext implements RequestContext {
|
||||
}
|
||||
}
|
||||
|
||||
// mutators
|
||||
// mutators for configuring the mock
|
||||
|
||||
/**
|
||||
* Sets the active flow session of the executing flow associated with this request. This will influence
|
||||
@@ -243,8 +243,33 @@ public class MockRequestContext implements RequestContext {
|
||||
attributes.remove(attributeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a request parameter to the configured external context.
|
||||
* @param parameterName the parameter name
|
||||
* @param parameterValue the parameter value
|
||||
*/
|
||||
public void putRequestParameter(String parameterName, String parameterValue) {
|
||||
getMockExternalContext().putRequestParameter(parameterName, parameterValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a multi-valued request parameter to the configured external context.
|
||||
* @param parameterName the parameter name
|
||||
* @param parameterValues the parameter values
|
||||
*/
|
||||
public void putRequestParameter(String parameterName, String[] parameterValues) {
|
||||
getMockExternalContext().putRequestParameter(parameterName, parameterValues);
|
||||
}
|
||||
|
||||
// convenience accessors
|
||||
|
||||
/**
|
||||
* Returns the root flow definition for this request context. Assumes a {@link Flow} implementation.
|
||||
*/
|
||||
public Flow getRootFlow() {
|
||||
return getMockFlowExecutionContext().getDefinitionInternal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contained mutable context {@link AttributeMap attribute map} allowing setting of mock context
|
||||
* attributes.
|
||||
@@ -268,22 +293,4 @@ public class MockRequestContext implements RequestContext {
|
||||
return (MockExternalContext) externalContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a request parameter to the configured external context.
|
||||
* @param parameterName the parameter name
|
||||
* @param parameterValue the parameter value
|
||||
*/
|
||||
public void putRequestParameter(String parameterName, String parameterValue) {
|
||||
getMockExternalContext().putRequestParameter(parameterName, parameterValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a multi-valued request parameter to the configured external context.
|
||||
* @param parameterName the parameter name
|
||||
* @param parameterValues the parameter values
|
||||
*/
|
||||
public void putRequestParameter(String parameterName, String[] parameterValues) {
|
||||
getMockExternalContext().putRequestParameter(parameterName, parameterValues);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class MockViewFactoryCreator implements ViewFactoryCreator {
|
||||
return new MockViewFactory(viewId);
|
||||
}
|
||||
|
||||
public String createViewIdByConvention(String viewStateId) {
|
||||
public String getViewIdByConvention(String viewStateId) {
|
||||
return viewStateId;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
public String createViewIdByConvention(String viewStateId) {
|
||||
public String getViewIdByConvention(String viewStateId) {
|
||||
return viewStateId;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.webflow.engine.builder.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.binding.convert.ConversionException;
|
||||
import org.springframework.webflow.engine.Flow;
|
||||
import org.springframework.webflow.engine.TransitionCriteria;
|
||||
import org.springframework.webflow.engine.WildcardTransitionCriteria;
|
||||
@@ -27,7 +26,6 @@ import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.test.MockFlowBuilderContext;
|
||||
import org.springframework.webflow.test.MockRequestContext;
|
||||
|
||||
// TODO - 2 expected failures do to limitations in OgnlExpressionParser
|
||||
public class TextToTransitionCriteriaTests extends TestCase {
|
||||
|
||||
private MockFlowBuilderContext serviceLocator = new MockFlowBuilderContext("flowId");
|
||||
@@ -43,6 +41,7 @@ public class TextToTransitionCriteriaTests extends TestCase {
|
||||
assertTrue("Criterion should evaluate to true", criterion.test(ctx));
|
||||
assertSame(WildcardTransitionCriteria.INSTANCE, converter.convert("*"));
|
||||
assertSame(WildcardTransitionCriteria.INSTANCE, converter.convert(""));
|
||||
assertSame(WildcardTransitionCriteria.INSTANCE, converter.convert(null));
|
||||
}
|
||||
|
||||
public void testStaticEventId() {
|
||||
@@ -66,43 +65,22 @@ public class TextToTransitionCriteriaTests extends TestCase {
|
||||
assertFalse("Criterion should evaluate to false", criterion.test(ctx));
|
||||
}
|
||||
|
||||
/*
|
||||
* public void testNonBooleanEvaluation() throws Exception { String expression = "${flowScope.foo}";
|
||||
* TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression); RequestContext ctx =
|
||||
* getRequestContext(); try { criterion.test(ctx); fail("Non-boolean evaluations are not allowed"); } catch
|
||||
* (IllegalArgumentException e) { // success } }
|
||||
*/
|
||||
|
||||
public void testInvalidSyntax() throws Exception {
|
||||
try {
|
||||
String expression = "${&foo<<m}";
|
||||
converter.convert(expression);
|
||||
fail("Syntax error should throw ExpressionSyntaxException");
|
||||
} catch (ConversionException ex) {
|
||||
// success
|
||||
}
|
||||
public void testNonStringEvaluation() throws Exception {
|
||||
String expression = "${3 + 4}";
|
||||
TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression);
|
||||
MockRequestContext ctx = getRequestContext();
|
||||
ctx.setLastEvent(new Event(this, "7"));
|
||||
assertTrue("Criterion should evaluate to true", criterion.test(ctx));
|
||||
}
|
||||
|
||||
/*
|
||||
* public void testEventId() throws Exception { String expression = "${lastEvent.id == 'sample'}";
|
||||
* TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression); RequestContext ctx =
|
||||
* getRequestContext(); assertTrue("Criterion should evaluate to true", criterion.test(ctx)); expression =
|
||||
* "${#result == 'sample'}"; criterion = (TransitionCriteria) converter.convert(expression); assertTrue("Criterion
|
||||
* should evaluate to true", criterion.test(ctx)); }
|
||||
*/
|
||||
|
||||
public void testBean() {
|
||||
TransitionCriteria myTransitionCriteria = new TransitionCriteria() {
|
||||
public boolean test(RequestContext context) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
serviceLocator.registerBean("myTransitionCriteria", myTransitionCriteria);
|
||||
TransitionCriteria criteria = (TransitionCriteria) converter.convert("bean:myTransitionCriteria");
|
||||
assertSame(myTransitionCriteria, criteria);
|
||||
public void testNullExpressionEvaluation() throws Exception {
|
||||
String expression = "${null}";
|
||||
TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression);
|
||||
RequestContext ctx = getRequestContext();
|
||||
assertFalse("Criterion should evaluate to false", criterion.test(ctx));
|
||||
}
|
||||
|
||||
private RequestContext getRequestContext() {
|
||||
private MockRequestContext getRequestContext() {
|
||||
Flow flow = new Flow("id");
|
||||
MockRequestContext ctx = new MockRequestContext(flow);
|
||||
RequestContextHolder.setRequestContext(ctx);
|
||||
|
||||
Reference in New Issue
Block a user