View Javadoc
1   package org.andromda.cartridges.jsf.portlet.myfaces.tomahawk.support;
2   
3   import java.io.BufferedReader;
4   import java.io.File;
5   import java.io.IOException;
6   import java.io.InputStream;
7   import java.io.UnsupportedEncodingException;
8   import java.security.Principal;
9   import java.util.Collections;
10  import java.util.Enumeration;
11  import java.util.HashMap;
12  import java.util.Iterator;
13  import java.util.List;
14  import java.util.Locale;
15  import java.util.Map;
16  import javax.portlet.ActionRequest;
17  import javax.portlet.PortalContext;
18  import javax.portlet.PortletMode;
19  import javax.portlet.PortletPreferences;
20  import javax.portlet.PortletSession;
21  import javax.portlet.WindowState;
22  import org.apache.commons.fileupload.FileItem;
23  import org.apache.commons.fileupload.FileUploadBase;
24  import org.apache.commons.fileupload.FileUploadException;
25  import org.apache.commons.fileupload.disk.DiskFileItemFactory;
26  import org.apache.commons.fileupload.portlet.PortletFileUpload;
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.myfaces.webapp.filter.MultipartRequestWrapper;
30  
31  /**
32   * This class handles multipart/form-date request for Portlet. It will be called
33   * if the request is multipart/form-data.
34   *
35   * @author <a href="mailto:shinsuke@yahoo.co.jp">Shinsuke Sugaya</a>
36   * @author Sylvain Vieujot
37   */
38  public class MultipartPortletRequestWrapper
39  implements ActionRequest, MultipartRequest
40  {
41      private static Log log = LogFactory.getLog(MultipartPortletRequestWrapper.class);
42  
43      private ActionRequest request = null;
44  
45      private Map parametersMap = null;
46  
47      private PortletFileUpload fileUpload = null;
48  
49      private Map fileItems = null;
50  
51      private final int maxSize;
52  
53      private final int thresholdSize;
54  
55      private final String repositoryPath;
56  
57      /**
58       * @param request
59       * @param maxSize
60       * @param thresholdSize
61       * @param repositoryPath
62       */
63      public MultipartPortletRequestWrapper(
64          final ActionRequest request,
65          final int maxSize,
66          final int thresholdSize,
67          final String repositoryPath)
68      {
69          this.request = request;
70          this.maxSize = maxSize;
71          this.thresholdSize = thresholdSize;
72          this.repositoryPath = repositoryPath;
73      }
74  
75      private void parseRequest()
76      {
77          final DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
78  
79          diskFileItemFactory.setSizeThreshold(thresholdSize);
80  
81          if (repositoryPath != null && repositoryPath.trim().length() > 0)
82          {
83              diskFileItemFactory.setRepository(new File(repositoryPath));
84          }
85  
86          fileUpload = new PortletFileUpload();
87          fileUpload.setFileItemFactory(diskFileItemFactory);
88          fileUpload.setSizeMax(maxSize);
89  
90          final String charset = request.getCharacterEncoding();
91          fileUpload.setHeaderEncoding(charset);
92  
93          List requestParameters = null;
94          try
95          {
96              requestParameters = fileUpload.parseRequest(request);
97          }
98          catch (final FileUploadBase.SizeLimitExceededException e)
99          {
100             // TODO: find a way to notify the user about the fact that the
101             // uploaded file exceeded size limit
102 
103             if (MultipartPortletRequestWrapper.log.isInfoEnabled())
104             {
105                 MultipartPortletRequestWrapper.log.info("user tried to upload a file that exceeded file-size limitations.", e);
106             }
107 
108             requestParameters = Collections.EMPTY_LIST;
109 
110         }
111         catch (final FileUploadException fue)
112         {
113             MultipartPortletRequestWrapper.log.error("Exception while uploading file.", fue);
114             requestParameters = Collections.EMPTY_LIST;
115         }
116 
117         parametersMap = new HashMap(requestParameters.size());
118         fileItems = new HashMap();
119 
120         for (final Iterator iter = requestParameters.iterator(); iter.hasNext();)
121         {
122             final FileItem fileItem = (FileItem)iter.next();
123 
124             if (fileItem.isFormField())
125             {
126                 final String name = fileItem.getFieldName();
127 
128                 // The following code avoids commons-fileupload charset problem.
129                 // After fixing commons-fileupload, this code should be
130                 //
131                 // String value = fileItem.getString();
132                 //
133                 String value = null;
134                 if (charset == null)
135                 {
136                     value = fileItem.getString();
137                 }
138                 else
139                 {
140                     try
141                     {
142                         value = new String(fileItem.get(), charset);
143                     }
144                     catch (final UnsupportedEncodingException e)
145                     {
146                         value = fileItem.getString();
147                     }
148                 }
149 
150                 addTextParameter(name, value);
151             }
152             else
153             { // fileItem is a File
154                 if (fileItem.getName() != null)
155                 {
156                     fileItems.put(fileItem.getFieldName(), fileItem);
157                 }
158             }
159         }
160 
161         // Add the query string paramters
162         for (final Iterator it = request.getParameterMap().entrySet().iterator(); it.hasNext();)
163         {
164             final Map.Entry entry = (Map.Entry)it.next();
165             final String[] valuesArray = (String[])entry.getValue();
166             for (final String element : valuesArray)
167             {
168                 addTextParameter((String)entry.getKey(), element);
169             }
170         }
171     }
172 
173     private void addTextParameter(final String name, final String value)
174     {
175         if (!parametersMap.containsKey(name))
176         {
177             final String[] valuesArray =
178             {
179                 value
180             };
181             parametersMap.put(name, valuesArray);
182         }
183         else
184         {
185             final String[] storedValues = (String[])parametersMap.get(name);
186             final int lengthSrc = storedValues.length;
187             final String[] valuesArray = new String[lengthSrc + 1];
188             System.arraycopy(storedValues, 0, valuesArray, 0, lengthSrc);
189             valuesArray[lengthSrc] = value;
190             parametersMap.put(name, valuesArray);
191         }
192     }
193 
194     /**
195      * @see javax.portlet.PortletRequest#getParameterNames()
196      */
197     public Enumeration getParameterNames()
198     {
199         if (parametersMap == null)
200         {
201             parseRequest();
202         }
203 
204         return Collections.enumeration(parametersMap.keySet());
205     }
206 
207     /**
208      * @see javax.portlet.PortletRequest#getParameter(String)
209      */
210     public String getParameter(final String name)
211     {
212         if (parametersMap == null)
213         {
214             parseRequest();
215         }
216 
217         final String[] values = (String[])parametersMap.get(name);
218         if (values == null)
219         {
220             return null;
221         }
222         return values[0];
223     }
224 
225     /**
226      * @see javax.portlet.PortletRequest#getParameterValues(String)
227      */
228     public String[] getParameterValues(final String name)
229     {
230         if (parametersMap == null)
231         {
232             parseRequest();
233         }
234 
235         return (String[])parametersMap.get(name);
236     }
237 
238     /**
239      * @see javax.portlet.PortletRequest#getParameterMap()
240      */
241     public Map getParameterMap()
242     {
243         if (parametersMap == null)
244         {
245             parseRequest();
246         }
247 
248         return parametersMap;
249     }
250 
251     // Hook for the x:inputFileUpload tag.
252     /**
253      * @see org.andromda.cartridges.jsf.portlet.myfaces.tomahawk.support.MultipartRequest#getFileItem(String)
254      */
255     public FileItem getFileItem(final String fieldName)
256     {
257         if (fileItems == null)
258         {
259             parseRequest();
260         }
261 
262         return (FileItem)fileItems.get(fieldName);
263     }
264 
265     /**
266      * Not used internally by MyFaces, but provides a way to handle the uploaded
267      * files out of MyFaces.
268      * @return fileItems
269      */
270     public Map getFileItems()
271     {
272         if (fileItems == null)
273         {
274             parseRequest();
275         }
276 
277         return fileItems;
278     }
279 
280     /**
281      * @see javax.portlet.PortletRequest#getAttribute(String)
282      */
283     public Object getAttribute(final String arg0)
284     {
285         if (arg0.equals(MultipartRequestWrapper.UPLOADED_FILES_ATTRIBUTE))
286         {
287             return getFileItems();
288         }
289         return request.getAttribute(arg0);
290     }
291 
292     /**
293      * @see javax.portlet.PortletRequest#getAttributeNames()
294      */
295     public Enumeration getAttributeNames()
296     {
297         return request.getAttributeNames();
298     }
299 
300     /**
301      * @see javax.portlet.PortletRequest#getAuthType()
302      */
303     public String getAuthType()
304     {
305         return request.getAuthType();
306     }
307 
308     /**
309      * @see javax.portlet.PortletRequest#getContextPath()
310      */
311     public String getContextPath()
312     {
313         return request.getContextPath();
314     }
315 
316     /**
317      * @see javax.portlet.PortletRequest#getLocale()
318      */
319     public Locale getLocale()
320     {
321         return request.getLocale();
322     }
323 
324     /**
325      * @see javax.portlet.PortletRequest#getLocales()
326      */
327     public Enumeration getLocales()
328     {
329         return request.getLocales();
330     }
331 
332     /**
333      * @see javax.portlet.PortletRequest#getPortalContext()
334      */
335     public PortalContext getPortalContext()
336     {
337         return request.getPortalContext();
338     }
339 
340     /**
341      * @see javax.portlet.PortletRequest#getPortletMode()
342      */
343     public PortletMode getPortletMode()
344     {
345         return request.getPortletMode();
346     }
347 
348     /**
349      * @see javax.portlet.PortletRequest#getPortletSession()
350      */
351     public PortletSession getPortletSession()
352     {
353         return request.getPortletSession();
354     }
355 
356     /**
357      * @see javax.portlet.PortletRequest#getPortletSession(boolean)
358      */
359     public PortletSession getPortletSession(final boolean arg0)
360     {
361         return request.getPortletSession(arg0);
362     }
363 
364     /**
365      * @see javax.portlet.PortletRequest#getPreferences()
366      */
367     public PortletPreferences getPreferences()
368     {
369         return request.getPreferences();
370     }
371 
372     /**
373      * @see javax.portlet.PortletRequest#getProperties(String)
374      */
375     public Enumeration getProperties(final String arg0)
376     {
377         return request.getProperties(arg0);
378     }
379 
380     /**
381      * @see javax.portlet.PortletRequest#getProperty(String)
382      */
383     public String getProperty(final String arg0)
384     {
385         return request.getProperty(arg0);
386     }
387 
388     /**
389      * @see javax.portlet.PortletRequest#getPropertyNames()
390      */
391     public Enumeration getPropertyNames()
392     {
393         return request.getPropertyNames();
394     }
395 
396     /**
397      * @see javax.portlet.PortletRequest#getRemoteUser()
398      */
399     public String getRemoteUser()
400     {
401         return request.getRemoteUser();
402     }
403 
404     /**
405      * @see javax.portlet.PortletRequest#getRequestedSessionId()
406      */
407     public String getRequestedSessionId()
408     {
409         return request.getRequestedSessionId();
410     }
411 
412     /**
413      * @see javax.portlet.PortletRequest#getResponseContentType()
414      */
415     public String getResponseContentType()
416     {
417         return request.getResponseContentType();
418     }
419 
420     /**
421      * @see javax.portlet.PortletRequest#getResponseContentTypes()
422      */
423     public Enumeration getResponseContentTypes()
424     {
425         return request.getResponseContentTypes();
426     }
427 
428     /**
429      * @see javax.portlet.PortletRequest#getScheme()
430      */
431     public String getScheme()
432     {
433         return request.getScheme();
434     }
435 
436     /**
437      * @see javax.portlet.PortletRequest#getServerName()
438      */
439     public String getServerName()
440     {
441         return request.getServerName();
442     }
443 
444     /**
445      * @see javax.portlet.PortletRequest#getServerPort()
446      */
447     public int getServerPort()
448     {
449         return request.getServerPort();
450     }
451 
452     /**
453      * @see javax.portlet.PortletRequest#getUserPrincipal()
454      */
455     public Principal getUserPrincipal()
456     {
457         return request.getUserPrincipal();
458     }
459 
460     /**
461      * @see javax.portlet.PortletRequest#getWindowState()
462      */
463     public WindowState getWindowState()
464     {
465         return request.getWindowState();
466     }
467 
468     /**
469      * @see javax.portlet.PortletRequest#isPortletModeAllowed(javax.portlet.PortletMode)
470      */
471     public boolean isPortletModeAllowed(final PortletMode arg0)
472     {
473         return request.isPortletModeAllowed(arg0);
474     }
475 
476     /**
477      * @see javax.portlet.PortletRequest#isRequestedSessionIdValid()
478      */
479     public boolean isRequestedSessionIdValid()
480     {
481         return request.isRequestedSessionIdValid();
482     }
483 
484     /**
485      * @see javax.portlet.PortletRequest#isSecure()
486      */
487     public boolean isSecure()
488     {
489         return request.isSecure();
490     }
491 
492     /**
493      * @see javax.portlet.PortletRequest#isUserInRole(String)
494      */
495     public boolean isUserInRole(final String arg0)
496     {
497         return request.isUserInRole(arg0);
498     }
499 
500     /**
501      * @see javax.portlet.PortletRequest#isWindowStateAllowed(javax.portlet.WindowState)
502      */
503     public boolean isWindowStateAllowed(final WindowState arg0)
504     {
505         return request.isWindowStateAllowed(arg0);
506     }
507 
508     /**
509      * @see javax.portlet.PortletRequest#removeAttribute(String)
510      */
511     public void removeAttribute(final String arg0)
512     {
513         request.removeAttribute(arg0);
514     }
515 
516     /**
517      * @see javax.portlet.PortletRequest#setAttribute(String,
518      *      Object)
519      */
520     public void setAttribute(final String arg0, final Object arg1)
521     {
522         request.setAttribute(arg0, arg1);
523     }
524 
525     /**
526      * @see javax.portlet.ActionRequest#getCharacterEncoding()
527      */
528     public String getCharacterEncoding()
529     {
530         return request.getCharacterEncoding();
531     }
532 
533     /**
534      * @see javax.portlet.ActionRequest#getContentLength()
535      */
536     public int getContentLength()
537     {
538         return request.getContentLength();
539     }
540 
541     /**
542      * @see javax.portlet.ActionRequest#getContentType()
543      */
544     public String getContentType()
545     {
546         return request.getContentType();
547     }
548 
549     /**
550      * @see javax.portlet.ActionRequest#getPortletInputStream()
551      */
552     public InputStream getPortletInputStream() throws IOException
553     {
554         return request.getPortletInputStream();
555     }
556 
557     /**
558      * @see javax.portlet.ActionRequest#getReader()
559      */
560     public BufferedReader getReader() throws UnsupportedEncodingException, IOException
561     {
562         return request.getReader();
563     }
564 
565     /**
566      * @see javax.portlet.ActionRequest#setCharacterEncoding(String)
567      */
568     public void setCharacterEncoding(final String arg0) throws UnsupportedEncodingException
569     {
570         request.setCharacterEncoding(arg0);
571     }
572 }