This commit is contained in:
Keith Donald
2008-02-26 16:11:35 +00:00
parent 9804e6a858
commit 3ec7887fa9
14 changed files with 1269 additions and 201 deletions

View File

@@ -1,112 +0,0 @@
package org.springframework.faces.ui.resource;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.ClassUtils;
import org.springframework.webflow.execution.Action;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
/**
* Special action for resolving and rendering static resources from within a JAR file.
*
* @author Jeremy Grelle
*/
public class RenderResourceAction implements Action {
private static final String IF_MODIFIED_SINCE_HEADER = "If-Modified-Since";
private static final String HTTP_CONTENT_LENGTH_HEADER = "Content-Length";
private static final String HTTP_LAST_MODIFIED_HEADER = "Last-Modified";
private static final String HTTP_EXPIRES_HEADER = "Expires";
private static final String HTTP_CACHE_CONTROL_HEADER = "Cache-Control";
private Map defaultMimeTypes = new HashMap();
{
defaultMimeTypes.put(".css", "text/css");
defaultMimeTypes.put(".gif", "image/gif");
defaultMimeTypes.put(".ico", "image/vnd.microsoft.icon");
defaultMimeTypes.put(".jpeg", "image/jpeg");
defaultMimeTypes.put(".jpg", "image/jpeg");
defaultMimeTypes.put(".js", "text/javascript");
defaultMimeTypes.put(".png", "image/png");
}
public Event execute(RequestContext context) throws Exception {
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
ServletContext servletContext = (ServletContext) context.getExternalContext().getContext();
String localResourcePath = context.getExternalContext().getRequestPath().toString();
String jarResourcePath = "META-INF" + context.getExternalContext().getRequestPath().toString();
URL resource;
resource = servletContext.getResource(localResourcePath);
if (resource == null) {
resource = ClassUtils.getDefaultClassLoader().getResource(jarResourcePath);
if (resource == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return new Event(this, "success");
}
}
URLConnection resourceConn = resource.openConnection();
long lastModified = resourceConn.getLastModified();
long ifModifiedSince = request.getDateHeader(IF_MODIFIED_SINCE_HEADER);
if (ifModifiedSince > 0 && lastModified / 1000 <= ifModifiedSince / 1000) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return new Event(this, "success");
}
String mimeType = servletContext.getMimeType(jarResourcePath);
if (mimeType == null) {
String extension = jarResourcePath.substring(jarResourcePath.lastIndexOf('.'));
mimeType = (String) defaultMimeTypes.get(extension);
}
response.setContentType(mimeType);
response.setHeader(HTTP_CONTENT_LENGTH_HEADER, Long.toString(resourceConn.getContentLength()));
response.setDateHeader(HTTP_LAST_MODIFIED_HEADER, lastModified);
configureCaching(response, 31556926);
InputStream in = resourceConn.getInputStream();
OutputStream out = response.getOutputStream();
try {
byte[] buffer = new byte[1024];
while (in.available() > 0) {
int len = in.read(buffer);
out.write(buffer, 0, len);
}
} finally {
in.close();
out.close();
}
return new Event(this, "success");
}
/**
* Set HTTP headers to allow caching for the given number of seconds.
* @param seconds number of seconds into the future that the response should be cacheable for
*/
private void configureCaching(HttpServletResponse response, int seconds) {
// HTTP 1.0 header
response.setDateHeader(HTTP_EXPIRES_HEADER, System.currentTimeMillis() + seconds * 1000L);
// HTTP 1.1 header
response.setHeader(HTTP_CACHE_CONTROL_HEADER, "max-age=" + seconds);
}
}

View File

@@ -1,16 +0,0 @@
package org.springframework.faces.ui.resource;
import org.springframework.webflow.engine.EndState;
import org.springframework.webflow.engine.builder.FlowBuilderException;
import org.springframework.webflow.engine.builder.support.AbstractFlowBuilder;
/**
* Builder for generating the "resources" flow which is responsible for serving static resources from the classpath.
* @author Jeremy Grelle
*/
public class ResourcesFlowBuilder extends AbstractFlowBuilder {
public void buildStates() throws FlowBuilderException {
EndState renderResource = new EndState(getFlow(), "renderResource");
renderResource.setFinalResponseAction(new RenderResourceAction());
}
}

View File

@@ -1,73 +0,0 @@
package org.springframework.faces.ui.resource;
import org.easymock.EasyMock;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.ServletContext;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.context.RequestPath;
import org.springframework.webflow.execution.RequestContext;
public class RenderResourceActionTests extends TestCase {
ExternalContext externalContext = (ExternalContext) EasyMock.createMock(ExternalContext.class);
RequestContext requestContext = (RequestContext) EasyMock.createMock(RequestContext.class);
ServletContext servletContext = new ResourceTestMockServletContext();
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest();
RequestPath requestPath;
String[] requestElements;
RenderResourceAction action;
protected void setUp() throws Exception {
action = new RenderResourceAction();
EasyMock.expect(requestContext.getExternalContext()).andStubReturn(externalContext);
EasyMock.expect(externalContext.getContext()).andStubReturn(servletContext);
EasyMock.expect(externalContext.getResponse()).andStubReturn(response);
EasyMock.expect(externalContext.getRequest()).andStubReturn(request);
EasyMock.expect(externalContext.getResponseWriter()).andStubReturn(new PrintWriter(new StringWriter()));
}
public final void testExecute() throws Exception {
requestPath = new RequestPath("/ext/ext.js");
EasyMock.expect(externalContext.getRequestPath()).andStubReturn(requestPath);
EasyMock.replay(new Object[] { requestContext, externalContext });
action.execute(requestContext);
}
public final void testExecute_ResourceNotFound() throws Exception {
requestPath = new RequestPath("/xxx/xxx.js");
EasyMock.expect(externalContext.getRequestPath()).andStubReturn(requestPath);
EasyMock.replay(new Object[] { requestContext, externalContext });
action.execute(requestContext);
assertEquals(404, response.getStatus());
}
private class ResourceTestMockServletContext extends MockServletContext {
public String getMimeType(String filePath) {
return null;
}
}
}

View File

@@ -0,0 +1,87 @@
package org.springframework.webflow.context.servlet;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.util.UrlPathHelper;
import org.springframework.web.util.WebUtils;
import org.springframework.webflow.core.collection.AttributeMap;
public class DefaultFlowUrlHandler implements FlowUrlHandler {
private static final String DEFAULT_URL_ENCODING_SCHEME = "UTF-8";
private String urlEncodingScheme = DEFAULT_URL_ENCODING_SCHEME;
private UrlPathHelper urlPathHelper;
public DefaultFlowUrlHandler() {
urlPathHelper = new UrlPathHelper();
}
public String getFlowExecutionKey(HttpServletRequest request) {
return request.getParameter("execution");
}
public String getFlowId(HttpServletRequest request) {
return WebUtils.extractFilenameFromUrlPath(urlPathHelper.getLookupPathForRequest(request));
}
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, HttpServletRequest request) {
StringBuffer url = new StringBuffer();
url.append(request.getContextPath());
url.append(request.getServletPath());
url.append('/');
url.append(encode(flowId));
url.append('?');
appendQueryParameter(url, "execution", flowExecutionKey);
return url.toString();
}
public String createFlowDefinitionUrl(String flowId, AttributeMap input, HttpServletRequest request) {
StringBuffer url = new StringBuffer();
url.append(request.getContextPath());
url.append(request.getServletPath());
url.append('/');
url.append(encode(flowId));
if (input != null && !input.isEmpty()) {
url.append('?');
appendQueryParameters(url, input.asMap());
}
return url.toString();
}
private void appendQueryParameters(StringBuffer url, Map parameters) {
Iterator entries = parameters.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
appendQueryParameter(url, entry.getKey(), entry.getValue());
if (entries.hasNext()) {
url.append('&');
}
}
}
private void appendQueryParameter(StringBuffer url, Object key, Object value) {
String encodedKey = encode(key);
String encodedValue = encode(value);
url.append(encodedKey).append('=').append(encodedValue);
}
private String encode(Object value) {
return value != null ? urlEncode(String.valueOf(value)) : "";
}
private String urlEncode(String value) {
try {
return URLEncoder.encode(String.valueOf(value), urlEncodingScheme);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Cannot url encode " + value);
}
}
}

View File

@@ -0,0 +1,39 @@
package org.springframework.webflow.context.servlet;
import javax.servlet.http.HttpServletRequest;
import org.springframework.webflow.core.collection.AttributeMap;
public interface FlowUrlHandler {
/**
* Extract the flow execution from the request.
* @param request the request
* @return the flow execution key, or null if no flow execution key is present
*/
public String getFlowExecutionKey(HttpServletRequest request);
/**
* Extract the flow id from the request.
* @param request the request
* @return the flow id, or null if no flow id is present
*/
public String getFlowId(HttpServletRequest request);
/**
* Create a URL that when addressed will launch a new execution of a flow.
* @param flowId the id of the flow definition
* @param input the input to pass the new flow execution
* @param request the current request
* @return the flow definition url
*/
public String createFlowDefinitionUrl(String flowId, AttributeMap input, HttpServletRequest request);
/**
* Create a URL that when addressed will resume an existing execution of a flow.
* @param flowExecutionKey the flow execution key that is paused and waiting to be resumed
* @param request the current request
* @return the flow execution url
*/
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, HttpServletRequest request);
}

View File

@@ -0,0 +1,85 @@
package org.springframework.webflow.context.servlet;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.webflow.core.collection.AttributeMap;
public class ParameterBasedFlowUrlHandler implements FlowUrlHandler {
private static final String DEFAULT_URL_ENCODING_SCHEME = "UTF-8";
private String urlEncodingScheme = DEFAULT_URL_ENCODING_SCHEME;
public String getFlowExecutionKey(HttpServletRequest request) {
return request.getParameter("_flowExecutionKey");
}
public String getFlowId(HttpServletRequest request) {
return request.getParameter("_flowId");
}
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, HttpServletRequest request) {
StringBuffer url = new StringBuffer();
url.append(request.getContextPath());
url.append(request.getServletPath());
if (request.getPathInfo() != null) {
url.append(request.getPathInfo());
}
url.append('?');
appendQueryParameter(url, "_flowId", flowId);
url.append('&');
appendQueryParameter(url, "_flowExecutionKey", flowExecutionKey);
return url.toString();
}
public String createFlowDefinitionUrl(String flowId, AttributeMap input, HttpServletRequest request) {
StringBuffer url = new StringBuffer();
url.append(request.getContextPath());
url.append(request.getServletPath());
if (request.getPathInfo() != null) {
url.append(request.getPathInfo());
}
url.append('?');
appendQueryParameter(url, "_flowId", flowId);
if (input != null && !input.isEmpty()) {
url.append('&');
appendQueryParameters(url, input.asMap());
}
return url.toString();
}
private void appendQueryParameters(StringBuffer url, Map parameters) {
Iterator entries = parameters.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
appendQueryParameter(url, entry.getKey(), entry.getValue());
if (entries.hasNext()) {
url.append('&');
}
}
}
private void appendQueryParameter(StringBuffer url, Object key, Object value) {
String encodedKey = encode(key);
String encodedValue = encode(value);
url.append(encodedKey).append('=').append(encodedValue);
}
private String encode(Object value) {
return value != null ? urlEncode(String.valueOf(value)) : "";
}
private String urlEncode(String value) {
try {
return URLEncoder.encode(String.valueOf(value), urlEncodingScheme);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Cannot url encode " + value);
}
}
}

View File

@@ -0,0 +1,51 @@
package org.springframework.webflow.executor;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.execution.Event;
public class FlowExecutionResult {
private String flowId;
private String flowExecutionKey;
private String outcome;
private AttributeMap output;
private FlowExecutionResult(String flowId, String flowExecutionKey, String outcome, AttributeMap output) {
this.flowId = flowId;
this.flowExecutionKey = flowExecutionKey;
this.outcome = outcome;
this.output = output;
}
public static FlowExecutionResult createPausedResult(String flowId, String flowExecutionKey) {
return new FlowExecutionResult(flowId, flowExecutionKey, null, null);
}
public static FlowExecutionResult createEndedResult(String flowId, Event outcome) {
return new FlowExecutionResult(flowId, null, outcome.getId(), outcome.getAttributes());
}
public String getFlowId() {
return flowId;
}
public boolean paused() {
return flowExecutionKey != null;
}
public String getPausedKey() {
return flowExecutionKey;
}
public boolean ended() {
return flowExecutionKey == null;
}
public String getEndedOutcome() {
return outcome;
}
public AttributeMap getEndedOutput() {
return output;
}
}

View File

@@ -0,0 +1,20 @@
package org.springframework.webflow.mvc;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.webflow.core.FlowException;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.MutableAttributeMap;
public interface FlowHandler {
public String getFlowId();
public MutableAttributeMap createExecutionInputMap(HttpServletRequest request);
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
HttpServletResponse response);
public ModelAndView handleException(FlowException e, HttpServletRequest request, HttpServletResponse response);
}

View File

@@ -0,0 +1,142 @@
package org.springframework.webflow.mvc;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.support.WebApplicationObjectSupport;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.webflow.context.servlet.DefaultFlowUrlHandler;
import org.springframework.webflow.context.servlet.FlowUrlHandler;
import org.springframework.webflow.context.servlet.ServletExternalContext;
import org.springframework.webflow.core.FlowException;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.execution.repository.NoSuchFlowExecutionException;
import org.springframework.webflow.executor.FlowExecutionResult;
import org.springframework.webflow.executor.FlowExecutor;
public class FlowHandlerAdapter extends WebApplicationObjectSupport implements HandlerAdapter {
private FlowExecutor flowExecutor;
private FlowUrlHandler urlHandler;
public FlowHandlerAdapter(FlowExecutor flowExecutor) {
this.flowExecutor = flowExecutor;
this.urlHandler = new DefaultFlowUrlHandler();
}
public FlowUrlHandler getFlowUrlHandler() {
return urlHandler;
}
public void setFlowUrlHandler(FlowUrlHandler urlHandler) {
this.urlHandler = urlHandler;
}
public boolean supports(Object handler) {
return handler instanceof FlowHandler;
}
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
FlowHandler flowHandler = (FlowHandler) handler;
String flowExecutionKey = urlHandler.getFlowExecutionKey(request);
if (flowExecutionKey != null) {
try {
ServletExternalContext context = createServletExternalContext(request, response);
FlowExecutionResult result = flowExecutor.resumeExecution(flowExecutionKey, context);
return handleFlowExecutionResult(result, context, request, response, flowHandler);
} catch (FlowException e) {
return handleFlowException(e, request, response, flowHandler);
}
} else {
try {
MutableAttributeMap input = flowHandler.createExecutionInputMap(request);
ServletExternalContext context = createServletExternalContext(request, response);
FlowExecutionResult result = flowExecutor.launchExecution(flowHandler.getFlowId(), input, context);
return handleFlowExecutionResult(result, context, request, response, flowHandler);
} catch (FlowException e) {
return handleFlowException(e, request, response, flowHandler);
}
}
}
// subclassing hooks
protected ServletExternalContext createServletExternalContext(HttpServletRequest request,
HttpServletResponse response) {
return new ServletExternalContext(getServletContext(), request, response, urlHandler);
}
protected MutableAttributeMap defaultFlowExecutionInputMap(HttpServletRequest request) {
return new LocalAttributeMap(request.getParameterMap());
}
protected ModelAndView defaultHandleFlowOutcome(String flowId, String outcome, AttributeMap endedOutput,
HttpServletRequest request, HttpServletResponse response) throws IOException {
// by default, just start the flow over passing the output as input
response.sendRedirect(urlHandler.createFlowDefinitionUrl(flowId, endedOutput, request));
return null;
}
protected ModelAndView defaultHandleFlowException(String flowId, FlowException e, HttpServletRequest request,
HttpServletResponse response) throws IOException {
if (e instanceof NoSuchFlowExecutionException && flowId != null) {
// by default, attempt to restart the flow
response.sendRedirect(urlHandler.createFlowDefinitionUrl(flowId, null, request));
return null;
} else {
throw e;
}
}
// internal helpers
private ModelAndView handleFlowExecutionResult(FlowExecutionResult result, ServletExternalContext context,
HttpServletRequest request, HttpServletResponse response, FlowHandler handler) throws IOException {
if (result.paused()) {
if (context.flowExecutionRedirectRequested()) {
String url = urlHandler.createFlowExecutionUrl(result.getFlowId(), result.getPausedKey(), request);
response.sendRedirect(url);
return null;
} else if (context.externalRedirectRequested()) {
response.sendRedirect(context.getExternalRedirectUrl());
return null;
} else {
return null;
}
} else if (result.ended()) {
if (context.flowDefinitionRedirectRequested()) {
String flowId = context.getFlowRedirectFlowId();
AttributeMap input = context.getFlowRedirectFlowInput();
response.sendRedirect(urlHandler.createFlowDefinitionUrl(flowId, input, request));
return null;
} else if (context.externalRedirectRequested()) {
response.sendRedirect(context.getExternalRedirectUrl());
return null;
} else {
ModelAndView mv = handler.handleExecutionOutcome(result.getEndedOutcome(), result.getEndedOutput(),
request, response);
return mv != null ? mv : defaultHandleFlowOutcome(handler.getFlowId(), result.getEndedOutcome(), result
.getEndedOutput(), request, response);
}
} else {
throw new IllegalStateException("Execution result should have been one of [paused] or [ended]");
}
}
private ModelAndView handleFlowException(FlowException e, HttpServletRequest request, HttpServletResponse response,
FlowHandler handler) throws IOException {
ModelAndView result = handler.handleException(e, request, response);
return result != null ? result : defaultHandleFlowException(handler.getFlowId(), e, request, response);
}
public long getLastModified(HttpServletRequest request, Object handler) {
return -1;
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.test;
import org.springframework.webflow.execution.FlowExecutionKey;
/**
* A simple flow execution key implementation. New instances of this class get their values from a sequence encapsulated
* as a static private variable of this class.
*
* @author Keith Donald
*/
public class GeneratedFlowExecutionKey extends FlowExecutionKey {
private static int nextKey = 1;
private int value;
/**
* Creates a new mock flow execution key.
*/
public GeneratedFlowExecutionKey() {
this.value = nextKey();
}
public boolean equals(Object o) {
if (!(o instanceof GeneratedFlowExecutionKey)) {
return false;
}
GeneratedFlowExecutionKey key = (GeneratedFlowExecutionKey) o;
return value == key.value;
}
public int hashCode() {
return value * 29;
}
public String toString() {
return String.valueOf(value);
}
private static int nextKey() {
int key = nextKey;
nextKey++;
return key;
}
}

View File

@@ -0,0 +1,69 @@
package org.springframework.webflow.context.servlet;
import java.util.LinkedHashMap;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.webflow.context.servlet.DefaultFlowUrlHandler;
import org.springframework.webflow.core.collection.CollectionUtils;
import org.springframework.webflow.core.collection.LocalAttributeMap;
public class DefaultFlowUrlHandlerTests extends TestCase {
private DefaultFlowUrlHandler urlHandler = new DefaultFlowUrlHandler();
private MockHttpServletRequest request = new MockHttpServletRequest();
public void testGetFlowId() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
assertEquals("foo", urlHandler.getFlowId(request));
}
public void testGetFlowExecutionKey() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.addParameter("execution", "12345");
assertEquals("12345", urlHandler.getFlowExecutionKey(request));
}
public void testCreateFlowDefinitionUrl() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
String url = urlHandler.createFlowDefinitionUrl("bookHotel", null, request);
assertEquals("/springtravel/app/bookHotel", url);
}
public void testCreateFlowDefinitionUrlEmptyInput() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
String url = urlHandler.createFlowDefinitionUrl("bookHotel", CollectionUtils.EMPTY_ATTRIBUTE_MAP, request);
assertEquals("/springtravel/app/bookHotel", url);
}
public void testCreateFlowDefinitionUrlWithFlowInput() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
LocalAttributeMap input = new LocalAttributeMap(new LinkedHashMap());
input.put("foo", "bar");
input.put("bar", "needs encoding");
input.put("baz", new Integer(1));
input.put("boop", null);
String url = urlHandler.createFlowDefinitionUrl("bookHotel", input, request);
assertEquals("/springtravel/app/bookHotel?foo=bar&bar=needs+encoding&baz=1&boop=", url);
}
public void testCreateFlowExecutionUrl() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
String url = urlHandler.createFlowExecutionUrl("foo", "12345", request);
assertEquals("/springtravel/app/foo?execution=12345", url);
}
}

View File

@@ -0,0 +1,62 @@
package org.springframework.webflow.context.servlet;
import java.util.LinkedHashMap;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.webflow.context.servlet.ParameterBasedFlowUrlHandler;
import org.springframework.webflow.core.collection.CollectionUtils;
import org.springframework.webflow.core.collection.LocalAttributeMap;
public class ParameterBasedFlowUrlHandlerTests extends TestCase {
private ParameterBasedFlowUrlHandler urlHandler = new ParameterBasedFlowUrlHandler();
private MockHttpServletRequest request = new MockHttpServletRequest();
public void testGetFlowId() {
request.addParameter("_flowId", "foo");
assertEquals("foo", urlHandler.getFlowId(request));
}
public void testGetFlowExecutionKey() {
request.addParameter("_flowExecutionKey", "12345");
assertEquals("12345", urlHandler.getFlowExecutionKey(request));
}
public void testCreateFlowDefinitionUrl() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/flows");
String url = urlHandler.createFlowDefinitionUrl("bookHotel", null, request);
assertEquals("/springtravel/app/flows?_flowId=bookHotel", url);
}
public void testCreateFlowDefinitionUrlEmptyInput() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/flows");
String url = urlHandler.createFlowDefinitionUrl("bookHotel", CollectionUtils.EMPTY_ATTRIBUTE_MAP, request);
assertEquals("/springtravel/app/flows?_flowId=bookHotel", url);
}
public void testCreateFlowDefinitionUrlWithFlowInput() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/flows");
LocalAttributeMap input = new LocalAttributeMap(new LinkedHashMap());
input.put("foo", "bar");
input.put("bar", "needs encoding");
input.put("baz", new Integer(1));
input.put("boop", null);
String url = urlHandler.createFlowDefinitionUrl("bookHotel", input, request);
assertEquals("/springtravel/app/flows?_flowId=bookHotel&foo=bar&bar=needs+encoding&baz=1&boop=", url);
}
public void testCreateFlowExecutionUrl() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/flows");
String url = urlHandler.createFlowExecutionUrl("bookHotel", "12345", request);
assertEquals("/springtravel/app/flows?_flowId=bookHotel&_flowExecutionKey=12345", url);
}
}

View File

@@ -0,0 +1,354 @@
package org.springframework.webflow.mvc;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.easymock.EasyMock;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.webflow.context.servlet.ServletExternalContext;
import org.springframework.webflow.core.FlowException;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.repository.NoSuchFlowExecutionException;
import org.springframework.webflow.executor.FlowExecutionResult;
import org.springframework.webflow.executor.FlowExecutor;
import org.springframework.webflow.test.MockFlowExecutionKey;
public class FlowControllerTests extends TestCase {
private FlowController controller;
private FlowExecutor executor;
private MockServletContext servletContext;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private ServletExternalContext context;
protected void setUp() {
executor = (FlowExecutor) EasyMock.createMock(FlowExecutor.class);
controller = new FlowController(executor) {
protected ServletExternalContext createServletExternalContext(HttpServletRequest request,
HttpServletResponse response) {
return context;
}
};
servletContext = new MockServletContext();
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
context = new ServletExternalContext(servletContext, request, response, controller.getFlowUrlHandler());
controller.setApplicationContext(new StaticWebApplicationContext());
controller.setServletContext(servletContext);
}
public void testLaunchFlowRequest() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
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);
EasyMock.verify(new Object[] { executor });
}
public void testLaunchFlowRequestEndsAfterProcessing() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
executor.launchExecution("foo", new LocalAttributeMap(parameters), context);
LocalAttributeMap output = new LocalAttributeMap();
output.put("bar", "baz");
Event outcome = new Event(this, "finish", output);
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handleRequest(request, response);
assertNull(mv);
assertEquals("/springtravel/app/foo?bar=baz", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testResumeFlowRequest() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("POST");
request.addParameter("execution", "12345");
Map parameters = new HashMap();
request.setParameters(parameters);
executor.resumeExecution("12345", context);
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "123456");
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handleRequest(request, response);
assertNull(mv);
EasyMock.verify(new Object[] { executor });
}
public void testResumeFlowRequestEndsAfterProcessing() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("POST");
request.addParameter("execution", "12345");
Map parameters = new HashMap();
request.setParameters(parameters);
executor.resumeExecution("12345", context);
LocalAttributeMap output = new LocalAttributeMap();
output.put("bar", "baz");
Event outcome = new Event(this, "finish", output);
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handleRequest(request, response);
assertNull(mv);
assertEquals("/springtravel/app/foo?bar=baz", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testLaunchFlowWithExecutionRedirect() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
context.requestFlowExecutionRedirect();
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);
EasyMock.verify(new Object[] { executor });
assertEquals("/springtravel/app/foo?execution=12345", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testLaunchFlowWithDefinitionRedirect() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
LocalAttributeMap input = new LocalAttributeMap();
input.put("baz", "boop");
context.requestFlowDefinitionRedirect("bar", input);
executor.launchExecution("foo", new LocalAttributeMap(parameters), context);
LocalAttributeMap output = new LocalAttributeMap();
output.put("bar", "baz");
Event outcome = new Event(this, "finish", output);
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handleRequest(request, response);
assertNull(mv);
EasyMock.verify(new Object[] { executor });
assertEquals("/springtravel/app/bar?baz=boop", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testLaunchFlowWithExternalRedirect() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
context.requestExternalRedirect("http://www.paypal.com");
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);
EasyMock.verify(new Object[] { executor });
assertEquals("http://www.paypal.com", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testDefaultHandleFlowException() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
executor.launchExecution("foo", new LocalAttributeMap(parameters), context);
FlowException flowException = new FlowException("Error") {
};
EasyMock.expectLastCall().andThrow(flowException);
EasyMock.replay(new Object[] { executor });
try {
controller.handleRequest(request, response);
fail("Should have thrown exception");
} catch (FlowException e) {
assertEquals(flowException, e);
}
EasyMock.verify(new Object[] { executor });
}
public void testDefaultHandleNoSuchFlowExecutionException() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
request.addParameter("execution", "12345");
executor.resumeExecution("12345", context);
FlowException flowException = new NoSuchFlowExecutionException(new MockFlowExecutionKey("12345"), null);
EasyMock.expectLastCall().andThrow(flowException);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handleRequest(request, response);
assertNull(mv);
assertEquals("/springtravel/app/foo", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testLaunchFlowWithCustomFlowHandler() throws Exception {
final LocalAttributeMap input = new LocalAttributeMap();
input.put("bar", "boop");
controller.registerFlowHandler(new FlowHandler() {
public String getFlowId() {
return "foo";
}
public MutableAttributeMap createExecutionInputMap(HttpServletRequest request) {
return input;
}
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
HttpServletResponse response) {
return null;
}
public ModelAndView handleException(FlowException e, HttpServletRequest request,
HttpServletResponse response) {
return null;
}
});
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
executor.launchExecution("foo", input, context);
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345");
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handleRequest(request, response);
assertNull(mv);
EasyMock.verify(new Object[] { executor });
}
public void testHandleFlowOutcomeCustomFlowHandler() throws Exception {
final LocalAttributeMap input = new LocalAttributeMap();
input.put("bar", "boop");
controller.registerFlowHandler(new FlowHandler() {
public String getFlowId() {
return "foo";
}
public MutableAttributeMap createExecutionInputMap(HttpServletRequest request) {
return input;
}
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
HttpServletResponse response) {
assertEquals("finish", outcome);
assertEquals("baz", output.get("bar"));
assertEquals(FlowControllerTests.this.request, request);
assertEquals(FlowControllerTests.this.response, response);
return null;
}
public ModelAndView handleException(FlowException e, HttpServletRequest request,
HttpServletResponse response) {
return null;
}
});
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
executor.launchExecution("foo", input, context);
LocalAttributeMap output = new LocalAttributeMap();
output.put("bar", "baz");
Event outcome = new Event(this, "finish", output);
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handleRequest(request, response);
assertNull(mv);
assertEquals("/springtravel/app/foo?bar=baz", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testHandleFlowExceptionCustomFlowHandler() throws Exception {
final FlowException flowException = new FlowException("Error") {
};
controller.registerFlowHandler(new FlowHandler() {
public String getFlowId() {
return "foo";
}
public MutableAttributeMap createExecutionInputMap(HttpServletRequest request) {
return null;
}
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
HttpServletResponse response) {
return null;
}
public ModelAndView handleException(FlowException e, HttpServletRequest request,
HttpServletResponse response) {
assertEquals(flowException, e);
return null;
}
});
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
executor.launchExecution("foo", null, context);
EasyMock.expectLastCall().andThrow(flowException);
EasyMock.replay(new Object[] { executor });
try {
controller.handleRequest(request, response);
fail("Should have thrown exception");
} catch (FlowException e) {
assertEquals(flowException, e);
}
EasyMock.verify(new Object[] { executor });
}
}

View File

@@ -0,0 +1,300 @@
package org.springframework.webflow.mvc;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.easymock.EasyMock;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.webflow.context.servlet.ServletExternalContext;
import org.springframework.webflow.core.FlowException;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.repository.NoSuchFlowExecutionException;
import org.springframework.webflow.executor.FlowExecutionResult;
import org.springframework.webflow.executor.FlowExecutor;
import org.springframework.webflow.test.MockFlowExecutionKey;
public class FlowHandlerAdapterTests extends TestCase {
private FlowHandlerAdapter controller;
private FlowExecutor executor;
private MockServletContext servletContext;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private ServletExternalContext context;
private FlowHandler flowHandler;
private LocalAttributeMap flowInput;
private boolean handleException;
private boolean handleExecutionOutcome;
protected void setUp() {
executor = (FlowExecutor) EasyMock.createMock(FlowExecutor.class);
controller = new FlowHandlerAdapter(executor) {
protected ServletExternalContext createServletExternalContext(HttpServletRequest request,
HttpServletResponse response) {
return context;
}
};
servletContext = new MockServletContext();
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
context = new ServletExternalContext(servletContext, request, response, controller.getFlowUrlHandler());
controller.setApplicationContext(new StaticWebApplicationContext());
controller.setServletContext(servletContext);
flowHandler = new FlowHandler() {
public MutableAttributeMap createExecutionInputMap(HttpServletRequest request) {
assertEquals(FlowHandlerAdapterTests.this.request, request);
return flowInput;
}
public String getFlowId() {
return "foo";
}
public ModelAndView handleException(FlowException e, HttpServletRequest request,
HttpServletResponse response) {
if (handleException) {
return new ModelAndView("error");
} else {
return null;
}
}
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
HttpServletResponse response) {
if (handleExecutionOutcome) {
return new ModelAndView("redirect:/home");
} else {
return null;
}
}
};
}
public void testLaunchFlowRequest() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/whatever");
request.setRequestURI("/springtravel/app/whatever");
request.setMethod("GET");
executor.launchExecution("foo", flowInput, context);
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345");
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNull(mv);
EasyMock.verify(new Object[] { executor });
}
public void testLaunchFlowRequestEndsAfterProcessing() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/whatever");
request.setRequestURI("/springtravel/app/whatever");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
executor.launchExecution("foo", null, context);
LocalAttributeMap output = new LocalAttributeMap();
output.put("bar", "baz");
Event outcome = new Event(this, "finish", output);
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNull(mv);
assertEquals("/springtravel/app/foo?bar=baz", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testResumeFlowRequest() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("POST");
request.addParameter("execution", "12345");
Map parameters = new HashMap();
request.setParameters(parameters);
executor.resumeExecution("12345", context);
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "123456");
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNull(mv);
EasyMock.verify(new Object[] { executor });
}
public void testResumeFlowRequestEndsAfterProcessing() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("POST");
request.addParameter("execution", "12345");
Map parameters = new HashMap();
request.setParameters(parameters);
executor.resumeExecution("12345", context);
LocalAttributeMap output = new LocalAttributeMap();
output.put("bar", "baz");
Event outcome = new Event(this, "finish", output);
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNull(mv);
assertEquals("/springtravel/app/foo?bar=baz", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testLaunchFlowWithExecutionRedirect() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
context.requestFlowExecutionRedirect();
executor.launchExecution("foo", null, context);
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345");
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNull(mv);
EasyMock.verify(new Object[] { executor });
assertEquals("/springtravel/app/foo?execution=12345", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testLaunchFlowWithDefinitionRedirect() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
LocalAttributeMap input = new LocalAttributeMap();
input.put("baz", "boop");
context.requestFlowDefinitionRedirect("bar", input);
executor.launchExecution("foo", null, context);
LocalAttributeMap output = new LocalAttributeMap();
output.put("bar", "baz");
Event outcome = new Event(this, "finish", output);
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNull(mv);
EasyMock.verify(new Object[] { executor });
assertEquals("/springtravel/app/bar?baz=boop", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testLaunchFlowWithExternalRedirect() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
context.requestExternalRedirect("http://www.paypal.com");
executor.launchExecution("foo", null, context);
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345");
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNull(mv);
EasyMock.verify(new Object[] { executor });
assertEquals("http://www.paypal.com", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testDefaultHandleFlowException() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
Map parameters = new HashMap();
request.setParameters(parameters);
executor.launchExecution("foo", null, context);
FlowException flowException = new FlowException("Error") {
};
EasyMock.expectLastCall().andThrow(flowException);
EasyMock.replay(new Object[] { executor });
try {
controller.handle(request, response, flowHandler);
fail("Should have thrown exception");
} catch (FlowException e) {
assertEquals(flowException, e);
}
EasyMock.verify(new Object[] { executor });
}
public void testDefaultHandleNoSuchFlowExecutionException() throws Exception {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
request.addParameter("execution", "12345");
executor.resumeExecution("12345", context);
FlowException flowException = new NoSuchFlowExecutionException(new MockFlowExecutionKey("12345"), null);
EasyMock.expectLastCall().andThrow(flowException);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNull(mv);
assertEquals("/springtravel/app/foo", response.getRedirectedUrl());
EasyMock.verify(new Object[] { executor });
}
public void testHandleFlowOutcomeCustomFlowHandler() throws Exception {
handleExecutionOutcome = true;
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
executor.launchExecution("foo", flowInput, context);
LocalAttributeMap output = new LocalAttributeMap();
output.put("bar", "baz");
Event outcome = new Event(this, "finish", output);
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
EasyMock.expectLastCall().andReturn(result);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNotNull(mv);
EasyMock.verify(new Object[] { executor });
}
public void testHandleFlowExceptionCustomFlowHandler() throws Exception {
handleException = true;
final FlowException flowException = new FlowException("Error") {
};
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
request.setMethod("GET");
executor.launchExecution("foo", null, context);
EasyMock.expectLastCall().andThrow(flowException);
EasyMock.replay(new Object[] { executor });
ModelAndView mv = controller.handle(request, response, flowHandler);
assertNotNull(mv);
EasyMock.verify(new Object[] { executor });
}
}