| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| DiskFileItem | 
 | 
 | 2.4615384615384617;2.462 | 
| 1 |  /* | |
| 2 |   * Licensed to the Apache Software Foundation (ASF) under one or more | |
| 3 |   * contributor license agreements.  See the NOTICE file distributed with | |
| 4 |   * this work for additional information regarding copyright ownership. | |
| 5 |   * The ASF licenses this file to You under the Apache License, Version 2.0 | |
| 6 |   * (the "License"); you may not use this file except in compliance with | |
| 7 |   * the License.  You may obtain a copy of the License at | |
| 8 |   * | |
| 9 |   *      http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 |   * | |
| 11 |   * Unless required by applicable law or agreed to in writing, software | |
| 12 |   * distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 |   * See the License for the specific language governing permissions and | |
| 15 |   * limitations under the License. | |
| 16 |   */ | |
| 17 |  package org.apache.commons.fileupload.disk; | |
| 18 | ||
| 19 | import static java.lang.String.format; | |
| 20 | ||
| 21 |  import java.io.ByteArrayInputStream; | |
| 22 |  import java.io.File; | |
| 23 |  import java.io.FileInputStream; | |
| 24 |  import java.io.FileOutputStream; | |
| 25 |  import java.io.IOException; | |
| 26 |  import java.io.InputStream; | |
| 27 |  import java.io.OutputStream; | |
| 28 |  import java.io.UnsupportedEncodingException; | |
| 29 |  import java.util.Map; | |
| 30 |  import java.util.UUID; | |
| 31 |  import java.util.concurrent.atomic.AtomicInteger; | |
| 32 | ||
| 33 |  import org.apache.commons.fileupload.FileItem; | |
| 34 |  import org.apache.commons.fileupload.FileItemHeaders; | |
| 35 |  import org.apache.commons.fileupload.FileUploadException; | |
| 36 |  import org.apache.commons.fileupload.ParameterParser; | |
| 37 |  import org.apache.commons.fileupload.util.Streams; | |
| 38 |  import org.apache.commons.io.FileUtils; | |
| 39 |  import org.apache.commons.io.IOUtils; | |
| 40 |  import org.apache.commons.io.output.DeferredFileOutputStream; | |
| 41 | ||
| 42 |  /** | |
| 43 |   * <p> The default implementation of the | |
| 44 |   * {@link org.apache.commons.fileupload.FileItem FileItem} interface. | |
| 45 |   * | |
| 46 |   * <p> After retrieving an instance of this class from a {@link | |
| 47 |   * DiskFileItemFactory} instance (see | |
| 48 |   * {@link org.apache.commons.fileupload.servlet.ServletFileUpload | |
| 49 |   * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may | |
| 50 |   * either request all contents of file at once using {@link #get()} or | |
| 51 |   * request an {@link java.io.InputStream InputStream} with | |
| 52 |   * {@link #getInputStream()} and process the file without attempting to load | |
| 53 |   * it into memory, which may come handy with large files. | |
| 54 |   * | |
| 55 |   * <p>Temporary files, which are created for file items, should be | |
| 56 |   * deleted later on. The best way to do this is using a | |
| 57 |   * {@link org.apache.commons.io.FileCleaningTracker}, which you can set on the | |
| 58 |   * {@link DiskFileItemFactory}. However, if you do use such a tracker, | |
| 59 |   * then you must consider the following: Temporary files are automatically | |
| 60 |   * deleted as soon as they are no longer needed. (More precisely, when the | |
| 61 |   * corresponding instance of {@link java.io.File} is garbage collected.) | |
| 62 |   * This is done by the so-called reaper thread, which is started and stopped | |
| 63 |   * automatically by the {@link org.apache.commons.io.FileCleaningTracker} when | |
| 64 |   * there are files to be tracked. | |
| 65 |   * It might make sense to terminate that thread, for example, if | |
| 66 |   * your web application ends. See the section on "Resource cleanup" | |
| 67 |   * in the users guide of commons-fileupload.</p> | |
| 68 |   * | |
| 69 |   * @since FileUpload 1.1 | |
| 70 |   */ | |
| 71 | public class DiskFileItem | |
| 72 |      implements FileItem { | |
| 73 | ||
| 74 |      // ----------------------------------------------------- Manifest constants | |
| 75 | ||
| 76 |      /** | |
| 77 |       * Default content charset to be used when no explicit charset | |
| 78 |       * parameter is provided by the sender. Media subtypes of the | |
| 79 |       * "text" type are defined to have a default charset value of | |
| 80 |       * "ISO-8859-1" when received via HTTP. | |
| 81 |       */ | |
| 82 | public static final String DEFAULT_CHARSET = "ISO-8859-1"; | |
| 83 | ||
| 84 |      // ----------------------------------------------------------- Data members | |
| 85 | ||
| 86 |      /** | |
| 87 |       * UID used in unique file name generation. | |
| 88 |       */ | |
| 89 | private static final String UID = | |
| 90 | 1 | UUID.randomUUID().toString().replace('-', '_'); | 
| 91 | ||
| 92 |      /** | |
| 93 |       * Counter used in unique identifier generation. | |
| 94 |       */ | |
| 95 | 1 | private static final AtomicInteger COUNTER = new AtomicInteger(0); | 
| 96 | ||
| 97 |      /** | |
| 98 |       * The name of the form field as provided by the browser. | |
| 99 |       */ | |
| 100 |      private String fieldName; | |
| 101 | ||
| 102 |      /** | |
| 103 |       * The content type passed by the browser, or <code>null</code> if | |
| 104 |       * not defined. | |
| 105 |       */ | |
| 106 | private final String contentType; | |
| 107 | ||
| 108 |      /** | |
| 109 |       * Whether or not this item is a simple form field. | |
| 110 |       */ | |
| 111 | private boolean isFormField; | |
| 112 | ||
| 113 |      /** | |
| 114 |       * The original filename in the user's filesystem. | |
| 115 |       */ | |
| 116 | private final String fileName; | |
| 117 | ||
| 118 |      /** | |
| 119 |       * The size of the item, in bytes. This is used to cache the size when a | |
| 120 |       * file item is moved from its original location. | |
| 121 |       */ | |
| 122 | 2174 | private long size = -1; | 
| 123 | ||
| 124 | ||
| 125 |      /** | |
| 126 |       * The threshold above which uploads will be stored on disk. | |
| 127 |       */ | |
| 128 | private final int sizeThreshold; | |
| 129 | ||
| 130 |      /** | |
| 131 |       * The directory in which uploaded files will be stored, if stored on disk. | |
| 132 |       */ | |
| 133 | private final File repository; | |
| 134 | ||
| 135 |      /** | |
| 136 |       * Cached contents of the file. | |
| 137 |       */ | |
| 138 | private byte[] cachedContent; | |
| 139 | ||
| 140 |      /** | |
| 141 |       * Output stream for this item. | |
| 142 |       */ | |
| 143 | private transient DeferredFileOutputStream dfos; | |
| 144 | ||
| 145 |      /** | |
| 146 |       * The temporary file to use. | |
| 147 |       */ | |
| 148 | private transient File tempFile; | |
| 149 | ||
| 150 |      /** | |
| 151 |       * The file items headers. | |
| 152 |       */ | |
| 153 |      private FileItemHeaders headers; | |
| 154 | ||
| 155 |      /** | |
| 156 |       * Default content charset to be used when no explicit charset | |
| 157 |       * parameter is provided by the sender. | |
| 158 |       */ | |
| 159 | 2174 |      private String defaultCharset = DEFAULT_CHARSET; | 
| 160 | ||
| 161 |      // ----------------------------------------------------------- Constructors | |
| 162 | ||
| 163 |      /** | |
| 164 |       * Constructs a new <code>DiskFileItem</code> instance. | |
| 165 |       * | |
| 166 |       * @param fieldName     The name of the form field. | |
| 167 |       * @param contentType   The content type passed by the browser or | |
| 168 |       *                      <code>null</code> if not specified. | |
| 169 |       * @param isFormField   Whether or not this item is a plain form field, as | |
| 170 |       *                      opposed to a file upload. | |
| 171 |       * @param fileName      The original filename in the user's filesystem, or | |
| 172 |       *                      <code>null</code> if not specified. | |
| 173 |       * @param sizeThreshold The threshold, in bytes, below which items will be | |
| 174 |       *                      retained in memory and above which they will be | |
| 175 |       *                      stored as a file. | |
| 176 |       * @param repository    The data repository, which is the directory in | |
| 177 |       *                      which files will be created, should the item size | |
| 178 |       *                      exceed the threshold. | |
| 179 |       */ | |
| 180 |      public DiskFileItem(String fieldName, | |
| 181 |              String contentType, boolean isFormField, String fileName, | |
| 182 | 2174 |              int sizeThreshold, File repository) { | 
| 183 | 2174 |          this.fieldName = fieldName; | 
| 184 | 2174 |          this.contentType = contentType; | 
| 185 | 2174 |          this.isFormField = isFormField; | 
| 186 | 2174 |          this.fileName = fileName; | 
| 187 | 2174 |          this.sizeThreshold = sizeThreshold; | 
| 188 | 2174 |          this.repository = repository; | 
| 189 | 2174 | } | 
| 190 | ||
| 191 |      // ------------------------------- Methods from javax.activation.DataSource | |
| 192 | ||
| 193 |      /** | |
| 194 |       * Returns an {@link java.io.InputStream InputStream} that can be | |
| 195 |       * used to retrieve the contents of the file. | |
| 196 |       * | |
| 197 |       * @return An {@link java.io.InputStream InputStream} that can be | |
| 198 |       *         used to retrieve the contents of the file. | |
| 199 |       * | |
| 200 |       * @throws IOException if an error occurs. | |
| 201 |       */ | |
| 202 | @Override | |
| 203 |      public InputStream getInputStream() | |
| 204 |          throws IOException { | |
| 205 | 0 |          if (!isInMemory()) { | 
| 206 | 0 |              return new FileInputStream(dfos.getFile()); | 
| 207 | } | |
| 208 | ||
| 209 | 0 |          if (cachedContent == null) { | 
| 210 | 0 |              cachedContent = dfos.getData(); | 
| 211 | } | |
| 212 | 0 |          return new ByteArrayInputStream(cachedContent); | 
| 213 | } | |
| 214 | ||
| 215 |      /** | |
| 216 |       * Returns the content type passed by the agent or <code>null</code> if | |
| 217 |       * not defined. | |
| 218 |       * | |
| 219 |       * @return The content type passed by the agent or <code>null</code> if | |
| 220 |       *         not defined. | |
| 221 |       */ | |
| 222 | @Override | |
| 223 |      public String getContentType() { | |
| 224 | 43 |          return contentType; | 
| 225 | } | |
| 226 | ||
| 227 |      /** | |
| 228 |       * Returns the content charset passed by the agent or <code>null</code> if | |
| 229 |       * not defined. | |
| 230 |       * | |
| 231 |       * @return The content charset passed by the agent or <code>null</code> if | |
| 232 |       *         not defined. | |
| 233 |       */ | |
| 234 |      public String getCharSet() { | |
| 235 | 35 |          ParameterParser parser = new ParameterParser(); | 
| 236 | 35 |          parser.setLowerCaseNames(true); | 
| 237 |          // Parameter parser can handle null input | |
| 238 | 35 |          Map<String, String> params = parser.parse(getContentType(), ';'); | 
| 239 | 35 | return params.get("charset"); | 
| 240 | } | |
| 241 | ||
| 242 |      /** | |
| 243 |       * Returns the original filename in the client's filesystem. | |
| 244 |       * | |
| 245 |       * @return The original filename in the client's filesystem. | |
| 246 |       * @throws org.apache.commons.fileupload.InvalidFileNameException The file name contains a NUL character, | |
| 247 |       *   which might be an indicator of a security attack. If you intend to | |
| 248 |       *   use the file name anyways, catch the exception and use | |
| 249 |       *   {@link org.apache.commons.fileupload.InvalidFileNameException#getName()}. | |
| 250 |       */ | |
| 251 | @Override | |
| 252 |      public String getName() { | |
| 253 | 19 |          return Streams.checkFileName(fileName); | 
| 254 | } | |
| 255 | ||
| 256 |      // ------------------------------------------------------- FileItem methods | |
| 257 | ||
| 258 |      /** | |
| 259 |       * Provides a hint as to whether or not the file contents will be read | |
| 260 |       * from memory. | |
| 261 |       * | |
| 262 |       * @return <code>true</code> if the file contents will be read | |
| 263 |       *         from memory; <code>false</code> otherwise. | |
| 264 |       */ | |
| 265 | @Override | |
| 266 | public boolean isInMemory() { | |
| 267 | 2432 | if (cachedContent != null) { | 
| 268 | 2 | return true; | 
| 269 | } | |
| 270 | 2430 |          return dfos.isInMemory(); | 
| 271 | } | |
| 272 | ||
| 273 |      /** | |
| 274 |       * Returns the size of the file. | |
| 275 |       * | |
| 276 |       * @return The size of the file, in bytes. | |
| 277 |       */ | |
| 278 | @Override | |
| 279 | public long getSize() { | |
| 280 | 536 |          if (size >= 0) { | 
| 281 | 0 |              return size; | 
| 282 | 536 |          } else if (cachedContent != null) { | 
| 283 | 0 |              return cachedContent.length; | 
| 284 | 536 | } else if (dfos.isInMemory()) { | 
| 285 | 4 |              return dfos.getData().length; | 
| 286 |          } else { | |
| 287 | 532 |              return dfos.getFile().length(); | 
| 288 | } | |
| 289 | } | |
| 290 | ||
| 291 |      /** | |
| 292 |       * Returns the contents of the file as an array of bytes.  If the | |
| 293 |       * contents of the file were not yet cached in memory, they will be | |
| 294 |       * loaded from the disk storage and cached. | |
| 295 |       * | |
| 296 |       * @return The contents of the file as an array of bytes | |
| 297 |       * or {@code null} if the data cannot be read | |
| 298 |       */ | |
| 299 | @Override | |
| 300 | public byte[] get() { | |
| 301 | 1451 | if (isInMemory()) { | 
| 302 | 922 |              if (cachedContent == null && dfos != null) { | 
| 303 | 920 | cachedContent = dfos.getData(); | 
| 304 | } | |
| 305 | 922 |              return cachedContent; | 
| 306 | } | |
| 307 | ||
| 308 | 529 | byte[] fileData = new byte[(int) getSize()]; | 
| 309 | 529 |          InputStream fis = null; | 
| 310 | ||
| 311 |          try { | |
| 312 | 529 |              fis = new FileInputStream(dfos.getFile()); | 
| 313 | 529 | IOUtils.readFully(fis, fileData); | 
| 314 | 0 |          } catch (IOException e) { | 
| 315 | 0 |              fileData = null; | 
| 316 |          } finally { | |
| 317 | 529 | IOUtils.closeQuietly(fis); | 
| 318 | 529 | } | 
| 319 | ||
| 320 | 529 |          return fileData; | 
| 321 | } | |
| 322 | ||
| 323 |      /** | |
| 324 |       * Returns the contents of the file as a String, using the specified | |
| 325 |       * encoding.  This method uses {@link #get()} to retrieve the | |
| 326 |       * contents of the file. | |
| 327 |       * | |
| 328 |       * @param charset The charset to use. | |
| 329 |       * | |
| 330 |       * @return The contents of the file, as a string. | |
| 331 |       * | |
| 332 |       * @throws UnsupportedEncodingException if the requested character | |
| 333 |       *                                      encoding is not available. | |
| 334 |       */ | |
| 335 | @Override | |
| 336 | public String getString(final String charset) | |
| 337 |          throws UnsupportedEncodingException { | |
| 338 | 0 |          return new String(get(), charset); | 
| 339 | } | |
| 340 | ||
| 341 |      /** | |
| 342 |       * Returns the contents of the file as a String, using the default | |
| 343 |       * character encoding.  This method uses {@link #get()} to retrieve the | |
| 344 |       * contents of the file. | |
| 345 |       * | |
| 346 |       * <b>TODO</b> Consider making this method throw UnsupportedEncodingException. | |
| 347 |       * | |
| 348 |       * @return The contents of the file, as a string. | |
| 349 |       */ | |
| 350 | @Override | |
| 351 |      public String getString() { | |
| 352 | 35 |          byte[] rawdata = get(); | 
| 353 | 35 | String charset = getCharSet(); | 
| 354 | 35 |          if (charset == null) { | 
| 355 | 35 | charset = defaultCharset; | 
| 356 | } | |
| 357 |          try { | |
| 358 | 35 | return new String(rawdata, charset); | 
| 359 | 0 |          } catch (UnsupportedEncodingException e) { | 
| 360 | 0 |              return new String(rawdata); | 
| 361 | } | |
| 362 | } | |
| 363 | ||
| 364 |      /** | |
| 365 |       * A convenience method to write an uploaded item to disk. The client code | |
| 366 |       * is not concerned with whether or not the item is stored in memory, or on | |
| 367 |       * disk in a temporary location. They just want to write the uploaded item | |
| 368 |       * to a file. | |
| 369 |       * <p> | |
| 370 |       * This implementation first attempts to rename the uploaded item to the | |
| 371 |       * specified destination file, if the item was originally written to disk. | |
| 372 |       * Otherwise, the data will be copied to the specified file. | |
| 373 |       * <p> | |
| 374 |       * This method is only guaranteed to work <em>once</em>, the first time it | |
| 375 |       * is invoked for a particular item. This is because, in the event that the | |
| 376 |       * method renames a temporary file, that file will no longer be available | |
| 377 |       * to copy or rename again at a later time. | |
| 378 |       * | |
| 379 |       * @param file The <code>File</code> into which the uploaded item should | |
| 380 |       *             be stored. | |
| 381 |       * | |
| 382 |       * @throws Exception if an error occurs. | |
| 383 |       */ | |
| 384 | @Override | |
| 385 | public void write(File file) throws Exception { | |
| 386 | 0 |          if (isInMemory()) { | 
| 387 | 0 |              FileOutputStream fout = null; | 
| 388 |              try { | |
| 389 | 0 |                  fout = new FileOutputStream(file); | 
| 390 | 0 |                  fout.write(get()); | 
| 391 | 0 |                  fout.close(); | 
| 392 |              } finally { | |
| 393 | 0 |                  IOUtils.closeQuietly(fout); | 
| 394 | 0 |              } | 
| 395 | 0 |          } else { | 
| 396 | 0 |              File outputFile = getStoreLocation(); | 
| 397 | 0 |              if (outputFile != null) { | 
| 398 |                  // Save the length of the file | |
| 399 | 0 |                  size = outputFile.length(); | 
| 400 |                  /* | |
| 401 |                   * The uploaded file is being stored on disk | |
| 402 |                   * in a temporary location so move it to the | |
| 403 |                   * desired file. | |
| 404 |                   */ | |
| 405 | 0 |                  FileUtils.moveFile(outputFile, file); | 
| 406 |              } else { | |
| 407 |                  /* | |
| 408 |                   * For whatever reason we cannot write the | |
| 409 |                   * file to disk. | |
| 410 |                   */ | |
| 411 | 0 |                  throw new FileUploadException( | 
| 412 |                      "Cannot write uploaded file to disk!"); | |
| 413 | } | |
| 414 | } | |
| 415 | 0 |      } | 
| 416 | ||
| 417 |      /** | |
| 418 |       * Deletes the underlying storage for a file item, including deleting any | |
| 419 |       * associated temporary disk file. Although this storage will be deleted | |
| 420 |       * automatically when the <code>FileItem</code> instance is garbage | |
| 421 |       * collected, this method can be used to ensure that this is done at an | |
| 422 |       * earlier time, thus preserving system resources. | |
| 423 |       */ | |
| 424 | @Override | |
| 425 | public void delete() { | |
| 426 | 707 |          cachedContent = null; | 
| 427 | 707 | File outputFile = getStoreLocation(); | 
| 428 | 707 |          if (outputFile != null && !isInMemory() && outputFile.exists()) { | 
| 429 | 265 | outputFile.delete(); | 
| 430 | } | |
| 431 | 707 | } | 
| 432 | ||
| 433 |      /** | |
| 434 |       * Returns the name of the field in the multipart form corresponding to | |
| 435 |       * this file item. | |
| 436 |       * | |
| 437 |       * @return The name of the form field. | |
| 438 |       * | |
| 439 |       * @see #setFieldName(java.lang.String) | |
| 440 |       * | |
| 441 |       */ | |
| 442 | @Override | |
| 443 |      public String getFieldName() { | |
| 444 | 1445 |          return fieldName; | 
| 445 | } | |
| 446 | ||
| 447 |      /** | |
| 448 |       * Sets the field name used to reference this file item. | |
| 449 |       * | |
| 450 |       * @param fieldName The name of the form field. | |
| 451 |       * | |
| 452 |       * @see #getFieldName() | |
| 453 |       * | |
| 454 |       */ | |
| 455 | @Override | |
| 456 | public void setFieldName(String fieldName) { | |
| 457 | 0 |          this.fieldName = fieldName; | 
| 458 | 0 |      } | 
| 459 | ||
| 460 |      /** | |
| 461 |       * Determines whether or not a <code>FileItem</code> instance represents | |
| 462 |       * a simple form field. | |
| 463 |       * | |
| 464 |       * @return <code>true</code> if the instance represents a simple form | |
| 465 |       *         field; <code>false</code> if it represents an uploaded file. | |
| 466 |       * | |
| 467 |       * @see #setFormField(boolean) | |
| 468 |       * | |
| 469 |       */ | |
| 470 | @Override | |
| 471 | public boolean isFormField() { | |
| 472 | 32 |          return isFormField; | 
| 473 | } | |
| 474 | ||
| 475 |      /** | |
| 476 |       * Specifies whether or not a <code>FileItem</code> instance represents | |
| 477 |       * a simple form field. | |
| 478 |       * | |
| 479 |       * @param state <code>true</code> if the instance represents a simple form | |
| 480 |       *              field; <code>false</code> if it represents an uploaded file. | |
| 481 |       * | |
| 482 |       * @see #isFormField() | |
| 483 |       * | |
| 484 |       */ | |
| 485 | @Override | |
| 486 | public void setFormField(boolean state) { | |
| 487 | 0 |          isFormField = state; | 
| 488 | 0 |      } | 
| 489 | ||
| 490 |      /** | |
| 491 |       * Returns an {@link java.io.OutputStream OutputStream} that can | |
| 492 |       * be used for storing the contents of the file. | |
| 493 |       * | |
| 494 |       * @return An {@link java.io.OutputStream OutputStream} that can be used | |
| 495 |       *         for storing the contents of the file. | |
| 496 |       * | |
| 497 |       * @throws IOException if an error occurs. | |
| 498 |       */ | |
| 499 | @Override | |
| 500 |      public OutputStream getOutputStream() | |
| 501 |          throws IOException { | |
| 502 | 2172 |          if (dfos == null) { | 
| 503 | 2172 | File outputFile = getTempFile(); | 
| 504 | 2172 |              dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); | 
| 505 | } | |
| 506 | 2172 |          return dfos; | 
| 507 | } | |
| 508 | ||
| 509 |      // --------------------------------------------------------- Public methods | |
| 510 | ||
| 511 |      /** | |
| 512 |       * Returns the {@link java.io.File} object for the <code>FileItem</code>'s | |
| 513 |       * data's temporary location on the disk. Note that for | |
| 514 |       * <code>FileItem</code>s that have their data stored in memory, | |
| 515 |       * this method will return <code>null</code>. When handling large | |
| 516 |       * files, you can use {@link java.io.File#renameTo(java.io.File)} to | |
| 517 |       * move the file to new location without copying the data, if the | |
| 518 |       * source and destination locations reside within the same logical | |
| 519 |       * volume. | |
| 520 |       * | |
| 521 |       * @return The data file, or <code>null</code> if the data is stored in | |
| 522 |       *         memory. | |
| 523 |       */ | |
| 524 |      public File getStoreLocation() { | |
| 525 | 709 |          if (dfos == null) { | 
| 526 | 0 |              return null; | 
| 527 | } | |
| 528 | 709 | if (isInMemory()) { | 
| 529 | 442 | return null; | 
| 530 | } | |
| 531 | 267 |          return dfos.getFile(); | 
| 532 | } | |
| 533 | ||
| 534 |      // ------------------------------------------------------ Protected methods | |
| 535 | ||
| 536 |      /** | |
| 537 |       * Removes the file contents from the temporary storage. | |
| 538 |       */ | |
| 539 | @Override | |
| 540 | protected void finalize() { | |
| 541 | 1417 |          if (dfos == null || dfos.isInMemory()) { | 
| 542 | 892 |              return; | 
| 543 | } | |
| 544 | 525 | File outputFile = dfos.getFile(); | 
| 545 | ||
| 546 | 525 |          if (outputFile != null && outputFile.exists()) { | 
| 547 | 262 | outputFile.delete(); | 
| 548 | } | |
| 549 | 525 | } | 
| 550 | ||
| 551 |      /** | |
| 552 |       * Creates and returns a {@link java.io.File File} representing a uniquely | |
| 553 |       * named temporary file in the configured repository path. The lifetime of | |
| 554 |       * the file is tied to the lifetime of the <code>FileItem</code> instance; | |
| 555 |       * the file will be deleted when the instance is garbage collected. | |
| 556 |       * <p> | |
| 557 |       * <b>Note: Subclasses that override this method must ensure that they return the | |
| 558 |       * same File each time.</b> | |
| 559 |       * | |
| 560 |       * @return The {@link java.io.File File} to be used for temporary storage. | |
| 561 |       */ | |
| 562 |      protected File getTempFile() { | |
| 563 | 2172 |          if (tempFile == null) { | 
| 564 | 2172 | File tempDir = repository; | 
| 565 | 2172 | if (tempDir == null) { | 
| 566 | 2165 | tempDir = new File(System.getProperty("java.io.tmpdir")); | 
| 567 | } | |
| 568 | ||
| 569 | 2172 |              String tempFileName = format("upload_%s_%s.tmp", UID, getUniqueId()); | 
| 570 | ||
| 571 | 2172 |              tempFile = new File(tempDir, tempFileName); | 
| 572 | } | |
| 573 | 2172 |          return tempFile; | 
| 574 | } | |
| 575 | ||
| 576 |      // -------------------------------------------------------- Private methods | |
| 577 | ||
| 578 |      /** | |
| 579 |       * Returns an identifier that is unique within the class loader used to | |
| 580 |       * load this class, but does not have random-like appearance. | |
| 581 |       * | |
| 582 |       * @return A String with the non-random looking instance identifier. | |
| 583 |       */ | |
| 584 | private static String getUniqueId() { | |
| 585 | 2172 | final int limit = 100000000; | 
| 586 | 2172 |          int current = COUNTER.getAndIncrement(); | 
| 587 | 2172 | String id = Integer.toString(current); | 
| 588 | ||
| 589 |          // If you manage to get more than 100 million of ids, you'll | |
| 590 |          // start getting ids longer than 8 characters. | |
| 591 | 2172 |          if (current < limit) { | 
| 592 | 2172 |              id = ("00000000" + id).substring(id.length()); | 
| 593 | } | |
| 594 | 2172 |          return id; | 
| 595 | } | |
| 596 | ||
| 597 |      /** | |
| 598 |       * Returns a string representation of this object. | |
| 599 |       * | |
| 600 |       * @return a string representation of this object. | |
| 601 |       */ | |
| 602 | @Override | |
| 603 |      public String toString() { | |
| 604 | 0 |          return format("name=%s, StoreLocation=%s, size=%s bytes, isFormField=%s, FieldName=%s", | 
| 605 | 0 |                        getName(), getStoreLocation(), Long.valueOf(getSize()), | 
| 606 | 0 |                        Boolean.valueOf(isFormField()), getFieldName()); | 
| 607 | } | |
| 608 | ||
| 609 |      /** | |
| 610 |       * Returns the file item headers. | |
| 611 |       * @return The file items headers. | |
| 612 |       */ | |
| 613 | @Override | |
| 614 |      public FileItemHeaders getHeaders() { | |
| 615 | 32 |          return headers; | 
| 616 | } | |
| 617 | ||
| 618 |      /** | |
| 619 |       * Sets the file item headers. | |
| 620 |       * @param pHeaders The file items headers. | |
| 621 |       */ | |
| 622 | @Override | |
| 623 | public void setHeaders(FileItemHeaders pHeaders) { | |
| 624 | 2160 | headers = pHeaders; | 
| 625 | 2160 | } | 
| 626 | ||
| 627 |      /** | |
| 628 |       * Returns the default charset for use when no explicit charset | |
| 629 |       * parameter is provided by the sender. | |
| 630 |       * @return the default charset | |
| 631 |       */ | |
| 632 |      public String getDefaultCharset() { | |
| 633 | 0 |          return defaultCharset; | 
| 634 | } | |
| 635 | ||
| 636 |      /** | |
| 637 |       * Sets the default charset for use when no explicit charset | |
| 638 |       * parameter is provided by the sender. | |
| 639 |       * @param charset the default charset | |
| 640 |       */ | |
| 641 | public void setDefaultCharset(String charset) { | |
| 642 | 2169 | defaultCharset = charset; | 
| 643 | 2169 | } | 
| 644 | } |