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 9d7b08f4..62eee304 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 @@ -42,40 +42,30 @@ import org.springframework.webflow.executor.support.RequestParameterFlowExecutor 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. + * 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
+ * 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.
*
- * 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: + * 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: *
- * This is a convenience method that sets the default flow id of the - * controller's argument handler. Don't use this when using - * {@link #setArgumentHandler(FlowExecutorArgumentHandler)}. + * This is a convenience method that sets the default flow id of the controller's argument handler. Don't use this + * when using {@link #setArgumentHandler(FlowExecutorArgumentHandler)}. */ public void setDefaultFlowId(String defaultFlowId) { argumentHandler.setDefaultFlowId(defaultFlowId); @@ -189,9 +173,8 @@ public class PortletFlowController extends AbstractController implements Initial } } else { - // this is either a "launch" flow request or a "confirmation view" - // render request. first, look for the cached "confirmation view" - // response instruction + // this is either a "launch" flow request or a "confirmation view" render request + // first look for the cached "confirmation view" response instruction ResponseInstruction responseInstruction = extractActionResponseInstruction(request); if (responseInstruction == null) { // no response instruction found in session - launch a new flow execution @@ -210,13 +193,18 @@ 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 + // 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 { - // cache response instruction for access during render phase of this - // portlet + // 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()); + } + // make response instruction available for rendering during the render phase of this portlet request exposeToRenderPhase(responseInstruction, request); } @@ -224,16 +212,13 @@ public class PortletFlowController extends AbstractController implements Initial // set flow id render parameter to request that a new flow be // launched within this portlet response.setRenderParameters(redirect.getExecutionInput()); - response.setRenderParameter( - argumentHandler.getFlowIdArgumentName(), redirect.getFlowDefinitionId()); + response.setRenderParameter(argumentHandler.getFlowIdArgumentName(), redirect.getFlowDefinitionId()); } 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()); + // is a flow execution redirect: simply expose key parameter to support refresh during render phase + response.setRenderParameter(argumentHandler.getFlowExecutionKeyArgumentName(), responseInstruction + .getFlowExecutionKey()); } protected void handleExternalRedirect(ExternalRedirect redirect) throws Exception { @@ -243,8 +228,7 @@ public class PortletFlowController extends AbstractController implements Initial } protected void handleNull() throws Exception { - // make response instruction available for rendering during the render phase - // of this portlet + // make response instruction available for rendering during the render phase of this portlet request exposeToRenderPhase(responseInstruction, request); } }.handle(responseInstruction); @@ -253,8 +237,7 @@ public class PortletFlowController extends AbstractController implements Initial // helpers /** - * Expose given response instruction to the render phase by putting it in - * the session. + * Expose given response instruction to the render phase by putting it in the session. */ private void exposeToRenderPhase(ResponseInstruction responseInstruction, ActionRequest request) { PortletSession session = request.getPortletSession(false); @@ -263,18 +246,17 @@ public class PortletFlowController extends AbstractController implements Initial } /** - * Extract a response instruction stored in the session during the action - * phase by {@link #exposeToRenderPhase(ResponseInstruction, ActionRequest)}. - * If a response instruction is found, it will be removed from the session. + * Extract a response instruction stored in the session during the action phase by + * {@link #exposeToRenderPhase(ResponseInstruction, ActionRequest)}. If a response instruction is found, it will be + * removed from the session. * @param request the portlet request - * @return the response instructions found in the session or null if not - * found + * @return the response instructions found in the session or null if not found */ private ResponseInstruction extractActionResponseInstruction(PortletRequest request) { PortletSession session = request.getPortletSession(false); ResponseInstruction response = null; if (session != null) { - response = (ResponseInstruction)session.getAttribute(RESPONSE_INSTRUCTION_SESSION_ATTRIBUTE); + response = (ResponseInstruction) session.getAttribute(RESPONSE_INSTRUCTION_SESSION_ATTRIBUTE); if (response != null) { // remove it session.removeAttribute(RESPONSE_INSTRUCTION_SESSION_ATTRIBUTE); @@ -284,16 +266,16 @@ public class PortletFlowController extends AbstractController implements Initial } /** - * Convert given response instruction into a Spring Portlet MVC model and - * view. Will only be called during the render phase. + * Convert given response instruction into a Spring Portlet MVC model and view. Will only be called during the + * render phase. */ protected ModelAndView toModelAndView(ResponseInstruction responseInstruction) { if (responseInstruction.isApplicationView()) { // forward to a view as part of an active conversation - ApplicationView forward = (ApplicationView)responseInstruction.getViewSelection(); + 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()) { @@ -305,8 +287,7 @@ public class PortletFlowController extends AbstractController implements Initial // available on ActionResponse during the action phase // furthermore, a FlowExecutionRedirect doesn't really makes sense since the // portlet container handles refreshes with the render phase - throw new IllegalArgumentException( - "Don't know how to render response instruction " + responseInstruction); + throw new IllegalArgumentException("Don't know how to render response instruction " + responseInstruction); } } } \ No newline at end of file