View Javadoc

1   package com.imcode.util;
2   
3   import org.apache.commons.collections.MultiHashMap;
4   import org.apache.commons.collections.MultiMap;
5   import org.apache.commons.collections.iterators.IteratorEnumeration;
6   import org.apache.commons.fileupload.*;
7   import org.apache.commons.lang.UnhandledException;
8   import org.apache.oro.text.perl.Perl5Util;
9   
10  import javax.servlet.http.HttpServletRequest;
11  import javax.servlet.http.HttpServletRequestWrapper;
12  import javax.activation.DataSource;
13  import java.io.*;
14  import java.util.*;
15  
16  /***
17   * Extends HttpServletRequest for RFC 1867 form based file upload support from Jakarta Commons-FileUpload
18   */
19  public class MultipartHttpServletRequest extends HttpServletRequestWrapper {
20      static final String CHARSET_ISO_8859_1 = "ISO-8859-1";
21  
22      private MultiMap fileItemMap;
23  
24      public MultipartHttpServletRequest( HttpServletRequest request ) throws IOException {
25          this(request,-1) ;
26      }
27  
28      /***
29          Constructor used to specify a size limit for uploads.
30  
31          @param sizeLimit The maximum size for an upload, in bytes.
32       **/
33      public MultipartHttpServletRequest( HttpServletRequest request, long sizeLimit ) throws IOException {
34          super( request );
35          if ( FileUploadBase.isMultipartContent( request ) ) {
36              FileUpload fileUpload = new FileUpload( new DefaultFileItemFactory() );
37              fileUpload.setSizeMax( sizeLimit );
38              List fileItems ;
39              try {
40                  fileItems = fileUpload.parseRequest( request );
41              } catch ( FileUploadException e ) {
42                  throw new IOException( e.getMessage() );
43              }
44              fileItemMap = new MultiHashMap();
45              for ( Iterator iterator = fileItems.iterator(); iterator.hasNext(); ) {
46                  FileItem fileItem = new BaseNameFileItem( (FileItem)iterator.next() );
47                  fileItemMap.put( fileItem.getFieldName(), fileItem );
48              }
49          }
50      }
51  
52      public String getParameter( String key ) {
53          String[] parameterValues = getParameterValues( key );
54          if ( null != parameterValues && parameterValues.length > 0 ) {
55              return parameterValues[0];
56          }
57          return null;
58      }
59  
60      public DataSourceFileItem getParameterFileItem( String key ) {
61          DataSourceFileItem[] parameterValues = getParameterFileItems( key );
62          if ( null != parameterValues && parameterValues.length > 0 ) {
63              return parameterValues[0];
64          }
65          return null;
66      }
67  
68      public DataSourceFileItem[] getParameterFileItems( String key ) {
69          if ( null == fileItemMap ) {
70              return null;
71          }
72          final Collection parameterFileItems = (Collection)fileItemMap.get( key );
73          if ( null == parameterFileItems ) {
74              return null;
75          }
76          return (DataSourceFileItem[])parameterFileItems.toArray( new DataSourceFileItem[parameterFileItems.size()] );
77      }
78  
79      public Map getParameterMap() {
80          Map map = super.getParameterMap() ;
81          if ( null != fileItemMap ) {
82              map = new HashMap( map );
83              Set fileItemKeys = fileItemMap.keySet();
84              for ( Iterator iterator = fileItemKeys.iterator(); iterator.hasNext(); ) {
85                  String key = (String)iterator.next();
86                  map.put( key, getParameterValues( key ) );
87              }
88          }
89          return map;
90      }
91  
92      public Enumeration getParameterNames() {
93          Enumeration superParameterNames = super.getParameterNames();
94          Set parameterNames = new HashSet();
95          while ( superParameterNames.hasMoreElements() ) {
96              parameterNames.add( superParameterNames.nextElement() );
97          }
98          if (null != fileItemMap) {
99              parameterNames.addAll( fileItemMap.keySet() );
100         }
101         return new IteratorEnumeration( parameterNames.iterator() );
102     }
103 
104     public String[] getParameterValues( String key ) {
105         if ( null != fileItemMap ) {
106             List parameterValues = new ArrayList();
107             Collection fileItems = (Collection)fileItemMap.get( key );
108             if ( null == fileItems ) {
109                 return null;
110             }
111             for ( Iterator iterator = fileItems.iterator(); iterator.hasNext(); ) {
112                 FileItem fileItem = (FileItem)iterator.next();
113                 String contentType = fileItem.getContentType();
114                 parameterValues.add( getStringFromBytesWithContentType( fileItem.get(), contentType ) );
115             }
116             return (String[])parameterValues.toArray( new String[parameterValues.size()] );
117         }
118         return super.getParameterValues( key );
119     }
120 
121     static String getStringFromBytesWithContentType( byte[] bytes, String contentType ) {
122         try {
123             return new String( bytes, getCharsetFromContentType(contentType) );
124         } catch ( UnsupportedEncodingException ignored ) {
125         }
126         try {
127             return new String( bytes, CHARSET_ISO_8859_1 );
128         } catch ( UnsupportedEncodingException never ) {
129             throw new UnhandledException(never);
130         }
131     }
132 
133     static String getCharsetFromContentType(String contentType) {
134         String charset = CHARSET_ISO_8859_1;
135         if ( null != contentType ) {
136             Perl5Util perl5Util = new Perl5Util();
137             if ( perl5Util.match( "///bcharset=\"?(//S+?)\"?(?:$|;|//s)/", contentType ) ) {
138                 charset = perl5Util.group( 1 );
139             }
140         }
141         return charset ;
142     }
143 
144     public interface DataSourceFileItem extends FileItem, DataSource {
145 
146     }
147 
148     private class BaseNameFileItem extends FileItemWrapper {
149 
150         private BaseNameFileItem( FileItem fileItem ) {
151             super( fileItem );
152         }
153 
154         public String getName() {
155             String filename = fileItem.getName();
156             if ( null != filename ) {
157                 filename = filename.substring( filename.lastIndexOf( '/' ) + 1 );
158                 filename = filename.substring( filename.lastIndexOf( '//' ) + 1 );
159             }
160             return filename;
161         }
162     }
163 
164     private class FileItemWrapper implements DataSourceFileItem {
165 
166         FileItem fileItem;
167 
168         private FileItemWrapper( FileItem fileItem ) {
169             this.fileItem = fileItem;
170         }
171 
172         public String getContentType() {
173             return fileItem.getContentType();
174         }
175 
176         public String getFieldName() {
177             return fileItem.getFieldName();
178         }
179 
180         public void setFieldName( String s ) {
181             fileItem.setFieldName( s );
182         }
183 
184         public InputStream getInputStream() throws IOException {
185             return fileItem.getInputStream();
186         }
187 
188         public String getName() {
189             return fileItem.getName();
190         }
191 
192         public OutputStream getOutputStream() throws IOException {
193             return fileItem.getOutputStream();
194         }
195 
196         public long getSize() {
197             return fileItem.getSize();
198         }
199 
200         public String getString() {
201             return fileItem.getString();
202         }
203 
204         public boolean isFormField() {
205             return fileItem.isFormField();
206         }
207 
208         public void setFormField( boolean b ) {
209             fileItem.setFormField( b );
210         }
211 
212         public boolean isInMemory() {
213             return fileItem.isInMemory();
214         }
215 
216         public byte[] get() {
217             return fileItem.get();
218         }
219 
220         public void delete() {
221             fileItem.delete();
222         }
223 
224         public String getString( String s ) throws UnsupportedEncodingException {
225             return fileItem.getString( s );
226         }
227 
228         public void write( File file ) throws Exception {
229             fileItem.write( file );
230         }
231     }
232 
233 }