Index: DefaultMultipartDecoder.java | |
=================================================================== | |
RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/multipart/DefaultMultipartDecoder.java,v | |
retrieving revision 1.1 | |
diff -c -r1.1 DefaultMultipartDecoder.java | |
*** DefaultMultipartDecoder.java 5 Mar 2003 22:59:49 -0000 1.1 | |
--- DefaultMultipartDecoder.java 21 Mar 2003 22:51:11 -0000 | |
*************** | |
*** 1,75 **** | |
! /* ==================================================================== | |
! * The Apache Software License, Version 1.1 | |
! * | |
! * Copyright (c) 2000-2003 The Apache Software Foundation. All rights | |
! * reserved. | |
! * | |
! * Redistribution and use in source and binary forms, with or without | |
! * modification, are permitted provided that the following conditions | |
! * are met: | |
! * | |
! * 1. Redistributions of source code must retain the above copyright | |
! * notice, this list of conditions and the following disclaimer. | |
! * | |
! * 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 end-user documentation included with the redistribution, | |
! * if any, must include the following acknowledgment: | |
! * "This product includes software developed by the | |
! * Apache Software Foundation (http://apache.org/)." | |
! * Alternately, this acknowledgment may appear in the software itself, | |
! * if and wherever such third-party acknowledgments normally appear. | |
! * | |
! * 4. The names "Apache" and "Apache Software Foundation", "Tapestry" | |
! * must not be used to endorse or promote products derived from this | |
! * software without prior written permission. For written | |
! * permission, please contact apache@apache.org. | |
! * | |
! * 5. Products derived from this software may not be called "Apache" | |
! * or "Tapestry", nor may "Apache" or "Tapestry" appear in their | |
! * name, without prior written permission of the Apache Software Foundation. | |
! * | |
! * THIS SOFTWARE IS PROVIDED ``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 TAPESTRY CONTRIBUTOR COMMUNITY | |
! * 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. | |
! * ==================================================================== | |
! * | |
! * This software consists of voluntary contributions made by many | |
! * individuals on behalf of the Apache Software Foundation. For more | |
! * information on the Apache Software Foundation, please see | |
! * <http://www.apache.org/>. | |
! * | |
*/ | |
- | |
package org.apache.tapestry.multipart; | |
- import java.io.ByteArrayOutputStream; | |
- import java.io.File; | |
- import java.io.IOException; | |
- import java.io.InputStream; | |
- import java.io.OutputStream; | |
import java.util.HashMap; | |
import java.util.Iterator; | |
import java.util.Map; | |
- | |
import javax.servlet.http.HttpServletRequest; | |
import org.apache.tapestry.ApplicationRuntimeException; | |
- import org.apache.tapestry.Tapestry; | |
import org.apache.tapestry.request.IUploadFile; | |
! import org.apache.tapestry.util.StringSplitter; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
--- 1,72 ---- | |
! /* | |
! * ==================================================================== | |
! * The Apache Software License, Version 1.1 | |
! * | |
! * Copyright (c) 2002 The Apache Software Foundation. All rights | |
! * reserved. | |
! * | |
! * Redistribution and use in source and binary forms, with or without | |
! * modification, are permitted provided that the following conditions | |
! * are met: | |
! * | |
! * 1. Redistributions of source code must retain the above copyright | |
! * notice, this list of conditions and the following disclaimer. | |
! * | |
! * 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 end-user documentation included with the redistribution, | |
! * if any, must include the following acknowledgment: | |
! * "This product includes software developed by the | |
! * Apache Software Foundation (http://www.apache.org/)." | |
! * Alternately, this acknowledgment may appear in the software itself, | |
! * if and wherever such third-party acknowledgments normally appear. | |
! * | |
! * 4. The names "Apache" and "Apache Software Foundation" and | |
! * "Apache Tapestry" must not be used to endorse or promote products | |
! * derived from this software without prior written permission. For | |
! * written permission, please contact apache@apache.org. | |
! * | |
! * 5. Products derived from this software may not be called "Apache", | |
! * "Apache Tapestry", nor may "Apache" appear in their name, without | |
! * prior written permission of the Apache Software Foundation. | |
! * | |
! * THIS SOFTWARE IS PROVIDED ``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 APACHE SOFTWARE FOUNDATION 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. | |
! * ==================================================================== | |
! * | |
! * This software consists of voluntary contributions made by many | |
! * individuals on behalf of the Apache Software Foundation. For more | |
! * information on the Apache Software Foundation, please see | |
! * <http://www.apache.org/>. | |
*/ | |
package org.apache.tapestry.multipart; | |
import java.util.HashMap; | |
import java.util.Iterator; | |
+ import java.util.List; | |
import java.util.Map; | |
import javax.servlet.http.HttpServletRequest; | |
import org.apache.tapestry.ApplicationRuntimeException; | |
import org.apache.tapestry.request.IUploadFile; | |
! | |
! import org.apache.commons.fileupload.FileItem; | |
! import org.apache.commons.fileupload.FileUpload; | |
! import org.apache.commons.fileupload.FileUploadException; | |
! | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
*************** | |
*** 78,475 **** | |
* file uploads and multi-valued parameters. After decoding, the class is used | |
* to access the parameter values. | |
* | |
! * <p>This implementation is partially based on the MultipartRequest from | |
! * <a href="http://sf.net/projects/jetty">Jetty</a> (which is LGPL), and | |
! * partly from research on the web, including a discussion of the | |
! * <a href="http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc1867.html">RFC</a>. | |
* | |
* <p>Supports single valued parameters, multi-valued parameters and individual | |
* file uploads. That is, for file uploads, each upload must be a unique parameter | |
! * (that is all the {@link org.apache.tapestry.form.Upload} component needs). | |
* | |
! * @author Howard Lewis Ship | |
! * @version $Id: DefaultMultipartDecoder.java,v 1.1 2003/03/05 22:59:49 hlship Exp $ | |
* @since 2.0.1 | |
* | |
**/ | |
! | |
! public class DefaultMultipartDecoder implements IMultipartDecoder | |
{ | |
! private static final Log LOG = LogFactory.getLog(DefaultMultipartDecoder.class); | |
! | |
! public static final String MULTIPART_FORM_DATA_CONTENT_TYPE = "multipart/form-data"; | |
! | |
! private static final String QUOTE = "\""; | |
! | |
! private Map partMap = new HashMap(); | |
! | |
! public static boolean isMultipartRequest(HttpServletRequest request) | |
! { | |
! String contentType = request.getContentType(); | |
! | |
! if (contentType == null) | |
! return false; | |
! | |
! return contentType.startsWith(MULTIPART_FORM_DATA_CONTENT_TYPE); | |
! } | |
! | |
! private void close(InputStream stream) | |
! { | |
! try | |
! { | |
! if (stream != null) | |
! stream.close(); | |
! } | |
! catch (IOException ex) | |
! { | |
! // Ignore. | |
! } | |
! } | |
! | |
! private static final String BOUNDARY = "boundary="; | |
! | |
! public void decode(HttpServletRequest request) | |
! { | |
! if (!isMultipartRequest(request)) | |
! throw new ApplicationRuntimeException( | |
! Tapestry.getString( | |
! "MultipartDecoder.wrong-content-type", | |
! request.getContentType())); | |
! | |
! String contentType = request.getContentType(); | |
! int pos = contentType.indexOf(BOUNDARY); | |
! | |
! String boundaryString = "--" + contentType.substring(pos + BOUNDARY.length()); | |
! byte[] boundary = (boundaryString + "--").getBytes(); | |
! | |
! LineInput input = null; | |
! | |
! try | |
! { | |
! input = new LineInput(request.getInputStream()); | |
! | |
! checkForInitialBoundary(input, boundaryString); | |
! | |
! boolean last = false; | |
! | |
! while (!last) | |
! { | |
! last = readNextPart(input, boundary); | |
! } | |
! } | |
! catch (IOException ex) | |
! { | |
! LOG.error( | |
! Tapestry.getString("MultipartDecoder.io-exception-reading-input", ex.getMessage()), | |
! ex); | |
! | |
! // Cleanup any partial upload files. | |
! | |
! cleanup(); | |
! | |
! throw new ApplicationRuntimeException(ex); | |
! } | |
! finally | |
! { | |
! // close(input); | |
! } | |
! | |
! } | |
! | |
! private void checkForInitialBoundary(LineInput input, String boundary) throws IOException | |
! { | |
! String line = input.readLine(); | |
! | |
! if (line != null && line.equals(boundary)) | |
! return; | |
! | |
! throw new ApplicationRuntimeException( | |
! Tapestry.getString("MultipartDecoder.missing-initial-boundary")); | |
! } | |
! | |
! private boolean readNextPart(LineInput input, byte[] boundary) throws IOException | |
! { | |
! String disposition = null; | |
! String contentType = null; | |
! | |
! // First read the various headers (before the content) | |
! | |
! while (true) | |
! { | |
! String line = input.readLine(); | |
! | |
! if (line == null || line.length() == 0) | |
! break; | |
! | |
! int colonx = line.indexOf(':'); | |
! | |
! if (colonx > 0) | |
! { | |
! String key = line.substring(0, colonx).toLowerCase(); | |
! | |
! if (key.equals("content-disposition")) | |
! { | |
! disposition = line.substring(colonx + 1).trim(); | |
! continue; | |
! } | |
! | |
! if (key.equals("content-type")) | |
! { | |
! contentType = line.substring(colonx + 1).trim(); | |
! continue; | |
! } | |
! } | |
! | |
! } | |
! | |
! if (disposition == null) | |
! throw new ApplicationRuntimeException( | |
! Tapestry.getString("MultipartDecoder.missing-content-disposition")); | |
! | |
! Map dispositionMap = explodeDisposition(disposition); | |
! String name = (String) dispositionMap.get("name"); | |
! | |
! if (Tapestry.isNull(name)) | |
! throw new ApplicationRuntimeException( | |
! Tapestry.getString("MultipartDecoder.invalid-content-disposition", disposition)); | |
! | |
! if (!dispositionMap.containsKey("filename")) | |
! return readValuePart(input, boundary, name); | |
! | |
! String fileName = (String) dispositionMap.get("filename"); | |
! | |
! return readFilePart(input, boundary, name, fileName, contentType); | |
! } | |
! | |
! private static StringSplitter splitter = new StringSplitter(';'); | |
! | |
! private Map explodeDisposition(String disposition) | |
! { | |
! Map result = new HashMap(); | |
! | |
! String[] elements = splitter.splitToArray(disposition); | |
! | |
! for (int i = 0; i < elements.length; i++) | |
! { | |
! String element = elements[i]; | |
! int x = element.indexOf('='); | |
! | |
! if (x < 0) | |
! continue; | |
! | |
! String key = element.substring(0, x).trim(); | |
! String rawValue = element.substring(x + 1); | |
! | |
! if (!(rawValue.startsWith(QUOTE) && rawValue.endsWith(QUOTE))) | |
! throw new ApplicationRuntimeException( | |
! Tapestry.getString( | |
! "MultipartDecoder.invalid-content-disposition", | |
! disposition)); | |
! | |
! result.put(key, rawValue.substring(1, rawValue.length() - 1)); | |
! | |
! } | |
! | |
! return result; | |
! } | |
! | |
! private boolean readFilePart( | |
! LineInput input, | |
! byte[] boundary, | |
! String name, | |
! String fileName, | |
! String contentType) | |
! throws IOException | |
! { | |
! UploadOutputStream uploadStream = new UploadOutputStream(); | |
! | |
! boolean last = readIntoStream(input, boundary, uploadStream); | |
! | |
! uploadStream.close(); | |
! | |
! File file = uploadStream.getContentFile(); | |
! | |
! UploadPart p; | |
! | |
! if (LOG.isDebugEnabled()) | |
! LOG.debug("Read file part '" + name + "'."); | |
! | |
! if (file != null) | |
! p = new UploadPart(fileName, contentType, file); | |
! else | |
! p = new UploadPart(fileName, contentType, uploadStream.getContent()); | |
! | |
! partMap.put(name, p); | |
! | |
! return last; | |
! } | |
! | |
! private boolean readValuePart(LineInput input, byte[] boundary, String name) throws IOException | |
! { | |
! ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
! | |
! boolean last = readIntoStream(input, boundary, baos); | |
! | |
! baos.close(); | |
! | |
! String value = baos.toString(); | |
! | |
! if (LOG.isDebugEnabled()) | |
! LOG.debug("Read value part '" + name + "' with value: " + value); | |
! | |
! ValuePart p = (ValuePart) partMap.get(name); | |
! | |
! if (p == null) | |
! { | |
! p = new ValuePart(value); | |
! partMap.put(name, p); | |
! } | |
! else | |
! p.add(value); | |
! | |
! return last; | |
! } | |
! | |
! private static final int CR = 13; | |
! private static final int LF = 10; | |
! private static final int SPECIAL = -2; | |
! | |
! /** | |
! * Copies the input stream into the output stream, stopping once the boundary is seen | |
! * (the boundary is not copied). Returns true when the input stream is exhausted, | |
! * false otherwise. | |
! * | |
! * This is an ugly cut and past of ugly code from Jetty. This really needs to be fixed! | |
! * | |
! **/ | |
! | |
! private boolean readIntoStream(LineInput input, byte[] boundary, OutputStream stream) | |
! throws IOException | |
! { | |
! boolean result = false; | |
! int c = 0; | |
! boolean cr = false; | |
! boolean lf = false; | |
! int _char = SPECIAL; | |
! boolean more = true; | |
! | |
! while (true) | |
! { | |
! int b = 0; | |
! | |
! while (more) | |
! { | |
! c = (_char != SPECIAL) ? _char : input.read(); | |
! | |
! if (c == -1) | |
! { | |
! more = false; | |
! continue; | |
! } | |
! | |
! _char = SPECIAL; | |
! | |
! // look for CR and/or LF | |
! if (c == CR || c == LF) | |
! { | |
! if (c == CR) | |
! _char = input.read(); | |
! break; | |
! } | |
! | |
! // look for boundary | |
! if (b >= 0 && b < boundary.length && c == boundary[b]) | |
! b++; | |
! else | |
! { | |
! // this is not a boundary | |
! if (cr) | |
! stream.write(CR); | |
! if (lf) | |
! stream.write(LF); | |
! cr = lf = false; | |
! | |
! if (b > 0) | |
! stream.write(boundary, 0, b); | |
! b = -1; | |
! | |
! stream.write(c); | |
! } | |
! } | |
! | |
! // check partial boundary | |
! if ((b > 0 && b < boundary.length - 2) || (b == boundary.length - 1)) | |
! { | |
! stream.write(boundary, 0, b); | |
! b = -1; | |
! } | |
! | |
! // boundary match | |
! if (b > 0 || c == -1) | |
! { | |
! if (b == boundary.length) | |
! result = true; | |
! | |
! if (_char == LF) | |
! _char = SPECIAL; | |
! | |
! break; | |
! } | |
! | |
! // handle CR LF | |
! if (cr) | |
! stream.write(CR); | |
! if (lf) | |
! stream.write(LF); | |
! | |
! cr = (c == CR); | |
! lf = (c == LF || _char == LF); | |
! | |
! if (_char == LF) | |
! _char = SPECIAL; | |
! } | |
! | |
! return result; | |
! } | |
/** | |
* Invokes {@link IPart#cleanup()} on each part. | |
* | |
**/ | |
- | |
public void cleanup() | |
{ | |
! Iterator i = partMap.values().iterator(); | |
while (i.hasNext()) | |
{ | |
IPart part = (IPart) i.next(); | |
part.cleanup(); | |
} | |
} | |
! public String getString(String name) | |
! { | |
! ValuePart p = (ValuePart) partMap.get(name); | |
! | |
! if (p == null) | |
! return null; | |
! | |
! return p.getValue(); | |
! } | |
! | |
! public String[] getStrings(String name) | |
! { | |
! ValuePart p = (ValuePart) partMap.get(name); | |
! | |
! if (p == null) | |
! return null; | |
! | |
! return p.getValues(); | |
! } | |
! | |
! public IUploadFile getUploadFile(String name) | |
! { | |
! return (UploadPart) partMap.get(name); | |
! } | |
! } | |
\ No newline at end of file | |
--- 75,266 ---- | |
* file uploads and multi-valued parameters. After decoding, the class is used | |
* to access the parameter values. | |
* | |
! * <p>This implementation is a thin wrapper around the Apache Jakarta | |
! * <a href="http://jakarta.apache.org/commons/fileupload/">FileUpload</a>. | |
* | |
* <p>Supports single valued parameters, multi-valued parameters and individual | |
* file uploads. That is, for file uploads, each upload must be a unique parameter | |
! * (that is all the {@link net.sf.tapestry.form.Upload} component needs). | |
* | |
! * @author Joe Panico | |
! * @version $Id: DefaultMultipartDecoder.java,v 1.1 2003/01/16 00:53:56 hlship Exp $ | |
* @since 2.0.1 | |
* | |
**/ | |
! public class DefaultMultipartDecoder | |
! extends Object | |
! implements IMultipartDecoder | |
{ | |
! public static final int DEFAULT_MAX_SIZE = 10000000; | |
! public static final int DEFAULT_THRESHOLD_SIZE = 1024; | |
! public static final String DEFAULT_REPOSITORY_PATH = System.getProperty("java.io.tmpdir"); | |
! | |
! private static final Log LOG = | |
! LogFactory.getLog(DefaultMultipartDecoder.class); | |
! | |
! private static int _maxSize = DEFAULT_MAX_SIZE; | |
! private static int _thresholdSize = DEFAULT_THRESHOLD_SIZE; | |
! private static String _repositoryPath = DEFAULT_REPOSITORY_PATH; | |
! | |
! private Map _partMap = new HashMap(); | |
! | |
! | |
! public static void setMaxSize(int maxSize) | |
! { | |
! _maxSize = maxSize; | |
! } | |
! | |
! public static int getMaxSize() | |
! { | |
! return _maxSize; | |
! } | |
! | |
! public static void setThresholdSize(int thresholdSize) | |
! { | |
! _thresholdSize = thresholdSize; | |
! } | |
! | |
! public static int getThresholdSize() | |
! { | |
! return _thresholdSize; | |
! } | |
! | |
! public static void setRepositoryPath(String repositoryPath) | |
! { | |
! _repositoryPath = repositoryPath; | |
! } | |
! | |
! public static String getRepositoryPath() | |
! { | |
! return _repositoryPath; | |
! } | |
! | |
! public static boolean isMultipartRequest(HttpServletRequest request) | |
! { | |
! return FileUpload.isMultipartContent(request); | |
! } | |
/** | |
* Invokes {@link IPart#cleanup()} on each part. | |
* | |
**/ | |
public void cleanup() | |
{ | |
! Iterator i = _partMap.values().iterator(); | |
while (i.hasNext()) | |
{ | |
IPart part = (IPart) i.next(); | |
part.cleanup(); | |
} | |
} | |
+ | |
+ /** | |
+ * @see net.sf.tapestry.multipart.IMultipartDecoder#decode(HttpServletRequest) | |
+ * | |
+ * @throws ApplicationRuntimeException if decode fails, for instance the | |
+ * request exceeds getMaxSize() | |
+ */ | |
+ public void decode(HttpServletRequest request) | |
+ { | |
+ if (request != null) | |
+ { | |
+ try | |
+ { | |
+ FileUpload aFileUpload = new FileUpload(); | |
+ | |
+ aFileUpload.setSizeMax(_maxSize); | |
+ aFileUpload.setSizeThreshold(_thresholdSize); | |
+ aFileUpload.setRepositoryPath(_repositoryPath); | |
+ | |
+ List someParts = aFileUpload.parseRequest(request); | |
+ | |
+ if ((someParts != null) && (someParts.size() > 0)) | |
+ { | |
+ Iterator aPartIterator = someParts.iterator(); | |
+ while (aPartIterator.hasNext()) | |
+ { | |
+ FileItem aPart = (FileItem) aPartIterator.next(); | |
+ if (aPart.isFormField()) | |
+ { | |
+ String aPartName = aPart.getFieldName(); | |
+ ValuePart aValuePart = (ValuePart) _partMap.get(aPartName); | |
+ if (aValuePart != null) | |
+ { | |
+ aValuePart.add(aPart.getString()); | |
+ } | |
+ else | |
+ { | |
+ aValuePart = new ValuePart(aPart.getString()); | |
+ _partMap.put(aPartName, aValuePart); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ UploadPart aFile = new UploadPart(aPart); | |
+ | |
+ _partMap.put(aPart.getFieldName(), aFile); | |
+ } | |
+ } | |
+ } | |
+ } | |
+ catch (FileUploadException e) | |
+ { | |
+ LOG.warn("decode", e); | |
+ throw new ApplicationRuntimeException(e); | |
+ } | |
+ } | |
+ | |
+ } | |
+ | |
+ /** | |
+ * @see net.sf.tapestry.multipart.IMultipartDecoder#getString(String) | |
+ */ | |
+ public String getString(String name) | |
+ { | |
+ String getString = null; | |
+ | |
+ if (name != null) | |
+ { | |
+ ValuePart aPart = (ValuePart) _partMap.get(name); | |
+ if (aPart != null) | |
+ { | |
+ getString = aPart.getValue(); | |
+ } | |
+ } | |
+ return getString; | |
+ } | |
+ | |
+ /** | |
+ * @see net.sf.tapestry.multipart.IMultipartDecoder#getStrings(String) | |
+ */ | |
+ public String[] getStrings(String name) | |
+ { | |
+ String[] getStrings = null; | |
+ | |
+ if (name != null) | |
+ { | |
+ ValuePart aPart = (ValuePart) _partMap.get(name); | |
+ if (aPart != null) | |
+ { | |
+ getStrings = aPart.getValues(); | |
+ } | |
+ } | |
+ return getStrings; | |
+ } | |
+ | |
+ /** | |
+ * @see net.sf.tapestry.multipart.IMultipartDecoder#getUploadFile(String) | |
+ */ | |
+ public IUploadFile getUploadFile(String name) | |
+ { | |
+ IUploadFile getUploadFile = null; | |
+ | |
+ if (name != null) | |
+ { | |
+ getUploadFile = (IUploadFile) _partMap.get(name); | |
+ } | |
+ return getUploadFile; | |
+ } | |
! } | |
Index: UploadPart.java | |
=================================================================== | |
RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/multipart/UploadPart.java,v | |
retrieving revision 1.1 | |
diff -c -r1.1 UploadPart.java | |
*** UploadPart.java 5 Mar 2003 22:59:49 -0000 1.1 | |
--- UploadPart.java 21 Mar 2003 22:51:11 -0000 | |
*************** | |
*** 1,193 **** | |
! /* ==================================================================== | |
! * The Apache Software License, Version 1.1 | |
! * | |
! * Copyright (c) 2000-2003 The Apache Software Foundation. All rights | |
! * reserved. | |
! * | |
! * Redistribution and use in source and binary forms, with or without | |
! * modification, are permitted provided that the following conditions | |
! * are met: | |
! * | |
! * 1. Redistributions of source code must retain the above copyright | |
! * notice, this list of conditions and the following disclaimer. | |
! * | |
! * 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 end-user documentation included with the redistribution, | |
! * if any, must include the following acknowledgment: | |
! * "This product includes software developed by the | |
! * Apache Software Foundation (http://apache.org/)." | |
! * Alternately, this acknowledgment may appear in the software itself, | |
! * if and wherever such third-party acknowledgments normally appear. | |
! * | |
! * 4. The names "Apache" and "Apache Software Foundation", "Tapestry" | |
! * must not be used to endorse or promote products derived from this | |
! * software without prior written permission. For written | |
! * permission, please contact apache@apache.org. | |
! * | |
! * 5. Products derived from this software may not be called "Apache" | |
! * or "Tapestry", nor may "Apache" or "Tapestry" appear in their | |
! * name, without prior written permission of the Apache Software Foundation. | |
! * | |
! * THIS SOFTWARE IS PROVIDED ``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 TAPESTRY CONTRIBUTOR COMMUNITY | |
! * 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. | |
! * ==================================================================== | |
! * | |
! * This software consists of voluntary contributions made by many | |
! * individuals on behalf of the Apache Software Foundation. For more | |
! * information on the Apache Software Foundation, please see | |
! * <http://www.apache.org/>. | |
! * | |
*/ | |
- | |
package org.apache.tapestry.multipart; | |
- import java.io.ByteArrayInputStream; | |
import java.io.File; | |
- import java.io.FileInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
- import org.apache.tapestry.ApplicationRuntimeException; | |
- import org.apache.tapestry.Tapestry; | |
- import org.apache.tapestry.request.IUploadFile; | |
/** | |
* Portion of a multi-part request representing an uploaded file. | |
* | |
! * @author Howard Lewis Ship | |
! * @version $Id: UploadPart.java,v 1.1 2003/03/05 22:59:49 hlship Exp $ | |
* @since 2.0.1 | |
* | |
**/ | |
! | |
! public class UploadPart implements IUploadFile, IPart | |
{ | |
! private static final Log LOG = LogFactory.getLog(UploadPart.class); | |
! private byte[] _content; | |
! private File _contentFile; | |
! private String _filePath; | |
! private String _contentType; | |
! | |
! public UploadPart(String filePath, String contentType, byte[] content) | |
! { | |
! _filePath = filePath; | |
! _contentType = contentType; | |
! _content = content; | |
! } | |
! | |
! public UploadPart(String filePath, String contentType, File contentFile) | |
! { | |
! _filePath = filePath; | |
! _contentType = contentType; | |
! _contentFile = contentFile; | |
! } | |
/** | |
* @since 2.0.4 | |
* | |
**/ | |
! | |
! public String getFilePath() | |
! { | |
! return _filePath; | |
! } | |
/** | |
! * Always returns false, at least so far. Future enhancements | |
! * may involve truncating the input if it exceeds a certain | |
! * size or upload time (such things may be used for denial | |
! * of service attacks). | |
! * | |
! **/ | |
! | |
! public boolean isTruncated() | |
! { | |
! return false; | |
! } | |
! | |
! public InputStream getStream() | |
! { | |
! if (_content != null) | |
! return new ByteArrayInputStream(_content); | |
! | |
! try | |
! { | |
! return new FileInputStream(_contentFile); | |
! } | |
! catch (IOException ex) | |
! { | |
! throw new ApplicationRuntimeException( | |
! Tapestry.getString( | |
! "UploadPart.unable-to-open-content-file", | |
! _filePath, | |
! _contentFile.getAbsolutePath()), | |
! ex); | |
! } | |
! } | |
! /** | |
! * Deletes the external content file, if one exists. | |
! * | |
! **/ | |
- public void cleanup() | |
- { | |
- if (_contentFile != null) | |
- { | |
- if (LOG.isDebugEnabled()) | |
- LOG.debug("Deleting upload file " + _contentFile + "."); | |
- | |
- boolean success = _contentFile.delete(); | |
- | |
- if (!success) | |
- LOG.warn( | |
- Tapestry.getString( | |
- "UploadPart.temporary-file-not-deleted", | |
- _contentFile.getAbsolutePath())); | |
- | |
- // In rare cases (when exceptions are thrown while the request | |
- // is decoded), cleanup() may be called multiple times. | |
- | |
- _contentFile = null; | |
- } | |
- | |
- } | |
- | |
- | |
/** | |
! * Leverages {@link File} to convert the full file path and extract | |
! * the name. | |
* | |
**/ | |
! | |
! public String getFileName() | |
! { | |
! File file = new File(_filePath); | |
! | |
! return file.getName(); | |
! } | |
! | |
! public String getContentType() | |
! { | |
! return _contentType; | |
! } | |
! } | |
\ No newline at end of file | |
--- 1,201 ---- | |
! /* | |
! * ==================================================================== | |
! * The Apache Software License, Version 1.1 | |
! * | |
! * Copyright (c) 2002 The Apache Software Foundation. All rights | |
! * reserved. | |
! * | |
! * Redistribution and use in source and binary forms, with or without | |
! * modification, are permitted provided that the following conditions | |
! * are met: | |
! * | |
! * 1. Redistributions of source code must retain the above copyright | |
! * notice, this list of conditions and the following disclaimer. | |
! * | |
! * 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 end-user documentation included with the redistribution, | |
! * if any, must include the following acknowledgment: | |
! * "This product includes software developed by the | |
! * Apache Software Foundation (http://www.apache.org/)." | |
! * Alternately, this acknowledgment may appear in the software itself, | |
! * if and wherever such third-party acknowledgments normally appear. | |
! * | |
! * 4. The names "Apache" and "Apache Software Foundation" and | |
! * "Apache Tapestry" must not be used to endorse or promote products | |
! * derived from this software without prior written permission. For | |
! * written permission, please contact apache@apache.org. | |
! * | |
! * 5. Products derived from this software may not be called "Apache", | |
! * "Apache Tapestry", nor may "Apache" appear in their name, without | |
! * prior written permission of the Apache Software Foundation. | |
! * | |
! * THIS SOFTWARE IS PROVIDED ``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 APACHE SOFTWARE FOUNDATION 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. | |
! * ==================================================================== | |
! * | |
! * This software consists of voluntary contributions made by many | |
! * individuals on behalf of the Apache Software Foundation. For more | |
! * information on the Apache Software Foundation, please see | |
! * <http://www.apache.org/>. | |
*/ | |
package org.apache.tapestry.multipart; | |
import java.io.File; | |
import java.io.IOException; | |
import java.io.InputStream; | |
+ import org.apache.tapestry.ApplicationRuntimeException; | |
+ import org.apache.tapestry.request.IUploadFile; | |
+ | |
+ import org.apache.commons.fileupload.DefaultFileItem; | |
+ import org.apache.commons.fileupload.FileItem; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
/** | |
* Portion of a multi-part request representing an uploaded file. | |
* | |
! * @author Joe Panico | |
! * @version $Id: UploadPart.java,v 1.10 2003/01/13 03:33:23 hlship Exp $ | |
* @since 2.0.1 | |
* | |
**/ | |
! public class UploadPart extends Object | |
! implements IUploadFile, IPart | |
{ | |
! private static final Log LOG = | |
! LogFactory.getLog(UploadPart.class); | |
! | |
! FileItem _fileItem; | |
! | |
! public UploadPart(FileItem fileItem) | |
! { | |
! if( fileItem != null) | |
! { | |
! _fileItem = fileItem; | |
! } | |
! else | |
! { | |
! String aMessage = "UploadPart(FileItem) does not accept null args"; | |
! throw new IllegalArgumentException( aMessage); | |
! } | |
! } | |
! | |
! public static UploadPart newInstance( | |
! String path, | |
! String name, | |
! String contentType, | |
! int requestSize, | |
! int threshold) | |
! { | |
! UploadPart newInstance = null; | |
! FileItem aFileItem = | |
! DefaultFileItem.newInstance( | |
! path, | |
! name, | |
! contentType, | |
! requestSize, | |
! threshold); | |
! | |
! if( aFileItem != null) | |
! { | |
! newInstance = new UploadPart( aFileItem); | |
! } | |
! return newInstance; | |
! } | |
! | |
! /** | |
! * @see net.sf.tapestry.IUploadFile#getContentType() | |
! */ | |
! public String getContentType() | |
! { | |
! return _fileItem.getContentType(); | |
! } | |
! /** | |
! * Leverages {@link File} to convert the full file path and extract | |
! * the name. | |
! * | |
! **/ | |
! public String getFileName() | |
! { | |
! File aFile = new File( this.getFilePath() ); | |
! | |
! return aFile.getName(); | |
! } | |
/** | |
* @since 2.0.4 | |
* | |
**/ | |
! public String getFilePath() | |
! { | |
! return _fileItem.getName(); | |
! } | |
/** | |
! * @see net.sf.tapestry.IUploadFile#getStream() | |
! */ | |
! public InputStream getStream() | |
! { | |
! InputStream getStream = null; | |
! | |
! try | |
! { | |
! getStream = _fileItem.getInputStream(); | |
! } | |
! catch (IOException e) | |
! { | |
! LOG.warn("getStream", e); | |
! | |
! throw new ApplicationRuntimeException( | |
! "Unable to open uploaded file", | |
! e); | |
! } | |
! | |
! return getStream; | |
! } | |
! /** | |
! * The current implementation does not truncate. Parts that are too | |
! * large cause a decode failure | |
! */ | |
! public boolean isTruncated() | |
! { | |
! return false; | |
! } | |
/** | |
! * Deletes the external content file, if one exists. | |
* | |
**/ | |
! public void cleanup() | |
! { | |
! _fileItem.delete(); | |
! // unfortunately FileItem.delete() does not signal success, so | |
! // we rely on a little more internal knowledge than is ideal | |
! File aStorageLocation = _fileItem.getStoreLocation(); | |
! if( (aStorageLocation != null) && (aStorageLocation.exists()) ) | |
! { | |
! String aMessage = "Unable to delete FileItem: " + _fileItem; | |
! | |
! throw new ApplicationRuntimeException(aMessage); | |
! } | |
! } | |
! } |