KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > webflow > executor > support > RequestParameterFlowExecutorArgumentHandler


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.springframework.webflow.executor.support;
17
18 import java.util.Iterator JavaDoc;
19 import java.util.Map JavaDoc;
20
21 import org.springframework.core.style.StylerUtils;
22 import org.springframework.util.StringUtils;
23 import org.springframework.webflow.context.ExternalContext;
24 import org.springframework.webflow.core.collection.ParameterMap;
25 import org.springframework.webflow.execution.FlowExecutionContext;
26 import org.springframework.webflow.execution.support.ExternalRedirect;
27 import org.springframework.webflow.execution.support.FlowDefinitionRedirect;
28 import org.springframework.webflow.executor.FlowExecutor;
29
30 /**
31  * Default {@link FlowExecutor} argument handler that extracts flow executor
32  * method arguments from the {@link ExternalContext#getRequestParameterMap()}
33  * and exposes arguments as URL encoded request parameters.
34  *
35  * @author Keith Donald
36  * @author Erwin Vervaet
37  */

38 public class RequestParameterFlowExecutorArgumentHandler extends FlowExecutorArgumentHandler {
39
40     /**
41      * The default delimiter used when a parameter value is encoded as part of
42      * the name of a parameter, e.g. "_eventId_submit" ("_").
43      * <p>
44      * This form is typically used to support multiple HTML buttons on a form
45      * without resorting to Javascript to communicate the event that corresponds
46      * to a button.
47      */

48     private static final String JavaDoc PARAMETER_VALUE_DELIMITER = "_";
49
50     /**
51      * The embedded parameter name/value delimiter, used to parse a parameter
52      * value when a value is embedded in a parameter name (e.g.
53      * "_eventId_submit"). Defaults to {@link #PARAMETER_VALUE_DELIMITER}.
54      */

55     private String JavaDoc parameterValueDelimiter = PARAMETER_VALUE_DELIMITER;
56
57     /**
58      * Returns the delimiter used to parse a parameter value when a value is
59      * embedded in a parameter name (e.g. "_eventId_submit"). Defaults to "_".
60      */

61     public String JavaDoc getParameterValueDelimiter() {
62         return parameterValueDelimiter;
63     }
64
65     /**
66      * Set the delimiter used to parse a parameter value when a value is
67      * embedded in a parameter name (e.g. "_eventId_submit").
68      */

69     public void setParameterValueDelimiter(String JavaDoc parameterValueDelimiter) {
70         this.parameterValueDelimiter = parameterValueDelimiter;
71     }
72
73     public boolean isFlowIdPresent(ExternalContext context) {
74         return context.getRequestParameterMap().contains(getFlowIdArgumentName());
75     }
76
77     public String JavaDoc extractFlowId(ExternalContext context) throws FlowExecutorArgumentExtractionException {
78         String JavaDoc flowId = context.getRequestParameterMap().get(getFlowIdArgumentName());
79         flowId = applyDefaultFlowId(flowId);
80         if (!StringUtils.hasText(flowId)) {
81             throw new FlowExecutorArgumentExtractionException(
82                     "Unable to extract the flow definition id parameter: make sure the client provides the '"
83                     + getFlowIdArgumentName()
84                     + "' parameter as input or set the 'defaultFlowId' property; "
85                     + "the parameters provided in this request are: "
86                     + StylerUtils.style(context.getRequestParameterMap()));
87         }
88         return flowId;
89     }
90
91     public boolean isFlowExecutionKeyPresent(ExternalContext context) {
92         return context.getRequestParameterMap().contains(getFlowExecutionKeyArgumentName());
93     }
94
95     public String JavaDoc extractFlowExecutionKey(ExternalContext context) throws FlowExecutorArgumentExtractionException {
96         String JavaDoc encodedKey = context.getRequestParameterMap().get(getFlowExecutionKeyArgumentName());
97         if (!StringUtils.hasText(encodedKey)) {
98             throw new FlowExecutorArgumentExtractionException(
99                     "Unable to extract the flow execution key parameter: make sure the client provides the '"
100                     + getFlowExecutionKeyArgumentName()
101                     + "' parameter as input; the parameters provided in this request are: "
102                     + StylerUtils.style(context.getRequestParameterMap()));
103         }
104         return encodedKey;
105     }
106
107     public boolean isEventIdPresent(ExternalContext context) {
108         return StringUtils.hasText(findParameter(getEventIdArgumentName(), context.getRequestParameterMap()));
109     }
110
111     public String JavaDoc extractEventId(ExternalContext context) throws FlowExecutorArgumentExtractionException {
112         String JavaDoc eventId = findParameter(getEventIdArgumentName(), context.getRequestParameterMap());
113         if (!StringUtils.hasText(eventId)) {
114             throw new FlowExecutorArgumentExtractionException(
115                     "Unable to extract the event id parameter: make sure the client provides the '"
116                     + getEventIdArgumentName() + "' parameter as input along with the '"
117                     + getFlowExecutionKeyArgumentName()
118                     + "' parameter; the parameters provided in this request are: "
119                     + StylerUtils.style(context.getRequestParameterMap()));
120         }
121         return eventId;
122     }
123
124     /**
125      * Obtain a named parameter from the request parameters. This method will try
126      * to obtain a parameter value using the following algorithm:
127      * <ol>
128      * <li>Try to get the parameter value using just the given <i>logical</i>
129      * name. This handles parameters of the form <tt>logicalName = value</tt>.
130      * For normal parameters, e.g. submitted using a hidden HTML form field,
131      * this will return the requested value.</li>
132      * <li>Try to obtain the parameter value from the parameter name, where the
133      * parameter name in the request is of the form
134      * <tt>logicalName_value = xyz</tt> with "_" being the configured
135      * delimiter. This deals with parameter values submitted using an HTML form
136      * submit button.</li>
137      * <li>If the value obtained in the previous step has a ".x" or ".y"
138      * suffix, remove that. This handles cases where the value was submitted
139      * using an HTML form image button. In this case the parameter in the request
140      * would actually be of the form <tt>logicalName_value.x = 123</tt>.
141      * </li>
142      * </ol>
143      * @param logicalParameterName the <i>logical</i> name of the request
144      * parameter
145      * @param parameters the available parameter map
146      * @return the value of the parameter, or <code>null</code> if the
147      * parameter does not exist in given request
148      */

149     protected String JavaDoc findParameter(String JavaDoc logicalParameterName, ParameterMap parameters) {
150         // first try to get it as a normal name=value parameter
151
String JavaDoc value = parameters.get(logicalParameterName);
152         if (value != null) {
153             return value;
154         }
155         // if no value yet, try to get it as a name_value=xyz parameter
156
String JavaDoc prefix = logicalParameterName + getParameterValueDelimiter();
157         Iterator JavaDoc paramNames = parameters.asMap().keySet().iterator();
158         while (paramNames.hasNext()) {
159             String JavaDoc paramName = (String JavaDoc)paramNames.next();
160             if (paramName.startsWith(prefix)) {
161                 String JavaDoc strValue = paramName.substring(prefix.length());
162                 // support images buttons, which would submit parameters as
163
// name_value.x=123
164
if (strValue.endsWith(".x") || strValue.endsWith(".y")) {
165                     strValue = strValue.substring(0, strValue.length() - 2);
166                 }
167                 return strValue;
168             }
169         }
170         // we couldn't find the parameter value
171
return null;
172     }
173
174     public String JavaDoc createFlowDefinitionUrl(FlowDefinitionRedirect flowDefinitionRedirect, ExternalContext context) {
175         StringBuffer JavaDoc url = new StringBuffer JavaDoc();
176         appendFlowExecutorPath(url, context);
177         url.append('?');
178         appendQueryParameter(url, getFlowIdArgumentName(), flowDefinitionRedirect.getFlowDefinitionId());
179         if (!flowDefinitionRedirect.getExecutionInput().isEmpty()) {
180             url.append('&');
181         }
182         appendQueryParameters(url, flowDefinitionRedirect.getExecutionInput());
183         return url.toString();
184     }
185
186     public String JavaDoc createFlowExecutionUrl(String JavaDoc flowExecutionKey, FlowExecutionContext flowExecution,
187             ExternalContext context) {
188         StringBuffer JavaDoc url = new StringBuffer JavaDoc();
189         appendFlowExecutorPath(url, context);
190         url.append('?');
191         appendQueryParameter(url, getFlowExecutionKeyArgumentName(), flowExecutionKey);
192         return url.toString();
193     }
194
195     public String JavaDoc createExternalUrl(ExternalRedirect redirect, String JavaDoc flowExecutionKey, ExternalContext context) {
196         StringBuffer JavaDoc externalUrl = new StringBuffer JavaDoc();
197         externalUrl.append(makeRedirectUrlContextRelativeIfNecessary(redirect.getUrl(), context));
198         if (flowExecutionKey != null) {
199             boolean first = redirect.getUrl().indexOf('?') < 0;
200             if (first) {
201                 externalUrl.append('?');
202             }
203             else {
204                 externalUrl.append('&');
205             }
206             appendQueryParameter(externalUrl, getFlowExecutionKeyArgumentName(), flowExecutionKey);
207         }
208         return externalUrl.toString();
209     }
210
211     // helpers
212

213     /**
214      * Append the URL path to the flow executor capable of accepting new
215      * requests.
216      * @param url the url buffer to append to
217      * @param context the context of this request
218      */

219     protected void appendFlowExecutorPath(StringBuffer JavaDoc url, ExternalContext context) {
220         url.append(context.getContextPath());
221         url.append(context.getDispatcherPath());
222         if (context.getRequestPathInfo() != null) {
223             url.append(context.getRequestPathInfo());
224         }
225     }
226
227     /**
228      * Append query parameters to the redirect URL. Stringifies, URL-encodes and
229      * formats model attributes as query parameters.
230      * @param url the StringBuffer to append the parameters to
231      * @param parameters Map that contains attributes
232      */

233     protected void appendQueryParameters(StringBuffer JavaDoc url, Map JavaDoc parameters) {
234         Iterator JavaDoc entries = parameters.entrySet().iterator();
235         while (entries.hasNext()) {
236             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)entries.next();
237             appendQueryParameter(url, entry.getKey(), entry.getValue());
238             if (entries.hasNext()) {
239                 url.append('&');
240             }
241         }
242     }
243
244     /**
245      * Appends a single query parameter to a URL.
246      * @param url the target url to append to
247      * @param key the parameter name
248      * @param value the parameter value
249      */

250     protected void appendQueryParameter(StringBuffer JavaDoc url, Object JavaDoc key, Object JavaDoc value) {
251         String JavaDoc encodedKey = encodeValue(key);
252         String JavaDoc encodedValue = encodeValue(value);
253         url.append(encodedKey).append('=').append(encodedValue);
254     }
255 }
Popular Tags