blob: 9283cf545be122cd86b2d34d03d6d88608ddbf51 [file] [log] [blame]
// Copyright 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry5.upload.internal.services;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.services.ThreadCleanupListener;
import org.apache.tapestry5.upload.services.MultipartDecoder;
import org.apache.tapestry5.upload.services.UploadSymbols;
import org.apache.tapestry5.upload.services.UploadedFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
/**
* Implementation of multipart decoder for servlets. This implementation is perthread scope.
*/
public class MultipartDecoderImpl implements MultipartDecoder, ThreadCleanupListener
{
private final Map<String, UploadedFileItem> uploads = CollectionFactory.newMap();
private final String repositoryLocation;
private final int repositoryThreshold;
private final long maxRequestSize;
private final long maxFileSize;
public MultipartDecoderImpl(
@Inject @Symbol(UploadSymbols.REPOSITORY_LOCATION)
String repositoryLocation,
@Symbol(UploadSymbols.REPOSITORY_THRESHOLD)
int repositoryThreshold,
@Symbol(UploadSymbols.REQUESTSIZE_MAX)
long maxRequestSize,
@Symbol(UploadSymbols.FILESIZE_MAX)
long maxFileSize)
{
this.repositoryLocation = repositoryLocation;
this.repositoryThreshold = repositoryThreshold;
this.maxRequestSize = maxRequestSize;
this.maxFileSize = maxFileSize;
}
public UploadedFile getFileUpload(String parameterName)
{
return uploads.get(parameterName);
}
public HttpServletRequest decode(HttpServletRequest request)
{
List<FileItem> fileItems = parseRequest(request);
return processFileItems(request, fileItems);
}
public void threadDidCleanup()
{
for (UploadedFileItem uploaded : uploads.values())
{
uploaded.cleanup();
}
}
@SuppressWarnings("unchecked")
protected List<FileItem> parseRequest(HttpServletRequest request)
{
try
{
return createFileUpload().parseRequest(request);
}
catch (FileUploadException e)
{
throw new RuntimeException(UploadMessages.unableToDecode(), e);
}
}
protected ServletFileUpload createFileUpload()
{
FileItemFactory factory = new DiskFileItemFactory(repositoryThreshold, new File(repositoryLocation));
ServletFileUpload upload = new ServletFileUpload(factory);
// set maximum file upload size
upload.setSizeMax(maxRequestSize);
upload.setFileSizeMax(maxFileSize);
return upload;
}
protected HttpServletRequest processFileItems(HttpServletRequest request, List<FileItem> fileItems)
{
if (fileItems == null || fileItems.isEmpty())
{
return request;
}
ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);
String encoding = request.getCharacterEncoding();
for (FileItem item : fileItems)
{
if (item.isFormField())
{
String fieldValue;
try
{
fieldValue = encoding == null ? item.getString() : item.getString(encoding);
}
catch (UnsupportedEncodingException e)
{
// TODO maybe log exception with level warn
fieldValue = item.getString();
}
wrapper.addParameter(item.getFieldName(), fieldValue);
}
else
{
wrapper.addParameter(item.getFieldName(), item.getName());
addUploadedFile(item.getFieldName(), new UploadedFileItem(item));
}
}
return wrapper;
}
protected void addUploadedFile(String name, UploadedFileItem file)
{
uploads.put(name, file);
}
}