Package org.hdiv.upload

Source Code of org.hdiv.upload.HDIVMultipartRequestHandler$CommonsFormFile

/**
* Copyright 2005-2013 hdiv.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hdiv.upload;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.upload.CommonsMultipartRequestHandler;
import org.apache.struts.upload.FormFile;
import org.apache.struts.upload.MultipartRequestWrapper;
import org.hdiv.config.multipart.IMultipartConfig;
import org.hdiv.config.multipart.exception.HdivMultipartException;
import org.hdiv.filter.RequestWrapper;

public class HDIVMultipartRequestHandler extends CommonsMultipartRequestHandler {

  /**
   * Commons Logging instance.
   */
  protected static Log log = LogFactory.getLog(HDIVMultipartRequestHandler.class);

  /**
   * The combined text and file request parameters.
   */
  private Hashtable elementsAll;

  /**
   * The file request parameters.
   */
  private Hashtable elementsFile;

  /**
   * The text request parameters.
   */
  private Hashtable elementsText;

  /**
   * Parses the input stream and partitions the parsed items into a set of form fields and a set of file items. In the
   * process, the parsed items are translated from Commons FileUpload <code>FileItem</code> instances to Struts
   * <code>FormFile</code> instances.
   *
   * @param request
   *            The multipart request to be processed.
   * @throws ServletException
   *             if an unrecoverable error occurs.
   */
  public void handleRequest(HttpServletRequest request) throws ServletException {

    // Create the hash tables to be populated.
    elementsText = new Hashtable();
    elementsFile = new Hashtable();
    elementsAll = new Hashtable();

    if (request instanceof MultipartRequestWrapper) {

      MultipartRequestWrapper wrapper = (MultipartRequestWrapper) request;
      ServletRequest origRequest = wrapper.getRequest();
      if (origRequest != null && origRequest instanceof RequestWrapper) {

        RequestWrapper requestWrapper = (RequestWrapper) origRequest;

        Boolean maxLengthExceeded = (Boolean) request.getAttribute(ATTRIBUTE_MAX_LENGTH_EXCEEDED);
        if ((maxLengthExceeded != null) && (maxLengthExceeded.booleanValue())) {
          return;
        }

        HdivMultipartException multipartException = (HdivMultipartException) request
            .getAttribute(IMultipartConfig.FILEUPLOAD_EXCEPTION);
        if (multipartException != null) {
          Exception orig = multipartException.getOriginal();
          log.error("Failed to parse multipart request", orig);
          if (orig instanceof ServletException) {
            throw (ServletException) orig;
          } else {
            throw new ServletException("Failed to parse multipart request", orig);
          }
        }

        // file items
        Map<String, Object> items = requestWrapper.getFileElements();

        for (Object fileItem : items.values()) {
          if (items != null) {
            addFileParameter((List) fileItem);
          }
        }

        // text items
        items = requestWrapper.getTextElements();

        for (String currentTextKey : items.keySet()) {

          String[] currentTextValue = (String[]) items.get(currentTextKey);
          this.addTextParameter(wrapper, currentTextKey, currentTextValue);
        }
      }
    }
  }

  /**
   * Adds a regular text parameter to the set of text parameters for this request and also to the list of all
   * parameters. Handles the case of multiple values for the same parameter by using an array for the parameter value.
   *
   * @param request
   *            The request in which the parameter was specified.
   * @param name
   *            Parameter name.
   * @param value
   *            Parameter value.
   */
  protected void addTextParameter(HttpServletRequest request, String name, String[] value) {

    if (request instanceof MultipartRequestWrapper) {
      MultipartRequestWrapper wrapper = (MultipartRequestWrapper) request;

      for (int i = 0; i < value.length; i++) {
        wrapper.setParameter(name, value[i]);
      }
    }

    elementsText.put(name, value);
    elementsAll.put(name, value);
  }

  /**
   * Adds a file parameter to the set of file parameters for this request and also to the list of all parameters.
   *
   * @param items
   *            file items for the parameter to add
   */
  protected void addFileParameter(List items) {

    FileItem currentItem;
    for (int i = 0; i < items.size(); i++) {

      currentItem = (FileItem) items.get(i);
      FormFile formFile = new CommonsFormFile(currentItem);

      elementsFile.put(currentItem.getFieldName(), formFile);
      elementsAll.put(currentItem.getFieldName(), formFile);
    }
  }

  /**
   * Returns a hash table containing the text (that is, non-file) request parameters.
   *
   * @return The text request parameters.
   */
  public Hashtable getTextElements() {
    return this.elementsText;
  }

  /**
   * Returns a hash table containing the file (that is, non-text) request parameters.
   *
   * @return The file request parameters.
   */
  public Hashtable getFileElements() {
    return this.elementsFile;
  }

  /**
   * Returns a hash table containing both text and file request parameters.
   *
   * @return The text and file request parameters.
   */
  public Hashtable getAllElements() {
    return this.elementsAll;
  }

  /**
   * Cleans up when a problem occurs during request processing.
   */
  public void rollback() {

    Iterator iter = elementsFile.values().iterator();

    while (iter.hasNext()) {
      FormFile formFile = (FormFile) iter.next();

      formFile.destroy();
    }
  }

  // ---------------- Inner Class --------------------

  /**
   * This class implements the Struts <code>FormFile</code> interface by wrapping the Commons FileUpload
   * <code>FileItem</code> interface. This implementation is <i>read-only</i>; any attempt to modify an instance of
   * this class will result in an <code>UnsupportedOperationException</code>.
   */
  static class CommonsFormFile implements FormFile, Serializable {

    /**
     * The <code>FileItem</code> instance wrapped by this object.
     */
    FileItem fileItem;

    /**
     * Constructs an instance of this class which wraps the supplied file item.
     *
     * @param fileItem
     *            The Commons file item to be wrapped.
     */
    public CommonsFormFile(FileItem fileItem) {
      this.fileItem = fileItem;
    }

    /**
     * Returns the content type for this file.
     *
     * @return A String representing content type.
     */
    public String getContentType() {
      return fileItem.getContentType();
    }

    /**
     * Sets the content type for this file.
     * <p>
     * NOTE: This method is not supported in this implementation.
     *
     * @param contentType
     *            A string representing the content type.
     */
    public void setContentType(String contentType) {
      throw new UnsupportedOperationException("The setContentType() method is not supported.");
    }

    /**
     * Returns the size, in bytes, of this file.
     *
     * @return The size of the file, in bytes.
     */
    public int getFileSize() {
      return (int) fileItem.getSize();
    }

    /**
     * Sets the size, in bytes, for this file.
     * <p>
     * NOTE: This method is not supported in this implementation.
     *
     * @param filesize
     *            The size of the file, in bytes.
     */
    public void setFileSize(int filesize) {
      throw new UnsupportedOperationException("The setFileSize() method is not supported.");
    }

    /**
     * Returns the (client-side) file name for this file.
     *
     * @return The client-size file name.
     */
    public String getFileName() {
      return getBaseFileName(fileItem.getName());
    }

    /**
     * Sets the (client-side) file name for this file.
     * <p>
     * NOTE: This method is not supported in this implementation.
     *
     * @param fileName
     *            The client-side name for the file.
     */
    public void setFileName(String fileName) {
      throw new UnsupportedOperationException("The setFileName() method is not supported.");
    }

    /**
     * Returns the data for this file as a byte array. Note that this may result in excessive memory usage for large
     * uploads. The use of the {@link #getInputStream() getInputStream} method is encouraged as an alternative.
     *
     * @return An array of bytes representing the data contained in this form file.
     *
     * @exception FileNotFoundException
     *                If some sort of file representation cannot be found for the FormFile
     * @exception IOException
     *                If there is some sort of IOException
     */
    public byte[] getFileData() throws FileNotFoundException, IOException {
      return fileItem.get();
    }

    /**
     * Get an InputStream that represents this file. This is the preferred method of getting file data.
     *
     * @exception FileNotFoundException
     *                If some sort of file representation cannot be found for the FormFile
     * @exception IOException
     *                If there is some sort of IOException
     */
    public InputStream getInputStream() throws FileNotFoundException, IOException {
      return fileItem.getInputStream();
    }

    /**
     * Destroy all content for this form file. Implementations should remove any temporary files or any temporary
     * file data stored somewhere
     */
    public void destroy() {
      fileItem.delete();
    }

    /**
     * Returns the base file name from the supplied file path. On the surface, this would appear to be a trivial
     * task. Apparently, however, some Linux JDKs do not implement <code>File.getName()</code> correctly for Windows
     * paths, so we attempt to take care of that here.
     *
     * @param filePath
     *            The full path to the file.
     *
     * @return The base file name, from the end of the path.
     */
    protected String getBaseFileName(String filePath) {

      // First, ask the JDK for the base file name.
      String fileName = new File(filePath).getName();

      // Now check for a Windows file name parsed incorrectly.
      int colonIndex = fileName.indexOf(":");
      if (colonIndex == -1) {
        // Check for a Windows SMB file path.
        colonIndex = fileName.indexOf("\\\\");
      }
      int backslashIndex = fileName.lastIndexOf("\\");

      if (colonIndex > -1 && backslashIndex > -1) {
        // Consider this filename to be a full Windows path, and parse it
        // accordingly to retrieve just the base file name.
        fileName = fileName.substring(backslashIndex + 1);
      }

      return fileName;
    }

    /**
     * Returns the (client-side) file name for this file.
     *
     * @return The client-size file name.
     */
    public String toString() {
      return getFileName();
    }
  }

}
TOP

Related Classes of org.hdiv.upload.HDIVMultipartRequestHandler$CommonsFormFile

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.