1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.dispatcher.multipart;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Enumeration;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import javax.servlet.http.HttpServletRequest;
31
32 import org.apache.commons.fileupload.FileItem;
33 import org.apache.commons.fileupload.FileUploadException;
34 import org.apache.commons.fileupload.RequestContext;
35 import org.apache.commons.fileupload.disk.DiskFileItem;
36 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
37 import org.apache.commons.fileupload.servlet.ServletFileUpload;
38
39 /***
40 * Multipart form data request adapter for Jakarta Commons Fileupload package.
41 *
42 */
43 public class JakartaMultiPartRequest extends MultiPartRequest {
44
45 private Map<String,List<FileItem>> files = new HashMap<String,List<FileItem>>();
46
47 private Map<String,List<String>> params = new HashMap<String,List<String>>();
48
49 private List<String> errors = new ArrayList<String>();
50
51 /***
52 * Creates a new request wrapper to handle multi-part data using methods adapted from Jason Pell's
53 * multipart classes (see class description).
54 *
55 * @param maxSize maximum size post allowed
56 * @param saveDir the directory to save off the file
57 * @param servletRequest the request containing the multipart
58 * @throws java.io.IOException is thrown if encoding fails.
59 */
60 public JakartaMultiPartRequest(HttpServletRequest servletRequest, String saveDir, int maxSize)
61 throws IOException {
62 DiskFileItemFactory fac = new DiskFileItemFactory();
63 fac.setSizeThreshold(0);
64 if (saveDir != null) {
65 fac.setRepository(new File(saveDir));
66 }
67
68
69 try {
70 ServletFileUpload upload = new ServletFileUpload(fac);
71 List items = upload.parseRequest(createRequestContext(servletRequest));
72
73 for (int i = 0; i < items.size(); i++) {
74 FileItem item = (FileItem) items.get(i);
75 if (log.isDebugEnabled()) log.debug("Found item " + item.getFieldName());
76 if (item.isFormField()) {
77 log.debug("Item is a normal form field");
78 List<String> values;
79 if (params.get(item.getFieldName()) != null) {
80 values = params.get(item.getFieldName());
81 } else {
82 values = new ArrayList<String>();
83 }
84
85
86
87
88
89 String charset = servletRequest.getCharacterEncoding();
90 if (charset != null) {
91 values.add(item.getString(charset));
92 } else {
93 values.add(item.getString());
94 }
95 params.put(item.getFieldName(), values);
96 } else {
97 log.debug("Item is a file upload");
98
99 List<FileItem> values;
100 if (files.get(item.getFieldName()) != null) {
101 values = files.get(item.getFieldName());
102 } else {
103 values = new ArrayList<FileItem>();
104 }
105
106 values.add(item);
107 files.put(item.getFieldName(), values);
108 }
109 }
110 } catch (FileUploadException e) {
111 log.error(e);
112 errors.add(e.getMessage());
113 }
114 }
115
116
117
118
119 public Enumeration<String> getFileParameterNames() {
120 return Collections.enumeration(files.keySet());
121 }
122
123
124
125
126 public String[] getContentType(String fieldName) {
127 List items = (List) files.get(fieldName);
128
129 if (items == null) {
130 return null;
131 }
132
133 List<String> contentTypes = new ArrayList<String>(items.size());
134 for (int i = 0; i < items.size(); i++) {
135 FileItem fileItem = (FileItem) items.get(i);
136 contentTypes.add(fileItem.getContentType());
137 }
138
139 return (String[]) contentTypes.toArray(new String[contentTypes.size()]);
140 }
141
142
143
144
145 public File[] getFile(String fieldName) {
146 List items = (List) files.get(fieldName);
147
148 if (items == null) {
149 return null;
150 }
151
152 List<File> fileList = new ArrayList<File>(items.size());
153 for (int i = 0; i < items.size(); i++) {
154 DiskFileItem fileItem = (DiskFileItem) items.get(i);
155 fileList.add(fileItem.getStoreLocation());
156 }
157
158 return (File[]) fileList.toArray(new File[fileList.size()]);
159 }
160
161
162
163
164 public String[] getFileNames(String fieldName) {
165 List<FileItem> items = files.get(fieldName);
166
167 if (items == null) {
168 return null;
169 }
170
171 List<String> fileNames = new ArrayList<String>(items.size());
172 for (int i = 0; i < items.size(); i++) {
173 DiskFileItem fileItem = (DiskFileItem) items.get(i);
174 fileNames.add(getCanonicalName(fileItem.getName()));
175 }
176
177 return (String[]) fileNames.toArray(new String[fileNames.size()]);
178 }
179
180
181
182
183 public String[] getFilesystemName(String fieldName) {
184 List items = (List) files.get(fieldName);
185
186 if (items == null) {
187 return null;
188 }
189
190 List<String> fileNames = new ArrayList<String>(items.size());
191 for (int i = 0; i < items.size(); i++) {
192 DiskFileItem fileItem = (DiskFileItem) items.get(i);
193 fileNames.add(fileItem.getStoreLocation().getName());
194 }
195
196 return (String[]) fileNames.toArray(new String[fileNames.size()]);
197 }
198
199
200
201
202 public String getParameter(String name) {
203 List v = (List) params.get(name);
204 if (v != null && v.size() > 0) {
205 return (String) v.get(0);
206 }
207
208 return null;
209 }
210
211
212
213
214 public Enumeration<String> getParameterNames() {
215 return Collections.enumeration(params.keySet());
216 }
217
218
219
220
221 public String[] getParameterValues(String name) {
222 List<String> v = params.get(name);
223 if (v != null && v.size() > 0) {
224 return (String[]) v.toArray(new String[v.size()]);
225 }
226
227 return null;
228 }
229
230
231
232
233 public List getErrors() {
234 return errors;
235 }
236
237 /***
238 * Returns the canonical name of the given file.
239 *
240 * @param filename the given file
241 * @return the canonical name of the given file
242 */
243 private String getCanonicalName(String filename) {
244 int forwardSlash = filename.lastIndexOf("/");
245 int backwardSlash = filename.lastIndexOf("//");
246 if (forwardSlash != -1 && forwardSlash > backwardSlash) {
247 filename = filename.substring(forwardSlash + 1, filename.length());
248 } else if (backwardSlash != -1 && backwardSlash >= forwardSlash) {
249 filename = filename.substring(backwardSlash + 1, filename.length());
250 }
251
252 return filename;
253 }
254
255 /***
256 * Creates a RequestContext needed by Jakarta Commons Upload.
257 *
258 * @param req the request.
259 * @return a new request context.
260 */
261 private RequestContext createRequestContext(final HttpServletRequest req) {
262 return new RequestContext() {
263 public String getCharacterEncoding() {
264 return req.getCharacterEncoding();
265 }
266
267 public String getContentType() {
268 return req.getContentType();
269 }
270
271 public int getContentLength() {
272 return req.getContentLength();
273 }
274
275 public InputStream getInputStream() throws IOException {
276 return req.getInputStream();
277 }
278 };
279 }
280
281 }