refinements related to ajax / popup menus
This commit is contained in:
@@ -85,7 +85,7 @@ public interface ExternalContext {
|
||||
public SharedAttributeMap getApplicationMap();
|
||||
|
||||
/**
|
||||
* Returns true if the current request is an Ajax request.
|
||||
* Returns true if the current request is an asynchronous Ajax request.
|
||||
* @return true if the current request is an Ajax request
|
||||
*/
|
||||
public boolean isAjaxRequest();
|
||||
@@ -123,13 +123,6 @@ public interface ExternalContext {
|
||||
*/
|
||||
public Writer getResponseWriter();
|
||||
|
||||
/**
|
||||
* Sets an entry in the response header.
|
||||
* @param name the entry name
|
||||
* @param value the entry value
|
||||
*/
|
||||
public void setResponseHeader(String name, String value);
|
||||
|
||||
/**
|
||||
* Request that a flow execution redirect be performed by the calling environment. Typically called from within a
|
||||
* flow execution to request a refresh operation, usually to support "refresh after event processing" behavior.
|
||||
@@ -156,6 +149,15 @@ public interface ExternalContext {
|
||||
*/
|
||||
public void requestExternalRedirect(String uri);
|
||||
|
||||
/**
|
||||
* Request that the redirect response requested be sent to the client in a manner that causes the client to issue
|
||||
* the redirect from a popup dialog. Calling this method only has an effect when a redirect has been requested.
|
||||
* @see #requestFlowExecutionRedirect()
|
||||
* @see #requestFlowDefinitionRedirect(String, AttributeMap)
|
||||
* @see #requestExternalRedirect(String)
|
||||
*/
|
||||
public void requestRedirectInPopup();
|
||||
|
||||
/**
|
||||
* Has the response been committed?
|
||||
* @return true if yes, false otherwise
|
||||
|
||||
@@ -22,7 +22,6 @@ import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
@@ -41,12 +40,6 @@ import org.springframework.webflow.core.collection.SharedAttributeMap;
|
||||
*/
|
||||
public class ServletExternalContext implements ExternalContext {
|
||||
|
||||
/** The accept header value that signifies an Ajax request */
|
||||
private static final String AJAX_ACCEPT_CONTENT_TYPE = "text/html;type=ajax";
|
||||
|
||||
/** Alternate request parameter to indicate an Ajax request for cases when control of the header is not available */
|
||||
private static final String AJAX_SOURCE_PARAM = "ajaxSource";
|
||||
|
||||
/**
|
||||
* The context.
|
||||
*/
|
||||
@@ -109,6 +102,17 @@ public class ServletExternalContext implements ExternalContext {
|
||||
*/
|
||||
private FlowUrlHandler flowUrlHandler;
|
||||
|
||||
/**
|
||||
* Whether this external request context originated from an Ajax request or not.
|
||||
*/
|
||||
private boolean ajaxRequest;
|
||||
|
||||
/**
|
||||
* In the case where a redirect response is requested, this flag indicates if the redirect should be issued from a
|
||||
* popup dialog.
|
||||
*/
|
||||
private boolean redirectInPopup;
|
||||
|
||||
/**
|
||||
* Create a new external context wrapping given servlet HTTP request and response and given servlet context.
|
||||
* @param context the servlet context
|
||||
@@ -131,6 +135,15 @@ public class ServletExternalContext implements ExternalContext {
|
||||
init(context, request, response, flowUrlHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the current request from this client is an ajax request. This flag may effect the handling of
|
||||
* response writing within Spring Web Flow.
|
||||
* @param ajaxRequest the ajax request flag
|
||||
*/
|
||||
public void setAjaxRequest(boolean ajaxRequest) {
|
||||
this.ajaxRequest = ajaxRequest;
|
||||
}
|
||||
|
||||
// implementing external context
|
||||
|
||||
public String getContextPath() {
|
||||
@@ -170,13 +183,7 @@ public class ServletExternalContext implements ExternalContext {
|
||||
}
|
||||
|
||||
public boolean isAjaxRequest() {
|
||||
String acceptHeader = request.getHeader("Accept");
|
||||
String ajaxParam = request.getParameter(AJAX_SOURCE_PARAM);
|
||||
if (AJAX_ACCEPT_CONTENT_TYPE.equals(acceptHeader) || StringUtils.hasText(ajaxParam)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return ajaxRequest;
|
||||
}
|
||||
|
||||
public String getFlowExecutionUri(String flowId, String flowExecutionKey) {
|
||||
@@ -191,10 +198,6 @@ public class ServletExternalContext implements ExternalContext {
|
||||
}
|
||||
}
|
||||
|
||||
public void setResponseHeader(String name, String value) {
|
||||
response.setHeader(name, value);
|
||||
}
|
||||
|
||||
public boolean isResponseCommitted() {
|
||||
return flowExecutionRedirectRequested() || flowDefinitionRedirectRequested() || externalRedirectRequested();
|
||||
}
|
||||
@@ -212,32 +215,63 @@ public class ServletExternalContext implements ExternalContext {
|
||||
flowDefinitionRedirectFlowInput = input;
|
||||
}
|
||||
|
||||
public void requestRedirectInPopup() {
|
||||
redirectInPopup = true;
|
||||
}
|
||||
|
||||
// implementation specific methods
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if a flow execution redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean flowExecutionRedirectRequested() {
|
||||
return flowExecutionRedirectRequested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if a flow definition redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean flowDefinitionRedirectRequested() {
|
||||
return flowDefinitionRedirectFlowId != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the flow definition to redirect to. Only set when {@link #flowDefinitionRedirectRequested()}
|
||||
* returns true.
|
||||
*/
|
||||
public String getFlowRedirectFlowId() {
|
||||
return flowDefinitionRedirectFlowId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input to pass the flow definition through the redirect. Only set when
|
||||
* {@link #flowDefinitionRedirectRequested()} returns true.
|
||||
*/
|
||||
public AttributeMap getFlowRedirectFlowInput() {
|
||||
return flowDefinitionRedirectFlowInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if an external redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean externalRedirectRequested() {
|
||||
return externalRedirectUrl != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL to redirect to. Only set if {@link #externalRedirectRequested()} returns true.
|
||||
*/
|
||||
public String getExternalRedirectUrl() {
|
||||
return externalRedirectUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a redirect response has been requested, indicates if the redirect should be issued from a popup dialog.
|
||||
*/
|
||||
public boolean redirectInPopup() {
|
||||
return redirectInPopup;
|
||||
}
|
||||
|
||||
// private helpers
|
||||
|
||||
private void init(ServletContext context, HttpServletRequest request, HttpServletResponse response,
|
||||
|
||||
@@ -117,11 +117,4 @@ public interface RequestControlContext extends RequestContext {
|
||||
*/
|
||||
public boolean getAlwaysRedirectOnPause();
|
||||
|
||||
/**
|
||||
* Request that a redirect be sent to this flow execution after the current request has processed. The current flow
|
||||
* execution must have its key assigned for this operation to be supported.
|
||||
* @throws IllegalStateException if the flow execution has not yet had its key assigned
|
||||
*/
|
||||
public void sendFlowExecutionRedirect() throws IllegalStateException;
|
||||
|
||||
}
|
||||
@@ -38,8 +38,6 @@ import org.springframework.webflow.execution.ViewFactory;
|
||||
*/
|
||||
public class ViewState extends TransitionableState {
|
||||
|
||||
private static final String POPUP_VIEW_HEADER = "Flow-Modal-View";
|
||||
|
||||
/**
|
||||
* The list of actions to be executed when this state is entered.
|
||||
*/
|
||||
@@ -163,10 +161,10 @@ public class ViewState extends TransitionableState {
|
||||
protected void doEnter(RequestControlContext context) throws FlowExecutionException {
|
||||
context.assignFlowExecutionKey();
|
||||
if (shouldRedirect(context)) {
|
||||
if (context.getExternalContext().isAjaxRequest() && popup) {
|
||||
context.getExternalContext().setResponseHeader(POPUP_VIEW_HEADER, "true");
|
||||
context.getExternalContext().requestFlowExecutionRedirect();
|
||||
if (popup) {
|
||||
context.getExternalContext().requestRedirectInPopup();
|
||||
}
|
||||
context.sendFlowExecutionRedirect();
|
||||
} else {
|
||||
View view = viewFactory.getView(context);
|
||||
render(context, view);
|
||||
|
||||
@@ -9,6 +9,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.AbstractController;
|
||||
import org.springframework.webflow.context.servlet.DefaultFlowUrlHandler;
|
||||
@@ -28,6 +29,26 @@ import org.springframework.webflow.executor.FlowExecutor;
|
||||
*/
|
||||
public class FlowController extends AbstractController {
|
||||
|
||||
/**
|
||||
* The response header to be set on an Ajax redirect
|
||||
*/
|
||||
private static final String FLOW_REDIRECT_URL_HEADER = "Flow-Redirect-URL";
|
||||
|
||||
/**
|
||||
* The response header to be set on an redirect that should be issued from a popup window.
|
||||
*/
|
||||
private static final String POPUP_VIEW_HEADER = "Flow-Modal-View";
|
||||
|
||||
/**
|
||||
* The accept header value that signifies an Ajax request.
|
||||
*/
|
||||
private static final String AJAX_ACCEPT_CONTENT_TYPE = "text/html;type=ajax";
|
||||
|
||||
/**
|
||||
* Alternate request parameter to indicate an Ajax request for cases when control of the header is not available.
|
||||
*/
|
||||
private static final String AJAX_SOURCE_PARAM = "ajaxSource";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowController.class);
|
||||
|
||||
private FlowExecutor flowExecutor;
|
||||
@@ -36,9 +57,6 @@ public class FlowController extends AbstractController {
|
||||
|
||||
private Map flowHandlers = new HashMap();
|
||||
|
||||
/** The response header to be set on an Ajax redirect */
|
||||
private static final String FLOW_REDIRECT_URL_HEADER = "Flow-Redirect-URL";
|
||||
|
||||
/**
|
||||
* @param flowExecutor the web flow executor service
|
||||
*/
|
||||
@@ -89,7 +107,19 @@ public class FlowController extends AbstractController {
|
||||
|
||||
protected ServletExternalContext createServletExternalContext(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return new ServletExternalContext(getServletContext(), request, response, urlHandler);
|
||||
ServletExternalContext context = new ServletExternalContext(getServletContext(), request, response, urlHandler);
|
||||
context.setAjaxRequest(isAjaxRequest(request));
|
||||
return context;
|
||||
}
|
||||
|
||||
protected boolean isAjaxRequest(HttpServletRequest request) {
|
||||
String acceptHeader = request.getHeader("Accept");
|
||||
String ajaxParam = request.getParameter(AJAX_SOURCE_PARAM);
|
||||
if (AJAX_ACCEPT_CONTENT_TYPE.equals(acceptHeader) || StringUtils.hasText(ajaxParam)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected MutableAttributeMap defaultFlowExecutionInputMap(HttpServletRequest request) {
|
||||
@@ -170,7 +200,10 @@ public class FlowController extends AbstractController {
|
||||
private void sendRedirect(ServletExternalContext context, HttpServletResponse response, String targetUrl)
|
||||
throws IOException {
|
||||
if (context.isAjaxRequest()) {
|
||||
context.setResponseHeader(FLOW_REDIRECT_URL_HEADER, response.encodeRedirectURL(targetUrl));
|
||||
if (context.redirectInPopup()) {
|
||||
response.setHeader(POPUP_VIEW_HEADER, "true");
|
||||
}
|
||||
response.setHeader(FLOW_REDIRECT_URL_HEADER, response.encodeRedirectURL(targetUrl));
|
||||
} else {
|
||||
response.sendRedirect(response.encodeRedirectURL(targetUrl));
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.support.WebApplicationObjectSupport;
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
@@ -23,15 +24,32 @@ import org.springframework.webflow.executor.FlowExecutor;
|
||||
|
||||
public class FlowHandlerAdapter extends WebApplicationObjectSupport implements HandlerAdapter {
|
||||
|
||||
/**
|
||||
* The response header to be set on an Ajax redirect
|
||||
*/
|
||||
private static final String FLOW_REDIRECT_URL_HEADER = "Flow-Redirect-URL";
|
||||
|
||||
/**
|
||||
* The response header to be set on an redirect that should be issued from a popup window.
|
||||
*/
|
||||
private static final String POPUP_VIEW_HEADER = "Flow-Modal-View";
|
||||
|
||||
/**
|
||||
* The accept header value that signifies an Ajax request.
|
||||
*/
|
||||
private static final String AJAX_ACCEPT_CONTENT_TYPE = "text/html;type=ajax";
|
||||
|
||||
/**
|
||||
* Alternate request parameter to indicate an Ajax request for cases when control of the header is not available.
|
||||
*/
|
||||
private static final String AJAX_SOURCE_PARAM = "ajaxSource";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowHandlerAdapter.class);
|
||||
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
private FlowUrlHandler urlHandler;
|
||||
|
||||
/** The response header to be set on an Ajax redirect */
|
||||
private static final String FLOW_REDIRECT_URL_HEADER = "Flow-Redirect-URL";
|
||||
|
||||
public FlowHandlerAdapter(FlowExecutor flowExecutor) {
|
||||
this.flowExecutor = flowExecutor;
|
||||
this.urlHandler = new DefaultFlowUrlHandler();
|
||||
@@ -77,7 +95,19 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H
|
||||
|
||||
protected ServletExternalContext createServletExternalContext(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return new ServletExternalContext(getServletContext(), request, response, urlHandler);
|
||||
ServletExternalContext context = new ServletExternalContext(getServletContext(), request, response, urlHandler);
|
||||
context.setAjaxRequest(isAjaxRequest(request));
|
||||
return context;
|
||||
}
|
||||
|
||||
protected boolean isAjaxRequest(HttpServletRequest request) {
|
||||
String acceptHeader = request.getHeader("Accept");
|
||||
String ajaxParam = request.getParameter(AJAX_SOURCE_PARAM);
|
||||
if (AJAX_ACCEPT_CONTENT_TYPE.equals(acceptHeader) || StringUtils.hasText(ajaxParam)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected MutableAttributeMap defaultFlowExecutionInputMap(HttpServletRequest request) {
|
||||
@@ -159,7 +189,10 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H
|
||||
private void sendRedirect(ServletExternalContext context, HttpServletResponse response, String targetUrl)
|
||||
throws IOException {
|
||||
if (context.isAjaxRequest()) {
|
||||
context.setResponseHeader(FLOW_REDIRECT_URL_HEADER, response.encodeRedirectURL(targetUrl));
|
||||
if (context.redirectInPopup()) {
|
||||
response.setHeader(POPUP_VIEW_HEADER, "true");
|
||||
}
|
||||
response.setHeader(FLOW_REDIRECT_URL_HEADER, response.encodeRedirectURL(targetUrl));
|
||||
} else {
|
||||
response.sendRedirect(response.encodeRedirectURL(targetUrl));
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.webflow.test;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.binding.collection.SharedMapDecorator;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
@@ -58,8 +57,6 @@ public class MockExternalContext implements ExternalContext {
|
||||
|
||||
private boolean ajaxRequest;
|
||||
|
||||
private Map responseHeaders = new HashMap();
|
||||
|
||||
private boolean flowExecutionRedirectRequested;
|
||||
|
||||
private String flowDefinitionRedirectFlowId;
|
||||
@@ -68,6 +65,8 @@ public class MockExternalContext implements ExternalContext {
|
||||
|
||||
private String externalRedirectUrl;
|
||||
|
||||
private boolean redirectInPopup;
|
||||
|
||||
/**
|
||||
* Creates a mock external context with an empty request parameter map. Allows for bean style usage.
|
||||
*/
|
||||
@@ -135,10 +134,6 @@ public class MockExternalContext implements ExternalContext {
|
||||
return responseWriter;
|
||||
}
|
||||
|
||||
public void setResponseHeader(String name, String value) {
|
||||
this.responseHeaders.put(name, value);
|
||||
}
|
||||
|
||||
public boolean isResponseCommitted() {
|
||||
return flowExecutionRedirectRequested() || flowDefinitionRedirectRequested() || externalRedirectRequested();
|
||||
}
|
||||
@@ -147,13 +142,17 @@ public class MockExternalContext implements ExternalContext {
|
||||
flowExecutionRedirectRequested = true;
|
||||
}
|
||||
|
||||
public void requestFlowDefinitionRedirect(String flowId, AttributeMap input) {
|
||||
flowDefinitionRedirectFlowId = flowId;
|
||||
flowDefinitionRedirectFlowInput = input;
|
||||
}
|
||||
|
||||
public void requestExternalRedirect(String uri) {
|
||||
externalRedirectUrl = uri;
|
||||
}
|
||||
|
||||
public void requestFlowDefinitionRedirect(String flowId, AttributeMap input) {
|
||||
flowDefinitionRedirectFlowId = flowId;
|
||||
flowDefinitionRedirectFlowInput = input;
|
||||
public void requestRedirectInPopup() {
|
||||
redirectInPopup = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,36 +265,54 @@ public class MockExternalContext implements ExternalContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the response header entry
|
||||
* @param name the entry name
|
||||
* @return the entry value, or null if no entry was set with this name
|
||||
* Returns the flag indicating if a flow execution redirect response has been requested by the flow.
|
||||
*/
|
||||
public String getResponseHeader(String name) {
|
||||
return (String) responseHeaders.get(name);
|
||||
}
|
||||
|
||||
public boolean flowExecutionRedirectRequested() {
|
||||
return flowExecutionRedirectRequested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if a flow definition redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean flowDefinitionRedirectRequested() {
|
||||
return flowDefinitionRedirectFlowId != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the flow definition to redirect to. Only set when {@link #flowDefinitionRedirectRequested()}
|
||||
* returns true.
|
||||
*/
|
||||
public String getFlowRedirectFlowId() {
|
||||
return flowDefinitionRedirectFlowId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input to pass the flow definition through the redirect. Only set when
|
||||
* {@link #flowDefinitionRedirectRequested()} returns true.
|
||||
*/
|
||||
public AttributeMap getFlowRedirectFlowInput() {
|
||||
return flowDefinitionRedirectFlowInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if an external redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean externalRedirectRequested() {
|
||||
return externalRedirectUrl != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL to redirect to. Only set if {@link #externalRedirectRequested()} returns true.
|
||||
*/
|
||||
public String getExternalRedirectUrl() {
|
||||
return externalRedirectUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a redirect response has been requested, indicates if the redirect should be issued from a popup dialog.
|
||||
*/
|
||||
public boolean redirectInPopup() {
|
||||
return redirectInPopup;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -61,12 +61,7 @@ public class ServletExternalContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testAjaxRequestAcceptHeader() {
|
||||
request.addHeader("Accept", "text/html;type=ajax");
|
||||
assertTrue(context.isAjaxRequest());
|
||||
}
|
||||
|
||||
public void testAjaxRequestParam() {
|
||||
request.addParameter("ajaxSource", "myButton");
|
||||
context.setAjaxRequest(true);
|
||||
assertTrue(context.isAjaxRequest());
|
||||
}
|
||||
|
||||
@@ -94,4 +89,30 @@ public class ServletExternalContextTests extends TestCase {
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
}
|
||||
|
||||
public void testCommitExecutionRedirectPopup() {
|
||||
context.requestFlowExecutionRedirect();
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.flowExecutionRedirectRequested());
|
||||
assertTrue(context.redirectInPopup());
|
||||
}
|
||||
|
||||
public void testCommitFlowRedirectPopup() {
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.flowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
assertTrue(context.redirectInPopup());
|
||||
}
|
||||
|
||||
public void testCommitExternalRedirectPopup() {
|
||||
context.requestExternalRedirect("foo");
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.externalRedirectRequested());
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
assertTrue(context.redirectInPopup());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.webflow.engine.support.DefaultTargetStateResolver;
|
||||
import org.springframework.webflow.engine.support.EventIdTransitionCriteria;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.test.MockRequestControlContext;
|
||||
|
||||
/**
|
||||
@@ -27,37 +28,75 @@ import org.springframework.webflow.test.MockRequestControlContext;
|
||||
*/
|
||||
public class ViewStateTests extends TestCase {
|
||||
|
||||
public void testEnterViewState() {
|
||||
public void testEnterViewStateDefaultBehavior() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
StubViewFactory viewFactory = new StubViewFactory();
|
||||
ViewState state = new ViewState(flow, "viewState", viewFactory);
|
||||
state.getTransitionSet().add(new Transition(on("submit"), to("finish")));
|
||||
new EndState(flow, "finish");
|
||||
MockRequestControlContext context = new MockRequestControlContext(flow);
|
||||
state.enter(context);
|
||||
assertTrue("Render not called", context.getFlowScope().contains("renderCalled"));
|
||||
assertFalse(context.getFlowExecutionRedirectSent());
|
||||
}
|
||||
|
||||
public void testEnterViewStateWithVariables() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
StubViewFactory viewFactory = new StubViewFactory();
|
||||
ViewState state = new ViewState(flow, "viewState", viewFactory);
|
||||
state.addVariable(new ViewVariable("foo", new VariableValueFactory() {
|
||||
public Object createInitialValue(RequestContext context) {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
public void restoreReferences(Object value, RequestContext context) {
|
||||
|
||||
}
|
||||
|
||||
}));
|
||||
MockRequestControlContext context = new MockRequestControlContext(flow);
|
||||
state.enter(context);
|
||||
assertEquals("bar", context.getFlowScope().getString("foo"));
|
||||
assertTrue("Render not called", context.getFlowScope().contains("renderCalled"));
|
||||
assertFalse(context.getFlowExecutionRedirectSent());
|
||||
}
|
||||
|
||||
public void testEnterViewStateWithLocalRedirect() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
StubViewFactory viewFactory = new StubViewFactory();
|
||||
ViewState state = new ViewState(flow, "viewState", viewFactory);
|
||||
state.setRedirect(Boolean.TRUE);
|
||||
state.getTransitionSet().add(new Transition(on("submit"), to("finish")));
|
||||
new EndState(flow, "finish");
|
||||
MockRequestControlContext context = new MockRequestControlContext(flow);
|
||||
state.enter(context);
|
||||
assertFalse("Render called", context.getFlowScope().contains("renderCalled"));
|
||||
assertTrue(context.getMockExternalContext().flowExecutionRedirectRequested());
|
||||
}
|
||||
|
||||
public void testEnterViewStateWithNoLocalRedirect() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
StubViewFactory viewFactory = new StubViewFactory();
|
||||
ViewState state = new ViewState(flow, "viewState", viewFactory);
|
||||
state.setRedirect(Boolean.FALSE);
|
||||
MockRequestControlContext context = new MockRequestControlContext(flow);
|
||||
state.enter(context);
|
||||
assertTrue("Render called", context.getFlowScope().contains("renderCalled"));
|
||||
assertFalse(context.getMockExternalContext().flowExecutionRedirectRequested());
|
||||
}
|
||||
|
||||
public void testEnterViewStateWithAlwaysRedirectOnPause() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
StubViewFactory viewFactory = new StubViewFactory();
|
||||
ViewState state = new ViewState(flow, "viewState", viewFactory);
|
||||
state.getTransitionSet().add(new Transition(on("submit"), to("finish")));
|
||||
new EndState(flow, "finish");
|
||||
MockRequestControlContext context = new MockRequestControlContext(flow);
|
||||
context.setAlwaysRedirectOnPause(true);
|
||||
state.enter(context);
|
||||
assertFalse("Render called", context.getFlowScope().contains("renderCalled"));
|
||||
assertTrue(context.getMockExternalContext().flowExecutionRedirectRequested());
|
||||
}
|
||||
|
||||
public void testEnterViewStateWithPopup() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
StubViewFactory viewFactory = new StubViewFactory();
|
||||
ViewState state = new ViewState(flow, "viewState", viewFactory);
|
||||
state.setPopup(true);
|
||||
MockRequestControlContext context = new MockRequestControlContext(flow);
|
||||
context.setAlwaysRedirectOnPause(true);
|
||||
state.enter(context);
|
||||
|
||||
@@ -142,11 +142,55 @@ public class FlowControllerTests extends TestCase {
|
||||
EasyMock.replay(new Object[] { executor });
|
||||
ModelAndView mv = controller.handleRequest(request, response);
|
||||
assertNull(mv);
|
||||
EasyMock.verify(new Object[] { executor });
|
||||
assertEquals("/springtravel/app/foo?execution=12345", response.getRedirectedUrl());
|
||||
EasyMock.verify(new Object[] { executor });
|
||||
}
|
||||
|
||||
public void testLaunchFlowWithExecutionRedirectAjaxHeaderOpenInPopup() throws Exception {
|
||||
request.setContextPath("/springtravel");
|
||||
request.setServletPath("/app");
|
||||
request.setPathInfo("/foo");
|
||||
request.setRequestURI("/springtravel/app/foo");
|
||||
request.setMethod("GET");
|
||||
request.addHeader("Accept", "text/html;type=ajax");
|
||||
Map parameters = new HashMap();
|
||||
request.setParameters(parameters);
|
||||
context.setAjaxRequest(true);
|
||||
context.requestFlowExecutionRedirect();
|
||||
context.requestRedirectInPopup();
|
||||
executor.launchExecution("foo", new LocalAttributeMap(parameters), context);
|
||||
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345");
|
||||
EasyMock.expectLastCall().andReturn(result);
|
||||
EasyMock.replay(new Object[] { executor });
|
||||
ModelAndView mv = controller.handleRequest(request, response);
|
||||
assertNull(mv);
|
||||
assertEquals(null, response.getRedirectedUrl());
|
||||
assertEquals("true", response.getHeader("Flow-Modal-View"));
|
||||
assertEquals("/springtravel/app/foo?execution=12345", response.getHeader("Flow-Redirect-URL"));
|
||||
EasyMock.verify(new Object[] { executor });
|
||||
}
|
||||
|
||||
public void testLaunchFlowWithExecutionRedirectAjaxParameter() throws Exception {
|
||||
request.setContextPath("/springtravel");
|
||||
request.setServletPath("/app");
|
||||
request.setPathInfo("/foo");
|
||||
request.setRequestURI("/springtravel/app/foo");
|
||||
request.setMethod("GET");
|
||||
request.addParameter("ajaxSource", "this");
|
||||
context.setAjaxRequest(true);
|
||||
context.requestFlowExecutionRedirect();
|
||||
executor.launchExecution("foo", new LocalAttributeMap(request.getParameterMap()), context);
|
||||
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345");
|
||||
EasyMock.expectLastCall().andReturn(result);
|
||||
EasyMock.replay(new Object[] { executor });
|
||||
ModelAndView mv = controller.handleRequest(request, response);
|
||||
assertNull(mv);
|
||||
assertEquals(null, response.getRedirectedUrl());
|
||||
assertEquals(null, response.getHeader("Flow-Modal-View"));
|
||||
assertEquals("/springtravel/app/foo?execution=12345", response.getHeader("Flow-Redirect-URL"));
|
||||
EasyMock.verify(new Object[] { executor });
|
||||
}
|
||||
|
||||
public void testLaunchFlowWithDefinitionRedirect() throws Exception {
|
||||
request.setContextPath("/springtravel");
|
||||
request.setServletPath("/app");
|
||||
|
||||
Reference in New Issue
Block a user