org.liquidsite.core.web.MultiPartRequest.java Source code

Java tutorial

Introduction

Here is the source code for org.liquidsite.core.web.MultiPartRequest.java

Source

/*
 * MultiPartRequest.java
 *
 * This work is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 *
 * This work is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 * Copyright (c) 2004 Per Cederberg. All rights reserved.
 */

package org.liquidsite.core.web;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;

import org.liquidsite.util.log.Log;

/**
 * An HTTP multi-part request and response.
 *
 * @author   Per Cederberg, <per at percederberg dot net>
 * @version  1.0
 */
public class MultiPartRequest extends Request {

    /**
     * The class logger.
     */
    private static final Log LOG = new Log(MultiPartRequest.class);

    /**
     * The temporary upload directory.
     */
    private String uploadDir = "";

    /**
     * The maximum upload size.
     */
    private int uploadSize = 0;

    /**
     * The normal query or post parameters.
     */
    private HashMap parameters = new HashMap();

    /**
     * The file parameters.
     */
    private HashMap files = new HashMap();

    /**
     * Creates a new multi-part request.
     *
     * @param context        the servlet context
     * @param request        the HTTP request
     * @param response       the HTTP response
     * @param tempDir        the temporary upload directory
     * @param maxSize        the maximum upload size (in bytes)
     *
     * @throws ServletException if the request couldn't be parsed
     *             correctly
     */
    public MultiPartRequest(ServletContext context, HttpServletRequest request, HttpServletResponse response,
            String tempDir, int maxSize) throws ServletException {

        super(context, request, response);
        this.uploadDir = tempDir;
        this.uploadSize = maxSize;
        try {
            parse(request);
        } catch (FileUploadException e) {
            LOG.error(e.getMessage());
            throw new ServletException("Couldn't handle multipart request: " + e.getMessage());
        }
    }

    /**
     * Parses the incoming multi-part HTTP request.
     *
     * @param request        the HTTP request
     *
     * @throws FileUploadException if the request couldn't be parsed
     *             correctly
     */
    private void parse(HttpServletRequest request) throws FileUploadException {

        DiskFileUpload parser = new DiskFileUpload();
        List list;
        FileItem item;
        String value;

        // Create multi-part parser
        parser.setRepositoryPath(uploadDir);
        parser.setSizeMax(uploadSize);
        parser.setSizeThreshold(4096);

        // Parse request
        list = parser.parseRequest(request);
        for (int i = 0; i < list.size(); i++) {
            item = (FileItem) list.get(i);
            if (item.isFormField()) {
                try {
                    value = item.getString("UTF-8");
                } catch (UnsupportedEncodingException ignore) {
                    value = item.getString();
                }
                parameters.put(item.getFieldName(), value);
            } else {
                files.put(item.getFieldName(), new MultiPartFile(item));
            }
        }
    }

    /**
     * Returns a map with all the request parameter names and values.
     *
     * @return the map with request parameter names and values
     */
    public Map getAllParameters() {
        return parameters;
    }

    /**
     * Returns the value of a request parameter. If the specified
     * parameter does not exits, a default value will be returned.
     *
     * @param name           the request parameter name
     * @param defVal         the default parameter value
     *
     * @return the request parameter value, or
     *         the default value if no such parameter was found
     */
    public String getParameter(String name, String defVal) {
        String value = (String) parameters.get(name);

        return (value == null) ? defVal : value;
    }

    /**
     * Returns the specified file request parameter.
     *
     * @param name           the request parameter name
     *
     * @return the request file parameter, or
     *         null if no such file parameter was found
     */
    public FileParameter getFileParameter(String name) {
        return (FileParameter) files.get(name);
    }

    /**
     * Disposes of all resources used by this request object. This
     * method shouldn't be called until a response has been written.
     */
    public void dispose() {
        Iterator iter = files.values().iterator();

        super.dispose();
        while (iter.hasNext()) {
            ((MultiPartFile) iter.next()).dispose();
        }
        parameters.clear();
        files.clear();
        parameters = null;
        files = null;
    }

    /**
     * Returns the upload directory.
     *
     * @return the upload directory
     */
    protected String getUploadDir() {
        return uploadDir;
    }

    /**
     * A request file parameter.
     *
     * @author   Per Cederberg, <per at percederberg dot net>
     * @version  1.0
     */
    private class MultiPartFile implements FileParameter {

        /**
         * The file item.
         */
        private FileItem item;

        /**
         * Creates a new request file parameter.
         *
         * @param item           the file item
         */
        MultiPartFile(FileItem item) {
            this.item = item;
        }

        /**
         * Returns the base file name including the extension. The
         * file name returned is guaranteed to not contain any file
         * path or directory name.
         *
         * @return the base file name (with extension)
         */
        public String getName() {
            String name = item.getName();

            if (name.lastIndexOf("/") >= 0) {
                name = name.substring(name.lastIndexOf("/") + 1);
            }
            if (name.lastIndexOf("\\") >= 0) {
                name = name.substring(name.lastIndexOf("\\") + 1);
            }
            return name;
        }

        /**
         * Returns the full file name including path and extension.
         * The file name returned should be exactly the one sent by
         * the browser.
         *
         * @return the full file path
         */
        public String getPath() {
            return item.getName();
        }

        /**
         * Returns the file size.
         *
         * @return the file size
         */
        public long getSize() {
            return item.getSize();
        }

        /**
         * Writes this file to a temporary file in the upload
         * directory. After calling this method, only the dispose()
         * method can be called.
         *
         * @return the file created
         *
         * @throws IOException if the file parameter couldn't be
         *             written
         */
        public File write() throws IOException {
            String name = getName();
            File file;

            file = new File(getUploadDir(), name);
            for (int i = 1; file.exists(); i++) {
                file = new File(getUploadDir(), i + "." + name);
            }
            write(file);
            return file;
        }

        /**
         * Writes this file to the specified destination file. After
         * calling this method, only the dispose() method can be
         * called.
         *
         * @param dest           the destination file
         *
         * @throws IOException if the file parameter couldn't be
         *             written to the specified file
         */
        public void write(File dest) throws IOException {
            String error;

            try {
                item.write(dest);
            } catch (Exception e) {
                error = "couldn't move request file to " + dest + ": " + e.getMessage();
                throw new IOException(error);
            }
        }

        /**
         * Disposes of all resources used by this object. This method
         * shouldn't be called until the file parameter should no
         * longer be used.
         */
        void dispose() {
            item.delete();
        }
    }
}