View Javadoc
1 package org.apache.turbine.util.upload; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 import java.io.ByteArrayInputStream; 58 import java.io.ByteArrayOutputStream; 59 import java.io.File; 60 import java.io.FileInputStream; 61 import java.io.FileOutputStream; 62 import java.io.FileWriter; 63 import java.io.IOException; 64 import java.io.InputStream; 65 import java.io.UnsupportedEncodingException; 66 import java.io.OutputStream; 67 68 import javax.activation.DataSource; 69 70 import org.apache.turbine.services.uniqueid.TurbineUniqueId; 71 import org.apache.turbine.services.upload.TurbineUpload; 72 73 /*** 74 * <p> This class represents a file that was received by Turbine using 75 * <code>multipart/form-data</code> POST request. 76 * 77 * <p> After retrieving an instance of this class from the {@link 78 * org.apache.turbine.util.ParameterParser ParameterParser} (see 79 * {@link org.apache.turbine.util.ParameterParser#getFileItem(String) 80 * ParameterParser.getFileItem(String)} and {@link 81 * org.apache.turbine.util.ParameterParser#getFileItems(String) 82 * ParameterParser.getFileItems(String)}) you can use it to acces the 83 * data that was sent by the browser. You may either request all 84 * contents of file at once using {@link #get()} or request an {@link 85 * java.io.InputStream InputStream} with {@link #getStream()} and 86 * process the file without attempting to load it into memory, which 87 * may come handy with large files. 88 * 89 * Implements the javax.activation.DataSource interface (which allows 90 * for example the adding of a FileItem as an attachment to a multipart 91 * email). 92 * 93 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> 94 * @author <a href="mailto:sean@informage.net">Sean Legassick</a> 95 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> 96 * @version $Id$ 97 */ 98 public class FileItem implements DataSource 99 { 100 /*** 101 * The maximal size of request that will have it's elements stored 102 * in memory. 103 */ 104 public static final int DEFAULT_UPLOAD_SIZE_THRESHOLD = 10240; 105 106 /*** The original filename in the user's filesystem. */ 107 protected String fileName; 108 109 /*** 110 * The content type passed by the browser or <code>null</code> if 111 * not defined. 112 */ 113 protected String contentType; 114 115 /*** Cached contents of the file. */ 116 protected byte[] content; 117 118 /*** Temporary storage location. */ 119 protected File storeLocation; 120 121 /*** Temporary storage for in-memory files. */ 122 protected ByteArrayOutputStream byteStream; 123 124 125 /*** 126 * Constructs a new <code>FileItem</code>. 127 * 128 * <p>Use {@link #newInstance(String,String,String,int)} to 129 * instantiate <code>FileItems</code>. 130 * 131 * @param fileName The original filename in the user's filesystem. 132 * @param contentType The content type passed by the browser or 133 * <code>null</code> if not defined. 134 */ 135 protected FileItem( String fileName, 136 String contentType ) 137 { 138 this.fileName = fileName; 139 this.contentType = contentType; 140 } 141 142 /*** 143 * Returns the original filename in the user's filesystem. 144 * (implements DataSource method) 145 * 146 * @return The original filename in the user's filesystem. 147 */ 148 public String getName() 149 { 150 return getFileName(); 151 } 152 153 /*** 154 * Returns the original filename in the user's filesystem. 155 * 156 * @return The original filename in the user's filesystem. 157 */ 158 public String getFileName() 159 { 160 return fileName; 161 } 162 163 /*** 164 * Returns the content type passed by the browser or 165 * <code>null</code> if not defined. (implements 166 * DataSource method). 167 * 168 * @return The content type passed by the browser or 169 * <code>null</code> if not defined. 170 */ 171 public String getContentType() 172 { 173 return contentType; 174 } 175 176 /*** 177 * Provides a hint if the file contents will be read from memory. 178 * 179 * @return <code>True</code> if the file contents will be read 180 * from memory. 181 */ 182 public boolean inMemory() 183 { 184 return (content != null || byteStream != null); 185 } 186 187 /*** 188 * Returns the size of the file. 189 * 190 * @return The size of the file. 191 */ 192 public long getSize() 193 { 194 if(storeLocation != null) 195 { 196 return storeLocation.length(); 197 } 198 else if(byteStream != null) 199 { 200 return byteStream.size(); 201 } 202 else 203 { 204 return content.length; 205 } 206 } 207 208 /*** 209 * Returns the contents of the file as an array of bytes. If the 210 * contents of the file were not yet cached int the memory, they 211 * will be loaded from the disk storage and chached. 212 * 213 * @return The contents of the file as an array of bytes. 214 */ 215 public byte[] get() 216 { 217 if(content == null) 218 { 219 if(storeLocation != null) 220 { 221 content = new byte[(int)getSize()]; 222 try 223 { 224 FileInputStream fis = new FileInputStream(storeLocation); 225 fis.read(content); 226 } 227 catch (Exception e) 228 { 229 content = null; 230 } 231 } 232 else 233 { 234 content = byteStream.toByteArray(); 235 byteStream = null; 236 } 237 } 238 return content; 239 } 240 241 /*** 242 * Returns the contents of the file as a String, using default 243 * encoding. This method uses {@link #get()} to retrieve the 244 * contents of the file. 245 * 246 * @return The contents of the file. 247 */ 248 public String getString() 249 { 250 return new String(get()); 251 } 252 253 /*** 254 * Returns the contents of the file as a String, using specified 255 * encoding. This method uses {@link #get()} to retireve the 256 * contents of the file.<br> 257 * 258 * @param encoding The encoding to use. 259 * @return The contents of the file. 260 * @exception UnsupportedEncodingException. 261 */ 262 public String getString( String encoding ) 263 throws UnsupportedEncodingException 264 { 265 return new String(get(), encoding); 266 } 267 268 /*** 269 * Returns an {@link java.io.InputStream InputStream} that can be 270 * used to retrieve the contents of the file. (implements DataSource 271 * method) 272 * 273 * @return An {@link java.io.InputStream InputStream} that can be 274 * used to retrieve the contents of the file. 275 * @exception Exception, a generic exception. 276 */ 277 public InputStream getInputStream() 278 throws IOException 279 { 280 return getStream(); 281 } 282 283 /*** 284 * Returns an {@link java.io.InputStream InputStream} that can be 285 * used to retrieve the contents of the file. 286 * 287 * @return An {@link java.io.InputStream InputStream} that can be 288 * used to retrieve the contents of the file. 289 * @exception Exception, a generic exception. 290 */ 291 public InputStream getStream() 292 throws IOException 293 { 294 if(content == null) 295 { 296 if(storeLocation != null) 297 { 298 return new FileInputStream(storeLocation); 299 } 300 else 301 { 302 content = byteStream.toByteArray(); 303 byteStream = null; 304 } 305 } 306 return new ByteArrayInputStream(content); 307 } 308 309 /*** 310 * Returns the {@link java.io.File} objects for the FileItems's 311 * data temporary location on the disk. Note that for 312 * <code>FileItems</code> that have their data stored in memory 313 * this method will return <code>null</code>. When handling large 314 * files, you can use {@link java.io.File#renameTo(File)} to 315 * move the file to new location without copying the data, if the 316 * source and destination locations reside within the same logical 317 * volume. 318 * 319 * @return A File. 320 */ 321 public File getStoreLocation() 322 { 323 return storeLocation; 324 } 325 326 /*** 327 * Removes the file contents from the temporary storage. 328 */ 329 protected void finalize() 330 { 331 if(storeLocation != null && storeLocation.exists()) 332 { 333 storeLocation.delete(); 334 } 335 } 336 337 /*** 338 * Returns an {@link java.io.OutputStream OutputStream} that can 339 * be used for storing the contents of the file. 340 * (implements DataSource method) 341 * 342 * @return an {@link java.io.OutputStream OutputStream} that can be 343 * used for storing the contensts of the file. 344 * @exception IOException. 345 */ 346 public OutputStream getOutputStream() 347 throws IOException 348 { 349 if(storeLocation == null) 350 { 351 return byteStream; 352 } 353 else 354 { 355 return new FileOutputStream(storeLocation); 356 } 357 } 358 359 /*** 360 * Instantiates a FileItem. It uses <code>requestSize</code> to 361 * decide what temporary storage approach the new item should 362 * take. The largest request that will have its items cached in 363 * memory can be configured in 364 * <code>TurbineResources.properties</code> in the entry named 365 * <code>file.upload.size.threshold</code> 366 * 367 * @param path A String. 368 * @param name The original filename in the user's filesystem. 369 * @param contentType The content type passed by the browser or 370 * <code>null</code> if not defined. 371 * @param requestSize The total size of the POST request this item 372 * belongs to. 373 * @return A FileItem. 374 */ 375 public static FileItem newInstance(String path, 376 String name, 377 String contentType, 378 int requestSize) 379 { 380 FileItem item = new FileItem(name, contentType); 381 if(requestSize > TurbineUpload.getSizeThreshold()) 382 { 383 String instanceName = TurbineUniqueId.getInstanceId(); 384 String fileName = TurbineUniqueId.getUniqueId(); 385 fileName = instanceName + "_upload_" + fileName + ".tmp"; 386 fileName = path + "/" + fileName; 387 item.storeLocation = new File(fileName); 388 } 389 else 390 { 391 item.byteStream = new ByteArrayOutputStream(); 392 } 393 return item; 394 } 395 396 /*** 397 * A convenience method to write an uploaded 398 * file to disk. The client code is not concerned 399 * whether or not the file is stored in memory, 400 * or on disk in a temporary location. They just 401 * want to write the uploaded file to disk. 402 * 403 * @param String full path to location where uploaded 404 * should be stored. 405 */ 406 public void write(String file) throws Exception 407 { 408 if (inMemory()) 409 { 410 FileWriter writer = new FileWriter(file); 411 writer.write(getString()); 412 } 413 else if (storeLocation != null) 414 { 415 /* 416 * The uploaded file is being stored on disk 417 * in a temporary location so move it to the 418 * desired file. 419 */ 420 if (storeLocation.renameTo(new File(file)) == false) 421 { 422 throw new Exception( 423 "Cannot write uploaded file to disk!"); 424 } 425 } 426 else 427 { 428 /* 429 * For whatever reason we cannot write the 430 * file to disk. 431 */ 432 throw new Exception("Cannot write uploaded file to disk!"); 433 } 434 } 435 }

This page was automatically generated by Maven