1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.dispatcher.multipart;
23
24 import java.io.File;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.Enumeration;
29 import java.util.HashMap;
30 import java.util.Map;
31 import java.util.Vector;
32
33 import javax.servlet.http.HttpServletRequest;
34
35 import org.apache.struts2.dispatcher.StrutsRequestWrapper;
36
37 import com.opensymphony.xwork2.util.logging.Logger;
38 import com.opensymphony.xwork2.util.logging.LoggerFactory;
39
40
41 /***
42 * Parse a multipart request and provide a wrapper around the request. The parsing implementation used
43 * depends on the <tt>struts.multipart.parser</tt> setting. It should be set to a class which
44 * extends {@link org.apache.struts2.dispatcher.multipart.MultiPartRequest}.
45 * <p/>
46 * The <tt>struts.multipart.parser</tt> property should be set to <tt>jakarta</tt> for the
47 * Jakarta implementation, <tt>pell</tt> for the Pell implementation and <tt>cos</tt> for the Jason Hunter
48 * implementation.
49 * <p/>
50 * The files are uploaded when the object is instantiated. If there are any errors they are logged using
51 * {@link #addError(String)}. An action handling a multipart form should first check {@link #hasErrors()}
52 * before doing any other processing.
53 * <p/>
54 * An alternate implementation, PellMultiPartRequest, is provided as a plugin.
55 *
56 */
57 public class MultiPartRequestWrapper extends StrutsRequestWrapper {
58 protected static final Logger LOG = LoggerFactory.getLogger(MultiPartRequestWrapper.class);
59
60 Collection<String> errors;
61 MultiPartRequest multi;
62
63 /***
64 * Process file downloads and log any errors.
65 *
66 * @param request Our HttpServletRequest object
67 * @param saveDir Target directory for any files that we save
68 * @param multiPartRequest Our MultiPartRequest object
69 */
70 public MultiPartRequestWrapper(MultiPartRequest multiPartRequest, HttpServletRequest request, String saveDir) {
71 super(request);
72
73 multi = multiPartRequest;
74 try {
75 multi.parse(request, saveDir);
76 for (Object o : multi.getErrors()) {
77 String error = (String) o;
78 addError(error);
79 }
80 } catch (IOException e) {
81 addError("Cannot parse request: "+e.toString());
82 }
83 }
84
85 /***
86 * Get an enumeration of the parameter names for uploaded files
87 *
88 * @return enumeration of parameter names for uploaded files
89 */
90 public Enumeration<String> getFileParameterNames() {
91 if (multi == null) {
92 return null;
93 }
94
95 return multi.getFileParameterNames();
96 }
97
98 /***
99 * Get an array of content encoding for the specified input field name or <tt>null</tt> if
100 * no content type was specified.
101 *
102 * @param name input field name
103 * @return an array of content encoding for the specified input field name
104 */
105 public String[] getContentTypes(String name) {
106 if (multi == null) {
107 return null;
108 }
109
110 return multi.getContentType(name);
111 }
112
113 /***
114 * Get a {@link java.io.File[]} for the given input field name.
115 *
116 * @param fieldName input field name
117 * @return a File[] object for files associated with the specified input field name
118 */
119 public File[] getFiles(String fieldName) {
120 if (multi == null) {
121 return null;
122 }
123
124 return multi.getFile(fieldName);
125 }
126
127 /***
128 * Get a String array of the file names for uploaded files
129 *
130 * @param fieldName Field to check for file names.
131 * @return a String[] of file names for uploaded files
132 */
133 public String[] getFileNames(String fieldName) {
134 if (multi == null) {
135 return null;
136 }
137
138 return multi.getFileNames(fieldName);
139 }
140
141 /***
142 * Get the filename(s) of the file(s) uploaded for the given input field name.
143 * Returns <tt>null</tt> if the file is not found.
144 *
145 * @param fieldName input field name
146 * @return the filename(s) of the file(s) uploaded for the given input field name or
147 * <tt>null</tt> if name not found.
148 */
149 public String[] getFileSystemNames(String fieldName) {
150 if (multi == null) {
151 return null;
152 }
153
154 return multi.getFilesystemName(fieldName);
155 }
156
157 /***
158 * @see javax.servlet.http.HttpServletRequest#getParameter(String)
159 */
160 public String getParameter(String name) {
161 return ((multi == null) || (multi.getParameter(name) == null)) ? super.getParameter(name) : multi.getParameter(name);
162 }
163
164 /***
165 * @see javax.servlet.http.HttpServletRequest#getParameterMap()
166 */
167 public Map getParameterMap() {
168 Map<String, String[]> map = new HashMap<String, String[]>();
169 Enumeration enumeration = getParameterNames();
170
171 while (enumeration.hasMoreElements()) {
172 String name = (String) enumeration.nextElement();
173 map.put(name, this.getParameterValues(name));
174 }
175
176 return map;
177 }
178
179 /***
180 * @see javax.servlet.http.HttpServletRequest#getParameterNames()
181 */
182 public Enumeration getParameterNames() {
183 if (multi == null) {
184 return super.getParameterNames();
185 } else {
186 return mergeParams(multi.getParameterNames(), super.getParameterNames());
187 }
188 }
189
190 /***
191 * @see javax.servlet.http.HttpServletRequest#getParameterValues(String)
192 */
193 public String[] getParameterValues(String name) {
194 return ((multi == null) || (multi.getParameterValues(name) == null)) ? super.getParameterValues(name) : multi.getParameterValues(name);
195 }
196
197 /***
198 * Returns <tt>true</tt> if any errors occured when parsing the HTTP multipart request, <tt>false</tt> otherwise.
199 *
200 * @return <tt>true</tt> if any errors occured when parsing the HTTP multipart request, <tt>false</tt> otherwise.
201 */
202 public boolean hasErrors() {
203 return !((errors == null) || errors.isEmpty());
204 }
205
206 /***
207 * Returns a collection of any errors generated when parsing the multipart request.
208 *
209 * @return the error Collection.
210 */
211 public Collection<String> getErrors() {
212 return errors;
213 }
214
215 /***
216 * Adds an error message.
217 *
218 * @param anErrorMessage the error message to report.
219 */
220 protected void addError(String anErrorMessage) {
221 if (errors == null) {
222 errors = new ArrayList<String>();
223 }
224
225 errors.add(anErrorMessage);
226 }
227
228 /***
229 * Merges 2 enumeration of parameters as one.
230 *
231 * @param params1 the first enumeration.
232 * @param params2 the second enumeration.
233 * @return a single Enumeration of all elements from both Enumerations.
234 */
235 protected Enumeration mergeParams(Enumeration params1, Enumeration params2) {
236 Vector temp = new Vector();
237
238 while (params1.hasMoreElements()) {
239 temp.add(params1.nextElement());
240 }
241
242 while (params2.hasMoreElements()) {
243 temp.add(params2.nextElement());
244 }
245
246 return temp.elements();
247 }
248 }