001: /*
002: * Copyright (c) 2002-2006 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.dispatcher.multipart;
006:
007: import org.apache.commons.fileupload.*;
008: import org.apache.commons.fileupload.servlet.ServletFileUpload;
009: import org.apache.commons.fileupload.disk.DiskFileItemFactory;
010: import org.apache.commons.fileupload.disk.DiskFileItem;
011:
012: import javax.servlet.http.HttpServletRequest;
013: import java.io.File;
014: import java.io.IOException;
015: import java.io.InputStream;
016: import java.util.*;
017:
018: /**
019: * Multipart form data request adapter for Jakarta's file upload package.
020: *
021: * @author Bruce Ritchie
022: */
023: public class JakartaMultiPartRequest extends MultiPartRequest {
024: // maps parameter name -> List of FileItem objects
025: private Map files = new HashMap();
026: // maps parameter name -> List of param values
027: private Map params = new HashMap();
028: // any errors while processing this request
029: private List errors = new ArrayList();
030:
031: /**
032: * Creates a new request wrapper to handle multi-part data using methods adapted from Jason Pell's
033: * multipart classes (see class description).
034: *
035: * @param maxSize maximum size post allowed
036: * @param saveDir the directory to save off the file
037: * @param servletRequest the request containing the multipart
038: * @throws java.io.IOException is thrown if encoding fails.
039: */
040: public JakartaMultiPartRequest(HttpServletRequest servletRequest,
041: String saveDir, int maxSize) throws IOException {
042: DiskFileItemFactory fac = new DiskFileItemFactory();
043: fac.setSizeThreshold(0);
044: if (saveDir != null) {
045: fac.setRepository(new File(saveDir));
046: }
047:
048: // Parse the request
049: try {
050: ServletFileUpload upload = new ServletFileUpload(fac);
051: List items = upload
052: .parseRequest(createRequestContext(servletRequest));
053:
054: for (int i = 0; i < items.size(); i++) {
055: FileItem item = (FileItem) items.get(i);
056: if (log.isDebugEnabled())
057: log.debug("Found item " + item.getFieldName());
058: if (item.isFormField()) {
059: log.debug("Item is a normal form field");
060: List values;
061: if (params.get(item.getFieldName()) != null) {
062: values = (List) params.get(item.getFieldName());
063: } else {
064: values = new ArrayList();
065: }
066:
067: // note: see http://jira.opensymphony.com/browse/WW-633
068: // basically, in some cases the charset may be null, so
069: // we're just going to try to "other" method (no idea if this
070: // will work)
071: String charset = servletRequest
072: .getCharacterEncoding();
073: if (charset != null) {
074: values.add(item.getString(charset));
075: } else {
076: values.add(item.getString());
077: }
078: params.put(item.getFieldName(), values);
079: } else if (item.getSize() == 0) {
080: log
081: .warn("Item is a file upload of 0 size, ignoring");
082: } else {
083: log.debug("Item is a file upload");
084:
085: List values;
086: if (files.get(item.getFieldName()) != null) {
087: values = (List) files.get(item.getFieldName());
088: } else {
089: values = new ArrayList();
090: }
091:
092: values.add(item);
093: files.put(item.getFieldName(), values);
094: }
095: }
096: } catch (FileUploadException e) {
097: log.error(e, e);
098: errors.add(e.getMessage());
099: }
100: }
101:
102: public Enumeration getFileParameterNames() {
103: return Collections.enumeration(files.keySet());
104: }
105:
106: public String[] getContentType(String fieldName) {
107: List items = (List) files.get(fieldName);
108:
109: if (items == null) {
110: return null;
111: }
112:
113: List contentTypes = new ArrayList(items.size());
114: for (int i = 0; i < items.size(); i++) {
115: FileItem fileItem = (FileItem) items.get(i);
116: contentTypes.add(fileItem.getContentType());
117: }
118:
119: return (String[]) contentTypes.toArray(new String[contentTypes
120: .size()]);
121: }
122:
123: public File[] getFile(String fieldName) {
124: List items = (List) files.get(fieldName);
125:
126: if (items == null) {
127: return null;
128: }
129:
130: List fileList = new ArrayList(items.size());
131: for (int i = 0; i < items.size(); i++) {
132: DiskFileItem fileItem = (DiskFileItem) items.get(i);
133: fileList.add(fileItem.getStoreLocation());
134: }
135:
136: return (File[]) fileList.toArray(new File[fileList.size()]);
137: }
138:
139: public String[] getFileNames(String fieldName) {
140: List items = (List) files.get(fieldName);
141:
142: if (items == null) {
143: return null;
144: }
145:
146: List fileNames = new ArrayList(items.size());
147: for (int i = 0; i < items.size(); i++) {
148: DiskFileItem fileItem = (DiskFileItem) items.get(i);
149: fileNames.add(getCanonicalName(fileItem.getName()));
150: }
151:
152: return (String[]) fileNames
153: .toArray(new String[fileNames.size()]);
154: }
155:
156: public String[] getFilesystemName(String fieldName) {
157: List items = (List) files.get(fieldName);
158:
159: if (items == null) {
160: return null;
161: }
162:
163: List fileNames = new ArrayList(items.size());
164: for (int i = 0; i < items.size(); i++) {
165: DiskFileItem fileItem = (DiskFileItem) items.get(i);
166: fileNames.add(fileItem.getStoreLocation().getName());
167: }
168:
169: return (String[]) fileNames
170: .toArray(new String[fileNames.size()]);
171: }
172:
173: public String getParameter(String name) {
174: List v = (List) params.get(name);
175: if (v != null && v.size() > 0) {
176: return (String) v.get(0);
177: }
178:
179: return null;
180: }
181:
182: public Enumeration getParameterNames() {
183: return Collections.enumeration(params.keySet());
184: }
185:
186: public String[] getParameterValues(String name) {
187: List v = (List) params.get(name);
188: if (v != null && v.size() > 0) {
189: return (String[]) v.toArray(new String[v.size()]);
190: }
191:
192: return null;
193: }
194:
195: public List getErrors() {
196: return errors;
197: }
198:
199: /**
200: * Returns the canonical name of the given file.
201: *
202: * @param filename the given file
203: * @return the canonical name of the given file
204: */
205: private String getCanonicalName(String filename) {
206: int forwardSlash = filename.lastIndexOf("/");
207: int backwardSlash = filename.lastIndexOf("\\");
208: if (forwardSlash != -1 && forwardSlash > backwardSlash) {
209: filename = filename.substring(forwardSlash + 1, filename
210: .length());
211: } else if (backwardSlash != -1 && backwardSlash >= forwardSlash) {
212: filename = filename.substring(backwardSlash + 1, filename
213: .length());
214: }
215:
216: return filename;
217: }
218:
219: /**
220: * Creates a RequestContext needed by Jakarta Commons Upload.
221: *
222: * @param req the request.
223: * @return a new request context.
224: */
225: private RequestContext createRequestContext(
226: final HttpServletRequest req) {
227: return new RequestContext() {
228: public String getCharacterEncoding() {
229: return req.getCharacterEncoding();
230: }
231:
232: public String getContentType() {
233: return req.getContentType();
234: }
235:
236: public int getContentLength() {
237: return req.getContentLength();
238: }
239:
240: public InputStream getInputStream() throws IOException {
241: return req.getInputStream();
242: }
243: };
244: }
245:
246: }
|