Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/jcorporate/expresso/core/misc/upload/FileItem.java


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;
71  import java.io.ByteArrayInputStream;
72  import java.io.ByteArrayOutputStream;
73  import java.io.File;
74  import java.io.FileInputStream;
75  import java.io.FileNotFoundException;
76  import java.io.FileOutputStream;
77  import java.io.IOException;
78  import java.io.InputStream;
79  import java.io.OutputStream;
80  import java.io.UnsupportedEncodingException;
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 {
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 fileName;
115 
116     /**
117      * The content type passed by the browser or <code>null</code> if
118      * not defined.
119      */
120     protected String 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 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 fileName, String 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 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 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 fis = new FileInputStream(storeLocation);
211                     fis.read(content);
212                 } catch (Exception 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 getString() {
232         return new String(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 getString(String encoding)
244             throws UnsupportedEncodingException {
245         return new String(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 getStream()
257             throws Exception {
258         if (content == null) {
259             if (storeLocation != null) {
260                 try {
261                     return new FileInputStream(storeLocation);
262                 } catch (FileNotFoundException e) {
263                     throw new Exception("FileItem: stored item was lost");
264                 }
265             } else {
266                 content = byteStream.toByteArray();
267                 byteStream = null;
268             }
269         }
270 
271         return new ByteArrayInputStream(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 getOutputStream()
298             throws IOException {
299         if (storeLocation == null) {
300             return byteStream;
301         } else {
302             return new FileOutputStream(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 path, String name,
324                                        String 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 de) {
354                 throw new IllegalArgumentException("Unable to create upload temp file " +
355                         de.getMessage());
356             }
357         } else {
358             item.byteStream = new ByteArrayOutputStream();
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 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(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 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, IOException {
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 getInputStream()
432             throws FileNotFoundException, IOException {
433         return new FileInputStream(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 getName() {
452         return this.fileName;
453     }
454 }