/*
 * Copyright (c) 2003, Morpho Project.
 * 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. Neither the name of the Morpho Project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
 */
package jp.morpho.webapp.servlet.http.impl;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import jp.morpho.io.UploadFile;
import jp.morpho.util.ConversionMap;
import jp.morpho.webapp.servlet.ServletRequestAttributeNames;
import jp.morpho.webapp.servlet.http.HttpActionRequest;

/**
 * <P>
 * HttpActionRequestImpl クラスは、HTTP サーブレット用の要求情報を提供する HttpActionRequest インタフェースの実装です。
 * このクラスは、ラッパーまたはデコレータのパターンに基づいて実装されています。
 * 各メソッドは、ラップされた要求オブジェクトのメソッドをデフォルトで呼び出します。
 * </P>
 * <P>
 * HttpActionRequestImpl クラスには、要求を処理するために必要なアクションやステータスを取得するためのメソッドが提供されます。
 * </P>
 * @author Kenichi Fukuda
 */
public class HttpActionRequestImpl
	extends HttpServletRequestWrapper
	implements HttpActionRequest
{

	/**
	 * <P>
	 * 指定された要求をラップした HttpActionRequestImpl を構築します。
	 * </P>
	 * @param request サーブレットへの要求
	 * @exception IllegalArgumentException 要求が null の場合
	 */
	public HttpActionRequestImpl(HttpServletRequest request)
	{
		super(request);
	}

	/**
	 * <P>
	 * 要求を処理するアクションの値を取得します。
	 * </P>
	 * @return 要求を処理するアクションの値
	 */
	public String getAction()
	{
		return (String)this.getAttribute(ServletRequestAttributeNames.action);
	}

	/**
	 * <P>
	 * 要求を処理するアクションの値を設定します。
	 * </P>
	 * @param action 要求を処理するアクションの値
	 */
	public void setAction(String action)
	{
		this.setAttribute(ServletRequestAttributeNames.action, action);
	}

	/**
	 * <P>
	 * 要求を処理するステータスの値を取得します。
	 * </P>
	 * @return 要求を処理するステータスの値
	 */
	public String getStatus()
	{
		return (String)this.getAttribute(ServletRequestAttributeNames.status);
	}

	/**
	 * <P>
	 * 要求を処理するステータスの値を設定します。
	 * </P>
	 * @param status 要求を処理するステータスの値
	 */
	public void setStatus(String status)
	{
		this.setAttribute(ServletRequestAttributeNames.status, status);
	}

	/**
	 * <P>
	 * この要求から取得できるパラメータを java.util.Map で返します。
	 * 要求パラメータとは、要求とともに送信される追加情報です。
	 * HTTP サーブレットの場合、パラメータはクエリー文字列内または POST された形式のデータ内に格納されています。
	 * </P>
	 * @return キーとしてパラメータ名、マップ値としてパラメータ値が格納された java.util.Map。パラメータマップ内のキーは String 型。パラメータマップ内の値は、パラメータに 1 つの値のみが含まれている場合は String 、複数の値を持つパラメータの場合は String の配列型。パラメータの値がアップロードされたファイルの場合は jp.morpho.io.UploadFile または jp.morpho.io.UploadFile の配列型
	 */
	public Map getParameterMap()
	{
		Map formValues = (Map)this.getAttribute(ServletRequestAttributeNames.form);
		if (formValues == null)
		{
			formValues = new ConversionMap();
			this.setParameterMap(formValues);
		}
		return formValues;
	}

	/**
	 * <P>
	 * この要求にパラメータを設定します。
	 * </P>
	 * @param map 要求パラメータ
	 */
	public void setParameterMap(Map map)
	{
		this.setAttribute(ServletRequestAttributeNames.form, map);
	}

	/**
	 * <P>
	 * この要求にパラメータのマップがある場合に、そのパラメータのマップを要求から削除します。<br>
	 * </P>
	 */
	public void removeParameterMap()
	{
		this.removeAttribute(ServletRequestAttributeNames.form);
	}

	/**
	 * <P>
	 * 要求パラメータの値を String として返します。
	 * パラメータが存在しない場合は、null を返します。
	 * 要求パラメータは、要求とともに送信される追加情報です。
	 * HTTP サーブレットの場合、クエリー文字列内または POST された形式のデータ内にパラメータが格納されています。
	 * </P>
	 * <P>
	 * パラメータに 1 つの値のみが含まれていることが確実な場合にのみ、このメソッドを使用してください。
	 * パラメータに複数の値が含まれている可能性がある場合は、getParameterValues(java.lang.String) を使用します。
	 * </P>
	 * <P>
	 * 複数の値を持つパラメータに対してこのメソッドを使用した場合、返される値は、getParameterValues で返される配列内の最初の値と同じです。
	 * </P>
	 * @param name パラメータの名前を指定する String
	 * @return パラメータの単一の値を表す String
	 * @see javax.servlet.ServletRequest#getParameter(String)
	 */
	public String getParameter(String name)
	{
		ConversionMap formValues = ConversionMap.valueOf(this.getParameterMap());

		if (formValues.getObject(name) instanceof UploadFile)
		{
			return null;
		}
		if (formValues.isNull(name))
		{
			return null;
		}
		if (formValues.isArray(name))
		{
			Object[] objs = (Object[])formValues.getObject(name);
			return objs[0].toString();
		}
		return formValues.getString(name);
	}
}
