From 9b43f9320087a89689ded791b620e19bd336d3b1 Mon Sep 17 00:00:00 2001 From: Erwin Vervaet Date: Mon, 2 Apr 2007 08:21:56 +0000 Subject: [PATCH] Fixed bug in handling of null view. --- .../executor/mvc/PortletFlowController.java | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/spring-webflow/src/main/java/org/springframework/webflow/executor/mvc/PortletFlowController.java b/spring-webflow/src/main/java/org/springframework/webflow/executor/mvc/PortletFlowController.java index 62eee304..0f8b9ee1 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/executor/mvc/PortletFlowController.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/executor/mvc/PortletFlowController.java @@ -45,25 +45,26 @@ import org.springframework.webflow.executor.support.ResponseInstructionHandler; * Point of integration between Spring Portlet MVC and Spring Web Flow: a {@link Controller} that routes incoming * portlet requests to one or more managed flow executions. *

- * Requests into the web flow system are handled by a {@link FlowExecutor}, which this class delegates to. Consult the - * JavaDoc of that class for more information on how requests are processed. + * Requests into the web flow system are handled by a {@link FlowExecutor}, which this class delegates to. Consult + * the JavaDoc of that class for more information on how requests are processed. *

* Note: a single PortletFlowController may execute all flows within your application. See the - * phonebook-portlet sample application for examples of the various strategies for launching and resuming - * flow executions in a Portlet environment. + * phonebook-portlet sample application for examples of the various strategies for launching and + * resuming flow executions in a Portlet environment. *

- * It is also possible to customize the {@link FlowExecutorArgumentHandler} strategy to allow for different types of - * controller parameterization, for example perhaps in conjunction with a REST-style request mapper. + * It is also possible to customize the {@link FlowExecutorArgumentHandler} strategy to allow for different types + * of controller parameterization, for example perhaps in conjunction with a REST-style request mapper. *

* Integrating Spring Web Flow into a Portlet environment puts some minor contraints on your flows. These constraints * result from technical limitations in the Portlet API, for instance the fact that a render request cannot issue a * redirect. Keep the following in mind when developing Portlets using Spring Web Flow: *

@@ -193,16 +194,21 @@ public class PortletFlowController extends AbstractController implements Initial final PortletExternalContext context = new PortletExternalContext(getPortletContext(), request, response); final String flowExecutionKey = argumentHandler.extractFlowExecutionKey(context); final String eventId = argumentHandler.extractEventId(context); + // signal the event against the flow execution, returning the next response instruction final ResponseInstruction responseInstruction = flowExecutor.resume(flowExecutionKey, eventId, context); + new ResponseInstructionHandler() { protected void handleApplicationView(ApplicationView view) throws Exception { // response instruction is a forward to an "application view" if (responseInstruction.isActiveView()) { // is an "active" forward returned by a view-state (not an end-state) -- // set the flow execution key render parameter to support browser refresh - response.setRenderParameter(argumentHandler.getFlowExecutionKeyArgumentName(), responseInstruction - .getFlowExecutionKey()); + // we need to do this because the responseInstruction stored in the session + // below will be removed from the session when the next render request + // extracts it (see extractActionResponseInstruction) + response.setRenderParameter(argumentHandler.getFlowExecutionKeyArgumentName(), + responseInstruction.getFlowExecutionKey()); } // make response instruction available for rendering during the render phase of this portlet request exposeToRenderPhase(responseInstruction, request); @@ -217,8 +223,8 @@ public class PortletFlowController extends AbstractController implements Initial protected void handleFlowExecutionRedirect(FlowExecutionRedirect redirect) throws Exception { // is a flow execution redirect: simply expose key parameter to support refresh during render phase - response.setRenderParameter(argumentHandler.getFlowExecutionKeyArgumentName(), responseInstruction - .getFlowExecutionKey()); + response.setRenderParameter(argumentHandler.getFlowExecutionKeyArgumentName(), + responseInstruction.getFlowExecutionKey()); } protected void handleExternalRedirect(ExternalRedirect redirect) throws Exception { @@ -228,6 +234,12 @@ public class PortletFlowController extends AbstractController implements Initial } protected void handleNull() throws Exception { + if (responseInstruction.getFlowExecutionContext().isActive()) { + // flow execution is still active + // set the flow execution key render parameter to support browser refresh + response.setRenderParameter(argumentHandler.getFlowExecutionKeyArgumentName(), + responseInstruction.getFlowExecutionKey()); + } // make response instruction available for rendering during the render phase of this portlet request exposeToRenderPhase(responseInstruction, request); } @@ -274,8 +286,8 @@ public class PortletFlowController extends AbstractController implements Initial // forward to a view as part of an active conversation ApplicationView forward = (ApplicationView) responseInstruction.getViewSelection(); Map model = new HashMap(forward.getModel()); - argumentHandler.exposeFlowExecutionContext(responseInstruction.getFlowExecutionKey(), responseInstruction - .getFlowExecutionContext(), model); + argumentHandler.exposeFlowExecutionContext( + responseInstruction.getFlowExecutionKey(), responseInstruction.getFlowExecutionContext(), model); return new ModelAndView(forward.getViewName(), model); } else if (responseInstruction.isNull()) {