diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java
index 6ecba1d70..ae34cabf8 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java
@@ -3,8 +3,15 @@
package edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
@@ -12,6 +19,8 @@ import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
*
@@ -44,21 +53,39 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload;
*/
@SuppressWarnings("deprecation")
public abstract class FileUploadServletRequest extends HttpServletRequestWrapper {
+
+ private static final Log log = LogFactory
+ .getLog(FileUploadServletRequest.class);
+
public static final String FILE_ITEM_MAP = "file_item_map";
public static final String FILE_UPLOAD_EXCEPTION = "file_upload_exception";
+ private Map> parameters;
+ private Map> files;
+ private FileUploadException fileUploadException;
+
+ private static final String[] EMPTY_ARRAY = new String[0];
+
// ----------------------------------------------------------------------
// The factory method
// ----------------------------------------------------------------------
/**
* Wrap this {@link HttpServletRequest} in an appropriate wrapper class.
+ * set maxTempFileSize to 0 or -1 if streaming is desired. Set it to > 0 if
+ * you want any parts uploaded to a temporary directory
*/
- public static FileUploadServletRequest parseRequest(
- HttpServletRequest request, int maxFileSize) throws IOException {
+ public static FileUploadServletRequest parseRequest(
+ HttpServletRequest request, int maxTempFileSize) throws IOException {
+
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
+
if (isMultipart) {
- return new MultipartHttpServletRequest(request, maxFileSize);
+ if( maxTempFileSize <= 0 ){
+ return new StreamingMultipartHttpServletRequest(request);
+ }else{
+ return new MultipartHttpServletRequest(request, maxTempFileSize);
+ }
} else {
return new SimpleHttpServletRequestWrapper(request);
}
@@ -85,29 +112,184 @@ public abstract class FileUploadServletRequest extends HttpServletRequestWrapper
/** Was this a multipart HTTP request? */
public abstract boolean isMultipart();
+
+ protected void stashParametersInRequest(HttpServletRequest request, ServletFileUpload upload){
+ Map> parameters = new HashMap>();
+ Map> files = new HashMap>();
+
+ parseQueryString(request.getQueryString(), parameters);
+
+ try {
+ List items = upload.parseRequest( request );
+
+ for (FileItem item : items) {
+ // Process a regular form field
+ if (item.isFormField()) {
+ addToParameters(parameters, item.getFieldName(), item
+ .getString("UTF-8"));
+ log.debug("Form field (parameter) " + item.getFieldName()
+ + "=" + item.getString());
+ } else {
+ addToFileItems(files, item);
+ log.debug("File " + item.getFieldName() + ": "
+ + item.getName());
+ }
+ }
+ } catch (FileUploadException e) {
+ fileUploadException = e;
+ request.setAttribute(
+ FileUploadServletRequest.FILE_UPLOAD_EXCEPTION, e);
+ } catch (UnsupportedEncodingException e) {
+ log.error("could not convert to UTF-8",e);
+ }
+
+ this.parameters = Collections.unmodifiableMap(parameters);
+ log.debug("Parameters are: " + this.parameters);
+ this.files = Collections.unmodifiableMap(files);
+ log.debug("Files are: " + this.files);
+ request.setAttribute(FILE_ITEM_MAP, this.files);
+ }
+
+
/**
- * Get the map of file items, by name.
+ * Pull any parameters out of the URL.
*/
- public abstract Map> getFiles();
+ private void parseQueryString(String queryString,
+ Map> parameters) {
+ log.debug("Query string is : '" + queryString + "'");
+ if (queryString != null) {
+ String[] pieces = queryString.split("&");
+
+ for (String piece : pieces) {
+ int equalsHere = piece.indexOf('=');
+ if (piece.trim().isEmpty()) {
+ // Ignore an empty piece.
+ } else if (equalsHere <= 0) {
+ // A parameter without a value.
+ addToParameters(parameters, decode(piece), "");
+ } else {
+ // A parameter with a value.
+ String key = piece.substring(0, equalsHere);
+ String value = piece.substring(equalsHere + 1);
+ addToParameters(parameters, decode(key), decode(value));
+ }
+ }
+ }
+ log.debug("Parameters from query string are: " + parameters);
+ }
/**
- * Find a non-empty file item with this name.
- *
- * @return the first such file item, or null
if no matching,
- * non-empty items were found.
+ * Remove any special URL-style encoding.
*/
- public abstract FileItem getFileItem(String string);
+ private String decode(String encoded) {
+ try {
+ return URLDecoder.decode(encoded, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ log.error(e, e);
+ return encoded;
+ }
+ }
- /**
- * Was there an exception when uploading the file items?
- */
- public abstract boolean hasFileUploadException();
- /**
- * Get the exception that occurred when uploading the file items. If no such
- * exception, return null
.
- */
- public abstract FileUploadException getFileUploadException();
+ /** Either create a new List for the value, or add to an existing List. */
+ private void addToParameters(Map> map, String name,
+ String value) {
+ if (!map.containsKey(name)) {
+ map.put(name, new ArrayList());
+ }
+ map.get(name).add(value);
+ }
+
+ /** Either create a new List for the file, or add to an existing List. */
+ private void addToFileItems(Map> map, FileItem file) {
+ String name = file.getFieldName();
+ if (!map.containsKey(name)) {
+ map.put(name, new ArrayList());
+ }
+ map.get(name).add(file);
+ }
+
+
+ public FileUploadException getFileUploadException() {
+ return fileUploadException;
+ }
+
+ public boolean hasFileUploadException() {
+ return fileUploadException != null;
+ }
+
+ // ----------------------------------------------------------------------
+ // Parameter-related methods won't find anything on the delegate request,
+ // since parsing consumed the parameters. So we need to look to the parsed
+ // info for the answers.
+ // ----------------------------------------------------------------------
+
+ @Override
+ public String getParameter(String name) {
+ if (parameters.containsKey(name)) {
+ return parameters.get(name).get(0);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Enumeration> getParameterNames() {
+ return Collections.enumeration(parameters.keySet());
+ }
+
+ @Override
+ public String[] getParameterValues(String name) {
+ if (parameters.containsKey(name)) {
+ return parameters.get(name).toArray(EMPTY_ARRAY);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Map getParameterMap() {
+ Map result = new HashMap();
+ for (Entry> entry : parameters.entrySet()) {
+ result.put(entry.getKey(), entry.getValue().toArray(EMPTY_ARRAY));
+ }
+ log.debug("resulting parameter map: " + result);
+ return result;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * There may be more than one file item with the given name. If the first
+ * one is empty (size is zero), keep looking for a non-empty one.
+ *
+ */
+ public FileItem getFileItem(String name) {
+ List items = files.get(name);
+ if (items == null) {
+ return null;
+ }
+
+ for (FileItem item : items) {
+ if (item.getSize() > 0L) {
+ return item;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets a map of parameter names to files.
+ * This will should return null.
+ */
+ public Map> getFiles() {
+ if( files == null )
+ return Collections.emptyMap();
+ else
+ return files;
+ }
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java
index 76f90a174..a276e2275 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java
@@ -33,32 +33,8 @@ public class MultipartHttpServletRequest extends FileUploadServletRequest {
private static final Log log = LogFactory
.getLog(MultipartHttpServletRequest.class);
- private static final String[] EMPTY_ARRAY = new String[0];
-
- private Map> parameters;
- private Map> files;
- private FileUploadException fileUploadException;
-
- private boolean storeFilesToTempDir = false;
private int maxFileSize = 0;
- private File tempDir = null;
-
- /**
- * Parse the multipart request. Store the info about the request parameters.
- * Don't store the uploaded files to a temporary directory to allow streaming.
- *
- * Only use this constructor if you plan to consume the FileItems using streaming
- * to deal with inputs of very large sizes.
- *
- * In all other case you should use the maxFileSize constructor to deal with
- * the size of the uploaded file in a safe way.
- */
- public MultipartHttpServletRequest(HttpServletRequest request)
- throws IOException{
- super(request);
- storeFilesToTempDir = false;
-
- }
+ private File tempDir = null;
/**
* Parse the multipart request. Store the info about the request parameters
@@ -70,92 +46,16 @@ public class MultipartHttpServletRequest extends FileUploadServletRequest {
public MultipartHttpServletRequest(HttpServletRequest request,
int maxFileSize) throws IOException {
super(request);
- storeFilesToTempDir = true;
+
this.maxFileSize = maxFileSize;
this.tempDir = figureTemporaryDirectory(request);
+
+ //use an upload handler that will stash the file items in a temporary directory.
+ ServletFileUpload upload = createUploadHandler( this.maxFileSize, this.tempDir );
+ stashParametersInRequest( request , upload );
}
- private void setup(HttpServletRequest request){
- Map> parameters = new HashMap>();
- Map> files = new HashMap>();
-
- ServletFileUpload upload = createUploadHandler();
-
- //File tempDir = figureTemporaryDirectory(request);
- //ServletFileUpload upload = createUploadHandler(maxFileSize, tempDir);
-
- parseQueryString(request.getQueryString(), parameters);
-
- try {
- List items = parseRequestIntoFileItems(request, upload);
-
- for (FileItem item : items) {
- // Process a regular form field
- if (item.isFormField()) {
- addToParameters(parameters, item.getFieldName(), item
- .getString("UTF-8"));
- log.debug("Form field (parameter) " + item.getFieldName()
- + "=" + item.getString());
- } else {
- addToFileItems(files, item);
- log.debug("File " + item.getFieldName() + ": "
- + item.getName());
- }
- }
- } catch (FileUploadException e) {
- fileUploadException = e;
- request.setAttribute(
- FileUploadServletRequest.FILE_UPLOAD_EXCEPTION, e);
- } catch (UnsupportedEncodingException e) {
- log.error("could not convert to UTF-8",e);
- }
-
- this.parameters = Collections.unmodifiableMap(parameters);
- log.debug("Parameters are: " + this.parameters);
- this.files = Collections.unmodifiableMap(files);
- log.debug("Files are: " + this.files);
- request.setAttribute(FILE_ITEM_MAP, this.files);
- }
-
- /**
- * Pull any parameters out of the URL.
- */
- private void parseQueryString(String queryString,
- Map> parameters) {
- log.debug("Query string is : '" + queryString + "'");
- if (queryString != null) {
- String[] pieces = queryString.split("&");
-
- for (String piece : pieces) {
- int equalsHere = piece.indexOf('=');
- if (piece.trim().isEmpty()) {
- // Ignore an empty piece.
- } else if (equalsHere <= 0) {
- // A parameter without a value.
- addToParameters(parameters, decode(piece), "");
- } else {
- // A parameter with a value.
- String key = piece.substring(0, equalsHere);
- String value = piece.substring(equalsHere + 1);
- addToParameters(parameters, decode(key), decode(value));
- }
- }
- }
- log.debug("Parameters from query string are: " + parameters);
- }
-
- /**
- * Remove any special URL-style encoding.
- */
- private String decode(String encoded) {
- try {
- return URLDecoder.decode(encoded, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- log.error(e, e);
- return encoded;
- }
- }
-
+
/**
* Find the temporary storage directory for this webapp.
*/
@@ -163,19 +63,7 @@ public class MultipartHttpServletRequest extends FileUploadServletRequest {
return (File) request.getSession().getServletContext().getAttribute(
"javax.servlet.context.tempdir");
}
-
- /**
- * Create an upload handler based on this.storeFilesToTempDir.
- */
- private ServletFileUpload createUploadHandler(){
- if( storeFilesToTempDir ){
- return createUploadHandler( this.maxFileSize, this.tempDir );
- }else{
- return new ServletFileUpload();
- }
- }
-
/**
* Create an upload handler that will throw an exception if the file is too
* large.
@@ -191,116 +79,10 @@ public class MultipartHttpServletRequest extends FileUploadServletRequest {
return upload;
}
- /** Either create a new List for the value, or add to an existing List. */
- private void addToParameters(Map> map, String name,
- String value) {
- if (!map.containsKey(name)) {
- map.put(name, new ArrayList());
- }
- map.get(name).add(value);
- }
-
- /** Either create a new List for the file, or add to an existing List. */
- private void addToFileItems(Map> map, FileItem file) {
- String name = file.getFieldName();
- if (!map.containsKey(name)) {
- map.put(name, new ArrayList());
- }
- map.get(name).add(file);
- }
-
- /** Minimize the code that uses the unchecked cast. */
- @SuppressWarnings("unchecked")
- private List parseRequestIntoFileItems(HttpServletRequest req,
- ServletFileUpload upload) throws FileUploadException {
- return upload.parseRequest(req);
- }
-
- // ----------------------------------------------------------------------
- // This is a multipart request, so make the file info available. If there
- // was an exception during parsing, make that available too.
- // ----------------------------------------------------------------------
-
- @Override
- public boolean isMultipart() {
- return true;
- }
-
- @Override
- public Map> getFiles() {
- return files;
- }
-
- /**
- * {@inheritDoc}
- *
- * There may be more than one file item with the given name. If the first
- * one is empty (size is zero), keep looking for a non-empty one.
- *
- */
- @Override
- public FileItem getFileItem(String name) {
- List items = files.get(name);
- if (items == null) {
- return null;
- }
-
- for (FileItem item : items) {
- if (item.getSize() > 0L) {
- return item;
- }
- }
-
- return null;
- }
-
- @Override
- public FileUploadException getFileUploadException() {
- return fileUploadException;
- }
-
- @Override
- public boolean hasFileUploadException() {
- return fileUploadException != null;
- }
-
- // ----------------------------------------------------------------------
- // Parameter-related methods won't find anything on the delegate request,
- // since parsing consumed the parameters. So we need to look to the parsed
- // info for the answers.
- // ----------------------------------------------------------------------
-
- @Override
- public String getParameter(String name) {
- if (parameters.containsKey(name)) {
- return parameters.get(name).get(0);
- } else {
- return null;
- }
- }
-
- @Override
- public Enumeration> getParameterNames() {
- return Collections.enumeration(parameters.keySet());
- }
-
- @Override
- public String[] getParameterValues(String name) {
- if (parameters.containsKey(name)) {
- return parameters.get(name).toArray(EMPTY_ARRAY);
- } else {
- return null;
- }
- }
-
- @Override
- public Map getParameterMap() {
- Map result = new HashMap();
- for (Entry> entry : parameters.entrySet()) {
- result.put(entry.getKey(), entry.getValue().toArray(EMPTY_ARRAY));
- }
- log.debug("resulting parameter map: " + result);
- return result;
- }
+ @Override
+ public boolean isMultipart() {
+ return true;
+ }
+
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java
index 246377048..754226317 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java
@@ -33,26 +33,7 @@ class SimpleHttpServletRequestWrapper extends FileUploadServletRequest {
return false;
}
- @Override
- public Map> getFiles() {
- return Collections.emptyMap();
- }
-
- @Override
- public FileItem getFileItem(String string) {
- return null;
- }
-
- @Override
- public FileUploadException getFileUploadException() {
- return null;
- }
-
- @Override
- public boolean hasFileUploadException() {
- return false;
- }
-
+
// ----------------------------------------------------------------------
// Since this is not a multipart request, the parameter methods can be
// delegated.
@@ -64,7 +45,7 @@ class SimpleHttpServletRequestWrapper extends FileUploadServletRequest {
}
@Override
- public Map, ?> getParameterMap() {
+ public Map getParameterMap() {
return getDelegate().getParameterMap();
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/StreamingMultipartHttpServletRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/StreamingMultipartHttpServletRequest.java
new file mode 100644
index 000000000..7b74a2041
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/StreamingMultipartHttpServletRequest.java
@@ -0,0 +1,43 @@
+package edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+
+/**
+ * Wrapping ServletRequest that does multipart. In order to allow
+ * streaming, this class does NOT save the parts to a temporary directory.
+ *
+ *
+ */
+public class StreamingMultipartHttpServletRequest extends
+ FileUploadServletRequest {
+ /**
+ * Parse the multipart request. Store the info about the request parameters.
+ * Don't store the uploaded files to a temporary directory to allow streaming.
+ *
+ * Only use this if you plan to consume the FileItems using streaming
+ * to deal with inputs of very large sizes.
+ *
+ */
+ public StreamingMultipartHttpServletRequest(HttpServletRequest request)
+ throws IOException{
+ super(request);
+
+ //use a file uploader that does not save the files to a temporary directory.
+ stashParametersInRequest( request , new ServletFileUpload());
+ }
+
+ @Override
+ public boolean isMultipart() {
+ return true;
+ }
+
+
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SearchServiceController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SearchServiceController.java
index 61c23afc2..1d82546a6 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SearchServiceController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SearchServiceController.java
@@ -25,6 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServ
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
+import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.MultipartHttpServletRequest;
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
@@ -45,7 +46,7 @@ public class SearchServiceController extends FreemarkerHttpServlet {
protected Actions requiredActions(VitroRequest vreq) {
try{
// Works by side effect: parse the multi-part request and stash FileItems in request
- new MultipartHttpServletRequest( vreq );
+ FileUploadServletRequest.parseRequest(vreq, 0);
//first figure out if the password and email login to an account with a password
String pw = vreq.getParameter("password");