View Javadoc

1   /*
2    * $Id: MultiPartRequestWrapper.java 651946 2008-04-27 13:41:38Z apetrelli $
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  
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 }