You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gc...@apache.org on 2012/05/18 17:47:27 UTC
svn commit: r1340139 - in /myfaces/trinidad/branches/1.2.12.7.0-branch:
trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/
trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/
trinidad-api/src/test/java/org/apache/myfaces/trinida...
Author: gcrawford
Date: Fri May 18 15:47:26 2012
New Revision: 1340139
URL: http://svn.apache.org/viewvc?rev=1340139&view=rev
Log:
TRINIDAD-2258 Add Chunked File Upload support to the Trinidad Upload Framwork
Thanks to Kentaro
Modified:
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UploadedFileProcessor.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/CompositeUploadedFileProcessorImpl.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/ErrorFile.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/FileUploadConfiguratorImpl.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFileProcessorImpl.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFiles.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java
myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java Fri May 18 15:47:26 2012
@@ -616,6 +616,10 @@ abstract public class RequestContext
public abstract Long getUploadedFileMaxDiskSpace();
+ public abstract Long getUploadedFileMaxFileSize();
+
+ public abstract Long getUploadedFileMaxChunkSize();
+
public abstract String getUploadedFileTempDir();
/**
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UploadedFileProcessor.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UploadedFileProcessor.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UploadedFileProcessor.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UploadedFileProcessor.java Fri May 18 15:47:26 2012
@@ -41,8 +41,12 @@ import org.apache.myfaces.trinidad.model
* <li>org.apache.myfaces.trinidad.UPLOAD_MAX_DISK_SPACE: the maximum amount of
* disk space that can be used in a single request to store
* uploaded files. (Default of 2000K)
+ * <li>org.apache.myfaces.trinidad.UPLOAD_MAX_FILE_SIZE: the maximum
+ * file size that can be uploaded. (Default of 2000K)
* <li>org.apache.myfaces.trinidad.UPLOAD_TEMP_DIR: the name of a directory
* to store temporary files. (Defaults to the user's temporary directory)
+ * <li>org.apache.myfaces.trinidad.UPLOAD_MAX_CHUNK_SIZE: the maximum
+ * chunk size that large files will be split into during upload. (Default of 2000M)
* </ul>
*
* @see org.apache.myfaces.trinidad.model.UploadedFile
@@ -80,6 +84,47 @@ public interface UploadedFileProcessor
public static final String TEMP_DIR_PARAM_NAME = "org.apache.myfaces.trinidad.UPLOAD_TEMP_DIR";
/**
+ * Initialization parameter for the default
+ * <code>UploadedFileProcessor</code> that configures the maximum
+ * file size that can be uploaded. The default is -1 (unlimited). Any requests that
+ * exceed this size will result in an EOFException being thrown
+ * on that request.
+ */
+ public static final String MAX_FILE_SIZE_PARAM_NAME = "org.apache.myfaces.trinidad.UPLOAD_MAX_FILE_SIZE";
+
+ /**
+ * Initialization parameter for the default
+ * <code>UploadedFileProcessor</code> that configures the maximum
+ * chunk size that large files will be split into during upload.
+ * The default is 2000M and is also the maximum allowed value.
+ */
+ public static final String MAX_CHUNK_SIZE_PARAM_NAME = "org.apache.myfaces.trinidad.UPLOAD_MAX_CHUNK_SIZE";
+
+ /**
+ * Initialization parameter default value of 100 kilobytes for the default
+ * <code>UploadedFileProcessor</code> parameter MAX_MEMORY_PARAM_NAME.
+ */
+ public static final long DEFAULT_MAX_MEMORY = 102400L;
+
+ /**
+ * Initialization parameter default value of 2000 kilobytes for the default
+ * <code>UploadedFileProcessor</code> parameter MAX_DISK_SPACE_PARAM_NAME.
+ */
+ public static final long DEFAULT_MAX_DISK_SPACE = 2048000L;
+
+ /**
+ * Initialization parameter default value of 2000 kilobytes for the default
+ * <code>UploadedFileProcessor</code> parameter MAX_FILE_SIZE_PARAM_NAME.
+ */
+ public static final long DEFAULT_MAX_FILE_SIZE = -1L;
+
+ /**
+ * Initialization parameter default value of 2000 megabytes for the default
+ * <code>UploadedFileProcessor</code> parameter MAX_CHUNK_PARAM_NAME.
+ */
+ public static final long DEFAULT_MAX_CHUNK_SIZE = 2000000000L;
+
+ /**
* Initialize the UploadedFileProcessor with access to the current
* web application context.
*
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java Fri May 18 15:47:26 2012
@@ -299,6 +299,28 @@ public class MockRequestContext extends
return _maxDiskSpace;
}
+ public void setUploadedFileMaxFileSize(Long maxFileSize)
+ {
+ _maxFileSize = maxFileSize;
+ }
+
+ @Override
+ public Long getUploadedFileMaxFileSize()
+ {
+ return _maxFileSize;
+ }
+
+ public void setUploadedFileMaxChunkSize(Long maxChunkSize)
+ {
+ _maxChunkSize = maxChunkSize;
+ }
+
+ @Override
+ public Long getUploadedFileMaxChunkSize()
+ {
+ return _maxChunkSize;
+ }
+
public void setUploadedFileTempDir(String tempDir)
{
_tempDir= tempDir;
@@ -459,5 +481,7 @@ public class MockRequestContext extends
private Locale _formattingLocale;
private Long _maxMemory;
private Long _maxDiskSpace;
+ private Long _maxFileSize;
+ private Long _maxChunkSize;
private String _tempDir;
}
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/CompositeUploadedFileProcessorImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/CompositeUploadedFileProcessorImpl.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/CompositeUploadedFileProcessorImpl.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/CompositeUploadedFileProcessorImpl.java Fri May 18 15:47:26 2012
@@ -110,7 +110,7 @@ public class CompositeUploadedFileProces
catch (IOException ioe)
{
_LOG.severe(ioe);
- original = new ErrorFile(ioe.getLocalizedMessage());
+ original = new ErrorFile(tempFile.getFilename(), ioe.getLocalizedMessage());
// The chain breaks if one of the chained processor throws an IOException, if the intent
// is to allow rest of the processors in chain to process, they could return custom
// UploadedFile instance with length -1 and opaqueData having the failure details.
@@ -228,12 +228,12 @@ public class CompositeUploadedFileProces
}
catch (NumberFormatException nfe)
{
- _maxMemory = _DEFAULT_MAX_MEMORY;
+ _maxMemory = DEFAULT_MAX_MEMORY;
}
}
else
{
- _maxMemory = _DEFAULT_MAX_MEMORY;
+ _maxMemory = DEFAULT_MAX_MEMORY;
}
}
@@ -248,12 +248,12 @@ public class CompositeUploadedFileProces
}
catch (NumberFormatException nfe)
{
- _maxDiskSpace = _DEFAULT_MAX_DISK_SPACE;
+ _maxDiskSpace = DEFAULT_MAX_DISK_SPACE;
}
}
else
{
- _maxDiskSpace = _DEFAULT_MAX_DISK_SPACE;
+ _maxDiskSpace = DEFAULT_MAX_DISK_SPACE;
}
}
@@ -270,6 +270,26 @@ public class CompositeUploadedFileProces
_tempDir = tempDirFile.getAbsolutePath();
}
}
+
+ if (_maxFileSize == -1)
+ {
+ String maxFileSize = info.initParams.get(MAX_FILE_SIZE_PARAM_NAME);
+ if (maxFileSize != null)
+ {
+ try
+ {
+ _maxFileSize = Long.parseLong(maxFileSize);
+ }
+ catch (NumberFormatException nfe)
+ {
+ _maxFileSize = DEFAULT_MAX_FILE_SIZE;
+ }
+ }
+ else
+ {
+ _maxFileSize = DEFAULT_MAX_FILE_SIZE;
+ }
+ }
}
private UploadedFile _processFile(
@@ -287,7 +307,8 @@ public class CompositeUploadedFileProces
Long maxMemory = (Long)requestMap.get(MAX_MEMORY_PARAM_NAME);
Long maxDiskSpace = (Long)requestMap.get(MAX_DISK_SPACE_PARAM_NAME);
String tempDir = (String)requestMap.get(TEMP_DIR_PARAM_NAME);
-
+ Long maxFileSizeSpace = (Long)requestMap.get(MAX_FILE_SIZE_PARAM_NAME);
+
if (maxMemory != null)
{
_maxMemory = maxMemory;
@@ -301,9 +322,19 @@ public class CompositeUploadedFileProces
if (tempDir != null)
_tempDir = tempDir;
+ if (maxFileSizeSpace != null)
+ {
+ _maxFileSize = maxFileSizeSpace;
+ }
+
if(contentLength>_maxDiskSpace)
{
- return new ErrorFile(_LOG.getMessage("UPLOADED_FILE_LARGE"));
+ return new ErrorFile(tempFile.getFilename(), _LOG.getMessage("UPLOADED_FILE_LARGE"));
+ }
+ // If the file is too large throw error
+ if(_maxFileSize > 0 && contentLength>_maxFileSize)
+ {
+ return new ErrorFile(tempFile.getFilename(), _LOG.getMessage("UPLOADED_FILE_LARGE"));
}
// Process one new file, loading only as much as can fit
// in the remaining memory and disk space.
@@ -318,7 +349,7 @@ public class CompositeUploadedFileProces
catch(IOException ioe)
{
_LOG.severe(ioe);
- return new ErrorFile(ioe.getLocalizedMessage());
+ return new ErrorFile(tempFile.getFilename(), ioe.getLocalizedMessage());
}
// Keep a tally of how much we've stored in memory and on disk.
@@ -448,11 +479,9 @@ public class CompositeUploadedFileProces
private long _maxMemory = -1;
private long _maxDiskSpace = -1;
+ private long _maxFileSize = -1;
private String _tempDir = null;
- private static final long _DEFAULT_MAX_MEMORY = 102400;
- private static final long _DEFAULT_MAX_DISK_SPACE = 2048000;
-
private static final String _REQUEST_INFO_KEY = CompositeUploadedFileProcessorImpl.class.getName()+
".UploadedFilesInfo";
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/ErrorFile.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/ErrorFile.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/ErrorFile.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/ErrorFile.java Fri May 18 15:47:26 2012
@@ -32,6 +32,12 @@ public class ErrorFile implements Upload
_errorMessage = errorMessage;
}
+ public ErrorFile(String filename, String errorMessage)
+ {
+ _filename = filename;
+ _errorMessage = errorMessage;
+ }
+
public void dispose()
{
}
@@ -43,7 +49,7 @@ public class ErrorFile implements Upload
public String getFilename()
{
- return null;
+ return _filename;
}
public InputStream getInputStream() throws IOException
@@ -62,6 +68,7 @@ public class ErrorFile implements Upload
}
private String _errorMessage = null;
+ private String _filename = null;
private static final long serialVersionUID = 2L;
-}
\ No newline at end of file
+}
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/FileUploadConfiguratorImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/FileUploadConfiguratorImpl.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/FileUploadConfiguratorImpl.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/FileUploadConfiguratorImpl.java Fri May 18 15:47:26 2012
@@ -19,12 +19,21 @@
package org.apache.myfaces.trinidadinternal.config.upload;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.SequenceInputStream;
+
import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import javax.faces.context.ExternalContext;
@@ -121,7 +130,7 @@ public class FileUploadConfiguratorImpl
final HashMap<String, String[]> parameters = new HashMap<String, String[]>();
MultipartFormItem item;
- final UploadedFiles files = new UploadedFiles(externalContext);
+ UploadedFiles files = new UploadedFiles(externalContext);
while ((item = mfh.getNextPart()) != null)
{
final String name = item.getName();
@@ -144,12 +153,74 @@ public class FileUploadConfiguratorImpl
parameters.put(name, newArray);
}
}
- // Upload a file
else if (item.getFilename().length() > 0)
{
+ // Upload a file
_doUploadFile(RequestContext.getCurrentInstance(), externalContext, files, item);
}
}
+ if (parameters.containsKey(_MULTIPLE_UPLOAD_PARAM))
+ {
+ String uploadType = parameters.get(_MULTIPLE_UPLOAD_PARAM)[0];
+ if (uploadType != null)
+ {
+ UploadedFiles sessionFiles = UploadedFiles.getSessionUploadedFiles(externalContext);
+ if (uploadType.equals("multipleAdd"))
+ {
+ Map<String, List<UploadedFile>> uploadedMapFile = files.getUploadedFileMap();
+ Iterator iterator = uploadedMapFile.keySet().iterator();
+ while (iterator.hasNext())
+ {
+ String name = (String) iterator.next();
+ List<UploadedFile> fileList = uploadedMapFile.get(name);
+ for (UploadedFile file: fileList)
+ {
+ sessionFiles.__put(name, file);
+ }
+ }
+ uploadedMapFile.clear();
+ }
+ else if (uploadType.equals("multipleDelete"))
+ {
+ String itemName = parameters.get("itemName")[0];
+ String fileName = parameters.get("fileName")[0];
+ List<UploadedFile> uploadedFiles = sessionFiles.getUploadedFileList(itemName);
+ if (uploadedFiles != null)
+ {
+ for (UploadedFile uploadedFile: uploadedFiles)
+ {
+ if (uploadedFile.getFilename().equals(fileName))
+ {
+ uploadedFiles.remove(uploadedFile);
+ break;
+ }
+ }
+ }
+ }
+ else if (uploadType.equals("multipleAddChunk"))
+ {
+ String itemName = parameters.get("itemName")[0];
+ String fileName = externalContext.getRequestHeaderMap().get(_MULTIPLE_UPLOAD_CHUNK_FILENAME_PARAM);
+ Long chunkNum = Long.parseLong(externalContext.getRequestHeaderMap().get(_MULTIPLE_UPLOAD_CHUNK_NUM_PARAM));
+ Long chunkCount = Long.parseLong(externalContext.getRequestHeaderMap().get(_MULTIPLE_UPLOAD_CHUNK_COUNT_PARAM));
+ UploadedFile file = files.getUploadedFile(itemName);
+ List<UploadedFile> chunkList = (List<UploadedFile>) externalContext.getSessionMap().get(_UPLOADED_CHUNK_FILES_LIST_KEY);
+ if (chunkList == null)
+ {
+ chunkList = new ArrayList<UploadedFile>();
+ externalContext.getSessionMap().put(_UPLOADED_CHUNK_FILES_LIST_KEY, chunkList);
+ }
+ chunkList.add(file);
+ if (chunkNum == chunkCount - 1)
+ {
+ UploadedFile combinedFile = new ChunkedUploadedFile(fileName, file.getContentType(), chunkList);
+ sessionFiles.__put(itemName, combinedFile);
+ externalContext.getSessionMap().remove(_UPLOADED_CHUNK_FILES_LIST_KEY);
+ }
+ files.getUploadedFileMap().clear();
+ }
+ }
+ }
externalContext.getRequestMap().put(_PARAMS, parameters);
}
catch (Throwable t)
@@ -210,14 +281,27 @@ public class FileUploadConfiguratorImpl
final UploadedFiles files,
final MultipartFormItem item) throws IOException
{
- final UploadedFile temp = new TempUploadedFile(item);
+ String filename = item.getFilename();
+ String chunkFilename = externalContext.getRequestHeaderMap().get(_MULTIPLE_UPLOAD_CHUNK_FILENAME_PARAM);
+ if (chunkFilename != null)
+ {
+ // We store the filename in a special header when sending chunked data. The reason is that
+ // browsers do not have an API for setting the filename on Blob objects. Also, append the chunk num
+ // so it's easier to keep track of.
+ String chunkNum = externalContext.getRequestHeaderMap().get(_MULTIPLE_UPLOAD_CHUNK_NUM_PARAM);
+ chunkFilename = chunkFilename + ".part" + chunkNum;
+ filename = chunkFilename;
+ }
+ final UploadedFile temp = new TempUploadedFile(filename, item);
Map<String, Object> sessionMap = externalContext.getSessionMap();
Map<String, Object> requestMap = externalContext.getRequestMap();
_copyParamsFromSessionToRequestMap(sessionMap, requestMap,
UploadedFileProcessor.MAX_MEMORY_PARAM_NAME,
UploadedFileProcessor.MAX_DISK_SPACE_PARAM_NAME,
- UploadedFileProcessor.TEMP_DIR_PARAM_NAME);
+ UploadedFileProcessor.TEMP_DIR_PARAM_NAME,
+ UploadedFileProcessor.MAX_FILE_SIZE_PARAM_NAME,
+ UploadedFileProcessor.MAX_CHUNK_SIZE_PARAM_NAME);
final UploadedFile file =
context.getUploadedFileProcessor().processFile(externalContext.getRequest(), temp);
@@ -320,15 +404,16 @@ public class FileUploadConfiguratorImpl
static private class TempUploadedFile implements UploadedFile
{
- public TempUploadedFile(MultipartFormItem item)
+ public TempUploadedFile(String filename, MultipartFormItem item)
{
+ _filename = filename;
_item = item;
assert(item.getValue() == null);
}
public String getFilename()
{
- return _item.getFilename();
+ return _filename != null ? _filename : _item.getFilename();
}
public String getContentType()
@@ -358,11 +443,92 @@ public class FileUploadConfiguratorImpl
}
private MultipartFormItem _item;
+ private String _filename = null;
+ }
+ static private class ChunkedUploadedFile implements UploadedFile
+ {
+ private List<UploadedFile> _uploadedFileChunkList = null;
+ private String _filename = null;
+ private String _contentType = null;
+
+ public ChunkedUploadedFile(String filename, String contentType, List<UploadedFile> uploadedFileChunkList)
+ {
+ _filename = filename;
+ _contentType = contentType;
+ _uploadedFileChunkList = uploadedFileChunkList;
+ }
+
+ public String getFilename()
+ {
+ return _filename;
+ }
+
+ public String getContentType()
+ {
+ return _contentType;
+ }
+
+ public long getLength()
+ {
+ Long totalLength = 0L;
+ for (UploadedFile file : _uploadedFileChunkList)
+ {
+ if (file.getLength() == -1L)
+ {
+ // there was an error so return -1
+ return -1L;
+ }
+ totalLength = totalLength + file.getLength();
+ }
+ return totalLength;
+ }
+
+ public Object getOpaqueData()
+ {
+ for (UploadedFile file : _uploadedFileChunkList)
+ {
+ if (file.getLength() == -1L)
+ {
+ // there was an error so return the data
+ return file.getOpaqueData();
+ }
+ }
+ return null;
+ }
+
+ public InputStream getInputStream() throws IOException
+ {
+ List<InputStream> inputSteamList = new ArrayList<InputStream>(_uploadedFileChunkList.size());
+ for (UploadedFile uploadedFileChunk : _uploadedFileChunkList)
+ inputSteamList.add(uploadedFileChunk.getInputStream());
+
+ return new SequenceInputStream(Collections.enumeration(inputSteamList));
+ }
+
+ public void dispose()
+ {
+ for (UploadedFile uploadedFileChunk : _uploadedFileChunkList)
+ {
+ try
+ {
+ uploadedFileChunk.dispose();
+ }
+ catch (Exception e)
+ {
+ // Just keep trying to dispose of the rest of the chunks
+ }
+ }
+ }
}
static private final String _APPLIED = FileUploadConfiguratorImpl.class.getName()+".APPLIED";
static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(FileUploadConfiguratorImpl.class);
static private final String _PARAMS = FileUploadConfiguratorImpl.class.getName()+".PARAMS";
static private final boolean _ENHANCED_PORTLET_SUPPORTED = ExternalContextUtils.isRequestTypeSupported(RequestType.RESOURCE);
+ static private final String _MULTIPLE_UPLOAD_PARAM = "org.apache.myfaces.trinidad.UploadedFiles";
+ static private final String _MULTIPLE_UPLOAD_CHUNK_NUM_PARAM = "X-Trinidad-chunkNum";
+ static private final String _MULTIPLE_UPLOAD_CHUNK_COUNT_PARAM = "X-Trinidad-chunkCount";
+ static private final String _MULTIPLE_UPLOAD_CHUNK_FILENAME_PARAM = "X-Trinidad-chunkFilename";
+ static private final String _UPLOADED_CHUNK_FILES_LIST_KEY = "org.apache.myfaces.trinidadinternal.webapp.UploadedFiles.ChunkList";
private long _maxAllowedBytes = 1L << 27;
}
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFileProcessorImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFileProcessorImpl.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFileProcessorImpl.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFileProcessorImpl.java Fri May 18 15:47:26 2012
@@ -78,12 +78,12 @@ public class UploadedFileProcessorImpl i
}
catch (NumberFormatException nfe)
{
- _maxMemory = _DEFAULT_MAX_MEMORY;
+ _maxMemory = DEFAULT_MAX_MEMORY;
}
}
else
{
- _maxMemory = _DEFAULT_MAX_MEMORY;
+ _maxMemory = DEFAULT_MAX_MEMORY;
}
}
@@ -98,12 +98,12 @@ public class UploadedFileProcessorImpl i
}
catch (NumberFormatException nfe)
{
- _maxDiskSpace = _DEFAULT_MAX_DISK_SPACE;
+ _maxDiskSpace = DEFAULT_MAX_DISK_SPACE;
}
}
else
{
- _maxDiskSpace = _DEFAULT_MAX_DISK_SPACE;
+ _maxDiskSpace = DEFAULT_MAX_DISK_SPACE;
}
}
@@ -120,6 +120,26 @@ public class UploadedFileProcessorImpl i
_tempDir = tempDirFile.getAbsolutePath();
}
}
+
+ if (_maxFileSize == -1)
+ {
+ String maxFileSize = info.initParams.get(MAX_FILE_SIZE_PARAM_NAME);
+ if (maxFileSize != null)
+ {
+ try
+ {
+ _maxFileSize = Long.parseLong(maxFileSize);
+ }
+ catch (NumberFormatException nfe)
+ {
+ _maxFileSize = DEFAULT_MAX_FILE_SIZE;
+ }
+ }
+ else
+ {
+ _maxFileSize = DEFAULT_MAX_FILE_SIZE;
+ }
+ }
}
public UploadedFile processFile(
@@ -153,7 +173,12 @@ public class UploadedFileProcessorImpl i
if(contentLength>_maxDiskSpace)
{
- return new ErrorFile(_LOG.getMessage("UPLOADED_FILE_LARGE"));
+ return new ErrorFile(tempFile.getFilename(), _LOG.getMessage("UPLOADED_FILE_LARGE"));
+ }
+ // If the file is too large throw error
+ if(_maxFileSize > 0 && contentLength>_maxFileSize)
+ {
+ return new ErrorFile(tempFile.getFilename(), _LOG.getMessage("UPLOADED_FILE_LARGE"));
}
// Process one new file, loading only as much as can fit
// in the remaining memory and disk space.
@@ -168,7 +193,7 @@ public class UploadedFileProcessorImpl i
catch(IOException ioe)
{
_LOG.severe(ioe);
- return new ErrorFile(ioe.getLocalizedMessage());
+ return new ErrorFile(tempFile.getFilename(), ioe.getLocalizedMessage());
}
// Keep a tally of how much we've stored in memory and on disk.
@@ -298,11 +323,9 @@ public class UploadedFileProcessorImpl i
private long _maxMemory = -1;
private long _maxDiskSpace = -1;
+ private long _maxFileSize = -1;
private String _tempDir = null;
- private static final long _DEFAULT_MAX_MEMORY = 102400;
- private static final long _DEFAULT_MAX_DISK_SPACE = 2048000;
-
private static final String _REQUEST_INFO_KEY = UploadedFileProcessorImpl.class.getName()+
".UploadedFilesInfo";
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFiles.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFiles.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFiles.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/upload/UploadedFiles.java Fri May 18 15:47:26 2012
@@ -18,24 +18,28 @@
*/
package org.apache.myfaces.trinidadinternal.config.upload;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
+
import javax.portlet.PortletRequest;
+
import javax.servlet.http.HttpServletRequest;
import org.apache.myfaces.trinidad.model.UploadedFile;
-
import org.apache.myfaces.trinidadinternal.share.util.CaboHttpUtils;
+
/**
* UploadedFiles defines the set of files that have been uploaded
* to the server.
@@ -52,17 +56,41 @@ final public class UploadedFiles
{
return getUploadedFiles(context.getExternalContext());
}
-
+
/**
* Returns the map of uploaded files for the current request.
*/
@SuppressWarnings("unchecked")
static public UploadedFiles getUploadedFiles(ExternalContext context)
{
- Map<String, Object> requestMap =
- context.getRequestMap();
+ Map<String, Object> requestMap = context.getRequestMap();
return (UploadedFiles) requestMap.get(_UPLOADED_FILES_KEY);
}
+
+ /**
+ * Returns the map of uploaded files for the current request.
+ */
+ @SuppressWarnings("unchecked")
+ static public UploadedFiles getSessionUploadedFiles(FacesContext context)
+ {
+ return getSessionUploadedFiles(context.getExternalContext());
+ }
+
+ /**
+ * Returns the map of uploaded files for the current session.
+ */
+ @SuppressWarnings("unchecked")
+ static public UploadedFiles getSessionUploadedFiles(ExternalContext context)
+ {
+ Map<String, Object> sessionMap = context.getSessionMap();
+ UploadedFiles files = (UploadedFiles) sessionMap.get(_UPLOADED_FILES_KEY);
+ if (files == null)
+ {
+ files = new UploadedFiles();
+ sessionMap.put(_UPLOADED_FILES_KEY, files);
+ }
+ return files;
+ }
/**
* Store the character encoding for the current request.
@@ -71,8 +99,7 @@ final public class UploadedFiles
ExternalContext externalContext,
String encoding)
{
- UploadedFiles files = (UploadedFiles)
- externalContext.getRequestMap().get(_UPLOADED_FILES_KEY);
+ UploadedFiles files = getUploadedFiles(externalContext);
_setCharacterEncoding(files, encoding);
}
@@ -93,7 +120,7 @@ final public class UploadedFiles
req.getAttribute(_UPLOADED_FILES_KEY);
_setCharacterEncoding(files, encoding);
}
-
+
static private void _setCharacterEncoding(UploadedFiles files, String encoding)
{
if(files != null)
@@ -109,13 +136,63 @@ final public class UploadedFiles
*/
public UploadedFile getUploadedFile(String name)
{
- UploadedFile file = _map.get(name);
- if (file == null)
+ List<UploadedFile> files = getUploadedFileList(name);
+ if (files == null || files.isEmpty())
return null;
- return new FixFilename(file, _characterEncoding);
+ for (UploadedFile file : files)
+ {
+ if (file != null)
+ {
+ return file;
+ }
+ }
+
+ return null;
}
+ /**
+ * Returns a list of uploaded files.
+ * @param name the name under which the files are stored. In HTML forms,
+ * this will be derived from the "name" set on the <input> tag.
+ */
+ public List<UploadedFile> getUploadedFileList(String name)
+ {
+ List<UploadedFile> files = _map.get(name);
+ if (files == null || files.isEmpty())
+ return null;
+
+ return files;
+ }
+
+ /**
+ * Retrieves files uploaded during a multiple file upload and copies those
+ * files to the requestMap so they get processed and cleaned up as usual
+ * @param name the name under which the files are stored. In HTML forms,
+ * this will be derived from the "name" set on the <input> tag.
+ */
+ public static void retrieveSessionUploadedFiles(ExternalContext context, String name)
+ {
+ UploadedFiles sessionFiles = (UploadedFiles) context.getSessionMap().get(_UPLOADED_FILES_KEY);
+ if (sessionFiles != null)
+ {
+ List<UploadedFile> sessionFileList = sessionFiles.getUploadedFileList(name);
+ if (sessionFileList != null && !sessionFileList.isEmpty())
+ {
+ UploadedFiles requestFiles = (UploadedFiles) context.getRequestMap().get(_UPLOADED_FILES_KEY);
+ if (requestFiles == null)
+ {
+ requestFiles = new UploadedFiles(context);
+ }
+ for (UploadedFile sessionFile: sessionFileList)
+ {
+ requestFiles.__put(name, sessionFile);
+ }
+ // clear it in the sessionMap
+ sessionFiles.getUploadedFileMap().remove(name);
+ }
+ }
+ }
/**
* Returns an Iterator of the names of all uploaded files.
@@ -124,6 +201,14 @@ final public class UploadedFiles
{
return _map.keySet().iterator();
}
+
+ /**
+ * Returns an Map of all of the uploaded files and names
+ */
+ public Map<String, List<UploadedFile>> getUploadedFileMap()
+ {
+ return _map;
+ }
/**
* Dispose of all UploadedFiles. This will happen automatically
@@ -132,12 +217,21 @@ final public class UploadedFiles
* processing files, this will free up resources earlier.
*/
public void dispose()
- {
- Iterator<UploadedFile> iterator = _map.values().iterator();
+ {
+ Iterator<List<UploadedFile>> iterator = _map.values().iterator();
while (iterator.hasNext())
{
- UploadedFile file = iterator.next();
- file.dispose();
+ List<UploadedFile> files = iterator.next();
+ if (files != null)
+ {
+ for (UploadedFile file: files)
+ {
+ if (file != null)
+ {
+ file.dispose();
+ }
+ }
+ }
}
_map.clear();
@@ -145,26 +239,39 @@ final public class UploadedFiles
_totalMemory = 0;
_totalDiskSpace = 0;
}
-
+
/**
* Creates an UploadedFiles.
*/
@SuppressWarnings("unchecked")
UploadedFiles(ExternalContext externalContext)
{
+ _map = new HashMap<String, List<UploadedFile>>();
externalContext.getRequestMap().put(_UPLOADED_FILES_KEY, this);
- _map = new HashMap<String, UploadedFile>();
}
-
+
+ /**
+ * Creates an UploadedFiles.
+ */
+ UploadedFiles()
+ {
+ _map = new HashMap<String, List<UploadedFile>>();
+ }
+
/**
* Store a single UploadedFile.
*/
void __put(String name, UploadedFile file)
{
- _map.put(name, file);
+ List<UploadedFile> files = _map.get(name);
+ if (files == null)
+ {
+ files = new ArrayList<UploadedFile>();
+ }
+ files.add(new FixFilename(file, _characterEncoding));
+ _map.put(name, files);
}
-
/**
* Return the tally of total memory used.
*/
@@ -182,12 +289,10 @@ final public class UploadedFiles
return _totalDiskSpace;
}
-
-
private long _totalMemory;
private long _totalDiskSpace;
private String _characterEncoding;
- private final Map<String, UploadedFile> _map;
+ private final Map<String, List<UploadedFile>> _map;
private static final String _UPLOADED_FILES_KEY =
"org.apache.myfaces.trinidadinternal.webapp.UploadedFiles";
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java Fri May 18 15:47:26 2012
@@ -78,6 +78,10 @@ public class RequestContextBean extends
TYPE.registerKey("uploaded-file-max-memory", Long.class);
static public final PropertyKey UPLOADED_FILE_MAX_DISK_SPACE_KEY =
TYPE.registerKey("uploaded-file-max-disk-space", Long.class);
+ static public final PropertyKey UPLOADED_FILE_MAX_FILE_SIZE_KEY =
+ TYPE.registerKey("uploaded-file-max-file-size", Long.class);
+ static public final PropertyKey UPLOADED_FILE_MAX_CHUNK_SIZE_KEY =
+ TYPE.registerKey("uploaded-file-max-chunk-size", Long.class);
static public final PropertyKey UPLOADED_FILE_TEMP_DIR_KEY =
TYPE.registerKey("uploaded-file-temp-dir");
static public final PropertyKey REMOTE_DEVICE_REPOSITORY_URI =
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java Fri May 18 15:47:26 2012
@@ -178,6 +178,18 @@ public class RequestContextImpl extends
}
@Override
+ public Long getUploadedFileMaxFileSize()
+ {
+ return (Long) _bean.getProperty(RequestContextBean.UPLOADED_FILE_MAX_FILE_SIZE_KEY);
+ }
+
+ @Override
+ public Long getUploadedFileMaxChunkSize()
+ {
+ return (Long) _bean.getProperty(RequestContextBean.UPLOADED_FILE_MAX_CHUNK_SIZE_KEY);
+ }
+
+ @Override
public String getUploadedFileTempDir()
{
return (String) _bean.getProperty(RequestContextBean.UPLOADED_FILE_TEMP_DIR_KEY);
Modified: myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java?rev=1340139&r1=1340138&r2=1340139&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java (original)
+++ myfaces/trinidad/branches/1.2.12.7.0-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java Fri May 18 15:47:26 2012
@@ -296,6 +296,28 @@ public class MRequestContext extends Req
return _maxDiskSpace;
}
+ public void setUploadedFileMaxFileSize(Long maxFileSize)
+ {
+ _maxFileSize = maxFileSize;
+ }
+
+ @Override
+ public Long getUploadedFileMaxFileSize()
+ {
+ return _maxFileSize;
+ }
+
+ public void setUploadedFileMaxChunkSize(Long maxChunkSize)
+ {
+ _maxChunkSize = maxChunkSize;
+ }
+
+ @Override
+ public Long getUploadedFileMaxChunkSize()
+ {
+ return _maxChunkSize;
+ }
+
public void setUploadedFileTempDir(String tempDir)
{
_tempDir= tempDir;
@@ -457,6 +479,8 @@ public class MRequestContext extends Req
private String _skin;
private Long _maxMemory;
private Long _maxDiskSpace;
+ private Long _maxFileSize;
+ private Long _maxChunkSize;
private String _tempDir;
private Accessibility _accMode;
private AccessibilityProfile _accProfile;