package org.apache.turbine.util.parser;

/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache Turbine" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache Turbine", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import java.net.URLDecoder;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

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.turbine.services.upload.TurbineUpload;
import org.apache.turbine.services.upload.UploadService;

import org.apache.turbine.util.TurbineException;
import org.apache.turbine.util.pool.Recyclable;

/**
 * DefaultParameterParser is a utility object to handle parsing and
 * retrieving the data passed via the GET/POST/PATH_INFO arguments.
 *
 * <p>NOTE: The name= portion of a name=value pair may be converted
 * to lowercase or uppercase when the object is initialized and when
 * new data is added.  This behaviour is determined by the url.case.folding
 * property in TurbineResources.properties.  Adding a name/value pair may
 * overwrite existing name=value pairs if the names match:
 *
 * <pre>
 * ParameterParser pp = data.getParameters();
 * pp.add("ERROR",1);
 * pp.add("eRrOr",2);
 * int result = pp.getInt("ERROR");
 * </pre>
 *
 * In the above example, result is 2.
 * 
 * Note:  In the jakarta-turbine-2 codebase things look much updated for parsing.
 *
 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
 * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
 * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 * @version $Id$
 */
public class DefaultParameterParser
    extends BaseValueParser
    implements ParameterParser, Recyclable
{
    /** Logging */
    private static Log log = LogFactory.getLog(DefaultParameterParser.class);

    /** The servlet request to parse. */
    private HttpServletRequest request = null;

    /** The raw data of a file upload. */
    private byte[] uploadData = null;

    /** Map of request parameters to FileItem[]'s */
    private Map fileParameters = new HashMap();

    /** Turbine Upload Service reference */
    private static UploadService uploadService = null;

    /** Do we have an upload Service? */
    private static boolean uploadServiceIsAvailable = false;

    /**
     * Create a new empty instance of ParameterParser.  Uses the
     * default character encoding (US-ASCII).
     *
     * <p>To add name/value pairs to this set of parameters, use the
     * <code>add()</code> methods.
     */
    public DefaultParameterParser()
    {
        super();
        configureUploadService();
    }

    /**
     * Create a new empty instance of ParameterParser. Takes a
     * character encoding name to use when converting strings to
     * bytes.
     *
     * <p>To add name/value pairs to this set of parameters, use the
     * <code>add()</code> methods.
     *
     * @param characterEncoding The character encoding of strings.
     */
    public DefaultParameterParser(String characterEncoding)
    {
        super (characterEncoding);
        configureUploadService();
    }

    /**
     * Checks for availability of the Upload Service. We do this
     * check only once at Startup, because the getService() call
     * is really expensive and we don't have to run it every time
     * we process a request.
     */
    private void configureUploadService()
    {
        uploadServiceIsAvailable = TurbineUpload.isAvailable();
        if (uploadServiceIsAvailable)
        {
            uploadService = TurbineUpload.getService();
        }
    }

    /**
     * Disposes the parser.
     */
    public void dispose()
    {
        this.request = null;
        this.uploadData = null;
        this.fileParameters.clear();
        super.dispose();
    }

    /**
     * Gets the parsed servlet request.
     *
     * @return the parsed servlet request or null.
     */
    public HttpServletRequest getRequest()
    {
        return this.request;
    }

    /**
     * Sets the servlet request to be parser.  This requires a
     * valid HttpServletRequest object.  It will attempt to parse out
     * the GET/POST/PATH_INFO data and store the data into a Map.
     * There are convenience methods for retrieving the data as a
     * number of different datatypes.  The PATH_INFO data must be a
     * URLEncoded() string.
     * <p>
     * To add name/value pairs to this set of parameters, use the
     * <code>add()</code> methods.
     *
     * @param request An HttpServletRequest.
     */
    public void setRequest(HttpServletRequest request)
    {
        clear();

        uploadData = null;

        String enc = request.getCharacterEncoding();
        setCharacterEncoding(enc != null ? enc : "US-ASCII");

        // String object re-use at its best.
        String tmp = null;

        tmp = request.getHeader("Content-type");

        if (uploadServiceIsAvailable
                && uploadService.getAutomatic()
                && tmp != null
                && tmp.startsWith("multipart/form-data"))
        {
            log.debug("Running the Turbine Upload Service");
            try
            {
                TurbineUpload.parseRequest(request, this);
            }
            catch (TurbineException e)
            {
                log.error("File upload failed", e);
            }
        }

        for (Enumeration names = request.getParameterNames();
             names.hasMoreElements();)
        {
            tmp = (String) names.nextElement();
            add(convert(tmp),
                    request.getParameterValues(tmp));
        }

        // Also cache any pathinfo variables that are passed around as
        // if they are query string data.
        try
        {
            StringTokenizer st =
                    new StringTokenizer(request.getPathInfo(), "/");
            boolean isNameTok = true;
            String pathPart = null;
            while (st.hasMoreTokens())
            {
                if (isNameTok)
                {
                    tmp = URLDecoder.decode(st.nextToken());
                    isNameTok = false;
                }
                else
                {
                    pathPart = URLDecoder.decode(st.nextToken());
                    if (tmp.length() > 0)
                    {
                        add(convert(tmp), pathPart);
                    }
                    isNameTok = true;
                }
            }
        }
        catch (Exception e)
        {
            // If anything goes wrong above, don't worry about it.
            // Chances are that the path info was wrong anyways and
            // things that depend on it being right will fail later
            // and should be caught later.
        }

        this.request = request;

        if (log.isDebugEnabled())
        {
            log.debug("Parameters found in the Request:");
            for (Iterator it = keySet().iterator(); it.hasNext();)
            {
                String key = (String) it.next();
                log.debug("Key: " + key + " -> " + getString(key));
            }
        }
    }

    /**
     * Sets the uploadData byte[]
     *
     * @param uploadData A byte[] with data.
     */
    public void setUploadData(byte[] uploadData)
    {
        this.uploadData = uploadData;
    }

    /**
     * Gets the uploadData byte[]
     *
     * @return uploadData A byte[] with data.
     */
    public byte[] getUploadData()
    {
        return this.uploadData;
    }

    /**
     * Add a FileItem object as a parameters.  If there are any
     * FileItems already associated with the name, append to the
     * array.  The reason for this is that RFC 1867 allows multiple
     * files to be associated with single HTML input element.
     *
     * @param name A String with the name.
     * @param value A FileItem with the value.
     */
    public void append(String name, FileItem value)
    {
        FileItem[] items = this.getFileItems(name);
        if (items == null)
        {
            items = new FileItem[1];
            items[0] = value;
            fileParameters.put(convert(name), items);
        }
        else
        {
            FileItem[] newItems = new FileItem[items.length + 1];
            System.arraycopy(items, 0, newItems, 0, items.length);
            newItems[items.length] = value;
            fileParameters.put(convert(name), newItems);
        }
    }

    /**
     * Return a FileItem object for the given name.  If the name does
     * not exist or the object stored is not a FileItem, return null.
     *
     * @param name A String with the name.
     * @return A FileItem.
     */
    public FileItem getFileItem(String name)
    {
        try
        {
            FileItem value = null;
            Object object = fileParameters.get(convert(name));
            if (object != null)
            {
                value = ((FileItem[]) object)[0];
            }
            return value;
        }
        catch (ClassCastException e)
        {
            log.error("Parameter ("
                    + name + ") is not an instance of FileItem", e);
            return null;
        }
    }

    /**
     * Return an array of FileItem objects for the given name.  If the
     * name does not exist or the object stored is not a FileItem
     * array, return null.
     *
     * @param name A String with the name.
     * @return A FileItem[].
     */
    public FileItem[] getFileItems(String name)
    {
        try
        {
            return (FileItem[]) fileParameters.get(convert(name));
        }
        catch (ClassCastException e)
        {
            log.error("Parameter ("
                    + name + ") is not an instance of FileItem[]", e);
            return null;
        }
    }
}
