/*
 * $Header: /home/cvs/struts/xdocs/struts1.2/documentation/ja/src/share/org/apache/struts/action/ExceptionHandler.java,v 1.5 2005/02/11 03:27:20 tatakaha Exp $
 * $Revision: 1.5 $
 * $Date: 2005/02/11 03:27:20 $
 *
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * 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.apache.struts.action;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.Globals;
import org.apache.struts.config.ExceptionConfig;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.ModuleException;

/**
 * <p><code>Action.execute</code>メソッドによってスローされた例外の特定のタイプを扱うために、
 * <strong>ExceptionHandler</strong>はStruts設定ファイル中で設定されます。</p>
 * {@primary <p>An <strong>ExceptionHandler</strong> is configured in the Struts
 * configuration file to handle a specific type of exception thrown
 * by an <code>Action.execute</code> method.</p>}
 * 
 * @since Struts 1.1
 * @translator 棚澤 昌幸
 * @status firstdraft
 * @update 2005/1/31
 * @memo ブロックA
 */
public class ExceptionHandler {
    

    /**
     * <p>Commons loggingのインスタンス。</p>
     * {@primary <p>Commons logging instance.</p>}
     */
    private static final Log log = LogFactory.getLog(ExceptionHandler.class);
    

    /**
     * <p>このパッケージのメッセージリソース。</p>
     * {@primary <p>The message resources for this package.</p>}
     */
    private static MessageResources messages =
        MessageResources.getMessageResources(
            "org.apache.struts.action.LocalStrings");
    

    /**
     * <p><code>Exception</code>を取り扱います。
     * (もしあれば)
     * 呼ばれた<code>ExceptionHandler</code>によって返される<code>ActionForward</code>インスタンスを返します。</p>
     * {@primary <p>Handle the <code>Exception</code>.
     * Return the <code>ActionForward</code> instance (if any) returned by
     * the called <code>ExceptionHandler</code>.}
     *
     * @param ex 扱う例外
     * {@primary @param ex The exception to handle}
     * @param ae 例外に対応するExceptionConfig
     * {@primary @param ae The ExceptionConfig corresponding to the exception}
     * @param mapping 処理するActionMapping
     * {@primary @param mapping The ActionMapping we are processing}
     * @param formInstance 処理するActionForm
     * {@primary @param formInstance The ActionForm we are processing}
     * @param request 処理するサーブレットへのリクエスト
     * {@primary @param request The servlet request we are processing}
     * @param response 生成するサーブレットのレスポンス
     * {@primary @param response The servlet response we are creating}
     *
     * @exception ServletException サーブレットで例外が発生した場合
     * {@primary @exception ServletException if a servlet exception occurs}
     *
     * @since Struts 1.1
     */
    public ActionForward execute(
        Exception ex,
        ExceptionConfig ae,
        ActionMapping mapping,
        ActionForm formInstance,
        HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException {

        ActionForward forward = null;
        ActionMessage error = null;
        String property = null;

        // Build the forward from the exception mapping if it exists
        // or from the form input
        if (ae.getPath() != null) {
            forward = new ActionForward(ae.getPath());
        } else {
            forward = mapping.getInputForward();
        }

        // Figure out the error
        if (ex instanceof ModuleException) {
            error = ((ModuleException) ex).getActionMessage();
            property = ((ModuleException) ex).getProperty();
        } else {
            error = new ActionMessage(ae.getKey(), ex.getMessage());
            property = error.getKey();
        }

        this.logException(ex);

        // Store the exception
        request.setAttribute(Globals.EXCEPTION_KEY, ex);
        this.storeException(request, property, error, forward, ae.getScope());

        return forward;

    }


    /**
     * <p>commons-loggingを使用して<code>Exception</code>を記録します。</p>
     * {@primary <p>Logs the <code>Exception</code> using commons-logging.</p>}
     * @param e 記録する例外
     * {@primary @param e The Exception to log.}
     * @since Struts 1.2
     */
    protected void logException(Exception e){

        log.debug(messages.getMessage("exception.log"), e);

    }


    /**
     * <p><code>Action</code>を委譲している間、
     * <code>Exception</code>から発生した<code>ActionError</code>を取り扱うためのデフォルト実装です。
     * 用意されたスコープ(例外をマップするスコープ)により定義されたスコープとして、
     * デフォルト実装はリクエストまたはセッションの属性を設定します。
     * <code>ActionErrors</code>のインスタンスが生成され、
     * エラーがコレクションに追加されます。
     * そのコレクションは<code>Globals.ERROR_KEY</code>中のセットです。</p>
     * {@primary <p>Default implementation for handling an <code>ActionError</code> generated
     * from an <code>Exception</code> during <code>Action</code> delegation. The default
     * implementation is to set an attribute of the request or session, as
     * defined by the scope provided (the scope from the exception mapping). An
     * <code>ActionErrors</code> instance is created, the error is added to the collection
     * and the collection is set under the <code>Globals.ERROR_KEY</code>.</p>}
     *
     * @param request 扱うリクエスト
     * {@primary @param request The request we are handling}
     * @param property このエラーに使用するプロパティの名前
     * {@primary @param property The property name to use for this error}
     * @param error 例外マップから生成されたエラー
     * {@primary @param error The error generated from the exception mapping}
     * @param forward 入力パスから生成されたフォワード
     * (フォームまたは例外マップが入力パスとなります。)
     * {@primary @param forward The forward generated from the input path (from the form or exception mapping)}
     * @param scope 例外マップのスコープ
     * {@primary @param scope The scope of the exception mapping.}
     * @deprecated storeException(HttpServletRequest, String, ActionMessage, ActionForward, String)を代わりに使用してください。
     * このメソッドは Struts 1.2 より後で削除される予定です。
     * {@primary @deprecated Use storeException(HttpServletRequest, String, ActionMessage, ActionForward, String)
     * instead. This will be removed after Struts 1.2.}
     */
    protected void storeException(
        HttpServletRequest request,
        String property,
        ActionError error,
        ActionForward forward,
        String scope) {

        this.storeException(request, property, (ActionMessage) error, forward, scope);
        // :TODO: Remove after Struts 1.2

    }


    /**
     * <p><code>Action</code>を委譲している間、
     * <code>Exception</code>から発生した<code>ActionError</code>を取り扱うためのデフォルト実装です。
     * 用意されたスコープ(例外マップのスコープ)により定義されたスコープとして、
     * デフォルト実装はリクエストまたはセッションの属性を設定します。
     * <code>ActionErrors</code>のインスタンスが生成され、
     * エラーがコレクションに追加されます。
     * そのコレクションは<code>Globals.ERROR_KEY</code>中のセットです。</p>
     * {@primary <p>Default implementation for handling an <code>ActionMessage</code> generated
     * from an <code>Exception</code> during <code>Action</code> delegation. The default
     * implementation is to set an attribute of the request or session, as
     * defined by the scope provided (the scope from the exception mapping). An
     * <code>ActionMessages</code> instance is created, the error is added to the
     * collection and the collection is set under the <code>Globals.ERROR_KEY</code>.</p>}
     *
     * @param request 扱うリクエスト
     * {@primary @param request The request we are handling}
     * @param property このエラーに使用するプロパティの名前
     * {@primary @param property The property name to use for this error}
     * @param error 例外マップから生成されたエラー
     * {@primary @param error The error generated from the exception mapping}
     * @param forward 入力パスから生成されたフォワード
     * (フォームまたは例外マップが入力パスとなります。)
     * {@primary @param forward The forward generated from the input path (from the form or exception mapping)}
     * @param scope 例外マップのスコープ
     * {@primary @param scope The scope of the exception mapping.}
     * @since Struts 1.2
     */
    protected void storeException(
        HttpServletRequest request,
        String property,
        ActionMessage error,
        ActionForward forward,
        String scope) {

        ActionMessages errors = new ActionMessages();
        errors.add(property, error);

        if ("request".equals(scope)) {
            request.setAttribute(Globals.ERROR_KEY, errors);
        } else {
            request.getSession().setAttribute(Globals.ERROR_KEY, errors);
        }
    }

}

