SWF-1027 - FilenameFlowUrlHandler does not implement createFlowDefinitionUrl

This commit is contained in:
Jeremy Grelle
2009-08-05 18:46:41 +00:00
parent 1819f88e45
commit 84c2193f73
3 changed files with 121 additions and 5 deletions

View File

@@ -58,6 +58,7 @@ import org.springframework.webflow.core.collection.AttributeMap;
* execution "e1s1" of the "hotels/booking" flow.
*
* @author Keith Donald
* @author Jeremy Grelle
*/
public class DefaultFlowUrlHandler implements FlowUrlHandler {
@@ -109,6 +110,23 @@ public class DefaultFlowUrlHandler implements FlowUrlHandler {
return url.toString();
}
/**
* The flow definition URL for the given flow id will be built by appending the flow id to the base app context and
* servlet paths.
*
* <p>
* Example - given a request originating at:
*
* <pre>
* http://someHost/someApp/someServlet/nestedPath/foo
* </pre>
*
* and a request for the flow id "nestedPath/bar", the new flow definition URL would be:
*
* <pre>
* http://someHost/someApp/someServlet/nestedPath/bar
* </pre>
*/
public String createFlowDefinitionUrl(String flowId, AttributeMap input, HttpServletRequest request) {
StringBuffer url = new StringBuffer();
if (request.getPathInfo() != null) {
@@ -138,9 +156,7 @@ public class DefaultFlowUrlHandler implements FlowUrlHandler {
return url.toString();
}
// internal helpers
private String getEncodingScheme(HttpServletRequest request) {
protected String getEncodingScheme(HttpServletRequest request) {
if (encodingScheme != null) {
return encodingScheme;
} else {
@@ -152,7 +168,7 @@ public class DefaultFlowUrlHandler implements FlowUrlHandler {
}
}
private void appendQueryParameters(StringBuffer url, Map parameters, String encodingScheme) {
protected void appendQueryParameters(StringBuffer url, Map parameters, String encodingScheme) {
Iterator entries = parameters.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
@@ -163,6 +179,8 @@ public class DefaultFlowUrlHandler implements FlowUrlHandler {
}
}
// internal helpers
private void appendQueryParameter(StringBuffer url, Object key, Object value, String encodingScheme) {
String encodedKey = encode(key, encodingScheme);
String encodedValue = encode(value, encodingScheme);

View File

@@ -17,14 +17,16 @@ package org.springframework.webflow.context.servlet;
import javax.servlet.http.HttpServletRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UrlPathHelper;
import org.springframework.web.util.WebUtils;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.mvc.servlet.FlowController;
/**
* A file name based {@link FlowUrlHandler} implementation that is an alternative to the standard
* {@link DefaultFlowUrlHandler}. Treats the filename of a request without the URL suffix and/or prefix as the flow id.
* Used by the {@link FlowController} implementation as a default implementation to preserve compability with existing
* Used by the {@link FlowController} implementation as a default implementation to preserve compatibility with existing
* Web Flow 2 applications.
*
* <p>
@@ -54,6 +56,8 @@ import org.springframework.webflow.mvc.servlet.FlowController;
* well to avoid these clashes.
*
* @author Agim Emruli
* @author Jeremy Grelle
* @author Nazaret Kazarian
*/
public class FilenameFlowUrlHandler extends DefaultFlowUrlHandler {
@@ -66,4 +70,63 @@ public class FilenameFlowUrlHandler extends DefaultFlowUrlHandler {
public String getFlowId(HttpServletRequest request) {
return WebUtils.extractFilenameFromUrlPath(urlPathHelper.getLookupPathForRequest(request));
}
/**
* The flow definition URL for the given flowId will be inferred from the URL of the current request, re-using the
* same path and file extension.
*
* <p>
* Example - given a request originating at:
*
* <pre>
* http://someHost/someApp/someServlet/nestedPath/foo.html
* </pre>
*
* and a request for the flow id "bar", the new flow definition URL would be:
*
* <pre>
* http://someHost/someApp/someServlet/nestedPath/bar.html
* </pre>
*/
public String createFlowDefinitionUrl(String flowId, AttributeMap input, HttpServletRequest request) {
StringBuffer url = new StringBuffer();
String pathInfo = request.getPathInfo();
if (pathInfo != null) {
url.append(request.getContextPath());
url.append(request.getServletPath());
// include the pathInfo part up until the filename
url.append(pathInfo.substring(0, pathInfo.lastIndexOf("/") + 1));
url.append(flowId);
int dotIndex = pathInfo.lastIndexOf('.');
if (dotIndex != -1) {
url.append(pathInfo.substring(dotIndex));
}
} else {
String servletPath = request.getServletPath();
if (StringUtils.hasText(servletPath)) {
url.append(request.getContextPath());
// include the servletPath part up to the filename
int slashIndex = servletPath.lastIndexOf("/");
if (slashIndex != -1) {
url.append(servletPath.substring(0, slashIndex));
}
url.append('/');
url.append(flowId);
int dotIndex = servletPath.lastIndexOf('.');
if (dotIndex != -1) {
url.append(servletPath.substring(dotIndex));
}
} else {
// Leaving this for now, as DefaultFlowUrlHandler does the same thing,
// but this should probably be an error case in the future.
url.append('/');
url.append(flowId);
}
}
if (input != null && !input.isEmpty()) {
url.append('?');
appendQueryParameters(url, input.asMap(), getEncodingScheme(request));
}
return url.toString();
}
}

View File

@@ -45,4 +45,39 @@ public class FilenameFlowUrlHandlerTests extends TestCase {
request.setRequestURI("/springtravel");
assertEquals("", urlHandler.getFlowId(request));
}
public void testCreateFlowDefinitionUrlWithPathInfo() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/foo");
request.setRequestURI("/springtravel/app/foo");
String flowDefUrl = urlHandler.createFlowDefinitionUrl("bar", null, request);
assertEquals("/springtravel/app/bar", flowDefUrl);
}
public void testCreateFlowDefinitionUrlWithPathInfoNestedPath() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/nestedPath/foo");
request.setRequestURI("/springtravel/app/nestedPath/foo");
String flowDefUrl = urlHandler.createFlowDefinitionUrl("bar", null, request);
assertEquals("/springtravel/app/nestedPath/bar", flowDefUrl);
}
public void testCreateFlowDefinitionUrlWithPathInfoNestedPathAndFileExtension() {
request.setContextPath("/springtravel");
request.setServletPath("/app");
request.setPathInfo("/nestedPath/foo.flow");
request.setRequestURI("/springtravel/app/nestedPath/foo.flow");
String flowDefUrl = urlHandler.createFlowDefinitionUrl("bar", null, request);
assertEquals("/springtravel/app/nestedPath/bar.flow", flowDefUrl);
}
public void testCreateFlowDefinitionUrlWithServletPathAndFileExtension() {
request.setContextPath("/springtravel");
request.setServletPath("/nestedPath/foo.flow");
request.setRequestURI("/springtravel/nestedPath/foo.flow");
String flowDefUrl = urlHandler.createFlowDefinitionUrl("bar", null, request);
assertEquals("/springtravel/nestedPath/bar.flow", flowDefUrl);
}
}