Index: .classpath =================================================================== RCS file: /home/projects/groovy/scm/groovy/groovy-core/.classpath,v retrieving revision 1.51 diff -u -r1.51 .classpath --- .classpath 10 Jun 2005 13:42:21 -0000 1.51 +++ .classpath 21 Jun 2005 14:59:44 -0000 @@ -17,6 +17,7 @@ + Index: project.xml =================================================================== RCS file: /home/projects/groovy/scm/groovy/groovy-core/project.xml,v retrieving revision 1.146 diff -u -r1.146 project.xml --- project.xml 15 Jun 2005 11:30:55 -0000 1.146 +++ project.xml 21 Jun 2005 14:59:45 -0000 @@ -589,6 +589,12 @@ servletapi 2.3 + + commons-fileupload + commons-fileupload + 1.0 + http://jakarta.apache.org/commons/fileupload + Index: src/main/groovy/servlet/ServletBinding.java =================================================================== RCS file: /home/projects/groovy/scm/groovy/groovy-core/src/main/groovy/servlet/ServletBinding.java,v retrieving revision 1.6 diff -u -r1.6 ServletBinding.java --- src/main/groovy/servlet/ServletBinding.java 18 Jun 2005 07:53:58 -0000 1.6 +++ src/main/groovy/servlet/ServletBinding.java 21 Jun 2005 14:59:45 -0000 @@ -51,12 +51,18 @@ import java.io.IOException; import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.fileupload.DiskFileUpload; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUpload; +import org.apache.commons.fileupload.FileUploadException; + /** * Servlet-specific binding extension to lazy load the writer or the output * stream from the response. @@ -71,6 +77,7 @@ *
  • "session" : convenient for request.getSession(false) - can be null!
  • *
  • "params" : map of all form parameters - can be empty
  • *
  • "headers" : map of all request header fields
  • + *
  • "uploads" : map of all uploaded files
  • * * *

    @@ -84,6 +91,7 @@ * * @author Guillaume Laforge * @author Christian Stein + * @author Tomasz Blachowicz */ public class ServletBinding extends Binding { @@ -138,6 +146,40 @@ } } binding.setVariable("params", params); + + /* + * If request is multipart its content is parsed. + * For each decoded part we check its type. + * - When it is an regular form field we treat it as + * request parameter and put in "params" implicit object. + * (NOTE: when request is multipart values of parameters + * aren't accessible via HttpServletRequest.getParameter* + * methods!) + * - Otherwise we create new object of uploaded file and + * put it in "uploads" implicit object. + */ + Map uploads = new HashMap(); + if(FileUpload.isMultipartContent(request)) { + DiskFileUpload parser = new DiskFileUpload(); + List /* FileItem */ items; + try { + items = parser.parseRequest(request); + } catch (FileUploadException e) { + //Ooops! Something gone bad while parsing request. + throw new RuntimeException(e); + } + for(int i = 0, n = items.size(); i < n; i++) { //iterate over decoded parts + FileItem item = (FileItem) items.get(i); + String itemName = item.getFieldName(); + if(item.isFormField()) { //is regular form field + params.put(itemName, item.getString()); + } else { //is uploaded file + UploadedFile uploadedFile = new UploadedFile(item); + uploads.put(itemName, uploadedFile); + } + } + } + binding.setVariable("uploads", uploads); /* * Bind request header key-value hash map. Index: src/main/groovy/servlet/UploadedFile.java =================================================================== RCS file: src/main/groovy/servlet/UploadedFile.java diff -N src/main/groovy/servlet/UploadedFile.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/main/groovy/servlet/UploadedFile.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,118 @@ +/* +$Id$ + +Copyright 2005 (C) Guillaume Laforge. All Rights Reserved. + +Redistribution and use of this software and associated documentation +("Software"), with or without modification, are permitted provided +that the following conditions are met: + +1. Redistributions of source code must retain copyright + statements and notices. Redistributions must also contain a + copy of this document. + +2. Redistributions in binary form must reproduce the + above copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +3. The name "groovy" must not be used to endorse or promote + products derived from this Software without prior written + permission of The Codehaus. For written permission, + please contact info@codehaus.org. + +4. Products derived from this Software may not be called "groovy" + nor may "groovy" appear in their names without prior written + permission of The Codehaus. "groovy" is a registered + trademark of The Codehaus. + +5. Due credit should be given to The Codehaus - + http://groovy.codehaus.org/ + +THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +package groovy.servlet; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; + +import org.apache.commons.fileupload.FileItem; + +/** + * Object of this class are accessible by "uploads" impicit object accross Groovlets. + * It wraps Jakarta Commons FileUpload interface of uploaded disk file. + * + * @author Tomasz Blachowicz + */ +public class UploadedFile implements Serializable { + + /** + * Wrapped uploaded file + */ + private final FileItem fileItem; + + /** + * Creates new instance of uploaded file + * + * @param fileItem uploaded file to wrap + */ + public UploadedFile(FileItem fileItem) { + this.fileItem = fileItem; + } + + /** + * @return Name of uploaded file, as provided by browser + */ + public String getName() { + return fileItem.getName(); + } + + /** + * @return Size of uploaded file + */ + public long getSize() { + return fileItem.getSize(); + } + + /** + * @return Content type of uploaded file. + * Type should by MIME compilant. + */ + public String getContentType() { + return fileItem.getContentType(); + } + + /** + * @return Stream from uploaded file. When IO problem + * occur we re-throw RTE. + */ + public InputStream getInputStream() { + try { + return fileItem.getInputStream(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * @return Full content of uploaded file. Be careful + * invoking this method, content of file may be very big. + */ + public byte[] getContent() { + return fileItem.get(); + } + +}