KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > pageflow > MultipartRequestUtils


1 /*
2  * Copyright 2004 The Apache Software Foundation.
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  * $Header:$
17  */

18 package org.apache.beehive.netui.pageflow;
19
20 // java imports
21
import java.util.Enumeration JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Hashtable JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import javax.servlet.http.HttpServletRequest JavaDoc;
27 import javax.servlet.ServletException JavaDoc;
28 import javax.servlet.ServletContext JavaDoc;
29
30 // internal imports
31
import org.apache.beehive.netui.util.logging.Logger;
32 import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
33 import org.apache.beehive.netui.pageflow.scoping.ScopedRequest;
34 import org.apache.beehive.netui.pageflow.internal.InternalUtils;
35 import org.apache.beehive.netui.pageflow.internal.InternalConstants;
36
37 // external imports
38
import org.apache.struts.Globals;
39 import org.apache.struts.action.ActionForm;
40 import org.apache.struts.action.ActionMapping;
41 import org.apache.struts.action.ActionServletWrapper;
42 import org.apache.struts.config.ModuleConfig;
43 import org.apache.struts.upload.MultipartRequestHandler;
44 import org.apache.struts.upload.MultipartRequestWrapper;
45 import org.apache.struts.util.RequestUtils;
46
47 /**
48  * <p>
49  * NetUI utility to wrap Struts logic for handling multipart requests.
50  * </p>
51  *
52  * @exclude
53  */

54 /* package */ class MultipartRequestUtils
55 {
56     private static final Logger _log = Logger.getInstance(MultipartRequestUtils.class);
57     
58     private static final String JavaDoc PREHANDLED_MULTIPART_REQUEST_ATTR = InternalConstants.ATTR_PREFIX + "handledMultipart";
59     
60     /**
61      * <p>
62      * Handle a multipart request. The return value of this method will be <code>null</code>
63      * if the following conditions are not satisfied:
64      * <ol>
65      * <li>request.getContentType() != null</li>
66      * <li>content type is "multipart/form-data"</li>
67      * <li>request method is "POST"</li>
68      * </ol>
69      * If these are satisfied, a Struts {@link MultipartRequestHandler} is created. This object is used
70      * to provide a mapping over both the regular {@link HttpServletRequest} parameters and the
71      * paramters that Struts creates to represent the file(s) that was uploaded. If file(s) were
72      * uploaded, the {@link java.util.Map} returned has key / value pairs of these two structures:
73      * <ul>
74      * <li><code>String / String[]</code></li>
75      * <li><code>String / {@link org.apache.commons.fileupload.FileItem}</code></li>
76      * </ul>
77      * <br/>
78      * Invokers of this method should be aware that in this case, not all types returned from
79      * what looks like <code>request.getParameterValues(String key)</code> will be <code>String[]</code>.
80      * </p>
81      *
82      * @param request the request object
83      * @param bean the current action's associated {@link ActionForm}
84      * @return <code>null</code> if the request is <i>not</i> multipart. Otherwise, a {@link java.util.Map}
85      * is returned that contains the key / value pairs of the parameters in the request and the uploaded
86      * files.
87      * @throws ServletException if an error occurs loading this file. These exception messages
88      * are not internationalized as Struts does not internationalize them either.
89      */

90     /* package */ static final Map JavaDoc handleMultipartRequest(HttpServletRequest JavaDoc request, ActionForm bean)
91         throws ServletException JavaDoc
92     {
93         String JavaDoc contentType = request.getContentType();
94         String JavaDoc method = request.getMethod();
95         boolean isMultipart = false;
96
97         Map JavaDoc multipartParameters = null;
98
99         if(contentType != null &&
100            contentType.startsWith("multipart/form-data") &&
101            method.equalsIgnoreCase("POST"))
102         {
103             if ( ! InternalUtils.isMultipartHandlingEnabled( request ) )
104             {
105                 throw new ServletException JavaDoc( "Received a multipart request, but multipart handling is not enabled." );
106             }
107             
108             ActionServletWrapper servlet;
109             
110             if (bean != null)
111             {
112                 servlet = bean.getServletWrapper();
113             }
114             else
115             {
116                 ServletContext JavaDoc servletContext = InternalUtils.getServletContext(request);
117                 servlet = new ActionServletWrapper(InternalUtils.getActionServlet(servletContext));
118             }
119             
120             // @struts: does this -- but we can't rely on the bean not being null.
121
// if(bean instanceof ActionForm)
122
// servlet = bean.getServletWrapper();
123
// else if ( ! ( bean instanceof ActionForm ) )
124
// throw new ServletException
125
// ("bean that's supposed to be populated from a multipart request is not of type " +
126
// "\"org.apache.struts.action.ActionForm\", but type \"" + bean.getClass().getName() + "\"");
127

128             MultipartRequestHandler multipartHandler = getCachedMultipartHandler(request);
129             boolean preHandled = false;
130             
131             if (multipartHandler == null)
132             {
133                 multipartHandler = getMultipartHandler(request);
134             }
135             else
136             {
137                 preHandled = true;
138             }
139             
140             if (bean != null)
141             {
142                 bean.setMultipartRequestHandler(multipartHandler);
143             }
144             
145             if(multipartHandler != null)
146             {
147                 isMultipart = true;
148                 
149                 servlet.setServletFor(multipartHandler);
150                 multipartHandler.setMapping((ActionMapping)request.getAttribute(Globals.MAPPING_KEY));
151                 
152                 if (! preHandled)
153                 {
154                     multipartHandler.handleRequest(request);
155                 }
156                 
157                 Boolean JavaDoc maxLengthExceeded = (Boolean JavaDoc)request.getAttribute(MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);
158                 if(maxLengthExceeded != null && maxLengthExceeded.booleanValue())
159                 {
160                     // bail from RequestUtils.processPopulate
161
// @struts: semantics -- if this check fails, no values are updated into the form
162
return null;
163                 }
164                 multipartParameters = MultipartRequestUtils.getAllParametersForMultipartRequest(request, multipartHandler);
165
166                 // @struts: does this
167
//names = Collections.enumeration(multipartParameters.keySet());
168
}
169         }
170
171         if(!isMultipart)
172         {
173             // @struts: does this -- NetUI does not so that the ProcessPopulate method can be made faster; this way,
174
// ProcessPopulate doesn't care whether this is a MultipartRequest or not; it can just talk to a Map
175
// to get key / value pairs.
176
//names = request.getParameterNames();
177
return null;
178         }
179         else
180         {
181             ScopedRequest scopedRequest = ScopedServletUtils.unwrapRequest( PageFlowUtils.unwrapMultipart( request ) );
182             
183             if ( scopedRequest != null )
184             {
185                 multipartParameters = scopedRequest.filterParameterMap( multipartParameters );
186             }
187             return multipartParameters;
188         }
189     }
190
191     /**
192      * Can be called early in the request processing cycle to cache a single multipart handler for the request.
193      */

194     static void preHandleMultipartRequest(HttpServletRequest JavaDoc request)
195         throws ServletException JavaDoc
196     {
197         MultipartRequestHandler multipartHandler = getCachedMultipartHandler(request);
198         
199         if (multipartHandler == null)
200         {
201             multipartHandler = getMultipartHandler(request);
202             
203             if(multipartHandler != null)
204             {
205                 //
206
// Run the request through the handler, and cache the handler in the outer request.
207
//
208
multipartHandler.handleRequest(request);
209                 HttpServletRequest JavaDoc outerRequest =
210                     ScopedServletUtils.getOuterRequest(PageFlowUtils.unwrapMultipart(request));
211                 outerRequest.setAttribute(PREHANDLED_MULTIPART_REQUEST_ATTR, multipartHandler );
212             }
213         }
214     }
215     
216     /**
217      * Create an implementation of a {@link MultipartRequestHandler} for this
218      * mulitpart request.
219      *
220      * @param request the current request object
221      * @return the handler
222      * @throws ServletException if an error occurs loading this file. These exception messages
223      * are not internationalized as Struts does not internationalize them either.
224      */

225     // @Struts: org.apache.struts.util.RequestUtils.getMultipartHandler
226
private static final MultipartRequestHandler getMultipartHandler(HttpServletRequest JavaDoc request)
227         throws ServletException JavaDoc
228     {
229         MultipartRequestHandler multipartHandler = null;
230         String JavaDoc multipartClass = (String JavaDoc) request.getAttribute(Globals.MULTIPART_KEY);
231         request.removeAttribute(Globals.MULTIPART_KEY);
232
233         // Try to initialize the mapping specific request handler
234
if (multipartClass != null) {
235             try {
236                 multipartHandler = (MultipartRequestHandler)RequestUtils.applicationInstance(multipartClass);
237             } catch (ClassNotFoundException JavaDoc cnfe) {
238                 _log.error(
239                     "MultipartRequestHandler class \""
240                         + multipartClass
241                         + "\" in mapping class not found, "
242                         + "defaulting to global multipart class");
243             } catch (InstantiationException JavaDoc ie) {
244                 _log.error(
245                     "InstantiaionException when instantiating "
246                         + "MultipartRequestHandler \""
247                         + multipartClass
248                         + "\", "
249                         + "defaulting to global multipart class, exception: "
250                         + ie.getMessage());
251             } catch (IllegalAccessException JavaDoc iae) {
252                 _log.error(
253                     "IllegalAccessException when instantiating "
254                         + "MultipartRequestHandler \""
255                         + multipartClass
256                         + "\", "
257                         + "defaulting to global multipart class, exception: "
258                         + iae.getMessage());
259             }
260
261             if (multipartHandler != null)
262                 return multipartHandler;
263         }
264
265         ModuleConfig moduleConfig = (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);
266         multipartClass = moduleConfig.getControllerConfig().getMultipartClass();
267
268         // Try to initialize the global request handler
269
if (multipartClass != null) {
270             try {
271                 multipartHandler = (MultipartRequestHandler) RequestUtils.applicationInstance(multipartClass);
272             } catch (ClassNotFoundException JavaDoc cnfe) {
273                 throw new ServletException JavaDoc(
274                     "Cannot find multipart class \""
275                         + multipartClass
276                         + "\""
277                         + ", exception: "
278                         + cnfe.getMessage());
279             } catch (InstantiationException JavaDoc ie) {
280                 throw new ServletException JavaDoc(
281                     "InstantiaionException when instantiating "
282                         + "multipart class \""
283                         + multipartClass
284                         + "\", exception: "
285                         + ie.getMessage());
286             } catch (IllegalAccessException JavaDoc iae) {
287                 throw new ServletException JavaDoc(
288                     "IllegalAccessException when instantiating "
289                         + "multipart class \""
290                         + multipartClass
291                         + "\", exception: "
292                         + iae.getMessage());
293             }
294
295             if (multipartHandler != null)
296                 return multipartHandler;
297         }
298
299         return multipartHandler;
300     }
301
302     /**
303      * Get a {@link java.util.Map} object that reprensents the request parameters for
304      * a multipart request. As described in {@link #handleMultipartRequest}, the
305      * Map returned here may contain either String[] or FileItem values. The former
306      * are regular request parameters and the latter are the Struts abstraction
307      * on top of an uploaded file
308      *
309      * @param request the request
310      * @param multipartHandler the multipart handler for this request
311      * @return a Map of the key / value pairs of parameters in this request and object
312      * representations of the uploaded files.
313      */

314     // @Struts: org.apache.struts.util.RequestUtils.getAllParametrsForMultipartRequest
315
private static final Map JavaDoc getAllParametersForMultipartRequest(HttpServletRequest JavaDoc request, MultipartRequestHandler multipartHandler)
316     {
317         Map JavaDoc parameters = new HashMap JavaDoc();
318         Enumeration JavaDoc e;
319
320         Hashtable JavaDoc elements = multipartHandler.getAllElements();
321         e = elements.keys();
322         while (e.hasMoreElements()) {
323             String JavaDoc key = (String JavaDoc) e.nextElement();
324             parameters.put(key, elements.get(key));
325         }
326
327         if (request instanceof MultipartRequestWrapper) {
328             request = ((MultipartRequestWrapper)request).getRequest();
329             e = request.getParameterNames();
330             while (e.hasMoreElements()) {
331                 String JavaDoc key = (String JavaDoc) e.nextElement();
332                 parameters.put(key, request.getParameterValues(key));
333             }
334         } else {
335             _log.debug("Gathering multipart parameters for unwrapped request");
336         }
337
338         return parameters;
339     }
340     
341     static MultipartRequestHandler getCachedMultipartHandler( HttpServletRequest JavaDoc request )
342     {
343         HttpServletRequest JavaDoc req = ScopedServletUtils.getOuterRequest( PageFlowUtils.unwrapMultipart( request ) );
344         return ( MultipartRequestHandler ) req.getAttribute( MultipartRequestUtils.PREHANDLED_MULTIPART_REQUEST_ATTR );
345     }
346 }
347
Popular Tags