KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > 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 JavaDoc;
20
21 import java.util.Enumeration JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.StringTokenizer JavaDoc;
26
27 import javax.servlet.http.HttpServletRequest JavaDoc;
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     private static Log log = LogFactory.getLog(DefaultParameterParser.class);
71
72     /** The servlet request to parse. */
73     private HttpServletRequest JavaDoc request = null;
74
75     /** The raw data of a file upload. */
76     private byte[] uploadData = null;
77
78     /** Map of request parameters to FileItem[]'s */
79     private Map JavaDoc fileParameters = new HashMap JavaDoc();
80
81     /** Turbine Upload Service reference */
82     private static UploadService uploadService = null;
83
84     /** Do we have an upload Service? */
85     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         super();
97         configureUploadService();
98     }
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 JavaDoc characterEncoding)
111     {
112         super (characterEncoding);
113         configureUploadService();
114     }
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         uploadServiceIsAvailable = TurbineUpload.isAvailable();
125         if (uploadServiceIsAvailable)
126         {
127             uploadService = TurbineUpload.getService();
128         }
129     }
130
131     /**
132      * Disposes the parser.
133      */

134     public void dispose()
135     {
136         this.request = null;
137         this.uploadData = null;
138         this.fileParameters.clear();
139         super.dispose();
140     }
141
142     /**
143      * Gets the parsed servlet request.
144      *
145      * @return the parsed servlet request or null.
146      */

147     public HttpServletRequest JavaDoc getRequest()
148     {
149         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 JavaDoc request)
166     {
167         clear();
168
169         uploadData = null;
170
171         String JavaDoc enc = request.getCharacterEncoding();
172         setCharacterEncoding(enc != null ? enc : "US-ASCII");
173
174         // String object re-use at its best.
175
String JavaDoc tmp = null;
176
177         tmp = request.getHeader("Content-type");
178
179         if (uploadServiceIsAvailable
180                 && uploadService.getAutomatic()
181                 && tmp != null
182                 && tmp.startsWith("multipart/form-data"))
183         {
184             log.debug("Running the Turbine Upload Service");
185             try
186             {
187                 TurbineUpload.parseRequest(request, this);
188             }
189             catch (TurbineException e)
190             {
191                 log.error("File upload failed", e);
192             }
193         }
194
195         for (Enumeration JavaDoc names = request.getParameterNames();
196              names.hasMoreElements();)
197         {
198             tmp = (String JavaDoc) names.nextElement();
199             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             StringTokenizer JavaDoc st =
208                     new StringTokenizer JavaDoc(request.getPathInfo(), "/");
209             boolean isNameTok = true;
210             String JavaDoc pathPart = null;
211             while (st.hasMoreTokens())
212             {
213                 if (isNameTok)
214                 {
215                     tmp = URLDecoder.decode(st.nextToken());
216                     isNameTok = false;
217                 }
218                 else
219                 {
220                     pathPart = URLDecoder.decode(st.nextToken());
221                     if (tmp.length() > 0)
222                     {
223                         add(convert(tmp), pathPart);
224                     }
225                     isNameTok = true;
226                 }
227             }
228         }
229         catch (Exception JavaDoc 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
}
236
237         this.request = request;
238
239         if (log.isDebugEnabled())
240         {
241             log.debug("Parameters found in the Request:");
242             for (Iterator JavaDoc it = keySet().iterator(); it.hasNext();)
243             {
244                 String JavaDoc key = (String JavaDoc) it.next();
245                 log.debug("Key: " + key + " -> " + getString(key));
246             }
247         }
248     }
249
250     /**
251      * Sets the uploadData byte[]
252      *
253      * @param uploadData A byte[] with data.
254      */

255     public void setUploadData(byte[] uploadData)
256     {
257         this.uploadData = uploadData;
258     }
259
260     /**
261      * Gets the uploadData byte[]
262      *
263      * @return uploadData A byte[] with data.
264      */

265     public byte[] getUploadData()
266     {
267         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 JavaDoc name, FileItem value)
280     {
281         FileItem[] items = this.getFileItems(name);
282         if (items == null)
283         {
284             items = new FileItem[1];
285             items[0] = value;
286             fileParameters.put(convert(name), items);
287         }
288         else
289         {
290             FileItem[] newItems = new FileItem[items.length + 1];
291             System.arraycopy(items, 0, newItems, 0, items.length);
292             newItems[items.length] = value;
293             fileParameters.put(convert(name), newItems);
294         }
295     }
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 JavaDoc name)
305     {
306         try
307         {
308             FileItem value = null;
309             Object JavaDoc object = fileParameters.get(convert(name));
310             if (object != null)
311             {
312                 value = ((FileItem[]) object)[0];
313             }
314             return value;
315         }
316         catch (ClassCastException JavaDoc e)
317         {
318             log.error("Parameter ("
319                     + name + ") is not an instance of FileItem", e);
320             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 JavaDoc name)
333     {
334         try
335         {
336             return (FileItem[]) fileParameters.get(convert(name));
337         }
338         catch (ClassCastException JavaDoc e)
339         {
340             log.error("Parameter ("
341                     + name + ") is not an instance of FileItem[]", e);
342             return null;
343         }
344     }
345 }
346
Popular Tags