Introduced ResponseInstructionHandler convenience class and refactored FlowController, PortletFlowController, FlowAction and FlowPhaseListener to use it.
This commit is contained in:
@@ -56,6 +56,8 @@ Package org.springframework.webflow.executor
|
||||
* Added support for configuring a <flow:executor> in a JSF environment, greatly simplifying JSF SWF
|
||||
configuration and making it consistent with Spring MVC and Struts. This also means its much easier
|
||||
to benefit from defaults such as a continuation-based flow execution repository and 'alwaysRedirectOnPause'.
|
||||
* Introduced ResponseInstructionHandler convenience class and refactored FlowController, PortletFlowController,
|
||||
FlowAction and FlowPhaseListener to use it.
|
||||
|
||||
Package org.springframework.webflow.test
|
||||
* Added constructor taking test name argument to AbstractFlowExecutionTests, AbstractExternalizedFlowExecutionTests
|
||||
|
||||
@@ -42,8 +42,10 @@ import org.springframework.webflow.execution.support.ApplicationView;
|
||||
import org.springframework.webflow.execution.support.ExternalRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowDefinitionRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowExecutionRedirect;
|
||||
import org.springframework.webflow.executor.ResponseInstruction;
|
||||
import org.springframework.webflow.executor.support.FlowExecutorArgumentHandler;
|
||||
import org.springframework.webflow.executor.support.RequestParameterFlowExecutorArgumentHandler;
|
||||
import org.springframework.webflow.executor.support.ResponseInstructionHandler;
|
||||
|
||||
/**
|
||||
* JSF phase listener that is responsible for managing a {@link FlowExecution}
|
||||
@@ -196,7 +198,7 @@ public class FlowPhaseListener implements PhaseListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void prepareResponse(JsfExternalContext context, FlowExecutionHolder holder) {
|
||||
protected void prepareResponse(final JsfExternalContext context, final FlowExecutionHolder holder) {
|
||||
if (holder.needsSave()) {
|
||||
generateKey(context, holder);
|
||||
}
|
||||
@@ -205,26 +207,38 @@ public class FlowPhaseListener implements PhaseListener {
|
||||
selectedView = holder.getFlowExecution().refresh(context);
|
||||
holder.setViewSelection(selectedView);
|
||||
}
|
||||
if (selectedView instanceof ApplicationView) {
|
||||
prepareApplicationView(context.getFacesContext(), holder);
|
||||
}
|
||||
else if (selectedView instanceof FlowExecutionRedirect) {
|
||||
String url = argumentHandler.createFlowExecutionUrl(holder.getFlowExecutionKey().toString(), holder
|
||||
.getFlowExecution(), context);
|
||||
sendRedirect(url, context);
|
||||
}
|
||||
else if (selectedView instanceof ExternalRedirect) {
|
||||
String flowExecutionKey = holder.getFlowExecution().isActive() ? holder.getFlowExecutionKey().toString()
|
||||
: null;
|
||||
String url = argumentHandler.createExternalUrl((ExternalRedirect) holder.getViewSelection(),
|
||||
flowExecutionKey, context);
|
||||
sendRedirect(url, context);
|
||||
}
|
||||
else if (selectedView instanceof FlowDefinitionRedirect) {
|
||||
String url = argumentHandler.createFlowDefinitionUrl((FlowDefinitionRedirect) holder.getViewSelection(),
|
||||
context);
|
||||
sendRedirect(url, context);
|
||||
}
|
||||
|
||||
new ResponseInstructionHandler() {
|
||||
|
||||
protected void handleApplicationView(ApplicationView view) throws Exception {
|
||||
prepareApplicationView(context.getFacesContext(), holder);
|
||||
}
|
||||
|
||||
protected void handleFlowDefinitionRedirect(FlowDefinitionRedirect redirect) throws Exception {
|
||||
String url = argumentHandler.createFlowDefinitionUrl((FlowDefinitionRedirect) holder.getViewSelection(),
|
||||
context);
|
||||
sendRedirect(url, context);
|
||||
}
|
||||
|
||||
protected void handleFlowExecutionRedirect(FlowExecutionRedirect redirect) throws Exception {
|
||||
String url = argumentHandler.createFlowExecutionUrl(holder.getFlowExecutionKey().toString(), holder
|
||||
.getFlowExecution(), context);
|
||||
sendRedirect(url, context);
|
||||
}
|
||||
|
||||
protected void handleExternalRedirect(ExternalRedirect redirect) throws Exception {
|
||||
String flowExecutionKey = holder.getFlowExecution().isActive() ? holder.getFlowExecutionKey().toString()
|
||||
: null;
|
||||
String url = argumentHandler.createExternalUrl((ExternalRedirect) holder.getViewSelection(),
|
||||
flowExecutionKey, context);
|
||||
sendRedirect(url, context);
|
||||
}
|
||||
|
||||
protected void handleNull() throws Exception {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
}.handleQuietly(new ResponseInstruction(holder.getFlowExecution(), selectedView));
|
||||
}
|
||||
|
||||
protected void prepareApplicationView(FacesContext facesContext, FlowExecutionHolder holder) {
|
||||
|
||||
@@ -32,12 +32,14 @@ import org.springframework.webflow.context.servlet.ServletExternalContext;
|
||||
import org.springframework.webflow.execution.support.ApplicationView;
|
||||
import org.springframework.webflow.execution.support.ExternalRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowDefinitionRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowExecutionRedirect;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
import org.springframework.webflow.executor.ResponseInstruction;
|
||||
import org.springframework.webflow.executor.support.FlowExecutorArgumentHandler;
|
||||
import org.springframework.webflow.executor.support.FlowRequestHandler;
|
||||
import org.springframework.webflow.executor.support.RequestParameterFlowExecutorArgumentHandler;
|
||||
import org.springframework.webflow.executor.support.RequestPathFlowExecutorArgumentHandler;
|
||||
import org.springframework.webflow.executor.support.ResponseInstructionHandler;
|
||||
|
||||
/**
|
||||
* Point of integration between Spring Web MVC and Spring Web Flow: a
|
||||
@@ -186,41 +188,45 @@ public class FlowController extends AbstractController implements InitializingBe
|
||||
* Create a ModelAndView object based on the information in the selected
|
||||
* response instruction. Subclasses can override this to return a
|
||||
* specialized ModelAndView or to do custom processing on it.
|
||||
* @param response instruction the response instruction to convert
|
||||
* @param responseInstruction the response instruction to convert
|
||||
* @return a new ModelAndView object
|
||||
*/
|
||||
protected ModelAndView toModelAndView(ResponseInstruction response, ExternalContext context) {
|
||||
if (response.isApplicationView()) {
|
||||
// forward to a view as part of an active conversation
|
||||
ApplicationView view = (ApplicationView)response.getViewSelection();
|
||||
Map model = new HashMap(view.getModel());
|
||||
argumentHandler.exposeFlowExecutionContext(
|
||||
response.getFlowExecutionKey(), response.getFlowExecutionContext(), model);
|
||||
return new ModelAndView(view.getViewName(), model);
|
||||
}
|
||||
else if (response.isFlowDefinitionRedirect()) {
|
||||
// restart the flow by redirecting to flow launch URL
|
||||
String flowUrl = argumentHandler.createFlowDefinitionUrl((FlowDefinitionRedirect)response.getViewSelection(), context);
|
||||
return new ModelAndView(new RedirectView(flowUrl));
|
||||
}
|
||||
else if (response.isFlowExecutionRedirect()) {
|
||||
// redirect to active flow execution URL
|
||||
String flowExecutionUrl = argumentHandler.createFlowExecutionUrl(
|
||||
response.getFlowExecutionKey(), response.getFlowExecutionContext(), context);
|
||||
return new ModelAndView(new RedirectView(flowExecutionUrl));
|
||||
}
|
||||
else if (response.isExternalRedirect()) {
|
||||
// redirect to external URL
|
||||
ExternalRedirect redirect = (ExternalRedirect)response.getViewSelection();
|
||||
String externalUrl = argumentHandler.createExternalUrl(redirect, response.getFlowExecutionKey(), context);
|
||||
return new ModelAndView(new RedirectView(externalUrl));
|
||||
}
|
||||
else if (response.isNull()) {
|
||||
// no response to issue
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Don't know how to handle response instruction " + response);
|
||||
}
|
||||
protected ModelAndView toModelAndView(
|
||||
final ResponseInstruction responseInstruction, final ExternalContext context) {
|
||||
return (ModelAndView)new ResponseInstructionHandler() {
|
||||
protected void handleApplicationView(ApplicationView view) throws Exception {
|
||||
// forward to a view as part of an active conversation
|
||||
Map model = new HashMap(view.getModel());
|
||||
argumentHandler.exposeFlowExecutionContext(responseInstruction.getFlowExecutionKey(),
|
||||
responseInstruction.getFlowExecutionContext(), model);
|
||||
setResult(new ModelAndView(view.getViewName(), model));
|
||||
}
|
||||
|
||||
protected void handleFlowDefinitionRedirect(FlowDefinitionRedirect redirect) throws Exception {
|
||||
// restart the flow by redirecting to flow launch URL
|
||||
String flowUrl = argumentHandler.createFlowDefinitionUrl(redirect, context);
|
||||
setResult(new ModelAndView(new RedirectView(flowUrl)));
|
||||
}
|
||||
|
||||
protected void handleFlowExecutionRedirect(FlowExecutionRedirect redirect) throws Exception {
|
||||
// redirect to active flow execution URL
|
||||
String flowExecutionUrl = argumentHandler.createFlowExecutionUrl(
|
||||
responseInstruction.getFlowExecutionKey(),
|
||||
responseInstruction.getFlowExecutionContext(), context);
|
||||
setResult(new ModelAndView(new RedirectView(flowExecutionUrl)));
|
||||
}
|
||||
|
||||
protected void handleExternalRedirect(ExternalRedirect redirect) throws Exception {
|
||||
// redirect to external URL
|
||||
String externalUrl = argumentHandler.createExternalUrl(redirect,
|
||||
responseInstruction.getFlowExecutionKey(), context);
|
||||
setResult(new ModelAndView(new RedirectView(externalUrl)));
|
||||
}
|
||||
|
||||
protected void handleNull() throws Exception {
|
||||
// no response to issue
|
||||
setResult(null);
|
||||
}
|
||||
}.handleQuietly(responseInstruction).getResult();
|
||||
}
|
||||
}
|
||||
@@ -34,10 +34,12 @@ import org.springframework.webflow.context.portlet.PortletExternalContext;
|
||||
import org.springframework.webflow.execution.support.ApplicationView;
|
||||
import org.springframework.webflow.execution.support.ExternalRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowDefinitionRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowExecutionRedirect;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
import org.springframework.webflow.executor.ResponseInstruction;
|
||||
import org.springframework.webflow.executor.support.FlowExecutorArgumentHandler;
|
||||
import org.springframework.webflow.executor.support.RequestParameterFlowExecutorArgumentHandler;
|
||||
import org.springframework.webflow.executor.support.ResponseInstructionHandler;
|
||||
|
||||
/**
|
||||
* Point of integration between Spring Portlet MVC and Spring Web Flow: a
|
||||
@@ -186,50 +188,59 @@ public class PortletFlowController extends AbstractController implements Initial
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleActionRequestInternal(ActionRequest request, ActionResponse response) throws Exception {
|
||||
PortletExternalContext context = new PortletExternalContext(getPortletContext(), request, response);
|
||||
String flowExecutionKey = argumentHandler.extractFlowExecutionKey(context);
|
||||
String eventId = argumentHandler.extractEventId(context);
|
||||
protected void handleActionRequestInternal(final ActionRequest request, final ActionResponse response)
|
||||
throws Exception {
|
||||
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
|
||||
ResponseInstruction responseInstruction = flowExecutor.resume(flowExecutionKey, eventId, context);
|
||||
if (responseInstruction.isApplicationView()) {
|
||||
// response instruction is a forward to an "application view"
|
||||
if (responseInstruction.isActiveView()) {
|
||||
// is an "active" forward from a view-state (not end-state) --
|
||||
// set the flow execution key render parameter to support
|
||||
// browser refresh
|
||||
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 from a view-state (not end-state) --
|
||||
// set the flow execution key render parameter to support
|
||||
// browser refresh
|
||||
response.setRenderParameter(
|
||||
argumentHandler.getFlowExecutionKeyArgumentName(),
|
||||
responseInstruction.getFlowExecutionKey());
|
||||
}
|
||||
// cache response instruction for access during render phase of this
|
||||
// portlet
|
||||
exposeToRenderPhase(responseInstruction, request);
|
||||
}
|
||||
|
||||
protected void handleFlowDefinitionRedirect(FlowDefinitionRedirect redirect) throws Exception {
|
||||
// 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());
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
// cache response instruction for access during render phase of this
|
||||
// portlet
|
||||
exposeToRenderPhase(responseInstruction, request);
|
||||
}
|
||||
else if (responseInstruction.isFlowExecutionRedirect()) {
|
||||
// is a flow execution redirect: simply expose key parameter to
|
||||
// support refresh during render phase
|
||||
response.setRenderParameter(
|
||||
argumentHandler.getFlowExecutionKeyArgumentName(),
|
||||
responseInstruction.getFlowExecutionKey());
|
||||
}
|
||||
else if (responseInstruction.isFlowDefinitionRedirect()) {
|
||||
// set flow id render parameter to request that a new flow be
|
||||
// launched within this portlet
|
||||
FlowDefinitionRedirect redirect = (FlowDefinitionRedirect)responseInstruction.getViewSelection();
|
||||
response.setRenderParameters(redirect.getExecutionInput());
|
||||
response.setRenderParameter(argumentHandler.getFlowIdArgumentName(), redirect.getFlowDefinitionId());
|
||||
}
|
||||
else if (responseInstruction.isExternalRedirect()) {
|
||||
// issue the redirect to the external URL
|
||||
ExternalRedirect redirect = (ExternalRedirect)responseInstruction.getViewSelection();
|
||||
String url = argumentHandler.createExternalUrl(redirect, flowExecutionKey, context);
|
||||
response.sendRedirect(url);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Don't know how to handle response instruction " + responseInstruction);
|
||||
}
|
||||
|
||||
protected void handleExternalRedirect(ExternalRedirect redirect) throws Exception {
|
||||
// issue the redirect to the external URL
|
||||
String url = argumentHandler.createExternalUrl(redirect, flowExecutionKey, context);
|
||||
response.sendRedirect(url);
|
||||
}
|
||||
|
||||
protected void handleNull() throws Exception {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
}.handle(responseInstruction);
|
||||
}
|
||||
|
||||
// helpers
|
||||
@@ -269,21 +280,22 @@ public class PortletFlowController extends AbstractController implements Initial
|
||||
* Convert given response instruction into a Spring Portlet MVC model and
|
||||
* view.
|
||||
*/
|
||||
protected ModelAndView toModelAndView(ResponseInstruction response) {
|
||||
if (response.isApplicationView()) {
|
||||
protected ModelAndView toModelAndView(ResponseInstruction responseInstruction) {
|
||||
if (responseInstruction.isApplicationView()) {
|
||||
// forward to a view as part of an active conversation
|
||||
ApplicationView forward = (ApplicationView)response.getViewSelection();
|
||||
ApplicationView forward = (ApplicationView)responseInstruction.getViewSelection();
|
||||
Map model = new HashMap(forward.getModel());
|
||||
argumentHandler.exposeFlowExecutionContext(
|
||||
response.getFlowExecutionKey(), response.getFlowExecutionContext(), model);
|
||||
responseInstruction.getFlowExecutionKey(), responseInstruction.getFlowExecutionContext(), model);
|
||||
return new ModelAndView(forward.getViewName(), model);
|
||||
}
|
||||
else if (response.isNull()) {
|
||||
else if (responseInstruction.isNull()) {
|
||||
// no response to issue
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Don't know how to handle response instruction " + response);
|
||||
throw new IllegalArgumentException(
|
||||
"Don't know how to handle response instruction " + responseInstruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,11 +35,13 @@ import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.execution.support.ApplicationView;
|
||||
import org.springframework.webflow.execution.support.ExternalRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowDefinitionRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowExecutionRedirect;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
import org.springframework.webflow.executor.ResponseInstruction;
|
||||
import org.springframework.webflow.executor.support.FlowExecutorArgumentHandler;
|
||||
import org.springframework.webflow.executor.support.FlowRequestHandler;
|
||||
import org.springframework.webflow.executor.support.RequestParameterFlowExecutorArgumentHandler;
|
||||
import org.springframework.webflow.executor.support.ResponseInstructionHandler;
|
||||
|
||||
/**
|
||||
* Point of integration between Struts and Spring Web Flow: a Struts Action that
|
||||
@@ -232,50 +234,52 @@ public class FlowAction extends ActionSupport {
|
||||
* Return a Struts ActionForward given a ResponseInstruction. Adds all
|
||||
* attributes from the ResponseInstruction as request attributes.
|
||||
*/
|
||||
protected ActionForward toActionForward(ResponseInstruction response, ActionMapping mapping, ActionForm form,
|
||||
HttpServletRequest request, HttpServletResponse httpResponse, ExternalContext context) throws Exception {
|
||||
if (response.isApplicationView()) {
|
||||
// forward to a view as part of an active conversation
|
||||
ApplicationView forward = (ApplicationView)response.getViewSelection();
|
||||
Map model = new HashMap(forward.getModel());
|
||||
argumentHandler.exposeFlowExecutionContext(
|
||||
response.getFlowExecutionKey(), response.getFlowExecutionContext(), model);
|
||||
WebUtils.exposeRequestAttributes(request, model);
|
||||
if (form instanceof SpringBindingActionForm) {
|
||||
SpringBindingActionForm bindingForm = (SpringBindingActionForm)form;
|
||||
// expose the form object and associated errors as the
|
||||
// "current form object" in the request
|
||||
Errors currentErrors = (Errors)model.get(FormObjectAccessor.getCurrentFormErrorsName());
|
||||
bindingForm.expose(currentErrors, request);
|
||||
protected ActionForward toActionForward(final ResponseInstruction responseInstruction,
|
||||
final ActionMapping mapping, final ActionForm form,
|
||||
final HttpServletRequest request, final HttpServletResponse response,
|
||||
final ExternalContext context) throws Exception {
|
||||
return (ActionForward)new ResponseInstructionHandler() {
|
||||
protected void handleApplicationView(ApplicationView view) throws Exception {
|
||||
// forward to a view as part of an active conversation
|
||||
Map model = new HashMap(view.getModel());
|
||||
argumentHandler.exposeFlowExecutionContext(
|
||||
responseInstruction.getFlowExecutionKey(), responseInstruction.getFlowExecutionContext(), model);
|
||||
WebUtils.exposeRequestAttributes(request, model);
|
||||
if (form instanceof SpringBindingActionForm) {
|
||||
SpringBindingActionForm bindingForm = (SpringBindingActionForm)form;
|
||||
// expose the form object and associated errors as the
|
||||
// "current form object" in the request
|
||||
Errors currentErrors = (Errors)model.get(FormObjectAccessor.getCurrentFormErrorsName());
|
||||
bindingForm.expose(currentErrors, request);
|
||||
}
|
||||
setResult(findForward(view, mapping));
|
||||
}
|
||||
return findForward(forward, mapping);
|
||||
|
||||
}
|
||||
else if (response.isFlowExecutionRedirect()) {
|
||||
// redirect to active flow execution URL
|
||||
String flowExecutionUrl = argumentHandler.createFlowExecutionUrl(
|
||||
response.getFlowExecutionKey(), response.getFlowExecutionContext(), context);
|
||||
return createRedirectForward(flowExecutionUrl, httpResponse);
|
||||
}
|
||||
else if (response.isFlowDefinitionRedirect()) {
|
||||
// restart the flow by redirecting to flow launch URL
|
||||
String flowUrl = argumentHandler.createFlowDefinitionUrl(
|
||||
(FlowDefinitionRedirect)response.getViewSelection(), context);
|
||||
return createRedirectForward(flowUrl, httpResponse);
|
||||
}
|
||||
else if (response.isExternalRedirect()) {
|
||||
// redirect to external URL
|
||||
String externalUrl = argumentHandler.createExternalUrl(
|
||||
(ExternalRedirect)response.getViewSelection(), response.getFlowExecutionKey(), context);
|
||||
return createRedirectForward(externalUrl, httpResponse);
|
||||
}
|
||||
else if (response.isNull()) {
|
||||
// no response to issue
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Don't know how to handle response instruction " + response);
|
||||
}
|
||||
protected void handleFlowDefinitionRedirect(FlowDefinitionRedirect redirect) throws Exception {
|
||||
// restart the flow by redirecting to flow launch URL
|
||||
String flowUrl = argumentHandler.createFlowDefinitionUrl(redirect, context);
|
||||
setResult(createRedirectForward(flowUrl, response));
|
||||
}
|
||||
|
||||
protected void handleFlowExecutionRedirect(FlowExecutionRedirect redirect) throws Exception {
|
||||
// redirect to active flow execution URL
|
||||
String flowExecutionUrl = argumentHandler.createFlowExecutionUrl(
|
||||
responseInstruction.getFlowExecutionKey(), responseInstruction.getFlowExecutionContext(), context);
|
||||
setResult(createRedirectForward(flowExecutionUrl, response));
|
||||
}
|
||||
|
||||
protected void handleExternalRedirect(ExternalRedirect redirect) throws Exception {
|
||||
// redirect to external URL
|
||||
String externalUrl = argumentHandler.createExternalUrl(
|
||||
redirect, responseInstruction.getFlowExecutionKey(), context);
|
||||
setResult(createRedirectForward(externalUrl, response));
|
||||
}
|
||||
|
||||
protected void handleNull() throws Exception {
|
||||
// no response to issue
|
||||
setResult(null);
|
||||
}
|
||||
}.handle(responseInstruction).getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.executor.support;
|
||||
|
||||
import org.springframework.webflow.execution.ViewSelection;
|
||||
import org.springframework.webflow.execution.support.ApplicationView;
|
||||
import org.springframework.webflow.execution.support.ExternalRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowDefinitionRedirect;
|
||||
import org.springframework.webflow.execution.support.FlowExecutionRedirect;
|
||||
import org.springframework.webflow.executor.ResponseInstruction;
|
||||
|
||||
/**
|
||||
* Abstract helper class that allows easy handling of all known view
|
||||
* selection types. Users need to implement each of the hook methods
|
||||
* dealing with a particular type of view selection, typically in an
|
||||
* anonymous inner subclass of this class.
|
||||
*
|
||||
* @see ViewSelection
|
||||
*
|
||||
* @author Erwin Vervaet
|
||||
*/
|
||||
public abstract class ResponseInstructionHandler {
|
||||
|
||||
private Object result;
|
||||
|
||||
/**
|
||||
* Set the object resulting from response handling.
|
||||
* This is optional.
|
||||
* @param result the result object
|
||||
*/
|
||||
public void setResult(Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object resulting from response handling.
|
||||
* This is optional and will only be set if the subclass
|
||||
* calls {@link #setResult(Object)} to set the result object.
|
||||
* @return the result object, or null if none
|
||||
*/
|
||||
public Object getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue a response for given response instruction. Will delegate to
|
||||
* any of the available hook methods depending on the type of view selection
|
||||
* contained in the response instruction.
|
||||
* @param responseInstruction the response instruction to issue a response for
|
||||
* @return this object, for call chaining
|
||||
* @throws Exception when an error occured
|
||||
*/
|
||||
public final ResponseInstructionHandler handle(ResponseInstruction responseInstruction) throws Exception {
|
||||
if (responseInstruction.isApplicationView()) {
|
||||
handleApplicationView((ApplicationView)responseInstruction.getViewSelection());
|
||||
}
|
||||
else if (responseInstruction.isFlowDefinitionRedirect()) {
|
||||
handleFlowDefinitionRedirect((FlowDefinitionRedirect)responseInstruction.getViewSelection());
|
||||
}
|
||||
else if (responseInstruction.isFlowExecutionRedirect()) {
|
||||
handleFlowExecutionRedirect((FlowExecutionRedirect)responseInstruction.getViewSelection());
|
||||
}
|
||||
else if (responseInstruction.isExternalRedirect()) {
|
||||
handleExternalRedirect((ExternalRedirect)responseInstruction.getViewSelection());
|
||||
}
|
||||
else if (responseInstruction.isNull()) {
|
||||
handleNull();
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"Don't know how to handle response instruction " + responseInstruction);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quietly issue a response for given response instruction, turning any Exception
|
||||
* raised while handling the response instruction into a RuntimeException.
|
||||
* Will delegate to any of the available hook methods depending on the type of view selection
|
||||
* contained in the response instruction.
|
||||
* @param responseInstruction the response instruction to issue a response for
|
||||
* @return this object, for call chaining
|
||||
*/
|
||||
public final ResponseInstructionHandler handleQuietly(ResponseInstruction responseInstruction) {
|
||||
try {
|
||||
return handle(responseInstruction);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected exception handling response instruction " + responseInstruction, e);
|
||||
}
|
||||
}
|
||||
|
||||
// template methods
|
||||
|
||||
/**
|
||||
* Issue a response for given application view.
|
||||
* @param view the application view to issue a response for
|
||||
* @throws Exception when an error occured
|
||||
* @see ResponseInstruction#isActiveView()
|
||||
* @see ApplicationView
|
||||
*/
|
||||
protected abstract void handleApplicationView(ApplicationView view) throws Exception;
|
||||
|
||||
/**
|
||||
* Issue a response for given flow definition redirect.
|
||||
* @param redirect the flow definition redirect to issue a response for
|
||||
* @throws Exception when an error occured
|
||||
* @see ResponseInstruction#isFlowDefinitionRedirect()
|
||||
* @see FlowDefinitionRedirect
|
||||
*/
|
||||
protected abstract void handleFlowDefinitionRedirect(FlowDefinitionRedirect redirect) throws Exception;
|
||||
|
||||
/**
|
||||
* Issue a response for given flow execution redirect.
|
||||
* @param redirect the flow execution redirect to issue a response for
|
||||
* @throws Exception when an error occured
|
||||
* @see ResponseInstruction#isFlowExecutionRedirect()
|
||||
* @see FlowExecutionRedirect
|
||||
*/
|
||||
protected abstract void handleFlowExecutionRedirect(FlowExecutionRedirect redirect) throws Exception;
|
||||
|
||||
/**
|
||||
* Issue a response for given external redirect.
|
||||
* @param redirect the external redirect to issue a response for
|
||||
* @throws Exception when an error occured
|
||||
* @see ResponseInstruction#isExternalRedirect()
|
||||
* @see ExternalRedirect
|
||||
*/
|
||||
protected abstract void handleExternalRedirect(ExternalRedirect redirect) throws Exception;
|
||||
|
||||
/**
|
||||
* Issue a respone for the null view selection.
|
||||
* @throws Exception
|
||||
* @see ResponseInstruction#isNull()
|
||||
* @see ViewSelection#NULL_VIEW
|
||||
*/
|
||||
protected abstract void handleNull() throws Exception;
|
||||
}
|
||||
Reference in New Issue
Block a user