diff --git a/spring-webflow/src/main/java/org/springframework/webflow/executor/support/FlowIdMappingArgumentHandlerWrapper.java b/spring-webflow/src/main/java/org/springframework/webflow/executor/support/FlowIdMappingArgumentHandlerWrapper.java index 5eb21691..1a5cfad9 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/executor/support/FlowIdMappingArgumentHandlerWrapper.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/executor/support/FlowIdMappingArgumentHandlerWrapper.java @@ -25,15 +25,14 @@ import org.springframework.webflow.execution.support.ExternalRedirect; import org.springframework.webflow.execution.support.FlowDefinitionRedirect; /** - * Flow executor argument handler that wraps another argument handler - * and applies a flow id mapping. This can be used to avoid literal flow ids in - * URLs that launch flows. + * Flow executor argument handler that wraps another argument handler and applies a public to private flow id mapping. + * This can be used to avoid literal flow ids in URLs that launch flows. *
- * For example, when used in combination with {@link RequestParameterFlowExecutorArgumentHandler}
- * the url http://localhost/springair/reservation/booking.html would
- * launch a new execution of the booking-flow flow, assuming a context path of
- * /springair, a servlet mapping of /reservation/* and a flow id
- * mapping of booking->booking-flow.
+ * For example, when used in combination with {@link RequestPathFlowExecutorArgumentHandler} the url
+ * http://localhost/springair/reservation/booking.html would launch a new execution of the
+ * booking-flow flow, assuming a context path of /springair, a servlet mapping of
+ * /reservation/* and a flow id mapping of booking->booking-flow
+ * (the .html suffix would be removed by {@link RequestPathFlowExecutorArgumentHandler#extractFlowId(ExternalContext)}.
*
* @see RequestParameterFlowExecutorArgumentHandler
* @see RequestPathFlowExecutorArgumentHandler
@@ -42,12 +41,27 @@ import org.springframework.webflow.execution.support.FlowDefinitionRedirect;
* @author Erwin Vervaet
*/
public class FlowIdMappingArgumentHandlerWrapper extends FlowExecutorArgumentHandler {
-
- private FlowExecutorArgumentHandler argumentHandler;
+
+ /**
+ * The mappings between client-submitted flow identifiers and internal flow identifiers.
+ */
private Properties mappings = new Properties();
+
+ /**
+ * The reverse: mappings between internal flow identifiers and client-submitted flow identifiers.
+ */
private Properties reverseMappings = new Properties();
+
+ /**
+ * Whether or not to fallback to the argument handler delegate if no mapping is found.
+ */
private boolean fallback = true;
-
+
+ /**
+ * The argument handler delegate this handler wraps.
+ */
+ private FlowExecutorArgumentHandler argumentHandler;
+
/**
* Default constructor for bean style usage.
* @see #setArgumentHandler(FlowExecutorArgumentHandler)
@@ -70,52 +84,53 @@ public class FlowIdMappingArgumentHandlerWrapper extends FlowExecutorArgumentHan
public void setArgumentHandler(FlowExecutorArgumentHandler argumentHandler) {
this.argumentHandler = argumentHandler;
}
-
+
/**
- * Returns the flow id mappings in use.
+ * Returns the public-to-private flow id mappings in use.
*/
protected Properties getMappings() {
return mappings;
}
/**
- * Set the flow id mappings to use, overwriting any previous mappings.
+ * Set the mappings between client-submitted flow identifiers and internal flow identifiers. Overwrites any previous
+ * mappings.
+ * @param mappings the public to private flow id mappings
*/
public void setMappings(Properties mappings) {
- for (Enumeration fromFlowIds = mappings.propertyNames(); fromFlowIds.hasMoreElements(); ) {
- String fromFlowId = (String)fromFlowIds.nextElement();
- String toFlowId = mappings.getProperty(fromFlowId);
- addMapping(fromFlowId, toFlowId);
+ for (Enumeration publicFlowIds = mappings.propertyNames(); publicFlowIds.hasMoreElements();) {
+ String publicId = (String) publicFlowIds.nextElement();
+ String privateId = mappings.getProperty(publicId);
+ addMapping(publicId, privateId);
}
}
-
+
/**
- * Add a flow id mapping, overwriting any previous mapping for the same
- * flow ids.
+ * Add a flow id mapping, overwriting any previous mapping for the same flow ids.
+ * @param publicFlowId how the flow will be identified publically (to web clients)
+ * @param privateFlowId how the flow is identified internally (in the flow definition registry)
*/
- public void addMapping(String fromFlowId, String toFlowId) {
- mappings.setProperty(fromFlowId, toFlowId);
- reverseMappings.setProperty(toFlowId, fromFlowId);
+ public void addMapping(String publicFlowId, String privateFlowId) {
+ mappings.setProperty(publicFlowId, privateFlowId);
+ reverseMappings.setProperty(privateFlowId, publicFlowId);
}
-
+
/**
- * Should we fall back to the flow id extracted by the wrapped argument
- * handler if no mapping is defined for a flow id? Default is true.
+ * Should we fall back to the flow id extracted by the wrapped argument handler if no mapping is defined for a flow
+ * id? Default is true.
*/
public boolean isFallback() {
return fallback;
}
-
+
/**
- * Set whether or not to fall back on the flow id extracted by the
- * wrapped argument handler if no mapping is defined for a flow id.
- * Default is true. When false an exception is thrown when there is
- * a mapping failure.
+ * Set whether or not to fall back on the flow id extracted by the wrapped argument handler if no mapping is defined
+ * for a flow id. Default is true. When false an exception is thrown when there is a mapping failure.
*/
public void setFallback(boolean fallback) {
this.fallback = fallback;
}
-
+
public boolean isFlowIdPresent(ExternalContext context) {
if (argumentHandler.isFlowIdPresent(context)) {
return fallback || mappings.containsKey(argumentHandler.extractFlowId(context));
@@ -126,21 +141,20 @@ public class FlowIdMappingArgumentHandlerWrapper extends FlowExecutorArgumentHan
}
public String extractFlowId(ExternalContext context) throws FlowExecutorArgumentExtractionException {
- String originalFlowId = argumentHandler.extractFlowId(context);
- String flowId = mappings.getProperty(originalFlowId);
+ String publicFlowId = argumentHandler.extractFlowId(context);
+ String flowId = mappings.getProperty(publicFlowId);
if (!StringUtils.hasText(flowId)) {
if (fallback) {
- flowId = originalFlowId;
+ flowId = publicFlowId;
}
else {
- throw new FlowExecutorArgumentExtractionException(
- "Unable to extract flow definition id: no mapping was defined for flow id '" +
- originalFlowId + "'");
+ throw new FlowExecutorArgumentExtractionException("Unable to extract flow definition id: "
+ + "no mapping was defined for '" + publicFlowId + "'");
}
}
return flowId;
}
-
+
public boolean isFlowExecutionKeyPresent(ExternalContext context) {
return argumentHandler.isFlowExecutionKeyPresent(context);
}
@@ -159,28 +173,28 @@ public class FlowIdMappingArgumentHandlerWrapper extends FlowExecutorArgumentHan
public String createFlowDefinitionUrl(FlowDefinitionRedirect flowDefinitionRedirect, ExternalContext context) {
// do reverse mapping
- String flowId = reverseMappings.getProperty(flowDefinitionRedirect.getFlowDefinitionId());
- if (!StringUtils.hasText(flowId)) {
+ String publicFlowId = reverseMappings.getProperty(flowDefinitionRedirect.getFlowDefinitionId());
+ if (!StringUtils.hasText(publicFlowId)) {
if (fallback) {
- flowId = flowDefinitionRedirect.getFlowDefinitionId();
+ publicFlowId = flowDefinitionRedirect.getFlowDefinitionId();
}
else {
// this is a mapping problem
- throw new IllegalArgumentException(
- "Unable to create a flow definition URL for '" + flowDefinitionRedirect + "': " +
- "no reverse mapping was defined for flow id '" + flowDefinitionRedirect.getFlowDefinitionId() + "'");
+ throw new IllegalArgumentException("Unable to create a flow definition URL for '"
+ + flowDefinitionRedirect + "': " + "no reverse mapping was defined for flow id '"
+ + flowDefinitionRedirect.getFlowDefinitionId() + "'");
}
}
- flowDefinitionRedirect = new FlowDefinitionRedirect(flowId, flowDefinitionRedirect.getExecutionInput());
+ flowDefinitionRedirect = new FlowDefinitionRedirect(publicFlowId, flowDefinitionRedirect.getExecutionInput());
return argumentHandler.createFlowDefinitionUrl(flowDefinitionRedirect, context);
}
- public String createFlowExecutionUrl(String flowExecutionKey,
- FlowExecutionContext flowExecution, ExternalContext context) {
+ public String createFlowExecutionUrl(String flowExecutionKey, FlowExecutionContext flowExecution,
+ ExternalContext context) {
return argumentHandler.createFlowExecutionUrl(flowExecutionKey, flowExecution, context);
}
public String createExternalUrl(ExternalRedirect redirect, String flowExecutionKey, ExternalContext context) {
return argumentHandler.createExternalUrl(redirect, flowExecutionKey, context);
}
-}
+}
\ No newline at end of file