KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensymphony > webwork > interceptor > FileUploadInterceptor


1 /*
2  * Copyright (c) 2002-2003 by OpenSymphony
3  * All rights reserved.
4  */

5 package com.opensymphony.webwork.interceptor;
6
7 import com.opensymphony.webwork.ServletActionContext;
8 import com.opensymphony.webwork.dispatcher.multipart.MultiPartRequestWrapper;
9 import com.opensymphony.xwork.ActionInvocation;
10 import com.opensymphony.xwork.ValidationAware;
11 import com.opensymphony.xwork.interceptor.Interceptor;
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14
15 import java.io.File JavaDoc;
16 import java.util.*;
17
18 /**
19  * Interceptor that is based off of {@link MultiPartRequestWrapper}. It adds the following
20  * parameters, where [File Name] is the name given to the file uploaded by the HTML form:
21  * <ul>
22  * <li>[File Name] : File - the actual File</li>
23  * <li>[File Name]ContentType : String - the content type of the file</li>
24  * <li>[File Name]FileName : String - the actual name of the file uploaded (not the HTML name)</li>
25  * </ul>
26  * <p/>
27  * You can get access to these files by merely providing setters in your action that correspond to any
28  * of the three patterns above, such as setDocument(File document), setDocumentContentType(String contentType), etc.
29  */

30 public class FileUploadInterceptor implements Interceptor {
31 //~ Static fields/initializers /////////////////////////////////////////////
32

33     protected static final Log log = LogFactory.getLog(FileUploadInterceptor.class);
34
35     private static final String JavaDoc DEFAULT_DELIMITER = ",";
36
37 //~ Instance fields ////////////////////////////////////////////////////////
38

39     protected Long JavaDoc maximumSize;
40     protected String JavaDoc allowedTypes;
41     protected String JavaDoc disallowedTypes;
42     protected Set allowedTypesSet;
43     protected Set disallowedTypesSet;
44
45 //~ Methods ////////////////////////////////////////////////////////////////
46

47     public void setAllowedTypes(String JavaDoc allowedTypes) {
48         this.allowedTypes = allowedTypes;
49
50 // set the allowedTypes as a collection for easier access later
51
allowedTypesSet = getDelimitedValues(allowedTypes);
52     }
53
54     public void setDisallowedTypes(String JavaDoc disallowedTypes) {
55         this.disallowedTypes = disallowedTypes;
56
57 // set the disallowedTypes as a collection for easier access later
58
disallowedTypesSet = getDelimitedValues(disallowedTypes);
59     }
60
61     public void setMaximumSize(Long JavaDoc maximumSize) {
62         this.maximumSize = maximumSize;
63     }
64
65     public void destroy() {
66     }
67
68     public void init() {
69     }
70
71     public String JavaDoc intercept(ActionInvocation invocation) throws Exception JavaDoc {
72         if (!(ServletActionContext.getRequest() instanceof MultiPartRequestWrapper)) {
73             if (log.isDebugEnabled()) {
74                 log.debug("bypass " + invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName());
75             }
76
77             return invocation.invoke();
78         }
79
80         final Object JavaDoc action = invocation.getAction();
81         ValidationAware validation = null;
82
83         if (action instanceof ValidationAware) {
84             validation = (ValidationAware) action;
85         }
86
87         MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) ServletActionContext.getRequest();
88
89         if (multiWrapper.hasErrors()) {
90             for (Iterator errorIter = multiWrapper.getErrors().iterator(); errorIter.hasNext();) {
91                 String JavaDoc error = (String JavaDoc) errorIter.next();
92
93                 if (validation != null) {
94                     validation.addActionError(error);
95                 }
96
97                 log.error(error);
98             }
99         }
100
101         Map parameters = invocation.getInvocationContext().getParameters();
102
103 // Bind allowed Files
104
Enumeration fileParameterNames = multiWrapper.getFileParameterNames();
105         while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
106 // get the value of this input tag
107
String JavaDoc inputName = (String JavaDoc) fileParameterNames.nextElement();
108
109 // get the content type
110
String JavaDoc[] contentType = multiWrapper.getContentTypes(inputName);
111
112             if (isNonEmpty(contentType)) {
113 // get the name of the file from the input tag
114
String JavaDoc[] fileName = multiWrapper.getFileNames(inputName);
115
116                 if (isNonEmpty(fileName)) {
117                     // Get a File object for the uploaded File
118
File JavaDoc[] files = multiWrapper.getFiles(inputName);
119                     if (files != null) {
120                         for (int index = 0; index < files.length; index++) {
121                             log.info("file " + inputName + " " + contentType[index] + " " + fileName[index] + " " + files[index]);
122
123                             if (acceptFile(files[0], contentType[0], inputName, validation)) {
124                                 parameters.put(inputName, files);
125                                 parameters.put(inputName + "ContentType", contentType);
126                                 parameters.put(inputName + "FileName", fileName);
127                             }
128                         }
129                     }
130                 } else {
131                     log.error("Could not find a Filename for " + inputName + ". Verify that a valid file was submitted.");
132                 }
133             } else {
134                 log.error("Could not find a Content-Type for " + inputName + ". Verify that a valid file was submitted.");
135             }
136         }
137
138 // invoke action
139
String JavaDoc result = invocation.invoke();
140
141 // cleanup
142
fileParameterNames = multiWrapper.getFileParameterNames();
143         while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
144             String JavaDoc inputValue = (String JavaDoc) fileParameterNames.nextElement();
145             File JavaDoc[] file = multiWrapper.getFiles(inputValue);
146             for (int index = 0; index < file.length; index++) {
147                 File JavaDoc currentFile = file[index];
148                 log.info("removing file " + inputValue + " " + currentFile);
149
150                 if ((currentFile != null) && currentFile.isFile()) {
151                     currentFile.delete();
152                 }
153             }
154         }
155
156         return result;
157     }
158
159     /**
160      * Override for added functionality. Checks if the proposed file is acceptable by contentType and size.
161      *
162      * @param file - proposed upload file.
163      * @param contentType - contentType of the file.
164      * @param inputName - inputName of the file.
165      * @param validation - Non-null ValidationAware if the action implements ValidationAware, allowing for better logging.
166      * @return true if the proposed file is acceptable by contentType and size.
167      */

168     protected boolean acceptFile(File JavaDoc file, String JavaDoc contentType, String JavaDoc inputName, ValidationAware validation) {
169         boolean fileIsAcceptable = false;
170
171 // If it's null the upload failed
172
if (file == null) {
173             if (validation != null) {
174                 validation.addFieldError(inputName, "Could not upload file.");
175             }
176
177             log.error("Error uploading: " + inputName);
178
179         } else if (maximumSize != null && maximumSize.longValue() < file.length()) {
180             String JavaDoc errMsg = "File too large: " + inputName + " \"" + file.getName() + "\" " + file.length();
181             if (validation != null) {
182                 validation.addFieldError(inputName, errMsg);
183             }
184
185             log.error(errMsg);
186
187         } else if (containsItem(disallowedTypesSet, contentType)) {
188             String JavaDoc errMsg = "Content-Type disallowed: " + inputName + " \"" + file.getName() + "\" " + contentType;
189             if (validation != null) {
190                 validation.addFieldError(inputName, errMsg);
191             }
192
193             log.error(errMsg);
194
195         } else if (!containsItem(allowedTypesSet, contentType)) {
196             String JavaDoc errMsg = "Content-Type not allowed: " + inputName + " \"" + file.getName() + "\" " + contentType;
197             if (validation != null) {
198                 validation.addFieldError(inputName, errMsg);
199             }
200
201             log.error(errMsg);
202
203         } else {
204             fileIsAcceptable = true;
205         }
206
207         return fileIsAcceptable;
208     }
209
210     /**
211      * @param itemCollection - Collection of string items (all lowercase).
212      * @param key - Key to search for.
213      * @return true if itemCollection contains the key.
214      */

215     private static boolean containsItem(Collection itemCollection, String JavaDoc key) {
216         return itemCollection.contains(key.toLowerCase());
217     }
218
219     private static Set getDelimitedValues(String JavaDoc delimitedString) {
220         Set delimitedValues = new HashSet();
221         if (delimitedString != null) {
222             StringTokenizer stringTokenizer = new StringTokenizer(delimitedString, DEFAULT_DELIMITER);
223             while (stringTokenizer.hasMoreTokens()) {
224                 String JavaDoc nextToken = stringTokenizer.nextToken().toLowerCase().trim();
225                 if (nextToken.length() > 0) {
226                     delimitedValues.add(nextToken);
227                 }
228             }
229         }
230         return delimitedValues;
231     }
232
233     private static boolean isNonEmpty(Object JavaDoc[] objArray) {
234         boolean result = false;
235         for (int index = 0; index < objArray.length && !result; index++) {
236             if (objArray[index] != null) {
237                 result = true;
238             }
239         }
240         return result;
241     }
242 }
243
Popular Tags