/servlet/src/main/java/com/twelvemonkeys/servlet/fileupload/HttpFileUploadRequestWrapper.java

https://github.com/conceptboard/TwelveMonkeys · Java · 154 lines · 88 code · 22 blank · 44 comment · 11 complexity · 54b96d80966cdd5b390fb144bdf1cbbe MD5 · raw file

  1. /*
  2. * Copyright (c) 2008, Harald Kuhr
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name "TwelveMonkeys" nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  18. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  19. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  20. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  21. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  22. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  23. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  24. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  25. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. package com.twelvemonkeys.servlet.fileupload;
  29. import org.apache.commons.fileupload.*;
  30. import org.apache.commons.fileupload.servlet.ServletRequestContext;
  31. import org.apache.commons.fileupload.disk.DiskFileItemFactory;
  32. import javax.servlet.http.HttpServletRequestWrapper;
  33. import javax.servlet.http.HttpServletRequest;
  34. import javax.servlet.ServletException;
  35. import java.io.File;
  36. import java.util.*;
  37. /**
  38. * An {@code HttpFileUploadRequest} implementation, based on
  39. * <a href="http://jakarta.apache.org/commons/fileupload/">Jakarta Commons FileUpload</a>.
  40. *
  41. * @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
  42. * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/fileupload/HttpFileUploadRequestWrapper.java#1 $
  43. */
  44. class HttpFileUploadRequestWrapper extends HttpServletRequestWrapper implements HttpFileUploadRequest {
  45. private final Map<String, String[]> parameters = new HashMap<String, String[]>();
  46. private final Map<String, UploadedFile[]> files = new HashMap<String, UploadedFile[]>();
  47. public HttpFileUploadRequestWrapper(HttpServletRequest pRequest, File pUploadDir, long pMaxSize) throws ServletException {
  48. super(pRequest);
  49. DiskFileItemFactory factory = new DiskFileItemFactory(
  50. 128 * 1024, // 128 KByte
  51. new File(pUploadDir.getAbsolutePath())
  52. );
  53. FileUpload upload = new FileUpload(factory);
  54. upload.setSizeMax(pMaxSize);
  55. // TODO: Defer request parsing??
  56. try {
  57. //noinspection unchecked
  58. List<FileItem> items = upload.parseRequest(new ServletRequestContext(pRequest));
  59. for (FileItem item : items) {
  60. if (item.isFormField()) {
  61. processFormField(item.getFieldName(), item.getString());
  62. }
  63. else {
  64. processeFile(item);
  65. }
  66. }
  67. }
  68. catch (FileUploadBase.SizeLimitExceededException e) {
  69. throw new FileSizeExceededException(e);
  70. }
  71. catch (org.apache.commons.fileupload.FileUploadException e) {
  72. throw new FileUploadException(e);
  73. }
  74. }
  75. private void processeFile(final FileItem pItem) {
  76. UploadedFile value = new UploadedFileImpl(pItem);
  77. String name = pItem.getFieldName();
  78. UploadedFile[] values;
  79. UploadedFile[] oldValues = files.get(name);
  80. if (oldValues != null) {
  81. values = new UploadedFile[oldValues.length + 1];
  82. System.arraycopy(oldValues, 0, values, 0, oldValues.length);
  83. values[oldValues.length] = value;
  84. }
  85. else {
  86. values = new UploadedFile[] {value};
  87. }
  88. files.put(name, values);
  89. // Also add to normal fields
  90. processFormField(name, value.getName());
  91. }
  92. private void processFormField(String pName, String pValue) {
  93. // Multiple parameter values are not that common, so it's
  94. // probably faster to just use arrays...
  95. // TODO: Research and document...
  96. String[] values;
  97. String[] oldValues = parameters.get(pName);
  98. if (oldValues != null) {
  99. values = new String[oldValues.length + 1];
  100. System.arraycopy(oldValues, 0, values, 0, oldValues.length);
  101. values[oldValues.length] = pValue;
  102. }
  103. else {
  104. values = new String[] {pValue};
  105. }
  106. parameters.put(pName, values);
  107. }
  108. public Map getParameterMap() {
  109. // TODO: The spec dicates immutable map, but what about the value arrays?!
  110. // Probably just leave as-is, for performance
  111. return Collections.unmodifiableMap(parameters);
  112. }
  113. public Enumeration getParameterNames() {
  114. return Collections.enumeration(parameters.keySet());
  115. }
  116. public String getParameter(String pString) {
  117. String[] values = getParameterValues(pString);
  118. return values != null ? values[0] : null;
  119. }
  120. public String[] getParameterValues(String pString) {
  121. // TODO: Optimize?
  122. return parameters.get(pString).clone();
  123. }
  124. public UploadedFile getUploadedFile(String pName) {
  125. UploadedFile[] files = getUploadedFiles(pName);
  126. return files != null ? files[0] : null;
  127. }
  128. public UploadedFile[] getUploadedFiles(String pName) {
  129. // TODO: Optimize?
  130. return files.get(pName).clone();
  131. }
  132. }