diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/support/ActionExecutingViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/support/ActionExecutingViewFactory.java index 35d58533..8b238eb7 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/support/ActionExecutingViewFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/support/ActionExecutingViewFactory.java @@ -15,6 +15,9 @@ */ package org.springframework.webflow.engine.support; +import java.util.Iterator; + +import org.springframework.webflow.core.collection.ParameterMap; import org.springframework.webflow.engine.ActionExecutor; import org.springframework.webflow.execution.Action; import org.springframework.webflow.execution.Event; @@ -53,29 +56,81 @@ public class ActionExecutingViewFactory implements ViewFactory { private Action action; - private RequestContext context; + private RequestContext requestContext; - private ActionExecutingView(Action action, RequestContext context) { + private String eventId; + + private ActionExecutingView(Action action, RequestContext requestContext) { this.action = action; - this.context = context; + this.requestContext = requestContext; } public void render() { if (action != null) { - ActionExecutor.execute(action, context); + ActionExecutor.execute(action, requestContext); } } public void processUserEvent() { - + determineEventId(requestContext); } public boolean hasFlowEvent() { - return context.getExternalContext().getRequestParameterMap().contains("_eventId"); + return eventId != null; } public Event getFlowEvent() { - return new Event(this, context.getExternalContext().getRequestParameterMap().get("_eventId")); + if (!hasFlowEvent()) { + return null; + } + return new Event(this, eventId); + } + + private void determineEventId(RequestContext context) { + eventId = findParameter("_eventId", context.getRequestParameters()); + } + + /** + * Obtain a named parameter from the request parameters. This method will try to obtain a parameter value using + * the following algorithm: + *
null if the parameter does not exist in given request
+ */
+ private String findParameter(String logicalParameterName, ParameterMap parameters) {
+ // first try to get it as a normal name=value parameter
+ String value = parameters.get(logicalParameterName);
+ if (value != null) {
+ return value;
+ }
+ // if no value yet, try to get it as a name_value=xyz parameter
+ String prefix = logicalParameterName + "_";
+ Iterator paramNames = parameters.asMap().keySet().iterator();
+ while (paramNames.hasNext()) {
+ String paramName = (String) paramNames.next();
+ if (paramName.startsWith(prefix)) {
+ String strValue = paramName.substring(prefix.length());
+ // support images buttons, which would submit parameters as
+ // name_value.x=123
+ if (strValue.endsWith(".x") || strValue.endsWith(".y")) {
+ strValue = strValue.substring(0, strValue.length() - 2);
+ }
+ return strValue;
+ }
+ }
+ // we couldn't find the parameter value
+ return null;
}
}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/support/ActionExecutingViewFactoryTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/support/ActionExecutingViewFactoryTests.java
new file mode 100644
index 00000000..485abd1b
--- /dev/null
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/support/ActionExecutingViewFactoryTests.java
@@ -0,0 +1,63 @@
+package org.springframework.webflow.engine.support;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.springframework.webflow.execution.TestAction;
+import org.springframework.webflow.execution.View;
+import org.springframework.webflow.test.MockRequestContext;
+
+public class ActionExecutingViewFactoryTests extends TestCase {
+
+ public void testGetView() throws Exception {
+ TestAction action = new TestAction();
+ ActionExecutingViewFactory factory = new ActionExecutingViewFactory(action);
+ MockRequestContext context = new MockRequestContext();
+ View view = factory.getView(context);
+ assertFalse(action.isExecuted());
+ view.render();
+ assertTrue(action.isExecuted());
+ }
+
+ public void testProcessUserEvent() throws IOException {
+ TestAction action = new TestAction();
+ ActionExecutingViewFactory factory = new ActionExecutingViewFactory(action);
+ MockRequestContext context = new MockRequestContext();
+ View view = factory.getView(context);
+ assertFalse(action.isExecuted());
+ view.render();
+ assertTrue(action.isExecuted());
+ context.putRequestParameter("_eventId", "foo");
+ view.processUserEvent();
+ assertTrue(view.hasFlowEvent());
+ assertEquals("foo", view.getFlowEvent().getId());
+ }
+
+ public void testProcessUserEventButton() throws IOException {
+ TestAction action = new TestAction();
+ ActionExecutingViewFactory factory = new ActionExecutingViewFactory(action);
+ MockRequestContext context = new MockRequestContext();
+ View view = factory.getView(context);
+ assertFalse(action.isExecuted());
+ view.render();
+ assertTrue(action.isExecuted());
+ context.putRequestParameter("_eventId_foo", "doesn't matter");
+ view.processUserEvent();
+ assertTrue(view.hasFlowEvent());
+ assertEquals("foo", view.getFlowEvent().getId());
+ }
+
+ public void testProcessUserEventNoEvent() throws IOException {
+ TestAction action = new TestAction();
+ ActionExecutingViewFactory factory = new ActionExecutingViewFactory(action);
+ MockRequestContext context = new MockRequestContext();
+ View view = factory.getView(context);
+ assertFalse(action.isExecuted());
+ view.render();
+ assertTrue(action.isExecuted());
+ view.processUserEvent();
+ assertFalse(view.hasFlowEvent());
+ assertNull(view.getFlowEvent());
+ }
+}