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