KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > riotfamily > forms > element > upload > FileUpload


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1
3  * The contents of this file are subject to the Mozilla Public License Version
4  * 1.1 (the "License"); you may not use this file except in compliance with
5  * the License. You may obtain a copy of the License at
6  * http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the
11  * License.
12  *
13  * The Original Code is Riot.
14  *
15  * The Initial Developer of the Original Code is
16  * Neteye GmbH.
17  * Portions created by the Initial Developer are Copyright (C) 2006
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  * Felix Gnass [fgnass at neteye dot de]
22  *
23  * ***** END LICENSE BLOCK ***** */

24 package org.riotfamily.forms.element.upload;
25
26 import java.io.File JavaDoc;
27 import java.io.FileInputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.PrintWriter JavaDoc;
30
31 import javax.activation.MimetypesFileTypeMap JavaDoc;
32 import javax.servlet.http.HttpServletRequest JavaDoc;
33 import javax.servlet.http.HttpServletResponse JavaDoc;
34
35 import org.riotfamily.common.util.FormatUtils;
36 import org.riotfamily.common.web.file.FileStore;
37 import org.riotfamily.forms.CompositeElement;
38 import org.riotfamily.forms.ContentElement;
39 import org.riotfamily.forms.Editor;
40 import org.riotfamily.forms.EditorBinder;
41 import org.riotfamily.forms.Element;
42 import org.riotfamily.forms.ErrorUtils;
43 import org.riotfamily.forms.element.TemplateElement;
44 import org.riotfamily.forms.event.Button;
45 import org.riotfamily.forms.event.JavaScriptEvent;
46 import org.riotfamily.forms.event.JavaScriptEventAdapter;
47 import org.riotfamily.forms.fileupload.UploadStatus;
48 import org.riotfamily.forms.request.FormRequest;
49 import org.riotfamily.forms.resource.FormResource;
50 import org.riotfamily.forms.resource.ResourceElement;
51 import org.riotfamily.forms.resource.ScriptResource;
52 import org.riotfamily.forms.resource.StylesheetResource;
53 import org.springframework.util.Assert;
54 import org.springframework.util.FileCopyUtils;
55 import org.springframework.util.ObjectUtils;
56 import org.springframework.util.StringUtils;
57 import org.springframework.web.multipart.MultipartFile;
58
59
60 /**
61  * A widget to upload files.
62  */

63 public class FileUpload extends CompositeElement implements Editor,
64         ResourceElement {
65
66     private static MimetypesFileTypeMap JavaDoc defaultMimetypesMap =
67             new MimetypesFileTypeMap JavaDoc();
68
69     protected static FormResource RESOURCE = new ScriptResource(
70             "form/fileupload/upload.js", null,
71             new StylesheetResource("form/fileupload/progress.css"));
72
73     private String JavaDoc filenameProperty;
74
75     private String JavaDoc contentTypeProperty;
76
77     private String JavaDoc sizeProperty;
78
79     private MimetypesFileTypeMap JavaDoc mimetypesMap;
80
81     private FileStore fileStore;
82
83     private String JavaDoc uri;
84
85     private File JavaDoc file;
86
87     private File JavaDoc tempFile;
88
89     private File JavaDoc returnedFile;
90
91     private String JavaDoc fileName;
92
93     private String JavaDoc contentType;
94
95     private Long JavaDoc size;
96
97
98     public FileUpload() {
99         addComponent(new UploadElement());
100         addComponent(new RemoveButton());
101         addComponent(createPreviewElement());
102         setSurroundBySpan(true);
103     }
104
105     protected Element createPreviewElement() {
106         return new PreviewElement();
107     }
108
109     public FileStore getFileStore() {
110         return this.fileStore;
111     }
112
113     public void setFileStore(FileStore fileStore) {
114         this.fileStore = fileStore;
115     }
116
117     public FormResource getResource() {
118         return RESOURCE;
119     }
120
121     public void setFilenameProperty(String JavaDoc property) {
122         this.filenameProperty = property;
123     }
124
125     public void setContentTypeProperty(String JavaDoc property) {
126         this.contentTypeProperty = property;
127     }
128
129     public void setSizeProperty(String JavaDoc property) {
130         this.sizeProperty = property;
131     }
132
133     public String JavaDoc getSizeProperty() {
134         return this.sizeProperty;
135     }
136
137     public String JavaDoc getContentType() {
138         return contentType;
139     }
140
141     public String JavaDoc getFileName() {
142         return fileName;
143     }
144
145     public Long JavaDoc getSize() {
146         return size;
147     }
148
149     public String JavaDoc getFormatedSize() {
150         if (size != null) {
151             return FormatUtils.formatByteSize(size.longValue());
152         }
153         return null;
154     }
155
156     public boolean isPresent() {
157         return file != null;
158     }
159
160     protected File JavaDoc getFile() {
161         return this.file;
162     }
163
164     protected void setFile(File JavaDoc file) {
165         this.file = file;
166         this.size = new Long JavaDoc(file.length());
167         revalidate();
168     }
169
170     protected void afterFileUploaded() {
171     }
172
173     protected File JavaDoc getTempFile() {
174         return tempFile;
175     }
176
177     protected File JavaDoc getReturnedFile() {
178         return returnedFile;
179     }
180
181     protected void setContentType(String JavaDoc contentType) {
182         this.contentType = contentType;
183     }
184
185     public void setMimetypesMap(MimetypesFileTypeMap JavaDoc mimetypesMap) {
186         this.mimetypesMap = mimetypesMap;
187     }
188
189     protected String JavaDoc contentType(File JavaDoc file) {
190         if (mimetypesMap == null) {
191             mimetypesMap = defaultMimetypesMap;
192         }
193         return mimetypesMap.getContentType(file);
194     }
195
196     public void setValue(Object JavaDoc value) {
197         log.debug("Value set to: " + value);
198         if (value == null) {
199             return;
200         }
201         if (fileStore != null) {
202             if (!(value instanceof String JavaDoc)) {
203                 throw new IllegalArgumentException JavaDoc("Value is not a String: " + value);
204             }
205             uri = (String JavaDoc) value;
206             file = fileStore.retrieve(uri);
207             Assert.notNull(file, "File not found in FileStore: " + uri);
208         }
209         else {
210             if (!(value instanceof File JavaDoc)) {
211                 throw new IllegalArgumentException JavaDoc("Value is not a File: " + value);
212             }
213             uri = null;
214             file = (File JavaDoc) value;
215         }
216
217         EditorBinder editorBinder = getEditorBinding().getEditorBinder();
218         if (filenameProperty != null) {
219             fileName = (String JavaDoc) editorBinder.getPropertyValue(filenameProperty);
220         }
221         else {
222             fileName = file.getName();
223         }
224
225         if (contentTypeProperty != null) {
226             contentType = (String JavaDoc) editorBinder.getPropertyValue(contentTypeProperty);
227         }
228         else {
229             contentType = contentType(file);
230         }
231         size = new Long JavaDoc(file.length());
232     }
233
234     public Object JavaDoc getValue() {
235         EditorBinder editorBinder = getEditorBinding().getEditorBinder();
236         if (filenameProperty != null) {
237             editorBinder.setPropertyValue(filenameProperty, fileName);
238         }
239         if (contentTypeProperty != null) {
240             editorBinder.setPropertyValue(contentTypeProperty, contentType);
241         }
242         if (sizeProperty != null) {
243             editorBinder.setPropertyValue(sizeProperty, size);
244         }
245
246         if (fileStore != null) {
247             File JavaDoc originalFile = uri != null ? fileStore.retrieve(uri) : null;
248             if (!ObjectUtils.nullSafeEquals(originalFile, file)) {
249                 try {
250                     if (uri != null) {
251                         fileStore.delete(uri);
252                     }
253                     if (file != null) {
254                         uri = fileStore.store(file, FormatUtils.toFilename(fileName));
255                         file = fileStore.retrieve(uri);
256                         returnedFile = file;
257                     }
258                     else {
259                         uri = null;
260                     }
261                 }
262                 catch (IOException JavaDoc e) {
263                     throw new RuntimeException JavaDoc("Failed to store file: "
264                             + e.getMessage(), e);
265                 }
266             }
267             return uri;
268         }
269         else {
270             returnedFile = file;
271             return file;
272         }
273     }
274
275     protected void destroy() {
276         if (tempFile != null && !tempFile.equals(returnedFile)) {
277             tempFile.delete();
278         }
279     }
280
281     protected final void finalize() throws Throwable JavaDoc {
282         super.finalize();
283         destroy();
284     }
285
286     protected final void validate() {
287         if (isRequired() && file == null) {
288             ErrorUtils.rejectRequired(this);
289         }
290         if (file != null) {
291             validateFile(file);
292         }
293     }
294
295     protected void validateFile(File JavaDoc file) {
296     }
297
298     /**
299      * Though this is a composite element we want it to be treated as a
300      * single widget.
301      */

302     public boolean isCompositeElement() {
303         return false;
304     }
305
306     public class UploadElement extends TemplateElement
307             implements JavaScriptEventAdapter {
308
309         private String JavaDoc uploadId;
310
311         private UploadStatus status;
312
313         public UploadElement() {
314             this.uploadId = UploadStatus.createUploadId();
315         }
316
317         public String JavaDoc getUploadId() {
318             return uploadId;
319         }
320
321         public String JavaDoc getUploadUrl() {
322             return getFormContext().getUploadUrl(uploadId);
323         }
324
325         public UploadStatus getStatus() {
326             return status;
327         }
328
329         public void processRequestInternal(FormRequest request) {
330             log.debug("Processing " + getParamName());
331             MultipartFile multipartFile = request.getFile(getParamName());
332             if ((multipartFile != null) && (!multipartFile.isEmpty())) {
333                 try {
334                     fileName = multipartFile.getOriginalFilename();
335                     contentType = multipartFile.getContentType();
336                     if (tempFile != null) {
337                         tempFile.delete();
338                     }
339                     String JavaDoc ext = FormatUtils.getExtension(fileName);
340                     if (StringUtils.hasLength(ext)) {
341                         ext = '.' + ext;
342                     }
343                     tempFile = File.createTempFile("000", ext);
344
345                     multipartFile.transferTo(tempFile);
346                     log.debug("stored at: " + tempFile.getAbsolutePath());
347
348                     setFile(tempFile);
349                     afterFileUploaded();
350
351                     log.debug("File uploaded: " + fileName + " ("
352                             + contentType + ")");
353
354                 }
355                 catch (IOException JavaDoc e) {
356                     log.error("error saving uploaded file");
357                 }
358             }
359         }
360
361         /**
362          * @see org.riotfamily.forms.event.JavaScriptEventAdapter#getEventTypes()
363          */

364         public int getEventTypes() {
365             return 0;
366         }
367
368         /**
369          *
370          */

371         public void handleJavaScriptEvent(JavaScriptEvent event) {
372             status = UploadStatus.getStatus(uploadId);
373             if (getFormListener() != null) {
374                 getFormListener().elementChanged(this);
375                 if (status != null) {
376                     log.debug("Progress: " + status.getProgress());
377                     getFormListener().refresh(this);
378                 }
379                 else {
380                     log.debug("No status.");
381                     getFormListener().elementChanged(FileUpload.this);
382                 }
383             }
384         }
385
386     }
387
388     private class RemoveButton extends Button {
389
390         private RemoveButton() {
391             setCssClass("remove-file");
392         }
393
394         public String JavaDoc getLabel() {
395             return "Remove";
396         }
397
398         protected void onClick() {
399             file = null;
400             ErrorUtils.removeErrors(FileUpload.this);
401             if (getFormListener() != null) {
402                 getFormListener().elementChanged(FileUpload.this);
403             }
404         }
405
406         public void render(PrintWriter JavaDoc writer) {
407             if (!FileUpload.this.isRequired() && isPresent()) {
408                 super.render(writer);
409             }
410         }
411
412         public int getEventTypes() {
413             return JavaScriptEvent.ON_CLICK;
414         }
415     }
416
417     public class PreviewElement extends TemplateElement
418             implements ContentElement {
419
420         public PreviewElement() {
421             setAttribute("file", FileUpload.this);
422         }
423
424         public void handleContentRequest(HttpServletRequest JavaDoc request,
425                 HttpServletResponse JavaDoc response) throws IOException JavaDoc {
426
427             if (file != null && file.exists()) {
428                 response.setDateHeader("Expires", 0);
429                 response.setHeader("Content-Type", "application/x-download");
430                 response.setHeader("Content-Disposition",
431                         "attachment;filename=" + fileName);
432
433                 response.setContentLength(size.intValue());
434                 FileCopyUtils.copy(new FileInputStream JavaDoc(file),
435                         response.getOutputStream());
436             }
437             else {
438                 response.sendError(HttpServletResponse.SC_NO_CONTENT);
439             }
440         }
441
442         public String JavaDoc getDownloadUrl() {
443             return getFormContext().getContentUrl(this);
444         }
445
446     }
447
448
449 }
450
Popular Tags