View Javadoc

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