All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fastchar.multipart.FilePart Maven / Gradle / Ivy

// Copyright (C) 1999-2001 by Jason Hunter .
// All rights reserved.  Use of this class is limited.
// Please see the LICENSE for more information.

package com.fastchar.multipart;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.servlet.ServletInputStream;

/**
 * A FilePart is an upload part which represents a 
 * INPUT TYPE="file" form parameter.  Note that because file 
 * upload data arrives via a single InputStream, each FilePart's contents
 * must be read before moving onto the next part.  Don't try to store a
 * FilePart object for later processing because by then their content will
 * have been passed by.
 * 
 * @author Geoff Soutter
 * @version 1.2, 2001/01/22, getFilePath() addition thanks to Stefan Eissing
 * @version 1.1, 2000/11/26, writeTo() bug fix thanks to Mike Shivas
 * @version 1.0, 2000/10/27, initial revision
 */
public class FilePart extends Part {
  
  /** "file system" name of the file  */
  private String fileName;     
  
  /** path of the file as sent in the request, if given */
  private String filePath;

  /** content type of the file */
  private String contentType;   
  
  /** input stream containing file data */
  private PartInputStream partInput;  
    
  /** file rename policy */
  private FileRenamePolicy policy;

  /**
   * Construct a file part; this is called by the parser.
   * 
   * @param name the name of the parameter.
   * @param in the servlet input stream to read the file from.
   * @param boundary the MIME boundary that delimits the end of file.
   * @param contentType the content type of the file provided in the 
   * MIME header.
   * @param fileName the file system name of the file provided in the 
   * MIME header.
   * @param filePath the file system path of the file provided in the
   * MIME header (as specified in disposition info).
   * 
   * @exception IOException	if an input or output exception has occurred.
   */
  FilePart(String name, ServletInputStream in, String boundary,
           String contentType, String fileName, String filePath)
                                                   throws IOException {
    super(name);
    this.fileName = fileName;
    this.filePath = filePath;
    this.contentType = contentType;
    partInput = new PartInputStream(in, boundary);
  }

  /**
   * Puts in place the specified policy for handling file name collisions.
   */
  public void setRenamePolicy(FileRenamePolicy policy) {
    this.policy = policy;
  }
  
  /**
   * Returns the name that the file was stored with on the remote system, 
   * or null if the user didn't enter a file to be uploaded. 
   * Note: this is not the same as the name of the form parameter used to 
   * transmit the file; that is available from the getName
   * method.  Further note: if file rename logic is in effect, the file
   * name can change during the writeTo() method when there's a collision
   * with another file of the same name in the same directory.  If this
   * matters to you, be sure to pay attention to when you call the method.
   * 
   * @return name of file uploaded or null.
   * 
   * @see Part#getName()
   */
  public String getFileName() {
    return fileName;
  }

  /**
   * Returns the full path and name of the file on the remote system,
   * or null if the user didn't enter a file to be uploaded.
   * If path information was not supplied by the remote system, this method
   * will return the same as getFileName().
   *
   * @return path of file uploaded or null.
   *
   * @see Part#getName()
   */
  public String getFilePath() {
    return filePath;
  }

  /** 
   * Returns the content type of the file data contained within.
   * 
   * @return content type of the file data.
   */
  public String getContentType() {
    return contentType;
  }
  
  /**
   * Returns an input stream which contains the contents of the
   * file supplied. If the user didn't enter a file to upload
   * there will be 0 bytes in the input stream.
   * It's important to read the contents of the InputStream 
   * immediately and in full before proceeding to process the 
   * next part.  The contents will otherwise be lost on moving
   * to the next part.
   * 
   * @return an input stream containing contents of file.
   */
  public InputStream getInputStream() {
    return partInput;
  }

  /**
   * Write this file part to a file or directory. If the user 
   * supplied a file, we write it to that file, and if they supplied
   * a directory, we write it to that directory with the filename
   * that accompanied it. If this part doesn't contain a file this
   * method does nothing.
   *
   * @return number of bytes written
   * @exception IOException	if an input or output exception has occurred.
   */
  public long writeTo(File fileOrDirectory) throws IOException {
    long written = 0;
    
    OutputStream fileOut = null;
    try {
      // Only do something if this part contains a file
      if (fileName != null) {
        // Check if user supplied directory
        File file;
        if (fileOrDirectory.isDirectory()) {
          // Write it to that dir the user supplied, 
          // with the filename it arrived with
          file = new File(fileOrDirectory, fileName);
        }
        else {
          // Write it to the file the user supplied,
          // ignoring the filename it arrived with
          file = fileOrDirectory;
        }
        if (policy != null) {
          file = policy.rename(file);
          fileName = file.getName();
        }
        fileOut = new BufferedOutputStream(new FileOutputStream(file));
        written = write(fileOut);
      }
    }
    finally {
      if (fileOut != null) {
          fileOut.close();
      }
    }
    return written;
  }

  /**
   * Write this file part to the given output stream. If this part doesn't 
   * contain a file this method does nothing.
   *
   * @return number of bytes written.
   * @exception IOException	if an input or output exception has occurred.
   */
  public long writeTo(OutputStream out) throws IOException {
    long size=0;
    // Only do something if this part contains a file
    if (fileName != null) {
      // Write it out
      size = write( out );
    }
    return size;
  }

  /**
   * Internal method to write this file part; doesn't check to see
   * if it has contents first.
   *
   * @return number of bytes written.
   * @exception IOException	if an input or output exception has occurred.
   */
  long write(OutputStream out) throws IOException {
    // decode macbinary if this was sent
    if ("application/x-macbinary".equals(contentType)) {
      out = new MacBinaryDecoderOutputStream(out);
    }
    long size=0;
    int read;
    byte[] buf = new byte[8 * 1024];
    while((read = partInput.read(buf)) != -1) {
      out.write(buf, 0, read);
      size += read;
    }
    return size;
  }
  
  /**
   * Returns true to indicate this part is a file.
   * 
   * @return true.
   */
  @Override
  public boolean isFile() {
    return true;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy