package org.itscool.weber.action;

import java.util.HashMap;
import java.util.List;

import org.itscool.commons.bean.BeanFactory;
import org.itscool.commons.request.GeneralForm;
import org.itscool.weber.controller.Globals;
import org.itscool.weber.mapping.MessageMappings;
import org.itscool.weber.user.RoleException;
import org.itscool.weber.user.UserManager;
import org.itscool.weber.user.User;

/**
 * weberフレームワークで業務ロジックを実装するための基本クラスです<br>
 *
 * <p>
 * 開発者はActionクラスを継承したサブクラスを定義し、ビジネスメソッドを呼び出す
 * ためのdoExecuteメソッドをオーバーライドして実装する必要があります。<br>
 * doExecuteメソッドはフレームワークから適切なタイミングで呼び出されます。
 * </p>
 *
 * <br/><p><strong>1) weber-config.xml </strong></p>
 * <p>
 * アクションの定義はアクションマッピング定義ファイルに記述します。<br>
 * アクションマッピング定義ファイル（weber-config.xml）は、
 * weberアプリケーションの画面遷移やView?Model（つまり、「.jsp」ファイル
 *  とフォーム用JavaBeans、アクションクラス）を関連付ける
 * 一連の制御情報を記述するためのファイルです。<br>
 * </p>
 * <p>
 * weberフレームワークにはフロントサーブレットと呼ばれる、
 * すべての入出力制御を行なうための基本クラスが提供されていますが、
 * フロントサーブレットはこのweber-config.xmlを参照することで、
 * 処理の分岐を判断しています。<br>
 * </p>
 * <p>
 * このファイルにJSP(html)ファイルやJavaBean、アクションクラスを
 * 動かすために必要な設定情報を 記述していきます。<br>
 * </p>
 *
 * <br/><p><strong>(1) weber-config.xmlの作成例 </strong></p>
 * <p>
 * <p>weber-config.xmlの記述例を以下に記します。</p>
 * <br/>
 * <div id="area">
 * <pre>
 * &lt;?xml version="1.0" encoding="Shift_JIS" ?&gt;
 *
 * &lt;weber-config&gt;
 * &lt;global-exceptions&gt;
 *     &lt;exception name="java.lang.Exception" path="/jsp/exception.jsp"/&gt;
 *     &lt;exception name="java.io.IOException" path="/jsp/ioexception.jsp"/&gt;
 *     &lt;exception name="java.lang.NumberFormatException" path="/jsp/numberException.jsp"/&gt;
 * &lt;/global-exceptions&gt;
 *
 * &lt;action-mappings&gt;
 * &lt;action
 *     path="/tutorial2/input.do"
 *     type="tutorial2.InputAction"
 *     name="tutorial2.AskData"&gt;
 *     &lt;role name="admin"/&gt;
 *     &lt;role name="guest"/&gt;
 *
 *     &lt;!-- リクエストパラメータの入力チェック --&gt;
 *     &lt;param name="name"&gt;
 *         &lt;!-- 必須チェック --&gt;
 *           &lt;validate type="requird" msgkey="E0001" /&gt;
 *     &lt;/param&gt;
 *     &lt;param name="id"&gt;
 *         &lt;!-- 必須チェック --&gt;
 *           &lt;validate type="requird" msgkey="E0002" /&gt;
 *           &lt;!-- 半角数値チェック --&gt;
 *           &lt;validate type="digit" msgkey="E0003" /&gt;
 *     &lt;/param&gt;
 *     &lt;param name="score"&gt;
 *         &lt;!-- 必須チェック --&gt;
 *           &lt;validate type="requird" msgkey="E0004" /&gt;
 *           &lt;!-- 半角英数チェック --&gt;
 *           &lt;validate type="eisu" msgkey="E0005" /&gt;
 *           &lt;!-- 数値範囲チェック --&gt;
 *           &lt;validate type="digit_length" msgkey="E0006" min="0" max="100" /&gt;
 *     &lt;/param&gt;
 *
 *     &lt;forward name="org.itscool.weber.action.INPUT_ERROR" path="/html/tutorial2/input.html"/&gt;
 *     &lt;forward name="org.itscool.weber.action.ROLE_FAIL" path="/html/tutorial2/usercheck_error.html"/&gt;
 *     &lt;forward name="success" path="/html/tutorial2/confirm.html"/&gt;
 * &lt;/action&gt;
 * &lt;/action-mappings&gt;
 * &lt;/weber-config&gt;
 * </pre>
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(2) action要素 </strong></p>
 * <p>
 * action要素には、リクエストに対応するJavaBeanとアクションクラスの定義を行います。<br/>
 * 更にaction要素の子要素に、アクションの実行権限の付与や、入力チェック、アクション実行後の
 * JSPの遷移先等を定義することができます。<br/>
 * action要素は複数記述することができます。<br/>
 * </p>
 *
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>action要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>path</td>
 *       <td>このアクションを呼び出すためのリクエストURIを指定します(必須)</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>type</td>
 *       <td>
 *           このアクションに紐付くアクションクラスを指定します(必須)<br>
 *           weberフレームワークは、以下のアクションを標準で提供しています<br>
 *           <li>org.itscool.weber.action.NoOpAction･･･(実行結果をsuccessで返すだけのAction)
 *           <li>org.itscool.weber.action.LoginAction･･･ログインアクション（別途ユーザ管理の設定が必要です)
 *           <li>org.itscool.weber.action.LogoutAction･･･ログアウトアクション（別途ユーザ管理の設定が必要です)
 *
 *       </td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>クライアントから渡されてきたリクエストパラメータを保持する為のクラスを指定します</td></tr>
 *     </tr>
 * </table>
 *
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(3) forward要素 </strong></p>
 * <p>
 * forward要素には、アクションの実行結果から次にどの画面（JSP/HTML)に遷移すべきかを指定します。<br/>
 * forward要素は複数記述することができます。<br/>
 * </p>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>forward要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>このアクションで得られる実行結果の名前を指定します(必須)</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>path</td>
 *       <td>
 *           遷移先のパスを指定します(必須)
 *           weberフレームワークは、以下の遷移先を標準で提供しています<br>
 *           <li>org.itscool.weber.action.INPUT_ERROR･･･入力チェックでエラーになった場合</li>
 *           <li>org.itscool.weber.action.ROLE_SUCCESS･･･ログインアクションに成功した場合</li>
 *           <li>org.itscool.weber.action.ROLE_FAIL･･･ログアウトアクションに失敗した場合
 *           /ユーザ権限チェックでエラーになった場合</li>
 *
 *       </td>
 *     </tr>
 * </table>
 * </p>
 *
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(4) role要素 </strong></p>
 * <p>
 * role要素には、そのアクションで許可するユーザ権限を指定します（この機能を利用するためには
 * あらかじめユーザ管理の設定が必要です)。<br/>
 * role要素は複数記述することができます。<br/>
 * role要素が指定されていない場合、このアクションは全てのユーザから呼び出すことができます<br/>
 * </p>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>role要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>このアクションを許可する権限名を指定します(必須)</td>
 *     </tr>
 * </table>
 * </p>
 * <br/>
 * <div id="area">
 * role要素を指定するとweberフレームワーク内でこのユーザがアクションを実行する権限を持っている
 * かどうか判定します。<br>
 * アクションの実行権限を持っていない場合、フレームワークから"org.itscool.weber.action.ROLE_FAIL"が
 * 返されます。<br>
 * </div>
 *
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(5) param要素 </strong><img src="./img/newb.gif"></p>
 * <p>
 * param要素は、リクエストパラメータのチェック方法を指定します。<br>
 * </p>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>param要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>入力チェックの対象になるリクエストパラメータの名前を指定します(必須)</td>
 *     </tr>
 * </table>
 * </p>
 * <p>
 * param要素配下には更にvalidate要素の指定が必要です。
 * </p>
 * <br/>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 * <tr bgColor=aquamarine>
 *     <td>属性</td><td>必須</td><td>説明</td>
 * </tr>
 * <tr>
 *     <td>type</td><td>必須</td>
 *     <td>
 *         チェックする内容を選択します<br>
 *         type属性に指定可能なキーは以下の通りです<BR>
 *         <li>requird 必須入力チェック
 *         <li>zenkaku    全角チェック
 *         <li>hankaku    半角チェック
 *         <li>digit    半角数値チェック
 *         <li>eisu    半角英数チェック(半角スペース許可)
 *         <li>eiji    半角英字チェック(半角スペース許可)
 *         <li>hankaku_kana    半角カナチェック
 *         <li>str_length    文字列の桁数チェック（以下のmin、max属性必須）
 *         <li>digit_length 数値の範囲チェック（以下のmin、max属性必須）
 *
 *     </td>
 * </tr>
 * <tr>
 *     <td>msgkey</td><td>msgbodyを指定しない場合は必須</td>
 *     <td>入力チェックでエラーになったときに出力するメッセージを<a href="define3.html">message-config.xml</a>
 *     に登録されているメッセージIDで指定します</td>
 * </tr>
 * <tr>
 *     <td>msgbody</td><td>msgkeyを指定しない場合は必須</td>
 *     <td>入力チェックでエラーになった時に出力するメッセージを指定します</td>
 * </tr>
 * <tr>
 *     <td>min</td><td>type属性にstr_lengthもしくはdigit_lengthを指定したとき必須</td>
 *     <td>文字列の最小桁数あるいは数値の最小値を指定します</td>
 * </tr>
 * <tr>
 *     <td>max</td><td>type属性にstr_lengthもしくはdigit_lengthを指定したとき必須</td>
 *     <td>文字列の最大桁数あるいは数値の最大値を指定します</td>
 * </tr>
 * </table>
 * </p>
 * <br/>
 * <div id="area">
 * 入力チェックに失敗した場合、、フレームワークから"org.itscool.weber.action.INPUT_ERROR"が
 * 返されます。<br>
 * </div>
 *
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(6) exception要素 </strong></p>
 * <p>
 * Webアプリケーション実行中に例外が発生したときの遷移先（JSP/HTML)を指定します<br/>
 * </p>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>forward要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>例外クラスを指定します</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>path</td>
 *       <td>
 *           nameで指定された例外が発生したときの遷移先を指定します
 *       </td>
 *     </tr>
 * </table>
 * </p>
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(2) action要素 </strong></p>
 * <p>
 * action要素には、リクエストに対応するJavaBeanとアクションクラスの定義を行います。<br/ * >
 * 更にaction要素の子要素に、アクションの実行権限の付与や、入力チェック、アクション実 * 行後の
 * JSPの遷移先等を定義することができます。<br/>
 * action要素は複数記述することができます。<br/>
 * </p>
 *
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>action要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>path</td>
 *       <td>このアクションを呼び出すためのリクエストURIを指定します(必須)</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>type</td>
 *       <td>
 *           このアクションに紐付くアクションクラスを指定します(必須)<br>
 *           weberフレームワークは、以下のアクションを標準で提供しています<br>
 *           <li>org.itscool.weber.action.NoOpAction･･･(実行結果をsuccessで返すだけのAction)
 *           <li>org.itscool.weber.action.LoginAction･･･ログインアクション（別途ユーザ管理の設定が必要です)
 *           <li>org.itscool.weber.action.LogoutAction･･･ログアウトアクション（別途ユーザ管理の設定が必要です)
 *
 *       </td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>クライアントから渡されてきたリクエストパラメータを保持する為のクラスを指定します</td></tr>
 *     </tr>
 * </table>
 *
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(3) forward要素 </strong></p>
 * <p>
 * forward要素には、アクションの実行結果から次にどの画面（JSP/HTML)に遷移すべきかを指定します。<br/>
 * forward要素は複数記述することができます。<br/>
 * </p>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>forward要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>このアクションで得られる実行結果の名前を指定します(必須)</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>path</td>
 *       <td>
 *           遷移先のパスを指定します(必須)
 *           weberフレームワークは、以下の遷移先を標準で提供しています<br>
 *           <li>org.itscool.weber.action.INPUT_ERROR･･･入力チェックでエラーになった場合</li>
 *           <li>org.itscool.weber.action.ROLE_SUCCESS･･･ログインアクションに成功した場合</li>
 *           <li>org.itscool.weber.action.ROLE_FAIL･･･ログアウトアクションに失敗した場合
 *           /ユーザ権限チェックでエラーになった場合</li>
 *
 *       </td>
 *     </tr>
 * </table>
 * </p>
 *
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(4) role要素 </strong></p>
 * <p>
 * role要素には、そのアクションで許可するユーザ権限を指定します（この機能を利用するために * は
 * あらかじめユーザ管理の設定が必要です)。<b * r/>
 * role要素は複数記述することができます。<b * r/>
 * role要素が指定されていない場合、この * アクションは全てのユーザから呼び出すことができます<br/>
 * </p>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>role要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>このアクションを許可する権限名を指定します(必須)</td>
 *     </tr>
 * </table>
 * </p>
 * <br/>
 * <div id="area">
 * role要素を指定するとweberフレームワーク内でこのユーザがアクションを実行する権限を持っている
 * かどうか判定します。<br>
 * アクションの実行権限を持っていない場合、フレームワークから"org.itscool.weber.action.ROLE_FAIL"が
 * 返されます。<br>
 * </div>
 *
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(5) param要素 </strong><img src="./img/newb.gif"></p>
 * <p>
 * param要素は、リクエストパラメータのチェック方法を指定します。<br>
 * </p>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>param要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>入力チェックの対象になるリクエストパラメータの名前を指定します(必須)</td>
 *     </tr>
 * </table>
 * </p>
 * <p>
 * param要素配下には更にvalidate要素の指定が必要です。
 * </p>
 * <br/>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 * <tr bgColor=aquamarine>
 *     <td>属性</td><td>必須</td><td>説明</td>
 * </tr>
 * <tr>
 *     <td>type</td><td>必須</td>
 *     <td>
 *         チェックする内容を選択します<br>
 *         type属性に指定可能なキーは以下の通りです<BR>
 *         <li>requird 必須入力チェック
 *         <li>zenkaku    全角チェック
 *         <li>hankaku    半角チェック
 *         <li>digit    半角数値チェック
 *         <li>eisu    半角英数チェック(半角スペース許可)
 *         <li>eiji    半角英字チェック(半角スペース許可)
 *         <li>hankaku_kana    半角カナチェック
 *         <li>str_length    文字列の桁数チェック（以下のmin、max属性必須）
 *         <li>digit_length 数値の範囲チェック（以下のmin、max属性必須）
 *
 *     </td>
 * </tr>
 * <tr>
 *     <td>msgkey</td><td>msgbodyを指定しない場合は必須</td>
 *     <td>入力チェックでエラーになったときに出力するメッセージを<a href="define3.html">message-config.xml</a>
 *     に登録されているメッセージIDで指定します</td>
 * </tr>
 * <tr>
 *     <td>msgbody</td><td>msgkeyを指定しない場合は必須</td>
 *     <td>入力チェックでエラーになった時に出力するメッセージを指定します</td>
 * </tr>
 * <tr>
 *     <td>min</td><td>type属性にstr_lengthもしくはdigit_lengthを指定したとき必須</td>
 *     <td>文字列の最小桁数あるいは数値の最小値を指定します</td>
 * </tr>
 * <tr>
 *     <td>max</td><td>type属性にstr_lengthもしくはdigit_lengthを指定したとき必須</td>
 *     <td>文字列の最大桁数あるいは数値の最大値を指定します</td>
 * </tr>
 * </table>
 * </p>
 * <br/>
 * <div id="area">
 * 入力チェックに失敗した場合、、フレームワークから"org.itscool.weber.action.INPUT_ERROR"が
 * 返されます。<br>
 * </div>
 *
 * <!-- ---------------------------------------------------------------------------------- -->
 * <br/><p><strong>(6) exception要素 </strong></p>
 * <p>
 * Webアプリケーション実行中に例外が発生したときの遷移先（JSP/HTML)を指定します<br/>
 * </p>
 * <p>
 * <table cellSpacing=0 cellpadding=0 border=1>
 *     <tbody>
 *     <tr bgColor=aquamarine>
 *       <td>forward要素の属性</td>
 *       <td>設定内容</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>name</td>
 *       <td>例外クラスを指定します</td>
 *     </tr>
 *     <tbody>
 *     <tr>
 *       <td>path</td>
 *       <td>
 *           nameで指定された例外が発生したときの遷移先を指定します
 *       </td>
 *     </tr>
 * </table>
 * </p>
 *
 * @author KANO
 * @since jdk1.4.1
 * @version 1.00A 2004/11/1
 */
public abstract class Action{
    /**
     * フォワードインスタンス
     */
    private HashMap lnkForwards;
    /**
     * ActionBucketインスタンス
     */
    private ActionBucket bucket;
    /**
     * 入力チェックリスト
     */
    private List validates;
    
    /**
     * リクエストパラメータを保持する擬似HTTPServleteRequestクラス
     */
    private GeneralForm generalForm = null;
    /**
     * エラーリスト<BR>
     * 入力検証によって発生したエラー項目を保持するリスト
     */
    private HashMap errList = new HashMap();
    
    /**
     * 論理フォワード名からJSPの遷移先となるパスを取得します
     * @param name 論理フォワード名
     * @return 論理フォワード名からJSPの遷移先となるパス
     */
    public String getForward( String name ){
        return (String)lnkForwards.get(name);
    }
    
    /**
     * フォワード情報のリストをセットします
     * @param forwards フォワード情報のリスト
     */
    public void setForwards( HashMap forwards ){
        this.lnkForwards = forwards;
    }
    
    /**
     * @param generalForm GeneralForm を設定。
     */
    public void setGeneralForm(GeneralForm generalForm) {
        this.generalForm = generalForm;
    }
    
    /**
     * FrontServletインスタンスから呼ばれる最初のアクションです
     * @param bucket ActionBucketインスタンス
     * @param generalForm フォームインスタンス
     * @throws Exception
     */
    public void init(ActionBucket bucket, GeneralForm generalForm){
        this.bucket = bucket;
        this.setGeneralForm(generalForm);
    }
    
    /**
     * リクエストフォームをセットします
     * @param bean フォームオブジェクト
     */
    public void setForm(Object bean){
        bucket.setForm(bean);
    }
    
    /**
     * FrontServletインスタンスから呼ばれる最初のアクションです
     * @return フォワード先の論理名を返します
     * @throws Exception
     */
    public String execute() throws Exception{
        //=========================
        //ビジネスロジックを実行
        //=========================
        return doExecute(bucket);
    }
    
    /**
     * アクション実行前の処理を行います
     * @return 実行結果（正常処理時は"success"を返します)
     * @throws Exception
     */
    public String beforeExecute() throws Exception{
        String ret = Globals.RET_SUCCESS;
        
        //=========================
        //アクセス権限をチェックします
        //=========================
        beforeCheckRole();
        if(!checkRole(bucket)){
            ret= doAuthFailure(bucket);
            return ret;
        }
        
        //========
        //入力検証
        //========
        ret = validate(bucket);
        if(!ret.equals(Globals.RET_SUCCESS)){
            //リクエストパラメータをセットしなおす
            bucket.setRetryInputParam(generalForm);
            return ret;
        }
        
        return ret;
    }
    
    public void putRole(String roleName){
        bucket.putRole(roleName);
    }
    
    public void beforeCheckRole(){}
    
    /**
     * weberフレームワーク独自のアクセスユーザの権限をチェックします。<br>
     * 認証エラーの場合は、doAuthFailureメソッドが呼ばれます<br>
     * 独自の認証処理を行う場合は、サブクラスでこのメソッドをオーバーライド
     * して利用する事もできます。
     * @param bucket
     * @return このアクションが許可されている場合はtrueを返します
     */
    public boolean checkRole(ActionBucket bucket){
        boolean  ret = true;
        
        if(bucket.getRoles() == null || bucket.getRoles().size() == 0){
            return true;
        }else{
            //ログインチェック
            User user = (User)bucket.getAttributeFromSession(Globals.REQ_PARAM_USER);
            if(user == null){
//modify 2007/01/28 kano 認証エラー時はGlobalExceptioにより例外扱いとする weber4.x start
                throw new RoleException();
//                ret = false;
//modify 2007/01/28 kano weber4.x end
            }else{
                ret = isUserCheck(bucket.getRoles(), user);
            }
            
        }
        return ret;
    }
    
    /**
     * 入力検証を開始します<BR>
     * このメソッドはFrontServletから呼ばれます。<BR>
     * FontServletからこのメソッドが呼ばれると、エラー検証処理のための
     * 事前処理が行われ、その後doValidateメソッドを呼び出します<BR>
     * doValidateメソッドでは、サブクラス側で入力検証を行うためのロジック
     * を実装するために使用します。
     * @param bucket リクエストパラメータ保持クラス
     * @return 入力検証が正常に行われた場合はGlobals.RET_SUCCESSを返します<BR>
     * 入力検証エラーの場合はdoInputFailure()が返す値を呼び出し元に返します。
     * <BR>入力検証に失敗した場合は、エラーメッセージのリストをHashMapで返します
     */
    public String validate(ActionBucket bucket) throws Exception{
        //バリデーション機能による入力チェック処理
        Validation validation = Validation.getInstance();
        errList = validation.isValidate(validates, generalForm);
        if(isInputError()){
            bucket.setAttribute(Globals.REQ_PARAM_FORM_ERR, errList);
            return doInputFailure(bucket);
        }
        
        //ユーザ固有の入力チェック処理
        String ret =doValidate(bucket);
        if(isInputError() || !ret.equals(Globals.RET_SUCCESS)){
            if( !isInputError() ){
                return ret;
            }
            bucket.setAttribute(Globals.REQ_PARAM_FORM_ERR, errList);
            if( ret != null && ret.length() > 0 ){
                return ret;
            }else{
                return doInputFailure(bucket);
            }
        }else{
            return Globals.RET_SUCCESS;
        }
    }
    
    /**
     * Actionクラスのececute()メソッドをラップするメソッドです。<br>
     * サブクラス側で定義してください。<br>
     * doExecuteメソッドには引数としてBeanインスタンス、HttpServletRequest,
     * HttpServletResponseをラップしたActionBucketインスタンスが渡されます<br>
     * ので開発者はビジネスロジックのためにクライアントから送信されたリクエスト
     * データやリクエストスコープ、セッションスコープに格納されている情報を
     * 自由に処理する事ができ、またビジネスロジックの処理結果をリクエストスコープ
     * やセッションスコープに格納する処理を記述できます。<br>
     * @param bucket
     * @return Actionの実行結果をフォワード名で返します
     */
    public abstract String doExecute(ActionBucket bucket) throws Exception;
    
    /**
     * フォームの入力検証を行います。<br>
     * 必要に応じてActionクラスのサブクラスで定義してください
     */
//modify 2007/02/01 kano start
    //protected void doValidate() throws Exception{}
    protected String doValidate() throws Exception
    {
        return Globals.RET_SUCCESS;
    }
//modify 2007/02/01 kano end
    
    /**
     * 入力検証を行うメソッドです<BR>
     * このメソッドをサブクラスで定義し、各アクションごとの入力検証
     * ロジックを実装してください。
     */
    protected String doValidate(ActionBucket bucket) throws Exception{
        return this.doValidate();
    }
    
    /**
     * 権限のないユーザがアクションを要求したときに呼ばれます。<BR>
     * 独自の認証処理を実装する場合は、このメソッドをオーバーライド
     * して利用する事もできます。<br>
     * @param bucket ActionBucketインスタンス
     * @return　デフォルトではGlobals.ROLE_FAILを返します
     */
    protected String doAuthFailure(ActionBucket bucket){
        return Globals.RET_ROLE_FAIL;
    }
    
    /**
     * フォームの入力検証でエラーが発生したときに呼ばれます。<BR>
     * 独自の検証エラーを実装する場合は、このメソッドをオーバーライド
     * して利用する事もできます。<br>
     * @param bucket ActionBucketインスタンス
     * @return　デフォルトではGlobals.REQ_PARAM_FORM_ERRを返します
     */
    protected String doInputFailure(ActionBucket bucket){
        return Globals.REQ_PARAM_FORM_ERR;
    }
    
    /**
     * このアクションが許可されているか検査します<br>
     * このメソッドはcheckUserRoleメソッドから呼ばれます。<br>
     * 独自の認証処理を実装する場合は、このメソッドをオーバーライド
     * して利用する事もできます。
     * @param roles 権限情報
     * @param user ユーザ
     * @return このアクションが許可されている場合はtrueを
     * 返します
     */
    public boolean isUserCheck(HashMap roles, User user){
        boolean ret = false;
        BeanFactory factory = BeanFactory.getInstance();
        UserManager manager = (UserManager)factory.createInstance("UserManager");
        ret = manager.isUserCheck(roles, user);
//modify 2007/01/28 kano 認証エラー時はGlobalExceptioにより例外扱いとする weber4.x start
        if(!ret){
            throw new RoleException();
        }
//modify 2007/01/28 kano weber4.x end

        return ret;
        
    }
    /**
     * エラーコードを追加します
     * @param key エラーを特定するためのユニークキー
     * @param msg エラーメッセージ
     */
    protected void putMessage( Object key, Object msg){
        errList.put(key, msg);
    }
    
    /**
     * エラーコードを追加します<BR>
     * エラーキー(key)で指定されたメッセージをMessageResourcesインスタンス
     * から取得し、取得したエラーメッセージとエラーキーをエラーリストに追加します
     * @param key エラーを特定するためのユニークキー
     */
    protected void putMessage( Object key ){
        MessageMappings messages = MessageMappings.getInstance();
        String message = (String)messages.get(key);
        putMessage(key, message);
    }
    
    /**
     * エラー判定結果を返します
     * @return フォーム入力エラーが発生した場合はtrueを返します
     */
    public boolean isInputError(){
        boolean ret = false;
        
        if( errList.size() > 0 ){
            ret = true;
        }
        
        return ret;
    }
    
    
    /**
     * パラメータがint型であるか検証します
     * @param paramName パラメータ名を指定します
     * @return 検証が正しい場合はtrueを返します
     */
    protected boolean isInt(String paramName){
        boolean ret = true;
        
        try{
            String paramValue = (String)getParameter(paramName);
            Integer.parseInt(paramValue);
        }catch(Exception e ){
            ret = false;
        }
        return ret;
    }
    
    /**
     * パラメータがlong型であるか検証します
     * @param paramName パラメータ名を指定します
     * @return 検証が正しい場合はtrueを返します
     */
    protected boolean isLong(String paramName){
        boolean ret = true;
        
        try{
            String paramValue = (String)getParameter(paramName);
            Long.parseLong(paramValue);
        }catch(Exception e ){
            ret = false;
        }
        return ret;
    }
    
    /**
     * パラメータがdouble型であるか検証します
     * @param paramName パラメータ名を指定します
     * @return 検証が正しい場合はtrueを返します
     */
    protected boolean isDouble(String paramName){
        boolean ret = true;
        
        try{
            String paramValue = (String)getParameter(paramName);
            Double.parseDouble(paramValue);
        }catch(Exception e ){
            ret = false;
        }
        return ret;
    }
    
    /**
     * パラメータがfloat型であるか検証します
     * @param paramName パラメータ名を指定します
     * @return 検証が正しい場合はtrueを返します
     */
    protected boolean isFloat(String paramName){
        boolean ret = true;
        
        try{
            String paramValue = (String)getParameter(paramName);
            Float.parseFloat(paramValue);
        }catch(Exception e ){
            ret = false;
        }
        return ret;
    }
    
    /**
     * パラメータがshort型であるか検証します
     * @param paramName パラメータ名を指定します
     * @return 検証が正しい場合はtrueを返します
     */
    protected boolean isShort(String paramName){
        boolean ret = true;
        
        try{
            String paramValue = (String)getParameter(paramName);
            Short.parseShort(paramValue);
        }catch(Exception e ){
            ret = false;
        }
        return ret;
    }
    
    /**
     * パラメータがnullでないことを検証します
     * @param paramName パラメータ名を指定します
     * @return 検証が正しい場合はtrueを返します
     */
    protected boolean isNotNull(String paramName){
        boolean ret = true;
        
        try{
            Object paramValue = getParameter(paramName);
            if( paramValue == null || paramValue.toString().length() == 0){
                ret = false;
            }
        }catch(Exception e ){
            ret = false;
        }
        
        return ret;
    }
    
    
    /**
     * パラメータを取得します
     * @param paramName パラメータ名
     * @return パラメータをString型で返します
     */
    protected Object getParameter(String paramName){
        String result = null;
        Object obj = generalForm.getParameter(paramName);
        return obj;
    }
    
    /**
     * 入力チェックリストを取得します
     * @return 入力チェックリスト
     */
    public List getValidates() {
        return validates;
    }
    
    /**
     * 入力チェックリストを設定します
     * @param validates 入力チェックリスト
     */
    public void setValidates(List validates) {
        this.validates = validates;
    }
}

