%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.turbine.util.parser.DefaultParameterParser |
|
|
1 | package org.apache.turbine.util.parser; |
|
2 | ||
3 | /* |
|
4 | * Copyright 2001-2004 The Apache Software Foundation. |
|
5 | * |
|
6 | * Licensed under the Apache License, Version 2.0 (the "License") |
|
7 | * you may not use this file except in compliance with the License. |
|
8 | * You may obtain a copy of the License at |
|
9 | * |
|
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
11 | * |
|
12 | * Unless required by applicable law or agreed to in writing, software |
|
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 | * See the License for the specific language governing permissions and |
|
16 | * limitations under the License. |
|
17 | */ |
|
18 | ||
19 | import java.net.URLDecoder; |
|
20 | ||
21 | import java.util.Enumeration; |
|
22 | import java.util.HashMap; |
|
23 | import java.util.Iterator; |
|
24 | import java.util.Map; |
|
25 | import java.util.StringTokenizer; |
|
26 | ||
27 | import javax.servlet.http.HttpServletRequest; |
|
28 | ||
29 | import org.apache.commons.fileupload.FileItem; |
|
30 | ||
31 | import org.apache.commons.logging.Log; |
|
32 | import org.apache.commons.logging.LogFactory; |
|
33 | ||
34 | import org.apache.turbine.services.upload.TurbineUpload; |
|
35 | import org.apache.turbine.services.upload.UploadService; |
|
36 | ||
37 | import org.apache.turbine.util.TurbineException; |
|
38 | import org.apache.turbine.util.pool.Recyclable; |
|
39 | ||
40 | /** |
|
41 | * DefaultParameterParser is a utility object to handle parsing and |
|
42 | * retrieving the data passed via the GET/POST/PATH_INFO arguments. |
|
43 | * |
|
44 | * <p>NOTE: The name= portion of a name=value pair may be converted |
|
45 | * to lowercase or uppercase when the object is initialized and when |
|
46 | * new data is added. This behaviour is determined by the url.case.folding |
|
47 | * property in TurbineResources.properties. Adding a name/value pair may |
|
48 | * overwrite existing name=value pairs if the names match: |
|
49 | * |
|
50 | * <pre> |
|
51 | * ParameterParser pp = data.getParameters(); |
|
52 | * pp.add("ERROR",1); |
|
53 | * pp.add("eRrOr",2); |
|
54 | * int result = pp.getInt("ERROR"); |
|
55 | * </pre> |
|
56 | * |
|
57 | * In the above example, result is 2. |
|
58 | * |
|
59 | * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a> |
|
60 | * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a> |
|
61 | * @author <a href="mailto:sean@informage.net">Sean Legassick</a> |
|
62 | * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> |
|
63 | * @version $Id: DefaultParameterParser.java,v 1.20.2.2 2004/05/20 03:33:43 seade Exp $ |
|
64 | */ |
|
65 | public class DefaultParameterParser |
|
66 | extends BaseValueParser |
|
67 | implements ParameterParser, Recyclable |
|
68 | { |
|
69 | /** Logging */ |
|
70 | 34 | private static Log log = LogFactory.getLog(DefaultParameterParser.class); |
71 | ||
72 | /** The servlet request to parse. */ |
|
73 | 0 | private HttpServletRequest request = null; |
74 | ||
75 | /** The raw data of a file upload. */ |
|
76 | 0 | private byte[] uploadData = null; |
77 | ||
78 | /** Map of request parameters to FileItem[]'s */ |
|
79 | 0 | private Map fileParameters = new HashMap(); |
80 | ||
81 | /** Turbine Upload Service reference */ |
|
82 | 17 | private static UploadService uploadService = null; |
83 | ||
84 | /** Do we have an upload Service? */ |
|
85 | 17 | private static boolean uploadServiceIsAvailable = false; |
86 | ||
87 | /** |
|
88 | * Create a new empty instance of ParameterParser. Uses the |
|
89 | * default character encoding (US-ASCII). |
|
90 | * |
|
91 | * <p>To add name/value pairs to this set of parameters, use the |
|
92 | * <code>add()</code> methods. |
|
93 | */ |
|
94 | public DefaultParameterParser() |
|
95 | { |
|
96 | 0 | super(); |
97 | 0 | configureUploadService(); |
98 | 0 | } |
99 | ||
100 | /** |
|
101 | * Create a new empty instance of ParameterParser. Takes a |
|
102 | * character encoding name to use when converting strings to |
|
103 | * bytes. |
|
104 | * |
|
105 | * <p>To add name/value pairs to this set of parameters, use the |
|
106 | * <code>add()</code> methods. |
|
107 | * |
|
108 | * @param characterEncoding The character encoding of strings. |
|
109 | */ |
|
110 | public DefaultParameterParser(String characterEncoding) |
|
111 | { |
|
112 | 0 | super (characterEncoding); |
113 | 0 | configureUploadService(); |
114 | 0 | } |
115 | ||
116 | /** |
|
117 | * Checks for availability of the Upload Service. We do this |
|
118 | * check only once at Startup, because the getService() call |
|
119 | * is really expensive and we don't have to run it every time |
|
120 | * we process a request. |
|
121 | */ |
|
122 | private void configureUploadService() |
|
123 | { |
|
124 | 0 | uploadServiceIsAvailable = TurbineUpload.isAvailable(); |
125 | 0 | if (uploadServiceIsAvailable) |
126 | { |
|
127 | 0 | uploadService = TurbineUpload.getService(); |
128 | } |
|
129 | 0 | } |
130 | ||
131 | /** |
|
132 | * Disposes the parser. |
|
133 | */ |
|
134 | public void dispose() |
|
135 | { |
|
136 | 0 | this.request = null; |
137 | 0 | this.uploadData = null; |
138 | 0 | this.fileParameters.clear(); |
139 | 0 | super.dispose(); |
140 | 0 | } |
141 | ||
142 | /** |
|
143 | * Gets the parsed servlet request. |
|
144 | * |
|
145 | * @return the parsed servlet request or null. |
|
146 | */ |
|
147 | public HttpServletRequest getRequest() |
|
148 | { |
|
149 | 0 | return this.request; |
150 | } |
|
151 | ||
152 | /** |
|
153 | * Sets the servlet request to be parser. This requires a |
|
154 | * valid HttpServletRequest object. It will attempt to parse out |
|
155 | * the GET/POST/PATH_INFO data and store the data into a Map. |
|
156 | * There are convenience methods for retrieving the data as a |
|
157 | * number of different datatypes. The PATH_INFO data must be a |
|
158 | * URLEncoded() string. |
|
159 | * <p> |
|
160 | * To add name/value pairs to this set of parameters, use the |
|
161 | * <code>add()</code> methods. |
|
162 | * |
|
163 | * @param request An HttpServletRequest. |
|
164 | */ |
|
165 | public void setRequest(HttpServletRequest request) |
|
166 | { |
|
167 | 0 | clear(); |
168 | ||
169 | 0 | uploadData = null; |
170 | ||
171 | 0 | String enc = request.getCharacterEncoding(); |
172 | 0 | setCharacterEncoding(enc != null ? enc : "US-ASCII"); |
173 | ||
174 | // String object re-use at its best. |
|
175 | 0 | String tmp = null; |
176 | ||
177 | 0 | tmp = request.getHeader("Content-type"); |
178 | ||
179 | 0 | if (uploadServiceIsAvailable |
180 | && uploadService.getAutomatic() |
|
181 | && tmp != null |
|
182 | && tmp.startsWith("multipart/form-data")) |
|
183 | { |
|
184 | 0 | log.debug("Running the Turbine Upload Service"); |
185 | try |
|
186 | { |
|
187 | 0 | TurbineUpload.parseRequest(request, this); |
188 | } |
|
189 | 0 | catch (TurbineException e) |
190 | { |
|
191 | 0 | log.error("File upload failed", e); |
192 | 0 | } |
193 | } |
|
194 | ||
195 | 0 | for (Enumeration names = request.getParameterNames(); |
196 | 0 | names.hasMoreElements();) |
197 | { |
|
198 | 0 | tmp = (String) names.nextElement(); |
199 | 0 | add(convert(tmp), |
200 | request.getParameterValues(tmp)); |
|
201 | } |
|
202 | ||
203 | // Also cache any pathinfo variables that are passed around as |
|
204 | // if they are query string data. |
|
205 | try |
|
206 | { |
|
207 | 0 | StringTokenizer st = |
208 | new StringTokenizer(request.getPathInfo(), "/"); |
|
209 | 0 | boolean isNameTok = true; |
210 | 0 | String pathPart = null; |
211 | 0 | while (st.hasMoreTokens()) |
212 | { |
|
213 | 0 | if (isNameTok) |
214 | { |
|
215 | 0 | tmp = URLDecoder.decode(st.nextToken()); |
216 | 0 | isNameTok = false; |
217 | } |
|
218 | else |
|
219 | { |
|
220 | 0 | pathPart = URLDecoder.decode(st.nextToken()); |
221 | 0 | if (tmp.length() > 0) |
222 | { |
|
223 | 0 | add(convert(tmp), pathPart); |
224 | } |
|
225 | 0 | isNameTok = true; |
226 | } |
|
227 | } |
|
228 | } |
|
229 | 0 | catch (Exception e) |
230 | { |
|
231 | // If anything goes wrong above, don't worry about it. |
|
232 | // Chances are that the path info was wrong anyways and |
|
233 | // things that depend on it being right will fail later |
|
234 | // and should be caught later. |
|
235 | 0 | } |
236 | ||
237 | 0 | this.request = request; |
238 | ||
239 | 0 | if (log.isDebugEnabled()) |
240 | { |
|
241 | 0 | log.debug("Parameters found in the Request:"); |
242 | 0 | for (Iterator it = keySet().iterator(); it.hasNext();) |
243 | { |
|
244 | 0 | String key = (String) it.next(); |
245 | 0 | log.debug("Key: " + key + " -> " + getString(key)); |
246 | } |
|
247 | } |
|
248 | 0 | } |
249 | ||
250 | /** |
|
251 | * Sets the uploadData byte[] |
|
252 | * |
|
253 | * @param uploadData A byte[] with data. |
|
254 | */ |
|
255 | public void setUploadData(byte[] uploadData) |
|
256 | { |
|
257 | 0 | this.uploadData = uploadData; |
258 | 0 | } |
259 | ||
260 | /** |
|
261 | * Gets the uploadData byte[] |
|
262 | * |
|
263 | * @return uploadData A byte[] with data. |
|
264 | */ |
|
265 | public byte[] getUploadData() |
|
266 | { |
|
267 | 0 | return this.uploadData; |
268 | } |
|
269 | ||
270 | /** |
|
271 | * Add a FileItem object as a parameters. If there are any |
|
272 | * FileItems already associated with the name, append to the |
|
273 | * array. The reason for this is that RFC 1867 allows multiple |
|
274 | * files to be associated with single HTML input element. |
|
275 | * |
|
276 | * @param name A String with the name. |
|
277 | * @param value A FileItem with the value. |
|
278 | */ |
|
279 | public void append(String name, FileItem value) |
|
280 | { |
|
281 | 0 | FileItem[] items = this.getFileItems(name); |
282 | 0 | if (items == null) |
283 | { |
|
284 | 0 | items = new FileItem[1]; |
285 | 0 | items[0] = value; |
286 | 0 | fileParameters.put(convert(name), items); |
287 | } |
|
288 | else |
|
289 | { |
|
290 | 0 | FileItem[] newItems = new FileItem[items.length + 1]; |
291 | 0 | System.arraycopy(items, 0, newItems, 0, items.length); |
292 | 0 | newItems[items.length] = value; |
293 | 0 | fileParameters.put(convert(name), newItems); |
294 | } |
|
295 | 0 | } |
296 | ||
297 | /** |
|
298 | * Return a FileItem object for the given name. If the name does |
|
299 | * not exist or the object stored is not a FileItem, return null. |
|
300 | * |
|
301 | * @param name A String with the name. |
|
302 | * @return A FileItem. |
|
303 | */ |
|
304 | public FileItem getFileItem(String name) |
|
305 | { |
|
306 | try |
|
307 | { |
|
308 | 0 | FileItem value = null; |
309 | 0 | Object object = fileParameters.get(convert(name)); |
310 | 0 | if (object != null) |
311 | { |
|
312 | 0 | value = ((FileItem[]) object)[0]; |
313 | } |
|
314 | 0 | return value; |
315 | } |
|
316 | 0 | catch (ClassCastException e) |
317 | { |
|
318 | 0 | log.error("Parameter (" |
319 | + name + ") is not an instance of FileItem", e); |
|
320 | 0 | return null; |
321 | } |
|
322 | } |
|
323 | ||
324 | /** |
|
325 | * Return an array of FileItem objects for the given name. If the |
|
326 | * name does not exist or the object stored is not a FileItem |
|
327 | * array, return null. |
|
328 | * |
|
329 | * @param name A String with the name. |
|
330 | * @return A FileItem[]. |
|
331 | */ |
|
332 | public FileItem[] getFileItems(String name) |
|
333 | { |
|
334 | try |
|
335 | { |
|
336 | 0 | return (FileItem[]) fileParameters.get(convert(name)); |
337 | } |
|
338 | 0 | catch (ClassCastException e) |
339 | { |
|
340 | 0 | log.error("Parameter (" |
341 | + name + ") is not an instance of FileItem[]", e); |
|
342 | 0 | return null; |
343 | } |
|
344 | } |
|
345 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |