KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > core > misc > upload > FileItem


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65 package com.jcorporate.expresso.core.misc.upload;
66
67 import com.jcorporate.expresso.core.misc.StringUtil;
68 import org.apache.struts.upload.FormFile;
69
70 import javax.activation.DataSource JavaDoc;
71 import java.io.ByteArrayInputStream JavaDoc;
72 import java.io.ByteArrayOutputStream JavaDoc;
73 import java.io.File JavaDoc;
74 import java.io.FileInputStream JavaDoc;
75 import java.io.FileNotFoundException JavaDoc;
76 import java.io.FileOutputStream JavaDoc;
77 import java.io.IOException JavaDoc;
78 import java.io.InputStream JavaDoc;
79 import java.io.OutputStream JavaDoc;
80 import java.io.UnsupportedEncodingException JavaDoc;
81
82
83 /**
84  * <p> This class represents a file that was received by Turbine using
85  * <code>multipart/form-data</code> POST request.
86  * <p/>
87  * <p> After retrieving an instance of this class from the {@link
88  * org.apache.turbine.util.ParameterParser ParameterParser} (see
89  * {@link org.apache.turbine.util.ParameterParser#getFileItem(String)
90  * ParameterParser.getFileItem(String)} and {@link
91  * org.apache.turbine.util.ParameterParser#getFileItems(String)
92  * ParameterParser.getFileItems(String)}) you can use it to acces the
93  * data that was sent by the browser. You may either request all
94  * contents of file at once using {@link #get()} or request an {@link
95  * java.io.InputStream InputStream} with {@link #getStream()} and
96  * process the file without attempting to load it into memory, which
97  * may come handy with large files.
98  *
99  * @author <a HREF="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
100  * @version $Id: FileItem.java,v 1.8 2004/11/17 20:48:13 lhamel Exp $
101  */

102 public class FileItem
103         implements FormFile, DataSource JavaDoc {
104
105     /**
106      * The maximal size of request that will have it's elements stored
107      * in memory.
108      */

109     public static final int DEFAULT_UPLOAD_SIZE_THRESHOLD = 10240;
110
111     /**
112      * The original filename in the user's filesystem.
113      */

114     protected String JavaDoc fileName;
115
116     /**
117      * The content type passed by the browser or <code>null</code> if
118      * not defined.
119      */

120     protected String JavaDoc contentType;
121
122     /**
123      * Cached contents of the file.
124      */

125     protected byte[] content;
126
127     /**
128      * Temporary storage location.
129      */

130     protected File storeLocation = null;
131
132     /**
133      * Temporary storage for in-memory files.
134      */

135     protected ByteArrayOutputStream JavaDoc byteStream;
136
137     /**
138      * Constructs a new <code>FileItem</code>.
139      * <p/>
140      * <p>Use {@link #newInstance(String,String,String,int)} to
141      * instantiate <code>FileItems</code>.
142      *
143      * @param fileName The original filename in the user's filesystem.
144      * @param contentType The content type passed by the browser or
145      * <code>null</code> if not defined.
146      */

147     protected FileItem(String JavaDoc fileName, String JavaDoc contentType) {
148         this.fileName = fileName;
149         this.contentType = contentType;
150     }
151
152     /**
153      * Returns the original filename in the user's filesystem.
154      *
155      * @return The original filename in the user's filesystem.
156      */

157     public String JavaDoc getFileName() {
158         return fileName;
159     }
160
161     /**
162      * Returns the content type passed by the browser or
163      * <code>null</code> if not defined.
164      *
165      * @return The content type passed by the browser or
166      * <code>null</code> if not defined.
167      */

168     public String JavaDoc getContentType() {
169         return contentType;
170     }
171
172     /**
173      * Provides a hint if the file contents will be read from memory.
174      *
175      * @return <code>True</code> if the file contents will be read
176      * from memory.
177      */

178     public boolean inMemory() {
179         return (content != null || byteStream != null);
180     }
181
182     /**
183      * Returns the size of the file.
184      *
185      * @return The size of the file.
186      */

187     public long getSize() {
188         if (storeLocation != null) {
189             return storeLocation.length();
190         } else if (byteStream != null) {
191             return byteStream.size();
192         } else {
193             return content.length;
194         }
195     }
196
197     /**
198      * Returns the contents of the file as an array of bytes. If the
199      * contents of the file were not yet cached int the memory, they
200      * will be loaded from the disk storage and chached.
201      *
202      * @return The contents of the file as an array of bytes.
203      */

204     public byte[] get() {
205         if (content == null) {
206             if (storeLocation != null) {
207                 content = new byte[(int) getSize()];
208
209                 try {
210                     FileInputStream JavaDoc fis = new FileInputStream JavaDoc(storeLocation);
211                     fis.read(content);
212                 } catch (Exception JavaDoc e) {
213                     content = null;
214                 }
215             } else {
216                 content = byteStream.toByteArray();
217                 byteStream = null;
218             }
219         }
220
221         return content;
222     }
223
224     /**
225      * Returns the contents of the file as a String, using default
226      * encoding. This method uses {@link #get()} to retrieve the
227      * contents of the file.
228      *
229      * @return The contents of the file.
230      */

231     public String JavaDoc getString() {
232         return new String JavaDoc(get());
233     }
234
235     /**
236      * Returns the contents of the file as a String, using specified
237      * encoding. This method uses {@link #get()} to retireve the
238      * contents of the file.<br>
239      *
240      * @param encoding The encoding to use.
241      * @return The contents of the file.
242      */

243     public String JavaDoc getString(String JavaDoc encoding)
244             throws UnsupportedEncodingException JavaDoc {
245         return new String JavaDoc(get(), encoding);
246     }
247
248     /**
249      * Returns an {@link java.io.InputStream InputStream} that can be
250      * used to retrieve the contents of the file.
251      *
252      * @return An {@link java.io.InputStream InputStream} that can be
253      * used to retrieve the contents of the file.
254      * @throws Exception A generic exception.
255      */

256     public InputStream JavaDoc getStream()
257             throws Exception JavaDoc {
258         if (content == null) {
259             if (storeLocation != null) {
260                 try {
261                     return new FileInputStream JavaDoc(storeLocation);
262                 } catch (FileNotFoundException JavaDoc e) {
263                     throw new Exception JavaDoc("FileItem: stored item was lost");
264                 }
265             } else {
266                 content = byteStream.toByteArray();
267                 byteStream = null;
268             }
269         }
270
271         return new ByteArrayInputStream JavaDoc(content);
272     }
273
274     /**
275      * Returns the {@link java.io.File} objects for the FileItems's
276      * data temporary location on the disk. Note that for
277      * <code>FileItems</code> that have their data stored in memory
278      * this method will return <code>null</code>. When handling large
279      * files, you can use {@link java.io.File#renameTo(File)} to
280      * move the file to new location without copying the data, if the
281      * source and destination locations reside within the same logical
282      * volume.
283      *
284      * @return A File.
285      */

286     public File getStoreLocation() {
287         return storeLocation;
288     }
289
290     /**
291      * Returns an {@link java.io.OutputStream OutputStream} that can
292      * be used for storing the contensts of the file.
293      *
294      * @return an {@link java.io.OutputStream OutputStream} that can be
295      * used for storing the contensts of the file.
296      */

297     public OutputStream JavaDoc getOutputStream()
298             throws IOException JavaDoc {
299         if (storeLocation == null) {
300             return byteStream;
301         } else {
302             return new FileOutputStream JavaDoc(storeLocation);
303         }
304     }
305
306     /**
307      * Instantiates a FileItem. It uses <code>requestSize</code> to
308      * decide what temporary storage approach the new item should
309      * take. The largest request that will have its items cached in
310      * memory can be configured in
311      * <code>TurbineResources.properties</code> in the entry named
312      * <code>file.upload.size.threshold</code>
313      *
314      * @param path A String.
315      * @param name The original filename in the user's filesystem.
316      * @param contentType The content type passed by the browser or
317      * <code>null</code> if not defined.
318      * @param requestSize The total size of the POST request this item
319      * belongs to.
320      * @param storeAsFile Set to true if you want it stored as a local file.
321      * @return A FileItem.
322      */

323     public static FileItem newInstance(String JavaDoc path, String JavaDoc name,
324                                        String JavaDoc contentType, int requestSize,
325                                        boolean storeAsFile) {
326         FileItem item = new FileItem(name, contentType);
327
328         if (storeAsFile) {
329
330             /* if we need to stash it in a file */
331             try {
332
333                 // NextNumber myNext = new NextNumber();
334
// myNext.setDBName("default");
335
// Temporary filename becomes <path>/upload<seq-num>-<orig name>
336
name = StringUtil.replace(name, "\\", "/");
337
338                 File tmpFile = new File(name);
339
340                 // String fileName = path + "upload" + myNext.getNext("UPFILE")
341
// + "-" + tmpFile.getName();
342
File tempDir = new File(path);
343                 tempDir.mkdirs();
344
345                 //New method use SDK's version to create a temp file with
346
//the appropriate prefix and suffix
347
item.storeLocation = File.createTempFile("upload",
348                         "-" +
349                         tmpFile.getName(),
350                         tempDir);
351
352                 // item.storeLocation = new File(fileName);
353
} catch (IOException JavaDoc de) {
354                 throw new IllegalArgumentException JavaDoc("Unable to create upload temp file " +
355                         de.getMessage());
356             }
357         } else {
358             item.byteStream = new ByteArrayOutputStream JavaDoc();
359         }
360
361         return item;
362     }
363     /** Methods required by the Struts FormFile interface */
364     /**
365      * Set the content type for this file
366      *
367      * @param contentType The content type
368      */

369     public void setContentType(String JavaDoc contentType) {
370         this.contentType = contentType;
371     }
372
373     /**
374      * Get the size of this file
375      *
376      * @return An int representing the size of the file in bytes
377      */

378     public int getFileSize() {
379         return new Long JavaDoc(getSize()).intValue();
380     }
381
382     /**
383      * Set the file size
384      *
385      * @param filesize An int reprsenting the size of the file in bytes
386      */

387     public void setFileSize(int filesize) {
388
389         /* Ignore this */
390     }
391
392     /**
393      * Set the filename of this file
394      *
395      * @param newFileName The name of the file
396      */

397     public void setFileName(String JavaDoc newFileName) {
398         fileName = newFileName;
399     }
400
401     /**
402      * Get the data in byte array for for this file. Note that this can be
403      * a very hazardous method, files can be large enough to cause
404      * OutOfMemoryErrors. Short of being deprecated, it's strongly recommended
405      * that you use {@link #getInputStream() getInputStream} to get the file
406      * data.
407      *
408      * @return An array of bytes representing the data contained
409      * in the form file
410      * @throws FileNotFoundException If some sort of file representation
411      * cannot be found for the FormFile
412      * @throws IOException If there is some sort of IOException
413      */

414     public byte[] getFileData()
415             throws FileNotFoundException JavaDoc, IOException JavaDoc {
416         byte[] b = null;
417         getInputStream().read(b);
418
419         return b;
420     }
421
422     /**
423      * Get an InputStream that represents this file. This is the preferred
424      * method of getting file data.
425      *
426      * @return an InputStream object.
427      * @throws FileNotFoundException If some sort of file representation
428      * cannot be found for the FormFile
429      * @throws IOException If there is some sort of IOException
430      */

431     public InputStream JavaDoc getInputStream()
432             throws FileNotFoundException JavaDoc, IOException JavaDoc {
433         return new FileInputStream JavaDoc(getFileName());
434     }
435
436     /**
437      * Destroy all content for this form file.
438      * Implementations should remove any temporary
439      * files or any temporary file data stored somewhere
440      */

441     public void destroy() {
442         File theFile = new File(getFileName());
443         theFile.delete();
444     }
445
446     /**
447      * Returns the name of the FileItem
448      *
449      * @return java.lang.String
450      */

451     public String JavaDoc getName() {
452         return this.fileName;
453     }
454 }
Popular Tags