From e2ad45f2cbfaaefdb25fd03175274c7bb6202993 Mon Sep 17 00:00:00 2001
From: j2blake
Date: Fri, 20 Dec 2013 15:02:57 -0500
Subject: [PATCH 1/3] line-end characters
---
.../utilities/testing/VitroTestRunner.java | 288 +++++++++---------
1 file changed, 144 insertions(+), 144 deletions(-)
diff --git a/utilities/buildutils/src/edu/cornell/mannlib/vitro/utilities/testing/VitroTestRunner.java b/utilities/buildutils/src/edu/cornell/mannlib/vitro/utilities/testing/VitroTestRunner.java
index 76664d4e3..0c4f5ae2c 100644
--- a/utilities/buildutils/src/edu/cornell/mannlib/vitro/utilities/testing/VitroTestRunner.java
+++ b/utilities/buildutils/src/edu/cornell/mannlib/vitro/utilities/testing/VitroTestRunner.java
@@ -1,7 +1,7 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
-package edu.cornell.mannlib.vitro.utilities.testing;
-
+package edu.cornell.mannlib.vitro.utilities.testing;
+
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -9,145 +9,145 @@ import java.util.SortedSet;
import java.util.TreeSet;
import org.junit.runner.JUnitCore;
-
-/**
- * A Java application that will run the Vitro unit tests. It searches for unit
- * tests in the supplied source directory (any file whose name is *Test.Java).
- * It runs the tests with a variety of reporting detail, depending on the level
- * selected. If the level selector is absent or unrecognized, the medium level
- * is used.
- *
- * @author jeb228
- */
-public class VitroTestRunner {
- public enum ReportLevel {
- /** Report only the one-line summary. */
- BRIEF,
- /** Report times and statistics for each test class. */
- MORE,
- /** Report times and statistics for each test method. */
- FULL
- }
-
- private final List> classes;
- private final VitroTestRunListener listener;
-
- /**
- * Locate the test classes. Initialize the test listener.
- */
- public VitroTestRunner(File sourceRootDir, ReportLevel reportLevel) {
- List classNames = getListOfTestClassNames(sourceRootDir);
- this.classes = getTestClasses(classNames);
- this.listener = new VitroTestRunListener(reportLevel);
- }
-
- /**
- * Start a recursive search through the source directory.
- */
- private List getListOfTestClassNames(File sourceRootDir) {
- SortedSet names = new TreeSet();
- searchForTestClasses(names, "", sourceRootDir);
- return new ArrayList(names);
- }
-
- /**
- * Recursively search the directory for files in the form "*Test.java".
- * Ignore any files or directories whose names start with a "."
- */
- private void searchForTestClasses(SortedSet names, String prefix,
- File directory) {
- for (File file : directory.listFiles()) {
- String filename = file.getName();
- if (filename.startsWith(".")) {
- // ignore .svn, etc.
- } else if (file.isDirectory()) {
- searchForTestClasses(names, prefix + filename + ".", file);
- } else if (filename.endsWith("Test.java")) {
- String classname = filename.substring(0, filename.length() - 5);
- names.add(prefix + classname);
- }
- }
- }
-
- /**
- * Instantiate a class for each test class name.
- */
- private List> getTestClasses(List classNames) {
- List> classes = new ArrayList>();
- for (String classname : classNames) {
- try {
- classes.add(Class.forName(classname));
- } catch (ClassNotFoundException e) {
- throw new IllegalArgumentException("Can't load test class: "
- + classname, e);
- }
- }
- return classes;
- }
-
- /**
- * We've located all of the test clases. Now run them.
- */
- private void run() {
- JUnitCore junitCore = new JUnitCore();
- junitCore.addListener(this.listener);
- junitCore.run(this.classes.toArray(new Class>[0]));
- }
-
- /**
- * Did any of the tests fail?
- */
- private boolean didEverythingPass() {
- return this.listener.didEverythingPass();
- }
-
- /**
- *
- * You must provide a path to the source directory of the test classes.
- *
- *
- * You may also provide a reporting level of "BRIEF", "MORE", or "FULL". If
- * no level is provided, or if it is not recognized, "BRIEF" is used.
- *
- */
- public static void main(String[] args) {
- if ((args.length < 1) || (args.length > 2)) {
- usage("Wrong number of arguments: expecting 1 or 2, but found "
- + args.length + ".");
- }
- File sourceRootDir = new File(args[0]);
-
- if (!sourceRootDir.exists()) {
- usage(sourceRootDir + " does not exist.");
- }
- if (!sourceRootDir.isDirectory()) {
- usage(sourceRootDir + " is not a directory.");
- }
-
- ReportLevel reportLevel = ReportLevel.MORE;
- if (args.length == 2) {
- for (ReportLevel level : ReportLevel.values()) {
- if (level.toString().equalsIgnoreCase(args[1])) {
- reportLevel = level;
- }
- }
- }
-
- VitroTestRunner runner = new VitroTestRunner(sourceRootDir, reportLevel);
- runner.run();
-
- if (!runner.didEverythingPass()) {
- System.exit(1);
- }
- }
-
- /**
- * Tell them how it should have been done.
- */
- private static void usage(String message) {
- System.out.println(message);
- System.out.println("usage: " + VitroTestRunner.class.getSimpleName()
- + " sourceRootDirectory [ BRIEF | MORE | FULL ]");
- System.exit(1);
- }
-}
+
+/**
+ * A Java application that will run the Vitro unit tests. It searches for unit
+ * tests in the supplied source directory (any file whose name is *Test.Java).
+ * It runs the tests with a variety of reporting detail, depending on the level
+ * selected. If the level selector is absent or unrecognized, the medium level
+ * is used.
+ *
+ * @author jeb228
+ */
+public class VitroTestRunner {
+ public enum ReportLevel {
+ /** Report only the one-line summary. */
+ BRIEF,
+ /** Report times and statistics for each test class. */
+ MORE,
+ /** Report times and statistics for each test method. */
+ FULL
+ }
+
+ private final List> classes;
+ private final VitroTestRunListener listener;
+
+ /**
+ * Locate the test classes. Initialize the test listener.
+ */
+ public VitroTestRunner(File sourceRootDir, ReportLevel reportLevel) {
+ List classNames = getListOfTestClassNames(sourceRootDir);
+ this.classes = getTestClasses(classNames);
+ this.listener = new VitroTestRunListener(reportLevel);
+ }
+
+ /**
+ * Start a recursive search through the source directory.
+ */
+ private List getListOfTestClassNames(File sourceRootDir) {
+ SortedSet names = new TreeSet();
+ searchForTestClasses(names, "", sourceRootDir);
+ return new ArrayList(names);
+ }
+
+ /**
+ * Recursively search the directory for files in the form "*Test.java".
+ * Ignore any files or directories whose names start with a "."
+ */
+ private void searchForTestClasses(SortedSet names, String prefix,
+ File directory) {
+ for (File file : directory.listFiles()) {
+ String filename = file.getName();
+ if (filename.startsWith(".")) {
+ // ignore .svn, etc.
+ } else if (file.isDirectory()) {
+ searchForTestClasses(names, prefix + filename + ".", file);
+ } else if (filename.endsWith("Test.java")) {
+ String classname = filename.substring(0, filename.length() - 5);
+ names.add(prefix + classname);
+ }
+ }
+ }
+
+ /**
+ * Instantiate a class for each test class name.
+ */
+ private List> getTestClasses(List classNames) {
+ List> classes = new ArrayList>();
+ for (String classname : classNames) {
+ try {
+ classes.add(Class.forName(classname));
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException("Can't load test class: "
+ + classname, e);
+ }
+ }
+ return classes;
+ }
+
+ /**
+ * We've located all of the test clases. Now run them.
+ */
+ private void run() {
+ JUnitCore junitCore = new JUnitCore();
+ junitCore.addListener(this.listener);
+ junitCore.run(this.classes.toArray(new Class>[0]));
+ }
+
+ /**
+ * Did any of the tests fail?
+ */
+ private boolean didEverythingPass() {
+ return this.listener.didEverythingPass();
+ }
+
+ /**
+ *
+ * You must provide a path to the source directory of the test classes.
+ *
+ *
+ * You may also provide a reporting level of "BRIEF", "MORE", or "FULL". If
+ * no level is provided, or if it is not recognized, "BRIEF" is used.
+ *
+ */
+ public static void main(String[] args) {
+ if ((args.length < 1) || (args.length > 2)) {
+ usage("Wrong number of arguments: expecting 1 or 2, but found "
+ + args.length + ".");
+ }
+ File sourceRootDir = new File(args[0]);
+
+ if (!sourceRootDir.exists()) {
+ usage(sourceRootDir + " does not exist.");
+ }
+ if (!sourceRootDir.isDirectory()) {
+ usage(sourceRootDir + " is not a directory.");
+ }
+
+ ReportLevel reportLevel = ReportLevel.MORE;
+ if (args.length == 2) {
+ for (ReportLevel level : ReportLevel.values()) {
+ if (level.toString().equalsIgnoreCase(args[1])) {
+ reportLevel = level;
+ }
+ }
+ }
+
+ VitroTestRunner runner = new VitroTestRunner(sourceRootDir, reportLevel);
+ runner.run();
+
+ if (!runner.didEverythingPass()) {
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Tell them how it should have been done.
+ */
+ private static void usage(String message) {
+ System.out.println(message);
+ System.out.println("usage: " + VitroTestRunner.class.getSimpleName()
+ + " sourceRootDirectory [ BRIEF | MORE | FULL ]");
+ System.exit(1);
+ }
+}
From b7b28cc896ec6cc76c60af62a62ec9c80960c212 Mon Sep 17 00:00:00 2001
From: j2blake
Date: Fri, 20 Dec 2013 17:10:18 -0500
Subject: [PATCH 2/3] VIVO-617 Change the way we deal with Multipart requests.
---
.../controller/MultipartRequestWrapper.java | 288 ++++++++++++++++++
.../webapp/controller/VitroHttpServlet.java | 25 +-
.../vitro/webapp/controller/VitroRequest.java | 63 ++++
.../FileUploadServletRequest.java | 112 -------
.../MultipartHttpServletRequest.java | 261 ----------------
.../SimpleHttpServletRequestWrapper.java | 81 -----
6 files changed, 373 insertions(+), 457 deletions(-)
create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MultipartRequestWrapper.java
delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java
delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java
delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MultipartRequestWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MultipartRequestWrapper.java
new file mode 100644
index 000000000..02a7eee72
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MultipartRequestWrapper.java
@@ -0,0 +1,288 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+
+package edu.cornell.mannlib.vitro.webapp.controller;
+
+import java.io.File;
+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.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Wraps a multipart HTTP request, and pre-parses it for file uploads, without
+ * losing the request parameters.
+ *
+ * Parsing through the request with an Apache ServletFileUpload builds a list of
+ * FileItems that includes the parameters and the file parts. After that,
+ * however, the parameters are no longer accessible from the request. This
+ * wrapper will see that they don't get lost.
+ *
+ * The List of FileItems includes both "formField" items and "file" items. As
+ * with the usual parameters on a request, we can have more than one value with
+ * the same name. So this creates a map of > to hold the
+ * parameters, and a map of > to hold the files.
+ *
+ * The parameters will be available to the wrapper through the normal methods.
+ * The files will be available as an attribute that holds the map. Also, a
+ * separate attribute will hold a Boolean to indicate that this was indeed a
+ * multipart request.
+ *
+ * Conveninence methods in VitroRequest will make these easy to handle, without
+ * actually touching the attributes.
+ */
+public class MultipartRequestWrapper extends HttpServletRequestWrapper {
+ private static final Log log = LogFactory
+ .getLog(MultipartRequestWrapper.class);
+
+ private static final String CLASS_NAME = MultipartRequestWrapper.class
+ .getSimpleName();
+ public static final String ATTRIBUTE_IS_MULTIPART = CLASS_NAME
+ + "_isMultipart";
+ public static final String ATTRIBUTE_FILE_ITEM_MAP = CLASS_NAME
+ + "_fileItemMap";
+ public static final String ATTRIBUTE_FILE_SIZE_EXCEPTION = CLASS_NAME
+ + "_fileSizeException";
+
+ private static final String[] EMPTY_ARRAY = new String[0];
+
+ // ----------------------------------------------------------------------
+ // The factory
+ // ----------------------------------------------------------------------
+
+ /**
+ * If this is a multipart request, wrap it. Otherwise, just return the
+ * request as it is.
+ */
+ public static HttpServletRequest parse(HttpServletRequest req,
+ ParsingStrategy strategy) throws IOException {
+ if (!ServletFileUpload.isMultipartContent(req)) {
+ return req;
+ }
+
+ ListsMap parameters = new ListsMap<>();
+ ListsMap files = new ListsMap<>();
+
+ parseQueryString(req.getQueryString(), parameters);
+ parseFileParts(req, parameters, files, strategy);
+
+ return new MultipartRequestWrapper(req, parameters, files);
+ }
+
+ /**
+ * Pull any parameters out of the URL.
+ */
+ private static void parseQueryString(String queryString,
+ ListsMap 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.
+ parameters.add(decode(piece), "");
+ } else {
+ // A parameter with a value.
+ String key = piece.substring(0, equalsHere);
+ String value = piece.substring(equalsHere + 1);
+ parameters.add(decode(key), decode(value));
+ }
+ }
+ }
+ log.debug("Parameters from query string are: " + parameters);
+ }
+
+ /**
+ * Remove any special URL-style encoding.
+ */
+ private static String decode(String encoded) {
+ try {
+ return URLDecoder.decode(encoded, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ log.error(e, e);
+ return encoded;
+ }
+ }
+
+ private static void parseFileParts(HttpServletRequest req,
+ ListsMap parameters, ListsMap files,
+ ParsingStrategy strategy) throws IOException {
+
+ ServletFileUpload upload = createUploadHandler(req,
+ strategy.maximumMultipartFileSize());
+ List items = parseRequestIntoFileItems(req, upload, strategy);
+
+ for (FileItem item : items) {
+ // Process a regular form field
+ String name = item.getFieldName();
+ if (item.isFormField()) {
+ String value;
+ try {
+ value = item.getString("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ value = item.getString();
+ }
+ parameters.add(name, value);
+ log.debug("Form field (parameter) " + name + "=" + value);
+ } else {
+ files.add(name, item);
+ log.debug("File " + name + ": " + item.getSize() + " bytes.");
+ }
+ }
+ }
+
+ /**
+ * Create an upload handler that will throw an exception if the file is too
+ * large.
+ */
+ private static ServletFileUpload createUploadHandler(
+ HttpServletRequest req, long maxFileSize) {
+ File tempDir = figureTemporaryDirectory(req);
+
+ DiskFileItemFactory factory = new DiskFileItemFactory();
+ factory.setSizeThreshold(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD);
+ factory.setRepository(tempDir);
+
+ ServletFileUpload upload = new ServletFileUpload(factory);
+ upload.setSizeMax(maxFileSize);
+ return upload;
+ }
+
+ /**
+ * Find the temporary storage directory for this webapp.
+ */
+ private static File figureTemporaryDirectory(HttpServletRequest request) {
+ return (File) request.getSession().getServletContext()
+ .getAttribute("javax.servlet.context.tempdir");
+ }
+
+ /**
+ * Parse the raw request into a list of parts.
+ *
+ * If there is a parsing error, let the strategy handle it. If the strategy
+ * throws it back, wrap it in an IOException and throw it on up.
+ */
+ @SuppressWarnings("unchecked")
+ private static List parseRequestIntoFileItems(
+ HttpServletRequest req, ServletFileUpload upload,
+ ParsingStrategy strategy) throws IOException {
+ try {
+ return upload.parseRequest(req);
+ } catch (FileSizeLimitExceededException e) {
+ if (strategy.stashFileSizeException()) {
+ req.setAttribute(ATTRIBUTE_FILE_SIZE_EXCEPTION, e);
+ return Collections.emptyList();
+ } else {
+ throw new IOException(e);
+ }
+ } catch (FileUploadException e) {
+ throw new IOException(e);
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // The instance
+ // ----------------------------------------------------------------------
+
+ private final ListsMap parameters;
+
+ public MultipartRequestWrapper(HttpServletRequest req,
+ ListsMap parameters, ListsMap files) {
+ super(req);
+
+ this.parameters = parameters;
+
+ req.setAttribute(ATTRIBUTE_IS_MULTIPART, Boolean.TRUE);
+ req.setAttribute(ATTRIBUTE_FILE_ITEM_MAP, files);
+ }
+
+ /**
+ * Look in the map of parsed parameters.
+ */
+ @Override
+ public String getParameter(String name) {
+ if (parameters.containsKey(name)) {
+ return parameters.get(name).get(0);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Look in the map of parsed parameters. Make a protective copy.
+ */
+ @Override
+ public Enumeration> getParameterNames() {
+ return Collections.enumeration(new HashSet<>(parameters.keySet()));
+ }
+
+ /**
+ * Look in the map of parsed parameters.
+ */
+ @Override
+ public String[] getParameterValues(String name) {
+ if (parameters.containsKey(name)) {
+ return parameters.get(name).toArray(EMPTY_ARRAY);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Make a copy of the map of parsed parameters;
+ */
+ @Override
+ public Map getParameterMap() {
+ Map result = new HashMap();
+ for (String key : parameters.keySet()) {
+ result.put(key, parameters.get(key).toArray(EMPTY_ARRAY));
+ }
+ return result;
+ }
+
+ // ----------------------------------------------------------------------
+ // Helper classes
+ // ----------------------------------------------------------------------
+
+ private static class ListsMap extends HashMap> {
+ void add(String key, T value) {
+ if (!containsKey(key)) {
+ put(key, new ArrayList());
+ }
+ get(key).add(value);
+ }
+ }
+
+ public interface ParsingStrategy {
+ long maximumMultipartFileSize();
+
+ /**
+ * Allows you to handle the exception in your code.
+ *
+ * Be aware that the multipart parameters have been lost, and that may
+ * include form fields.
+ */
+ boolean stashFileSizeException();
+ }
+
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java
index dcc80a040..bf082aa56 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java
@@ -30,14 +30,13 @@ import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
-import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.beans.ResourceBean;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
-public class VitroHttpServlet extends HttpServlet {
+public class VitroHttpServlet extends HttpServlet implements MultipartRequestWrapper.ParsingStrategy {
private static final long serialVersionUID = 1L;
protected static DateFormat publicDateFormat = new SimpleDateFormat(
@@ -60,8 +59,9 @@ public class VitroHttpServlet extends HttpServlet {
if ((req instanceof HttpServletRequest)
&& (resp instanceof HttpServletResponse)) {
HttpServletRequest hreq = (HttpServletRequest) req;
- HttpServletResponse hresp = (HttpServletResponse) resp;
+ hreq = MultipartRequestWrapper.parse(hreq, this);
+
if (log.isTraceEnabled()) {
dumpRequestHeaders(hreq);
}
@@ -70,6 +70,25 @@ public class VitroHttpServlet extends HttpServlet {
super.service(req, resp);
}
+ /**
+ * Override this to change the maximum size of uploaded files in multipart
+ * requests.
+ */
+ @Override
+ public long maximumMultipartFileSize() {
+ return 50 * 1024 * 1024; // default is 50 megabytes
+ }
+
+ /**
+ * Override this to change the way that exceptions are handled when parsing
+ * a multipart request. Be aware that multipart parameters have been lost,
+ * and that may include form fields.
+ */
+ @Override
+ public boolean stashFileSizeException() {
+ return false;
+ }
+
/**
* doGet does nothing.
*/
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java
index 05c0fc158..9878fe0b9 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java
@@ -3,12 +3,20 @@
package edu.cornell.mannlib.vitro.webapp.controller;
+import static edu.cornell.mannlib.vitro.webapp.controller.MultipartRequestWrapper.ATTRIBUTE_FILE_ITEM_MAP;
+import static edu.cornell.mannlib.vitro.webapp.controller.MultipartRequestWrapper.ATTRIBUTE_FILE_SIZE_EXCEPTION;
+import static edu.cornell.mannlib.vitro.webapp.controller.MultipartRequestWrapper.ATTRIBUTE_IS_MULTIPART;
+
import java.text.Collator;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -231,4 +239,59 @@ public class VitroRequest extends HttpServletRequestWrapper {
public WebappDaoFactory getLanguageNeutralWebappDaoFactory() {
return (WebappDaoFactory) getAttribute("languageNeutralWebappDaoFactory");
}
+
+ // ----------------------------------------------------------------------
+ // Deal with parsed multipart requests.
+ // ----------------------------------------------------------------------
+
+ public boolean isMultipart() {
+ return getAttribute(ATTRIBUTE_IS_MULTIPART) != null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map> getFiles() {
+ Map> map;
+ map = (Map>) getAttribute(ATTRIBUTE_FILE_ITEM_MAP);
+ if (map == null) {
+ return Collections.emptyMap();
+ } else {
+ return map;
+ }
+ }
+
+ /**
+ * 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) {
+ Map> map = getFiles();
+ List items = map.get(name);
+ if (items == null) {
+ return null;
+ }
+ for (FileItem item : items) {
+ if (item.getSize() > 0L) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * If the uploaded file exceeded the maximum size, and if the strategy said
+ * to stash the exception, it will be stored as a request attribute.
+ */
+ public boolean hasFileSizeException() {
+ return getFileSizeException() != null;
+ }
+
+ public FileSizeLimitExceededException getFileSizeException() {
+ Object e = getAttribute(ATTRIBUTE_FILE_SIZE_EXCEPTION);
+ if (e instanceof FileSizeLimitExceededException) {
+ return (FileSizeLimitExceededException) e;
+ } else {
+ return null;
+ }
+ }
+
}
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
deleted file mode 100644
index 519e2f07c..000000000
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/FileUploadServletRequest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/* $This file is distributed under the terms of the license in /doc/license.txt$ */
-
-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 javax.servlet.http.HttpServletRequestWrapper;
-
-import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.FileUploadException;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-
-/**
- *
- * Wraps an HTTP request and parses it for file uploads, without losing the
- * request parameters.
- *
- *
- * The request will have an attribute named by {@link #FILE_ITEM_MAP}. Either
- * this attribute or the call to {@link #getFiles()} will produce a map that may
- * be empty but is never null. The keys to the map are the field names for the
- * file fields. Since a form may have multiple fields with the same name, each
- * field name maps to a list of items. If a user does not provide a file to be
- * uploaded in a given field, the length of the file will be 0.
- *
- *
- * If the uploaded file(s) would be larger than the maxFileSize,
- * {@link #parseRequest(HttpServletRequest, int)} does not throw an Exception.
- * Instead, it records the exception in a request attribute named by
- * {@link #FILE_UPLOAD_EXCEPTION}. This attribute can be accessed directly, or
- * indirectly via the methods {@link #hasFileUploadException()} and
- * {@link #getFileUploadException()}. If there is an exception, the file item
- * map (see above) will still be non-null, but it will be empty.
- *
- *
- * Most methods are declared here simply delegate to the wrapped request.
- * Methods that have to do with parameters, files, or parsing exceptions, are
- * handled differently for simple requests and multipart request, and are
- * implemented in the sub-classes.
- *
- */
-public abstract class FileUploadServletRequest extends HttpServletRequestWrapper {
- public static final String FILE_ITEM_MAP = "file_item_map";
- public static final String FILE_UPLOAD_EXCEPTION = "file_upload_exception";
-
- // ----------------------------------------------------------------------
- // The factory method
- // ----------------------------------------------------------------------
-
- /**
- * Wrap this {@link HttpServletRequest} in an appropriate wrapper class.
- */
- public static FileUploadServletRequest parseRequest(
- HttpServletRequest request, int maxFileSize) throws IOException {
- boolean isMultipart = ServletFileUpload.isMultipartContent(request);
- if (isMultipart) {
- return new MultipartHttpServletRequest(request, maxFileSize);
- } else {
- return new SimpleHttpServletRequestWrapper(request);
- }
- }
-
- // ----------------------------------------------------------------------
- // The constructor and the delegate.
- // ----------------------------------------------------------------------
-
- private final HttpServletRequest delegate;
-
- public FileUploadServletRequest(HttpServletRequest delegate) {
- super(delegate);
- this.delegate = delegate;
- }
-
- protected HttpServletRequest getDelegate() {
- return this.delegate;
- }
-
- // ----------------------------------------------------------------------
- // New functionality to be implemented by the subclasses.
- // ----------------------------------------------------------------------
-
- /** Was this a multipart HTTP request? */
- public abstract boolean isMultipart();
-
- /**
- * Get the map of file items, by name.
- */
- public abstract Map> getFiles();
-
- /**
- * 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.
- */
- public abstract FileItem getFileItem(String string);
-
- /**
- * 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();
-
-}
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
deleted file mode 100644
index 56cf480fc..000000000
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/* $This file is distributed under the terms of the license in /doc/license.txt$ */
-
-package edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest;
-
-import java.io.File;
-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 org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.FileUploadException;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A wrapper for a servlet request that holds multipart content. Parsing the
- * request will consume the parameters, so we need to hold them here to answer
- * any parameter-related requests. File-related information will also be held
- * here, to answer file-related requests.
- */
-class MultipartHttpServletRequest extends FileUploadServletRequest {
- private static final Log log = LogFactory
- .getLog(MultipartHttpServletRequest.class);
-
- private static final String[] EMPTY_ARRAY = new String[0];
-
- private final Map> parameters;
- private final Map> files;
- private FileUploadException fileUploadException;
-
- /**
- * Parse the multipart request. Store the info about the request parameters
- * and the uploaded files.
- */
- public MultipartHttpServletRequest(HttpServletRequest request,
- int maxFileSize) throws IOException {
- super(request);
-
- Map> parameters = new HashMap>();
- Map> files = new HashMap>();
-
- 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);
- }
-
- 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.
- */
- private File figureTemporaryDirectory(HttpServletRequest request) {
- return (File) request.getSession().getServletContext().getAttribute(
- "javax.servlet.context.tempdir");
- }
-
- /**
- * Create an upload handler that will throw an exception if the file is too
- * large.
- */
- private ServletFileUpload createUploadHandler(int maxFileSize, File tempDir) {
- DiskFileItemFactory factory = new DiskFileItemFactory();
- factory.setSizeThreshold(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD);
- factory.setRepository(tempDir);
-
- ServletFileUpload upload = new ServletFileUpload(factory);
- upload.setSizeMax(maxFileSize);
-
- 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;
- }
-
-}
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
deleted file mode 100644
index 246377048..000000000
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/SimpleHttpServletRequestWrapper.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/* $This file is distributed under the terms of the license in /doc/license.txt$ */
-
-package edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest;
-
-import java.util.Collections;
-import java.util.Enumeration;
-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;
-
-/**
- * A wrapper for a servlet request that does not hold multipart content. Pass
- * all parameter-related requests to the delegate, and give simple answers to
- * all file-related requests.
- */
-class SimpleHttpServletRequestWrapper extends FileUploadServletRequest {
-
- SimpleHttpServletRequestWrapper(HttpServletRequest request) {
- super(request);
- request.setAttribute(FILE_ITEM_MAP, Collections.EMPTY_MAP);
- }
-
- // ----------------------------------------------------------------------
- // Not a multipart request, so there are no files or upload exceptions.
- // ----------------------------------------------------------------------
-
- @Override
- public boolean isMultipart() {
- 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.
- // ----------------------------------------------------------------------
-
- @Override
- public String getParameter(String name) {
- return getDelegate().getParameter(name);
- }
-
- @Override
- public Map, ?> getParameterMap() {
- return getDelegate().getParameterMap();
- }
-
- @Override
- public Enumeration> getParameterNames() {
- return getDelegate().getParameterNames();
- }
-
- @Override
- public String[] getParameterValues(String name) {
- return getDelegate().getParameterValues(name);
- }
-
-}
From c42d9af70fe471baaf77ce6483af9986ea358cf0 Mon Sep 17 00:00:00 2001
From: j2blake
Date: Fri, 20 Dec 2013 17:11:16 -0500
Subject: [PATCH 3/3] VIVO-617 Adjust the client code to use the new file
upload tools.
---
.../FedoraDatastreamController.java | 19 ++-
.../freemarker/ImageUploadController.java | 109 ++++++------------
.../freemarker/ImageUploadHelper.java | 19 +--
.../jena/JenaCsv2RdfController.java | 24 ++--
.../controller/jena/JenaXMLFileUpload.java | 26 +++--
.../controller/jena/RDFUploadController.java | 39 ++++---
.../controller/SearchServiceController.java | 9 +-
.../search/controller/UpdateUrisInIndex.java | 11 +-
8 files changed, 116 insertions(+), 140 deletions(-)
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/FedoraDatastreamController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/FedoraDatastreamController.java
index 93def6de3..9ae6b7b86 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/FedoraDatastreamController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/FedoraDatastreamController.java
@@ -45,7 +45,6 @@ import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
-import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
import fedora.client.FedoraClient;
import fedora.common.Constants;
import fedora.server.management.FedoraAPIM;
@@ -220,12 +219,22 @@ public class FedoraDatastreamController extends VitroHttpServlet implements Cons
}
@Override
+ public long maximumMultipartFileSize() {
+ return maxFileSize;
+ }
+
+ @Override
+ public boolean stashFileSizeException() {
+ return true;
+ }
+
+ @Override
public void doPost(HttpServletRequest rawRequest, HttpServletResponse res)
throws ServletException, IOException {
- try{
- FileUploadServletRequest req = FileUploadServletRequest.parseRequest(rawRequest, maxFileSize);
- if (req.hasFileUploadException()) {
- throw new FdcException("Size limit exceeded: " + req.getFileUploadException().getLocalizedMessage());
+ try{
+ VitroRequest req = new VitroRequest(rawRequest);
+ if (req.hasFileSizeException()) {
+ throw new FdcException("Size limit exceeded: " + req.getFileSizeException().getLocalizedMessage());
}
if (!req.isMultipart()) {
throw new FdcException("Must POST a multipart encoded request");
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java
index 537b4573c..d01d163e9 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java
@@ -2,12 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
@@ -36,7 +30,6 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo;
-import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
@@ -52,6 +45,7 @@ public class ImageUploadController extends FreemarkerHttpServlet {
private static final String ERROR_CODE_UNRECOGNIZED_URI = "imageUpload.errorUnrecognizedURI";
private static final String ERROR_CODE_NO_URI = "imageUpload.errorNoURI";
+ private static final String ERROR_CODE_FILE_TOO_BIG = "imageUpload.errorFileTooBig";
/** Limit file size to 6 megabytes. */
public static final int MAXIMUM_FILE_SIZE = 6 * 1024 * 1024;
@@ -136,6 +130,22 @@ public class ImageUploadController extends FreemarkerHttpServlet {
+ FileStorage.class.getName() + "'");
}
}
+
+ /**
+ * How large an image file will we accept?
+ */
+ @Override
+ public long maximumMultipartFileSize() {
+ return MAXIMUM_FILE_SIZE;
+ }
+
+ /**
+ * What will we do if there is a problem parsing the request?
+ */
+ @Override
+ public boolean stashFileSizeException() {
+ return true;
+ }
/**
* The required action depends on what we are trying to do.
@@ -171,52 +181,17 @@ public class ImageUploadController extends FreemarkerHttpServlet {
}
}
- /**
- *
- * Parse the multi-part request, process the request, and produce the
- * output.
- *
- *
- * If the request was a multi-part file upload, it will parse to a
- * normal-looking request with a "file_item_map" attribute.
- *
- *
- * The processing will produce a {@link ResponseValues} object, which
- * represents either a request for a FreeMarker template or a forwarding
- * operation.
- *
- *
If a FreeMarker template, we emulate the actions that
- * FreeMarkerHttpServlet would have taken to produce the output.
- *
If a forwarding operation, we create a {@link RequestDispatcher} to
- * do the forwarding.
- *
- *
- */
-
- @Override
- protected ResponseValues processRequest(VitroRequest vreq) {
- try {
- // Parse the multi-part request.
- FileUploadServletRequest.parseRequest(vreq, MAXIMUM_FILE_SIZE);
- if (log.isTraceEnabled()) {
- dumpRequestDetails(vreq);
- }
-
- return buildTheResponse(vreq);
- } catch (Exception e) {
- // log.error("Could not produce response page", e);
- return new ExceptionResponseValues(e);
- }
- }
-
/**
* Handle the different actions. If not specified, the default action is to
* show the intro screen.
*/
- private ResponseValues buildTheResponse(VitroRequest vreq) {
- String action = vreq.getParameter(PARAMETER_ACTION);
-
+ @Override
+ protected ResponseValues processRequest(VitroRequest vreq) {
try {
+ checkForFileTooBigException(vreq);
+
+ String action = vreq.getParameter(PARAMETER_ACTION);
+
Individual entity = validateEntityUri(vreq);
if (ACTION_UPLOAD.equals(action)) {
return doUploadImage(vreq, entity);
@@ -240,6 +215,19 @@ public class ImageUploadController extends FreemarkerHttpServlet {
}
}
+ /**
+ * If our exception handler caught a "file too big" exception, we need to
+ * deal with it before anything else, since we can't trust the other
+ * parameters.
+ */
+ private void checkForFileTooBigException(VitroRequest vreq)
+ throws UserMistakeException {
+ if (vreq.hasFileSizeException()) {
+ int limit = MAXIMUM_FILE_SIZE / (1024 * 1024);
+ throw new UserMistakeException(ERROR_CODE_FILE_TOO_BIG, limit);
+ }
+ }
+
/**
* We are just starting the upload process. Record where we came from, so if
* they hit "cancel" we know where to send them. If we have problems, just
@@ -626,31 +614,6 @@ public class ImageUploadController extends FreemarkerHttpServlet {
}
- /**
- * For debugging, dump all sorts of information about the request.
- *
- * WARNING: if "req" represents a Multi-part request which has not yet been
- * parsed, then reading these parameters will consume them.
- */
- @SuppressWarnings("unchecked")
- private void dumpRequestDetails(HttpServletRequest req) {
- log.trace("Request is " + req.getClass().getName());
-
- Map parms = req.getParameterMap();
- for (Entry entry : parms.entrySet()) {
- log.trace("Parameter '" + entry.getKey() + "'="
- + Arrays.deepToString(entry.getValue()));
- }
-
- Enumeration attrs = req.getAttributeNames();
- while (attrs.hasMoreElements()) {
- String key = attrs.nextElement();
- String valueString = String.valueOf(req.getAttribute(key));
- String valueOneLine = valueString.replace("\n", " | ");
- log.trace("Attribute '" + key + "'=" + valueOneLine);
- }
- }
-
static class Dimensions {
final int width;
final int height;
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java
index 68d0d00f6..3528ecc35 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java
@@ -2,12 +2,9 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
-import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.MAXIMUM_FILE_SIZE;
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.PARAMETER_UPLOADED_FILE;
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_HEIGHT;
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_WIDTH;
-import static edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest.FILE_ITEM_MAP;
-import static edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest.FILE_UPLOAD_EXCEPTION;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -21,7 +18,6 @@ import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.media.jai.util.ImagingListener;
import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.FilenameUtils;
@@ -41,7 +37,6 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper;
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileAlreadyExistsException;
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
-import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
/**
* Handle the mechanics of validating, storing, and deleting file images.
@@ -55,7 +50,6 @@ public class ImageUploadHelper {
private static final String ERROR_CODE_NO_IMAGE_TO_CROP = "imageUpload.errorNoImageForCropping";
private static final String ERROR_CODE_IMAGE_TOO_SMALL = "imageUpload.errorImageTooSmall";
private static final String ERROR_CODE_UNKNOWN = "imageUpload.errorUnknown";
- private static final String ERROR_CODE_FILE_TOO_BIG = "imageUpload.errorFileTooBig";
private static final String ERROR_CODE_UNRECOGNIZED_FILE_TYPE = "imageUpload.errorUnrecognizedFileType";
private static final String ERROR_CODE_NO_PHOTO_SELECTED = "imageUpload.errorNoPhotoSelected";
private static final String ERROR_CODE_BAD_MULTIPART_REQUEST = "imageUpload.errorBadMultipartRequest";
@@ -133,20 +127,13 @@ public class ImageUploadHelper {
* if there is no file, if it is empty, or if it is not an image
* file.
*/
- @SuppressWarnings("unchecked")
- FileItem validateImageFromRequest(HttpServletRequest request)
+ FileItem validateImageFromRequest(VitroRequest vreq)
throws UserMistakeException {
- Object exception = request.getAttribute(FILE_UPLOAD_EXCEPTION);
- if (exception != null) {
- int limit = MAXIMUM_FILE_SIZE / (1024 * 1024);
- throw new UserMistakeException(ERROR_CODE_FILE_TOO_BIG, limit);
- }
-
- Map> map = (Map>) request
- .getAttribute(FILE_ITEM_MAP);
+ Map> map = vreq.getFiles();
if (map == null) {
throw new IllegalStateException(ERROR_CODE_BAD_MULTIPART_REQUEST);
}
+
List list = map.get(PARAMETER_UPLOADED_FILE);
if ((list == null) || list.isEmpty()) {
throw new UserMistakeException(ERROR_CODE_FORM_FIELD_MISSING,
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaCsv2RdfController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaCsv2RdfController.java
index c310de156..877bb05c0 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaCsv2RdfController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaCsv2RdfController.java
@@ -25,7 +25,6 @@ import com.hp.hpl.jena.rdf.model.ModelMaker;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
-import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
import edu.cornell.mannlib.vitro.webapp.utils.Csv2Rdf;
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils;
@@ -37,6 +36,17 @@ public class JenaCsv2RdfController extends JenaIngestController {
private static final String CSV2RDF_SELECT_URI_JSP = "/jenaIngest/csv2rdfSelectUri.jsp";
private static int maxFileSizeInBytes = 1024 * 1024 * 2000; //2000mb
+
+ @Override
+ public long maximumMultipartFileSize() {
+ return maxFileSizeInBytes;
+ }
+
+ @Override
+ public boolean stashFileSizeException() {
+ return true;
+ }
+
@Override
public void doPost(HttpServletRequest rawRequest,
HttpServletResponse response) throws ServletException, IOException {
@@ -45,15 +55,13 @@ public class JenaCsv2RdfController extends JenaIngestController {
return;
}
- FileUploadServletRequest req = FileUploadServletRequest.parseRequest(rawRequest,
- maxFileSizeInBytes);
- if (req.hasFileUploadException()) {
- forwardToFileUploadError(req.getFileUploadException().getLocalizedMessage(), req, response);
+ VitroRequest request = new VitroRequest(rawRequest);
+ if (request.hasFileSizeException()) {
+ forwardToFileUploadError(request.getFileSizeException().getLocalizedMessage(), request, response);
return;
}
- VitroRequest request = new VitroRequest(req);
- Map> fileStreams = req.getFiles();
+ Map> fileStreams = request.getFiles();
FileItem fileStream = fileStreams.get("filePath").get(0);
String filePath = fileStreams.get("filePath").get(0).getName();
@@ -70,7 +78,7 @@ public class JenaCsv2RdfController extends JenaIngestController {
csv2rdfResult = doExecuteCsv2Rdf(
request, fileStream, filePath);
}catch(Exception ex){
- forwardToFileUploadError(ex.getMessage(),req,response);
+ forwardToFileUploadError(ex.getMessage(),request,response);
return;
}
ModelMaker maker = getVitroJenaModelMaker(request);
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaXMLFileUpload.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaXMLFileUpload.java
index f9ea1335b..39e862325 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaXMLFileUpload.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaXMLFileUpload.java
@@ -36,7 +36,6 @@ import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
-import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
public class JenaXMLFileUpload extends JenaIngestController {
Log log = LogFactory.getLog(JenaXMLFileUpload.class);
@@ -76,6 +75,16 @@ public class JenaXMLFileUpload extends JenaIngestController {
}
}
+ @Override
+ public long maximumMultipartFileSize() {
+ return maxFileSize;
+ }
+
+ @Override
+ public boolean stashFileSizeException() {
+ return true;
+ }
+
/**
* Each file will be converted to RDF/XML and loaded to the target model.
* If any of the files fail, no data will be loaded.
@@ -86,14 +95,14 @@ public class JenaXMLFileUpload extends JenaIngestController {
*
*/
@Override
- public void doPost(HttpServletRequest rawRequest, HttpServletResponse resp)
+ public void doPost(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
- FileUploadServletRequest request = FileUploadServletRequest.parseRequest(rawRequest, maxFileSize);
- if (request.hasFileUploadException()) {
+ VitroRequest vreq = new VitroRequest(request);
+ if (vreq.hasFileSizeException()) {
throw new ServletException("Size limit exceeded: "
- + request.getFileUploadException().getLocalizedMessage());
+ + vreq.getFileSizeException().getLocalizedMessage());
}
- if (request.isMultipart()) {
+ if (vreq.isMultipart()) {
log.debug("multipart content detected");
} else {
// TODO: forward to error message
@@ -105,7 +114,6 @@ public class JenaXMLFileUpload extends JenaIngestController {
return;
}
- VitroRequest vreq = new VitroRequest(request);
ModelMaker modelMaker = getVitroJenaModelMaker(vreq);
String targetModel = request.getParameter("targetModel");
if (targetModel == null) {
@@ -117,7 +125,7 @@ public class JenaXMLFileUpload extends JenaIngestController {
throw new ServletException("targetModel '" + targetModel + "' was not found.");
request.setAttribute("targetModel", targetModel);
- List filesToLoad = saveFiles( request.getFiles() );
+ List filesToLoad = saveFiles( vreq.getFiles() );
List rdfxmlToLoad = convertFiles( filesToLoad);
List modelsToLoad = loadRdfXml( rdfxmlToLoad );
@@ -136,7 +144,7 @@ public class JenaXMLFileUpload extends JenaIngestController {
request.setAttribute("title","Uploaded files and converted to RDF");
request.setAttribute("bodyJsp","/jenaIngest/xmlFileUploadSuccess.jsp");
- request.setAttribute("fileItems",request.getFiles());
+ request.setAttribute("fileItems",vreq.getFiles());
RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("css", "");
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java
index a196d8d28..bcb2eb635 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java
@@ -42,7 +42,6 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
-import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
@@ -56,31 +55,39 @@ public class RDFUploadController extends JenaIngestController {
private static FileItem fileStream = null;
private static final String LOAD_RDF_DATA_JSP="/jenaIngest/loadRDFData.jsp";
- public void doPost(HttpServletRequest rawRequest,
+ @Override
+ public long maximumMultipartFileSize() {
+ return maxFileSizeInBytes;
+ }
+
+ @Override
+ public boolean stashFileSizeException() {
+ return true;
+ }
+
+ public void doPost(HttpServletRequest req,
HttpServletResponse response) throws ServletException, IOException {
- if (!isAuthorizedToDisplayPage(rawRequest, response,
+ if (!isAuthorizedToDisplayPage(req, response,
SimplePermission.USE_ADVANCED_DATA_TOOLS_PAGES.ACTIONS)) {
return;
}
- FileUploadServletRequest req = FileUploadServletRequest.parseRequest(
- rawRequest, maxFileSizeInBytes);
- if (req.hasFileUploadException()) {
+ VitroRequest request = new VitroRequest(req);
+ if (request.hasFileSizeException()) {
forwardToFileUploadError(
- req.getFileUploadException().getLocalizedMessage(),
+ request.getFileSizeException().getLocalizedMessage(),
req, response);
return;
}
- Map> fileStreams = req.getFiles();
+ Map> fileStreams = request.getFiles();
- VitroRequest request = new VitroRequest(req);
LoginStatusBean loginBean = LoginStatusBean.getBean(request);
try {
String modelName = req.getParameter("modelName");
if(modelName!=null){
- loadRDF(req,request,response);
+ loadRDF(request,response);
return;
}
} catch (Exception e) {
@@ -234,15 +241,13 @@ public class RDFUploadController extends JenaIngestController {
}
}
- public void loadRDF(FileUploadServletRequest req,
- VitroRequest request,
- HttpServletResponse response)
- throws ServletException, IOException {
- Map> fileStreams = req.getFiles();
+ public void loadRDF(VitroRequest request, HttpServletResponse response)
+ throws ServletException {
+ Map> fileStreams = request.getFiles();
String filePath = fileStreams.get("filePath").get(0).getName();
fileStream = fileStreams.get("filePath").get(0);
- String modelName = req.getParameter("modelName");
- String docLoc = req.getParameter("docLoc");
+ String modelName = request.getParameter("modelName");
+ String docLoc = request.getParameter("docLoc");
String languageStr = request.getParameter("language");
ModelMaker maker = getVitroJenaModelMaker(request);
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 88175db88..490fff4ef 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
@@ -23,7 +23,6 @@ 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.search.indexing.IndexBuilder;
/**
@@ -35,7 +34,10 @@ public class SearchServiceController extends FreemarkerHttpServlet {
.getLog(SearchServiceController.class);
/** Limit file size to 1 Gigabyte. */
- public static final int MAXIMUM_FILE_SIZE = 1024 * 1024 * 1024;
+ @Override
+ public long maximumMultipartFileSize() {
+ return 1024 * 1024 * 1024;
+ }
/**
* Handle the different actions. If not specified, the default action is to
@@ -44,9 +46,6 @@ public class SearchServiceController extends FreemarkerHttpServlet {
@Override
protected ResponseValues processRequest(VitroRequest req) {
try {
- req = new VitroRequest(FileUploadServletRequest.parseRequest(req,
- MAXIMUM_FILE_SIZE));
-
// Check the authorization here, because we don't want to redirect
// to the login page if they are not authorized. (The file upload
// would be lost.
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/UpdateUrisInIndex.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/UpdateUrisInIndex.java
index 5c3e1636f..f723613ac 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/UpdateUrisInIndex.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/UpdateUrisInIndex.java
@@ -2,8 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.search.controller;
-import static edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest.FILE_ITEM_MAP;
-
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
@@ -21,6 +19,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
/**
@@ -41,9 +40,7 @@ public class UpdateUrisInIndex {
*/
protected int doUpdateUris(HttpServletRequest req, IndexBuilder builder)
throws ServletException, IOException {
- @SuppressWarnings("unchecked")
- Map> map = (Map>) req
- .getAttribute(FILE_ITEM_MAP);
+ Map> map = new VitroRequest(req).getFiles();
if (map == null) {
throw new ServletException("Expected Multipart Content");
}
@@ -54,13 +51,13 @@ public class UpdateUrisInIndex {
for (String name : map.keySet()) {
for (FileItem item : map.get(name)) {
log.debug("Found " + item.getSize() + " byte file for '" + name + "'");
- uriCount += processFileItem(builder, name, item, enc);
+ uriCount += processFileItem(builder, item, enc);
}
}
return uriCount;
}
- private int processFileItem(IndexBuilder builder, String name,
+ private int processFileItem(IndexBuilder builder,
FileItem item, Charset enc) throws IOException {
int count = 0;
Reader reader = new InputStreamReader(item.getInputStream(), enc.name());