    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.hayabusa.taglib;
    017
    018import org.opengion.fukurou.security.HybsCryptography;
    019import org.opengion.fukurou.util.HybsDateUtil;
    020import static org.opengion.fukurou.util.StringUtil.nval;
    021
    022import java.io.IOException;
    023import java.io.ObjectInputStream;
    024import java.io.ObjectOutputStream;
    025import java.util.Calendar;
    026import java.util.Enumeration;
    027import java.util.LinkedHashSet;
    028import java.util.Locale;
    029import java.util.ArrayList;
    030import java.util.Set;
    031import java.text.NumberFormat;
    032
    033import javax.servlet.jsp.PageContext;
    034import javax.script.ScriptEngine;
    035import javax.script.ScriptEngineManager;
    036import javax.script.ScriptException;
    037
    038import org.opengion.hayabusa.common.HybsSystem;
    039import org.opengion.hayabusa.common.HybsSystemException;
    040import org.opengion.hayabusa.db.DBColumn;
    041import org.opengion.hayabusa.db.DBTableModel;
    042import org.opengion.hayabusa.db.Query;
    043import org.opengion.hayabusa.db.QueryFactory;
    044import org.opengion.fukurou.util.StringUtil;
    045import org.opengion.fukurou.db.Transaction;
    046import org.opengion.fukurou.db.TransactionReal;
    047
    048/**
    049 * JSP上からキー、値を設定することにより、リクエスト情報として、値を
    050 * 取出し可能にするタグです。
    051 *
    052 * 通常のリクエスト情報と同じ扱いができます(優先順位は、Valueタグが上位)。
    053 *
    054 * 設定した値は、{&#064;XXXX} 形式で 取り出すことができます。
    055 * また、command ="GET" で 直接画面に値を書き出すことも可能です。
    056 *
    057 * ※ このタグは、Transaction タグの対象です。
    058 *
    059 * @og.formSample
    060 * ●形式：&lt;og:value command="SET" key="ABC" value="123" /&gt;
    061 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    062 *
    063 * ●Tag定義：
    064 *   &lt;og:value
    065 *       command            【TAG】コマンド(SET,GET,REMOVE,SQL,SETTBL,GETTBL,KEYTBL,CLEAR,SETMEM)をセットします(初期値:SET)
    066 *       action             【TAG】アクション(UPPER,LOWER,MESSAGE,APPEND,ALL_APPEND,MAP,ALL_MAP,LIST,ALL_LIST,DAY_WEEK,
    067 *                                  MERGE,FIRST,ROW_APPEND,REPLACE,SUBSTR,SPLIT,MAX_MIN,ALL_MAX_MIN,EXEC,CASE,MD5)をセットします
    068 *       key                【TAG】リクエスト情報 に登録するキーをセットします
    069 *       value              【TAG】リクエスト情報 に登録する値をセットします
    070 *       defaultVal         【TAG】value値がNULLの場合に、この初期値を設定します
    071 *       nullSet            【廃止】value が NULL の時に、設定するかどうか[true/false]を指定します(初期値:true)
    072 *       separator          【TAG】各種アクションの文字列を連結/分解する項目区切り文字をセットします(初期値:",")
    073 *       useMultiRows       【TAG】マルチデータ(複数件検索)を使用するかどうか[true/false]を指定します(初期値:false)
    074 *       scope              【TAG】キャッシュする場合のスコープ(request,session)を指定します(初期値:request)
    075 *       tableId            【TAG】sessionから取得する DBTableModelオブジェクトの ID
    076 *       tblScope           【TAG】DBTableModel から取得する場合のスコープ(request,session)を指定します(初期値:session)
    077 *       dbid               【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します
    078 *       xssCheck           【TAG】リクエスト情報の HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_XSS_CHECK[=true])
    079 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
    080 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
    081 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true)
    082 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true)
    083 *       toVal              【TAG】部分文字列置換の 置換え後の部分文字列(to)を指定します
    084 *       fromVal            【TAG】部分文字列置換の 置換え前の部分文字列(from)を指定します
    085 *       cryptKey           【TAG】暗号化と複合化で利用する、暗号化キーを指定します。
    086 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    087 *   &gt;   ... Body ...
    088 *   &lt;/og:value&gt;
    089 *
    090 * ●使用例
    091 *     ・ &lt;og:value command="SET" key="ABC" value="123" /&gt;
    092 *     ・ &lt;og:value command="SQL"&gt;SELECT 1 TEST FROM DUAL&lt;/og:value&gt;
    093 *     ・ &lt;og:value command="SET" key="DEF" value="{&#064;NOCOMMAND}" defaultVal="0000" /&gt;
    094 *     ・ &lt;og:value command="GET" key="NOKEY" defaultVal="NODATA" /&gt;
    095 *     ・ &lt;og:value command="SET" key="{&#064;ABC}4" value="TEST1234" /&gt;
    096 *     ・ &lt;og:value command="GET" key="ABC" /&gt;
    097 *     ・ &lt;og:value command="SET" action="LOWER" key="LOWERTEST" value="ABCDEF" /&gt;
    098 *     ・ &lt;og:value command="GET" key="LOWERTEST" /&gt;
    099 *     ・ &lt;og:value command="GET" action="UPPER" key="LOWERTEST" /&gt;
    100 *     ・ &lt;og:value command="REMOVE" key="ABC" /&gt;
    101 *
    102 * &lt;style type="text/css"&gt;
    103 *   #valueJavaDoc th { text-align:center; vertical-align: middle; writing-mode: tb-rl; }
    104 *   #valueJavaDoc td { text-align:center; }
    105 * &lt;/style&gt;
    106 *
    107 * <table border="1" frame="box" rules="all" id="valueJavaDoc">
    108 *   <caption>command 一覧と使用可能 action の対応表</caption>
    109 *   <tr><th>command</th><th>UPPER</th><th>LOWER</th><th>MESSAGE</th><th>APPEND</th><th>ALL_APPEND</th><th>MAP</th><th>ALL_MAP</th><th>LIST</th><th>ALL_LIST</th>
    110 *       <th>DAY_WEEK  </th><th>MERGE</th><th>FIRST</th><th>ROW_APPEND</th><th>REPLACE</th><th>SUBSTR</th><th>SPLIT</th><th>MAX_MIN</th><th>ALL_MAX_MIN</th></tr>
    111 *   <tr><td>SET    </td><td>○</td><td>○</td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td>
    112 *       <td>○</td><td>○</td><td>×</td><td>×</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td></tr>
    113 *   <tr><td>GET    </td><td>○</td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td>
    114 *       <td>○</td><td>○</td><td>×</td><td>×</td><td>○</td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td></tr>
    115 *   <tr><td>REMOVE </td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td>
    116 *       <td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td></tr>
    117 *   <tr><td>CLEAR  </td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td>
    118 *       <td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td></tr>
    119 *   <tr><td>SQL    </td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>○</td><td>○</td><td>○</td><td>○</td>
    120 *       <td>×</td><td>×</td><td>×</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td></tr>
    121 *   <tr><td>SETTBL </td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td>
    122 *       <td>○</td><td>○</td><td>×</td><td>×</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td></tr>
    123 *   <tr><td>GETTBL </td><td>○</td><td>○</td><td>○</td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td>
    124 *       <td>○</td><td>○</td><td>×</td><td>×</td><td>○</td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td></tr>
    125 *   <tr><td>KEYTBL </td><td>○</td><td>○</td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td>
    126 *       <td>○</td><td>○</td><td>×</td><td>×</td><td>○</td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td></tr>
    127 *   <tr><td>SETMEM </td><td>○</td><td>○</td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td>
    128 *       <td>○</td><td>○</td><td>×</td><td>×</td><td>○</td><td>○</td><td>○</td><td>×</td><td>×</td><td>○</td><td>○</td></tr>
    129 *   <tr><td>SQLGET </td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td>
    130 *       <td>×</td><td>×</td><td>×</td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td></tr>
    131 * </table>
    132 *
    133 * @og.group その他部品
    134 *
    135 * @version  4.0
    136 * @author   M.Endou
    137 * @since    JDK5.0,
    138 */
    139public class ValueTag extends CommonTagSupport {
    140        //* このプログラムのVERSION文字列を設定します。   {@value} */
    141        private static final String VERSION = "5.7.7.2 (2014/06/20)" ;
    142
    143        private static final long serialVersionUID = 577220140620L ;
    144
    145        /** command 引数に渡す事の出来る コマンド  セット {@value} */
    146        public static final String CMD_SET              = "SET";
    147        /** command 引数に渡す事の出来る コマンド  ゲット {@value} */
    148        public static final String CMD_GET              = "GET";
    149        /** command 引数に渡す事の出来る コマンド  リムーブ {@value} */
    150        public static final String CMD_REMOVE   = "REMOVE";
    151        /** command 引数に渡す事の出来る コマンド  クリア {@value} */
    152        public static final String CMD_CLEAR    = "CLEAR";
    153        /** command 引数に渡す事の出来る コマンド  ＳＱＬ {@value} */
    154        public static final String CMD_SQL              = "SQL";
    155        /** command 引数に渡す事の出来る コマンド  セットテーブル {@value} */
    156        public static final String CMD_SETTBL   = "SETTBL";
    157        /** command 引数に渡す事の出来る コマンド  ゲットテーブル {@value} */
    158        public static final String CMD_GETTBL   = "GETTBL";
    159        /** command 引数に渡す事の出来る コマンド  キーテーブル {@value} */
    160        public static final String CMD_KEYTBL   = "KEYTBL";
    161        /** command 引数に渡す事の出来る コマンド  セットメモリ {@value} */
    162        public static final String CMD_SETMEM   = "SETMEM";                     // 3.7.1.0 (2005/04/15)
    163        /** command 引数に渡す事の出来る コマンド  ＳＱＬゲット {@value} */
    164        public static final String CMD_SQLGET   = "SQLGET";                     // 5.1.7.0 (2010/06/01) SQLGET対応
    165
    166        /** command 引数に渡す事の出来る コマンド リスト  */
    167        private static final String[] COMMAND_LIST = new String[] {
    168                        CMD_SET , CMD_GET , CMD_REMOVE , CMD_SQL , CMD_SETTBL , CMD_GETTBL ,
    169                        CMD_KEYTBL , CMD_CLEAR , CMD_SETMEM, CMD_SQLGET };
    170
    171        /** action 引数に渡す事の出来る アクション  アッパー(大文字化) {@value} */
    172        public static final String ACT_UPPER            = "UPPER" ;
    173        /** action 引数に渡す事の出来る アクション  ローワー(小文字化) {@value} */
    174        public static final String ACT_LOWER            = "LOWER" ;
    175        /** action 引数に渡す事の出来る アクション  メッセージ変換 {@value} */
    176        public static final String ACT_MESSAGE          = "MESSAGE" ;
    177        /** action 引数に渡す事の出来る アクション  データアペンド {@value} */
    178        public static final String ACT_APPEND           = "APPEND" ;
    179        /** action 引数に渡す事の出来る アクション  オールアペンド {@value} */
    180        public static final String ACT_ALL_APPEND       = "ALL_APPEND" ;                                // 3.6.1.0 (2005/01/05)
    181        /** action 引数に渡す事の出来る アクション  MAP {@value} */
    182        public static final String ACT_MAP                      = "MAP" ;                                               // 5.5.0.3 (2012/03/12)
    183        /** action 引数に渡す事の出来る アクション  ALL_MAP {@value} */
    184        public static final String ACT_ALL_MAP          = "ALL_MAP" ;                                   // 5.5.0.3 (2012/03/12)
    185        /** action 引数に渡す事の出来る アクション  LIST {@value} */
    186        public static final String ACT_LIST                     = "LIST" ;                                              // 4.3.7.5 (2009/07/13)
    187        /** action 引数に渡す事の出来る アクション  ALL_LIST {@value} */
    188        public static final String ACT_ALL_LIST         = "ALL_LIST" ;                                  // 4.3.7.5 (2009/07/13)
    189        /** action 引数に渡す事の出来る アクション  日付前方まるめ {@value} */
    190        public static final String ACT_DAY_WEEK         = "DAY_WEEK" ;                                  // 3.7.1.0 (2005/04/15)
    191        /** action 引数に渡す事の出来る アクション  マージ {@value} */
    192        public static final String ACT_MERGE            = "MERGE" ;                                             // 3.7.1.1 (2005/05/23)
    193        /** action 引数に渡す事の出来る アクション  ファースト {@value} */
    194        public static final String ACT_FIRST            = "FIRST" ;                                             // 3.8.0.4 (2005/08/08)
    195        /** action 引数に渡す事の出来る アクション  縦横回転 {@value} */
    196        public static final String ACT_ROW_APPEND       = "ROW_APPEND" ;                                // 3.8.9.2 (2007/07/28)
    197        /** action 引数に渡す事の出来る アクション  文字列置換 {@value} */
    198        public static final String ACT_REPLACE          = "REPLACE" ;                                   // 5.2.2.0 (2010/11/01)
    199        /** action 引数に渡す事の出来る アクション  部分文字列 {@value} */
    200        public static final String ACT_SUBSTR           = "SUBSTR" ;                                    // 5.2.2.0 (2010/11/01)
    201        /** action 引数に渡す事の出来る アクション  文字列分割 {@value} */
    202        public static final String ACT_SPLIT            = "SPLIT" ;                                             // 5.2.2.0 (2010/11/01)
    203        /** action 引数に渡す事の出来る アクション  最大_最小値 {@value} */
    204        public static final String ACT_MAX_MIN          = "MAX_MIN" ;                                   // 5.6.4.3 (2013/05/24)
    205        /** action 引数に渡す事の出来る アクション  ALL_最大_最小値 {@value} */
    206        public static final String ACT_ALL_MAX_MIN      = "ALL_MAX_MIN" ;                               // 5.6.4.3 (2013/05/24)
    207        /** action 引数に渡す事の出来る アクション  計算処理結果 {@value} */
    208        public static final String ACT_EXEC                     = "EXEC" ;                                              // 5.7.7.2 (2014/06/20)
    209        /** action 引数に渡す事の出来る アクション  条件分岐 {@value} */
    210        public static final String ACT_CASE                     = "CASE" ;                                              // 5.7.7.2 (2014/06/20)
    211        /** action 引数に渡す事の出来る アクション  MD5 {@value} */
    212        public static final String ACT_MD5              = "MD5" ;                                                       // 5.9.6.3 (2016/03/18)
    213        /** action 引数に渡す事の出来る アクション  ACT_CRYPT_ENC {@value} */
    214        public static final String ACT_CRYPT_ENC = "CRYPT_ENC";                                 // 5.10.4.0 (2018/10/05)
    215        /** action 引数に渡す事の出来る アクション  ACT_CRYPT_DEC {@value} */
    216        public static final String ACT_CRYPT_DEC = "CRYPT_DEC";                                 // 5.10.4.0 (2018/10/05)
    217
    218        /** action 引数に渡す事の出来る アクション リスト  */
    219        private static final String[] ACTION_LIST = new String[] {
    220                ACT_UPPER , ACT_LOWER , ACT_MESSAGE , ACT_APPEND , ACT_ALL_APPEND , ACT_MAP , ACT_ALL_MAP , ACT_LIST, ACT_ALL_LIST ,
    221                ACT_DAY_WEEK , ACT_MERGE , ACT_FIRST , ACT_ROW_APPEND , ACT_REPLACE , ACT_SUBSTR , ACT_SPLIT , ACT_MAX_MIN , ACT_ALL_MAX_MIN ,
    222                ACT_EXEC , ACT_CASE, ACT_MD5, ACT_CRYPT_ENC, ACT_CRYPT_DEC
    223        };
    224
    225        private String                  tableId         = HybsSystem.TBL_MDL_KEY;
    226        private String                  command         = CMD_SET;
    227        private String                  key                     = null;
    228        private String                  inValue         = null;         // 3.5.4.0 (2003/11/25)
    229        private String                  value           = null;
    230        private String                  defaultVal      = null;
    231        private String                  action          = null;
    232        private transient DBTableModel  table           = null;
    233        // 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
    234        private String                  dbid            = null;
    235        private String                  scope           = "request";    // "request","session"
    236        private String                  tblScope        = "session";    // 5.1.2.0 (2010/01/01) DBTableModel の取得先のscope
    237        private String                  separator       = ",";   // 項目区切り文字
    238        // 3.2.4.0 (2003/06/12) マルチデータ(複数件検索)を使用するかしないか。
    239        private boolean                 useMultiRows    = false;        // 初期値:使用せず
    240
    241        private boolean                 xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" ); // 5.1.7.0 (2010/06/01) XSS対策
    242
    243        private String  fromVal         = null;         // 5.2.2.0 (2010/11/01)
    244        private String  toVal           = null;         // 5.2.2.0 (2010/11/01)
    245
    246        private boolean tmpSelectedAll  = false;        // 5.6.4.3 (2013/05/24) action="ALL_xxx"を tmpSelectedAll="true" で内部処理します。
    247        private String cryptKey                 = null;         // 5.10.4.0 (2018/10/05) 暗号化キー
    248        /**
    249         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    250         *
    251         * @og.rev 3.1.7.0 (2003/05/02) isNullSet 属性が true(初期値)のときは、リクエスト情報から値を取得。
    252         * @og.rev 3.1.7.0 (2003/05/02) scope 属性を設定するタイミングを、早くする。
    253         * @og.rev 3.5.4.0 (2003/11/25) getRequestParameter( value ) メソッドを setValue に移動。
    254         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    255         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    256         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    257         *
    258         * @return      後続処理の指示
    259         */
    260        @Override
    261        public int doStartTag() {
    262                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    263                if( useTag() ) {
    264                        super.setScope( scope );                // デフォルトscope が "request" なので、再設定している。
    265
    266        //              if( isNullSet ) {
    267        //                      setUseValue( false );
    268        //              }
    269
    270                        // 5.1.7.0 (2010/06/01) SQLGET対応
    271                        if( CMD_SQL.equals( command ) || CMD_SET.equals( command ) || CMD_SQLGET.equals( command ) ) {
    272                                return EVAL_BODY_BUFFERED ;             // Body を評価する
    273                        }
    274                }
    275                return SKIP_BODY ;                              // Body を評価しない
    276        }
    277
    278        /**
    279         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
    280         *
    281         * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
    282         * @og.rev 3.6.0.8 (2004/11/19) エラー発生時に確実にリリースされるように try finally 追加
    283         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    284         * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
    285         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    286         * @og.rev 5.1.7.0 (2010/06/01) XSS解除対応
    287         * @og.rev 5.1.9.0 (2010/08/01) TransactionTag 対応。上位に TransactionTag があれば、そこからConnection をもらう。
    288         * @og.rev 5.2.1.0 (2010/10/01) command="SET" action="APPEND"でvalueをbody部に書いた場合に動作しないバグを修正
    289         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    290         * @og.rev 5.3.8.0 (2011/08/01) Transaction発生箇所でclose()
    291         *
    292         * @return      後続処理の指示(SKIP_BODY)
    293         */
    294        @Override
    295        public int doAfterBody() {
    296                if( value == null || value.length() <= 0 ) {
    297                        // 5.1.7.0 (2010/06/01) XSS対策
    298                        useXssCheck( xssCheck );
    299
    300                        value = getBodyString();
    301                        // 5.2.1.0 (2010/10/01)
    302                        inValue = getBodyRawString();
    303
    304                        // 5.1.7.0 (2010/06/01) SQLGET対応
    305                        if( CMD_SQL.equals( command ) || CMD_SQLGET.equals( command ) ) {
    306                                Query query = QueryFactory.newInstance();               // 4.0.0 (2005/01/31)
    307                                Transaction tran = null;
    308                                try {
    309                                        value = value.trim();
    310
    311                                        // 5.1.9.0 (2010/08/01) TransactionTag 対応
    312                                        TransactionTag tranTag = (TransactionTag)findAncestorWithClass( this,TransactionTag.class );
    313                                        if( tranTag == null ) {
    314                                                tran = new TransactionReal( getApplicationInfo() );             // 5.3.7.0 (2011/07/01) 引数変更
    315                                        }
    316                                        else {
    317                                                tran = tranTag.getTransaction();
    318                                        }
    319                                        query.setTransaction( dbid,tran );      // 5.1.9.0 (2010/08/01) TransactionTag 対応
    320
    321                                        query.setResourceManager( getResource() );      // 4.0.0 (2005/01/31)
    322
    323                                        query.setStatement( value );
    324                                        query.execute();
    325
    326                                        table = query.getDBTableModel();
    327                                }
    328                                finally {
    329                                        QueryFactory.close( query );
    330                                        if( tran != null ) {
    331                                                tran.close(); // 5.3.8.0 (2011/08/01) Transaction発生箇所でclose()
    332                                        }
    333                                }
    334                        }
    335                }
    336
    337                return SKIP_BODY ;
    338        }
    339
    340        /**
    341         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    342         *
    343         * @og.rev 3.1.0.1 (2003/03/26) DBTableModelの値をSET/GETできる command , action を追加。
    344         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    345         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    346         * @og.rev 3.1.5.0 (2003/04/22) DBTableModel が存在するときのみ実行するロジックになっていたバグ対応。
    347         * @og.rev 5.1.2.0 (2010/01/01) DBTableModel の取得先の tblScope を追加。
    348         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    349         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    350         *
    351         * @return      後続処理の指示
    352         */
    353        @Override
    354        public int doEndTag() {
    355                debugPrint();           // 4.0.0 (2005/02/28)
    356                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    357                if( useTag() ) {
    358                        if( check( command, COMMAND_LIST ) ) {
    359                                if( CMD_SETTBL.equals( command ) ||
    360                                        CMD_GETTBL.equals( command ) ||
    361                                        CMD_KEYTBL.equals( command ) ) {
    362        //                                      table = (DBTableModel)getSessionAttribute( tableId );
    363                                                // 5.1.2.0 (2010/01/01) DBTableModel の取得先の tblScope を追加。
    364                                                if( "session".equals( tblScope ) ) { table = (DBTableModel) getSessionAttribute( tableId ); }
    365                                                else if( "request".equals( tblScope ) ) { table = (DBTableModel) getRequestAttribute( tableId ); }
    366                                                else {
    367                                                        String errMsg = "このスコープはサポートされていません。[" + tblScope + "]";
    368                                                        throw new IllegalArgumentException( errMsg );
    369                                                }
    370                                }
    371                        }
    372
    373                        commandExec( command );
    374
    375                        // 5.1.7.0 (2010/06/01) SQLGET対応
    376                        if( CMD_GET.equals( command ) || CMD_GETTBL.equals( command ) || CMD_SQLGET.equals( command ) ) {
    377                                if( value != null ) { jspPrint( value ); }
    378                        }
    379                }
    380                return EVAL_PAGE ;
    381        }
    382
    383        /**
    384         * タグリブオブジェクトをリリースします。
    385         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    386         *
    387         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
    388         * @og.rev 3.1.0.1 (2003/03/26) DBTableModelの値をSET/GETできる command , action を追加。
    389         * @og.rev 3.1.0.1 (2003/03/26) query 属性を削除します。
    390         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    391         * @og.rev 3.2.4.0 (2003/06/12) マルチデータ(複数件検索)を使用するかしないか。
    392         * @og.rev 3.5.4.0 (2003/11/25) inValue 変数の追加
    393         * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
    394         * @og.rev 5.1.2.0 (2010/01/01) DBTableModel の取得先の tblScope を追加。
    395         * @og.rev 5.1.7.0 (2010/06/01) XSS解除対応
    396         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    397         * @og.rev 5.2.2.0 (2010/11/01) fromVal , toVal 属性 追加
    398         * @og.rev 5.6.4.3 (2013/05/24) parameter 属性は、未使用なので削除
    399         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    400         * @og.rev 5.10.4.0 (2018/10/03) CRYPT追加
    401         *
    402         */
    403        @Override
    404        protected void release2() {
    405                super.release2();
    406                tableId         = HybsSystem.TBL_MDL_KEY;
    407                command         = CMD_SET;
    408                key                     = null;
    409                value           = null;
    410                defaultVal      = null;
    411                action          = null;
    412                table           = null;
    413                dbid            = null;
    414                scope           = "request";    // "request","session"
    415                tblScope        = "session";    // 5.1.2.0 (2010/01/01) DBTableModel の取得先のscope
    416                separator       = ",";
    417                useMultiRows = false;
    418                tmpSelectedAll  = false;        // 5.6.4.3 (2013/05/24)
    419                inValue         = null;                 // 3.5.4.0 (2003/11/25)
    420                xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );        // 5.1.7.0 (2010/06/01) XSS解除対応
    421                fromVal         = null;                 // 5.2.2.0 (2010/11/01)
    422                toVal           = null;                 // 5.2.2.0 (2010/11/01)
    423                cryptKey        = null;                 // 5.10.4.0 (2018/10/05)
    424        }
    425
    426        /**
    427         * コマンドを実行します。
    428         *
    429         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    430         * フィールド定数値のいづれかを、指定できます。
    431         * コマンドを登録すると同時に,実行も行ないます。
    432         *
    433         * @og.rev 3.1.0.1 (2003/03/26) command に、SETTBL / GETTBL / KEYTBL / CLEAR を追加。
    434         * @og.rev 3.1.0.1 (2003/03/26) query 属性を削除します。
    435         * @og.rev 3.1.7.0 (2003/05/02) scope 属性を設定するタイミングを、早くする。
    436         * @og.rev 3.7.1.0 (2005/04/15) command に、SETMEM を追加。
    437         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    438         *
    439         * @param       command コマンド(public static final 宣言されている文字列)
    440         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ValueTag.CMD_GET">コマンド定数</a>
    441         */
    442        private void commandExec( final String command ) {
    443
    444                if( CMD_SQL.equals( command ) ) {
    445                        setSQLAttribute( table );
    446                }
    447                else if( CMD_SQLGET.equals( command ) ) {
    448                        value = getSQLAttribute( table );
    449                }
    450                else if( CMD_SET.equals( command ) ) {
    451                        value = nval( value, defaultVal );
    452                        setAttribute( key,value,action );
    453                }
    454                else if( CMD_GET.equals( command ) ) {
    455                        value = getAttribute( key,action );
    456                }
    457                else if( CMD_REMOVE.equals( command ) ) {
    458                        removeAttribute( key );
    459                }
    460                else if( CMD_CLEAR.equals( command ) ) {
    461                        clearAttribute( key );
    462                }
    463                else if( CMD_SETTBL.equals( command ) ) {
    464                        setTableAttribute( table,key,action );
    465                }
    466                else if( CMD_GETTBL.equals( command ) ) {
    467                        value = getTableAttribute( table,key,action );
    468                }
    469                else if( CMD_KEYTBL.equals( command ) ) {
    470                        setKeyTableAttribute( table,key,value,action );
    471                }
    472                else if( CMD_SETMEM.equals( command ) ) {               // 3.7.1.0 (2005/04/15)
    473                        value = nval( value, defaultVal );
    474                        setAttribute( key,value,action );
    475                        setRequestCacheData( key,(String)getObject( key ) );
    476                }
    477        }
    478
    479        /**
    480         * アクションを実行します。
    481         *
    482         * コマンドは action 属性で指定します。
    483         * action コマンド が、 null の場合は、なにも実行しません。
    484         *
    485         * @og.rev 3.0.1.3 (2003/03/11) MESSAGE action を追加
    486         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    487         * @og.rev 3.7.1.0 (2005/04/15) action に、DAY_WEEK を追加。
    488         * @og.rev 3.7.1.1 (2005/05/23) action に、MERGE を追加。
    489         * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage ⇒ getResource().getLabel )
    490         * @og.rev 5.2.2.0 (2010/11/01) ACT_MERGE 時には、カンマで分解、separator で合成を行います。
    491         * @og.rev 5.2.2.0 (2010/11/01) ACT_REPLACE 処理を新規追加します。
    492         * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。
    493         * @og.rev 5.6.6.1 (2013/07/12) value が null の場合は、無視します。
    494         * @og.rev 5.7.7.2 (2014/06/20) EXEC と CASE アクションを追加
    495         * @og.rev 5.9.6.3 (2016/02/18) MD5追加
    496         * @og.rev 5.10.4.0 (2018/10/05) CRYPT追加
    497         *
    498         * @param action        コマンド(public static final 宣言されている文字列)
    499         * @param value         旧の値
    500         *
    501         * @return      処理後の値
    502         */
    503        private String actionExec( final String action,final String value ) {
    504                String rtn = value;
    505
    506                // 5.6.6.1 (2013/07/12) value が null の場合は、無視します。
    507                if( action == null || value == null ) { return rtn; }
    508
    509                if( ACT_UPPER.equals( action ) ) {
    510                        // Localeを共通管理するようになった場合、String.toUpperCase( Locale locale )使用の事
    511                        rtn = value.toUpperCase(Locale.JAPAN);
    512                }
    513                else if( ACT_LOWER.equals( action ) ) {
    514                        // Localeを共通管理するようになった場合、String.toLowerCase( Locale locale )使用の事
    515                        rtn = value.toLowerCase(Locale.JAPAN);
    516                }
    517                else if( ACT_MESSAGE.equals( action ) ) {
    518                        // 引数をメッセージリソースのキーとして、メッセージ変換する。
    519                        rtn = getResource().getLabel( value );
    520                }
    521                else if( ACT_DAY_WEEK.equals( action ) ) {
    522                        // 日付型文字列(YYYYMMDD) の入力データを、開始日を月曜日にセットします。
    523                        // SUNDAY=1 , MONDAY=2 になります。月曜日との差だけ、前に戻します。
    524                        // 指定日が日曜日の場合は、次の日(月曜日)に進めます。
    525                        Calendar ymd = HybsSystem.getCalendar( value );
    526                        int shu = ymd.get( Calendar.DAY_OF_WEEK ) - Calendar.MONDAY ;
    527
    528                        if( shu != 0 ) { ymd.add( Calendar.DATE, -shu ); }
    529
    530                        rtn = HybsDateUtil.getDate( ymd.getTimeInMillis() , "yyyyMMdd" );               // 5.5.7.2 (2012/10/09) HybsDateUtil を利用
    531                }
    532                // 3.7.1.1 (2005/05/23)
    533                else if( ACT_MERGE.equals( action ) ) {
    534                        // 引数をカンマで文字列配列に分解します。
    535                        String[] str = StringUtil.csv2Array( value );
    536                        Set<String> set = new LinkedHashSet<String>();
    537                        for( int i=0; i<str.length; i++ ) {
    538                                if( str[i] != null && str[i].length() > 0 ) {
    539                                        set.add( str[i] );
    540                                }
    541                        }
    542
    543                        // 分解後、マージ(Setで)されます。 登録順は、キープします。
    544                        rtn = StringUtil.iterator2line( set.iterator(),separator );     // 5.2.2.0 (2010/11/01) separator 使用
    545                }
    546                // 5.2.2.0 (2010/11/01) ACT_REPLACE 処理を新規追加
    547                else if( ACT_REPLACE.equals( action ) ) {
    548                        // value.replaceAll( from, to ) という文法で処理します。
    549                        if( value != null && fromVal != null && toVal != null ) {
    550                                rtn = value.replaceAll( fromVal, toVal );
    551                        }
    552                }
    553                // 5.2.2.0 (2010/11/01) SUBSTR 処理を新規追加
    554                else if( ACT_SUBSTR.equals( action ) ) {
    555                        // value.substring( from, to ) という文法で処理します。
    556                        if( value != null) {
    557                                int from = (fromVal==null||fromVal.length()==0) ? 0              : Integer.parseInt( fromVal );
    558                                int to   = (  toVal==null||  toVal.length()==0) ? value.length() : Integer.parseInt( toVal );
    559
    560                                rtn = value.substring( from, to );
    561                        }
    562                }
    563                // 5.7.7.2 (2014/06/20) CASE 処理を新規追加
    564                else if( ACT_CASE.equals( action ) ) {
    565                        // fromVal="A:1 B:2 C:3 D:4" 形式
    566                        if( fromVal != null && fromVal.length()>0 ) {
    567                                String[] keys = StringUtil.csv2Array( fromVal , ' ' );
    568                                for( int i=0; i<keys.length; i++ ) {
    569                                        int idx = keys[i].indexOf( ':' );
    570                                        if( idx >= 0 ) {                                                             // 分解した値にコロン(:)がなければ、パス
    571                                                String key = keys[i].substring( 0,idx );        // 左辺(キー)
    572                                                if( value.equalsIgnoreCase( key ) ) {
    573                                                        rtn = keys[i].substring( idx+1 );               // 右辺(値)
    574                                                        break;
    575                                                }
    576                                        }
    577                                }
    578                        }
    579                }
    580                // 5.7.7.2 (2014/06/20) EXEC 処理を新規追加
    581                else if( ACT_EXEC.equals( action ) ) {
    582                        ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName( "JavaScript" );
    583                        try {
    584                                Object obj = jsEngine.eval( value );
    585                                rtn = String.valueOf( obj );
    586                        }
    587                        catch( ScriptException ex ) {
    588                                String errMsg = "JavaScript式のパースに失敗しました。[" + value + "]";
    589                                throw new HybsSystemException( errMsg , ex );
    590                        }
    591                }
    592                // 5.9.6.3 (2016/02/18)
    593                else if( ACT_MD5.equals(  action ) ){
    594                        rtn = HybsCryptography.getMD5( value );
    595                }
    596                // 5.10.4.0 (2018/10/05)
    597                else if( ACT_CRYPT_ENC.equals( action ) ) {
    598                        HybsCryptography hc = new HybsCryptography(cryptKey);
    599                        rtn = hc.encrypt( value );
    600                }else if( ACT_CRYPT_DEC.equals( action ) ) {
    601                        HybsCryptography hc = new HybsCryptography(cryptKey);
    602                        rtn = hc.decrypt( value );
    603                }
    604
    605                return rtn;
    606        }
    607
    608        /**
    609         * 指定のスコープの内部キャッシュ情報を、キーで登録します。
    610         *
    611         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    612         * @og.rev 3.5.4.0 (2003/11/25) APPENDアクションを有効にします。
    613         * @og.rev 3.5.6.5 (2004/08/09) APPEND時のセパレータを外部指定の変数を使用
    614         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    615         * @og.rev 5.2.2.0 (2010/11/01) ACT_SPLIT 追加
    616         * @og.rev 5.6.4.3 (2013/05/24) ACT_MAX_MIN アクションの追加
    617         * @og.rev 5.6.6.1 (2013/07/12) value が null の場合は、無視します。
    618         *
    619         * @param key           キー
    620         * @param value         値
    621         * @param action        アクション
    622         */
    623        private void setAttribute( final String key,final String value,final String action ) {
    624                if( key == null || key.length() == 0 ) {
    625                        String errMsg = "key がセットされていません。"
    626                                                + " command=" + command + " , action=" + action
    627                                                + " , value=" + value ;                 // 5.1.8.0 (2010/07/01) errMsg 修正
    628                        throw new HybsSystemException( errMsg );
    629                }
    630
    631                // 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    632                // 5.6.6.1 (2013/07/12) value が null の場合は、無視します。
    633                if( value != null ) {
    634                        if( ACT_APPEND.equals( action ) ) {
    635                                String[] array = getRequestParameterValues( inValue );
    636                                setObject( key, StringUtil.array2line( array,separator ) );
    637                        }
    638                        // 5.2.2.0 (2010/11/01) ACT_SPLIT 追加
    639                        else if( ACT_SPLIT.equals( action ) )  {
    640                                String[] array = value.split( separator );
    641                                setObject( key , array[0] );            // キー自体には、分割時の先頭の文字列を設定しておく。
    642                                for( int i=0; i<array.length; i++ ) {
    643                                        setObject( key + i , array[i] );
    644                                }
    645                        }
    646                        // 5.6.4.3 (2013/05/24) ACT_MAX_MIN アクションの追加
    647                        else if( ACT_MAX_MIN.equals( action ) )  {
    648                                String[] array = value.split( separator );
    649
    650                                // command="SET" では、数字型としてのみ処理します。
    651                                double minNum = Double.MAX_VALUE ;
    652                                double maxNum = Double.MIN_VALUE ;
    653                                double sumNum = 0d ;
    654                                int    cntSum = 0;              // 平均計算に有効な件数
    655
    656                                for( int i=0; i<array.length; i++ ) {
    657                                        String val = array[i].trim().replaceAll( ",","" );              // 数字型フォーマットのカンマを取り除く
    658                                        if( val.isEmpty() ) { continue; }               // ゼロ文字列の場合は、取り直し
    659
    660                                        double tmp = Double.parseDouble( val );
    661                                        if( minNum > tmp ) { minNum = tmp; }
    662                                        if( maxNum < tmp ) { maxNum = tmp; }
    663                                        sumNum += tmp ;  cntSum++ ;
    664                                }
    665
    666                                // command="SET" の場合は、数字型の場合のみ使用します。
    667                                if( cntSum > 0 ) {
    668                                        NumberFormat nf = NumberFormat.getInstance();
    669                                        nf.setGroupingUsed( false );                                    // カンマ編集なし
    670                                        nf.setMaximumFractionDigits(2);                                 // 最大小数部は２桁
    671                                        nf.setMinimumFractionDigits(0);                                 // できれば、整数表示
    672
    673                                        setObject( "MIN." + key,nf.format( minNum ) );          // Double.toString( minNum ) の代わり。
    674                                        setObject( "MAX." + key,nf.format( maxNum ) );
    675                                        setObject( "SUM." + key,nf.format( sumNum ) );
    676                                        setObject( "AVG." + key,nf.format( sumNum/cntSum ) );
    677                                }
    678                                else {
    679                                        setObject( "MIN." + key,nval( defaultVal , "" ) );
    680                                        setObject( "MAX." + key,nval( defaultVal , "" ) );
    681                                        setObject( "SUM." + key,nval( defaultVal , "" ) );
    682                                        setObject( "AVG." + key,nval( defaultVal , "" ) );
    683                                }
    684                        }
    685                        else {
    686                                setObject( key, actionExec( action,value ) );
    687                        }
    688                }
    689                else {
    690                        setObject( key, null );                 // 5.6.6.1 (2013/07/12) value が null の場合
    691                }
    692        }
    693
    694        /**
    695         * 指定のスコープの内部キャッシュ情報を、キーで取得します。
    696         *
    697         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    698         *
    699         * @param key           キー
    700         * @param action        アクション
    701         *
    702         * @return      キーに対する内部キャッシュ情報
    703         */
    704        private String getAttribute( final String key,final String action ) {
    705                if( key == null || key.length() == 0 ) {
    706                        String errMsg = "key がセットされていません。"
    707                                                + " command=" + command + " , action=" + action;        // 5.1.8.0 (2010/07/01) errMsg 修正
    708                        throw new HybsSystemException( errMsg );
    709                }
    710
    711                String rtn = defaultVal;
    712                Object obj = pageContext.findAttribute( key );
    713                if( obj != null ) { rtn = obj.toString(); }
    714
    715                return actionExec( action,rtn );
    716        }
    717
    718        /**
    719         * 指定のスコープの内部キャッシュ情報を削除します。
    720         *
    721         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    722         *
    723         * @param key           キー
    724         */
    725        private void removeAttribute( final String key ) {
    726                if( key == null || key.length() == 0 ) {
    727                        String errMsg = "key がセットされていません。"
    728                                                + " command=" + command ;                       // 5.1.8.0 (2010/07/01) errMsg 修正
    729                        throw new HybsSystemException( errMsg );
    730                }
    731                removeObject( key );
    732        }
    733
    734        /**
    735         * セッション/アプリケーションスコープのキャッシュ情報をクリアします。
    736         *
    737         * このクリアは、キーの前方一致で、大文字小文字の区別をせずにクリアします。
    738         * また、キーが null の場合は、"X_" で始めるもの以外のすべての値をクリアします。
    739         * また、Ｗｅｂエンジン内部で使用しているキーは、ここではクリアできません。
    740         *
    741         * @og.rev 3.1.0.1 (2003/03/26) クリアコマンドの追加。
    742         * @og.rev 4.3.4.0 (2008/12/01) PageContextのスコープをクラス変数としてアクセス
    743         *
    744         * @param key           キー
    745         */
    746        private void clearAttribute( final String key ) {
    747
    748                String lowKey = null;
    749                if( key != null ) { lowKey = key.toLowerCase(Locale.JAPAN); }
    750
    751                Enumeration<String> ekeys = pageContext.getAttributeNamesInScope( PageContext.APPLICATION_SCOPE );                // 4.3.3.6 (2008/11/15) Generics警告対応
    752                while ( ekeys.hasMoreElements() ) {
    753                        String ekey = ekeys.nextElement().toLowerCase(Locale.JAPAN);            // 4.3.3.6 (2008/11/15) Generics警告対応
    754                        if( ( ! ekey.startsWith( "h_") && ! ekey.startsWith( "x_") ) &&
    755                                (  lowKey == null || ekey.startsWith( key ) ) ) {
    756                                        pageContext.removeAttribute( ekey, PageContext.APPLICATION_SCOPE ) ;
    757                        }
    758                }
    759
    760                ekeys = pageContext.getAttributeNamesInScope( PageContext.SESSION_SCOPE );
    761                while ( ekeys.hasMoreElements() ) {
    762                        String ekey = String.valueOf( ekeys.nextElement() ).toLowerCase(Locale.JAPAN);
    763                        if( ( ! ekey.startsWith( "h_") && ! ekey.startsWith( "x_") ) &&
    764                                (  lowKey == null || ekey.startsWith( key ) ) ) {
    765                                        pageContext.removeAttribute( ekey, PageContext.SESSION_SCOPE ) ;
    766                        }
    767                }
    768        }
    769
    770        /**
    771         * 指定のスコープの内部キャッシュ情報を、指定のSQL文より作成します。
    772         *
    773         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    774         * @og.rev 3.2.4.0 (2003/06/12) マルチデータ(複数件検索)を使用するかしないか。
    775         * @og.rev 3.8.6.0 (2006/08/07) nullSet="true"(初期値)の時は、検索結果がゼロ件時に "" をセットする。
    776         * @og.rev 3.8.9.2 (2007/07/28) action="ROW_APPEND" 追加
    777         * @og.rev 4.3.7.5 (2009/07/13) ACT_LIST、ACT_ALL_LIST アクションの追加
    778         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    779         * @og.rev 5.5.0.3 (2012/03/12) ACT_MAP アクションの追加
    780         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    781         *
    782         * @param table DBTableModelオブジェクト
    783         */
    784        private void setSQLAttribute( final DBTableModel table ) {
    785                if( table == null ) {           // 3.8.6.0 (2006/08/07)
    786                        return;
    787                }
    788
    789                int clmCnt = table.getColumnCount();
    790                int rowCnt = table.getRowCount();
    791                String sqlkey ;
    792                String sqlval ;
    793                String sufix = "";
    794
    795                if( ACT_ROW_APPEND.equals( action ) ) {
    796                        for( int clm = 0; clm < clmCnt; clm++ ) {
    797                                StringBuilder buf = new StringBuilder();
    798                                for( int row=0; row<rowCnt; row++ ) {
    799                                        sqlval = table.getValue( row, clm );
    800                                        if( row > 0 ) { buf.append( separator ); }
    801                                        buf.append( sqlval );
    802                                }
    803                                sqlkey = table.getColumnName( clm );
    804                                setObject( sqlkey , buf.toString() );
    805                        }
    806                }
    807                // 4.3.7.5 (2009/07/13) ACT_LIST、ACT_ALL_LIST アクションの追加
    808                else if( ACT_LIST.equals( action ) ) {
    809                        for( int clm = 0; clm < clmCnt; clm++ ) {
    810                                ArrayList<String> list = new ArrayList<String>();
    811                                for( int row=0; row<rowCnt; row++ ) {
    812                                        sqlval = table.getValue( row, clm );
    813                                        list.add( sqlval );
    814                                }
    815                                sqlkey = table.getColumnName( clm );
    816                                setObject( sqlkey , list );
    817                        }
    818                }
    819                // 5.5.0.3 (2012/03/12) ACT_MAP アクションの追加
    820                else if( ACT_MAP.equals( action )  ) {
    821                        if( clmCnt < 2 ) {
    822                                String errMsg = "action=MAP 時には、カラムは、２つ以上必要です。カラム数=[" + clmCnt + "]";
    823                                throw new IllegalArgumentException( errMsg );
    824                        }
    825                        for( int row=0; row<rowCnt; row++ ) {
    826                                sqlkey = table.getValue( row, 0 );                      // 0番目カラムがキー
    827                                sqlval = table.getValue( row, 1 );                      // 1番目カラムが値
    828                                setObject( sqlkey , sqlval );
    829                        }
    830                }
    831                else {
    832                        // 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    833                        if( rowCnt == 0 ) {
    834                                if( useMultiRows ) { sufix = "0" ; }
    835                                for( int clm = 0; clm < clmCnt; clm++ ) {
    836                                        sqlkey = table.getColumnName( clm );
    837                                        sqlval = "";
    838                                        setObject( sqlkey + sufix, sqlval );
    839                                }
    840                        }
    841                        else {
    842                                for( int row=0; row<rowCnt; row++ ) {
    843                                        if( useMultiRows ) { sufix = String.valueOf( row ) ; }
    844                                        for( int clm = 0; clm < clmCnt; clm++ ) {
    845                                                sqlkey = table.getColumnName( clm );
    846                                                sqlval = table.getValue( row, clm );
    847                                                setObject( sqlkey + sufix, sqlval );
    848                                        }
    849                                        if( ! useMultiRows ) { break; }
    850                                }
    851                        }
    852                }
    853        }
    854
    855        /**
    856         * 指定のSQL文の結果を文字列として画面に出力します。
    857         * 画面に出力される項目は、1項目だけで2項目以降は無視されます。
    858         *
    859         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    860         *
    861         * @param table DBTableModelオブジェクト
    862         *
    863         * @return SQL文の結果文字列
    864         */
    865        private String getSQLAttribute( final DBTableModel table ) {
    866                if( table == null ) {           // 3.8.6.0 (2006/08/07)
    867                        return "";
    868                }
    869
    870                int rowCnt = table.getRowCount();
    871                final String rtn;
    872                if( ACT_ROW_APPEND.equals( action ) ) {
    873                        StringBuilder buf = new StringBuilder();
    874                        for( int row=0; row<rowCnt; row++ ) {
    875                                if( row > 0 ) { buf.append( separator ); }
    876                                buf.append( table.getValue( row, 0 ) );
    877                        }
    878                        rtn = buf.toString();
    879                }
    880                else if ( rowCnt == 0 ) {
    881                        rtn = "";
    882                }
    883                else {
    884                        rtn = table.getValue( 0, 0 );
    885                }
    886
    887                return rtn;
    888        }
    889
    890        /**
    891         * 指定のスコープの内部キャッシュ情報に、DBTableModel の選択された値を登録します。
    892         *
    893         * 複数選択行が存在する場合は、先頭行を処理します。ただし、action="APPEND"の
    894         * 場合は、separator属性で指定された文字を使用して、連結します。
    895         *
    896         * @og.rev 3.1.0.1 (2003/03/26) 新規作成
    897         * @og.rev 3.5.6.5 (2004/08/09) ACT_APPEND 時の処理変更
    898         * @og.rev 3.6.1.0 (2005/01/05) ACT_ALL_APPEND アクションの追加
    899         * @og.rev 4.3.7.5 (2009/07/13) ACT_LIST、ACT_ALL_LIST アクションの追加
    900         * @og.rev 5.1.6.0 (2010/05/01) ALL_APPENDで選択行がない場合に処理されないバグを修正
    901         * @og.rev 5.5.0.3 (2012/03/12) ACT_MAP アクションの追加
    902         * @og.rev 5.6.4.3 (2013/05/24) ACT_MAX_MIN,ACT_ALL_MAX_MIN アクションの追加
    903         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    904         *
    905         * @param table         DBTableModelオブジェクト
    906         * @param key           キー
    907         * @param action        アクション
    908         */
    909        private void setTableAttribute( final DBTableModel table,final String key,final String action ) {
    910                if( table == null || table.getRowCount() == 0 || table.getColumnCount() == 0 ) { return ; }
    911
    912                int[] rowNo = getParameterRows();
    913                // 5.1.6.0 (2010/05/01)
    914                if( rowNo.length == 0 ) { return; }                             // 5.6.4.3 (2013/05/24) tmpSelectedAll 属性を追加したので、0件判定が使える。
    915
    916                final String[] keys ;
    917                if( key == null || key.length() == 0 ) {
    918                        keys = table.getNames();
    919                }
    920                else {
    921                        keys = new String[] { key } ;
    922                }
    923
    924                // 5.6.4.3 (2013/05/24) tmpSelectedAll で、ロジックの共通化
    925                if( ACT_APPEND.equals( action ) ) {
    926                        for( int i=0; i<keys.length; i++ ) {
    927                                int clm = table.getColumnNo( keys[i] );
    928                                StringBuilder val = new StringBuilder();
    929                                val.append( table.getValue( rowNo[0],clm ) );
    930                                for( int j=1; j<rowNo.length; j++ ) {
    931                                        val.append( separator );
    932                                        val.append( table.getValue( rowNo[j],clm ) );
    933                                }
    934                                setObject( keys[i],val.toString() );
    935                        }
    936                }
    937
    938                // 5.5.0.3 (2012/03/12) ACT_MAP アクションの追加
    939                else if( ACT_MAP.equals( action ) ) {
    940                        int keyClm = table.getColumnNo( key   ,false );
    941                        int valClm = table.getColumnNo( value ,false );
    942
    943                        if( keyClm < 0 ) { keyClm = 0; }     // キーとなるカラムが指定されていない場合は、最初のカラム
    944                        if( valClm < 0 ) { valClm = 1; }     // 値となるカラムが指定されていない場合は、２番目のカラム
    945
    946                        for( int j=0; j<rowNo.length; j++ ) {
    947                                String mapkey = table.getValue( rowNo[j], keyClm );
    948                                String mapval = table.getValue( rowNo[j], valClm );
    949                                setObject( mapkey , mapval );
    950                        }
    951                }
    952
    953                // 4.3.7.5 (2009/07/13) ACT_LIST アクションの追加
    954                else if( ACT_LIST.equals( action ) ) {
    955                        for( int i=0; i<keys.length; i++ ) {
    956                                int clm = table.getColumnNo( keys[i] );
    957                                ArrayList<String> list = new ArrayList<String>();
    958                                for( int j=0; j<rowNo.length; j++ ) {
    959                                        list.add( table.getValue( rowNo[j],clm ) );
    960                                }
    961                                setObject( keys[i],list );
    962                        }
    963                }
    964
    965                // 5.6.4.3 (2013/05/24) ACT_MAX_MIN アクションの追加
    966                else if( ACT_MAX_MIN.equals( action ) ) {
    967                        NumberFormat nf = null;
    968                        for( int i=0; i<keys.length; i++ ) {
    969                                int clm = table.getColumnNo( keys[i] );
    970                                DBColumn clmObj = table.getDBColumn( clm );
    971                                String clsNm = clmObj.getClassName();                   // NUMBER,INTEGER,DECIMAL が数字型。
    972
    973                                boolean numFlag = "NUMBER,INTEGER,DECIMAL".indexOf( clsNm ) >= 0 ;           // 数字型:true
    974
    975                                String minVal = null ;
    976                                String maxVal = null ;
    977                                double minNum = Double.MAX_VALUE ;
    978                                double maxNum = Double.MIN_VALUE ;
    979                                double sumNum = 0d ;
    980                                int    cntSum = 0;              // 平均計算に有効な件数
    981
    982                                for( int j=0; j<rowNo.length; j++ ) {
    983                                        String val = table.getValue( rowNo[j],clm );
    984                                        if( val != null && val.length() > 0 ) {
    985                                                // 数字として比較
    986                                                if( numFlag ) {
    987                                                        double tmp = Double.parseDouble( val );
    988                                                        if( minNum > tmp ) { minNum = tmp; minVal = val; }
    989                                                        if( maxNum < tmp ) { maxNum = tmp; maxVal = val; }
    990                                                        sumNum += tmp ;  cntSum++ ;
    991                                                }
    992                                                else {
    993                                                        // 文字列として比較
    994                                                        if( minVal == null || minVal.compareTo( val ) > 0 ) { minVal = val; }        // 最初のデータは、必ずセットする。
    995                                                        if( maxVal == null || maxVal.compareTo( val ) < 0 ) { maxVal = val; }        // 最初のデータは、必ずセットする。
    996                                                }
    997                                        }
    998                                }
    999                                if( minVal == null ) { minVal = nval( defaultVal , "" ); }              // 最後まで値が決まらなければ、""(空文字列) にする。
    1000                                if( maxVal == null ) { maxVal = nval( defaultVal , "" ); }              // 最後まで値が決まらなければ、""(空文字列) にする。
    1001                                setObject( "MIN." + keys[i],minVal );
    1002                                setObject( "MAX." + keys[i],maxVal );
    1003
    1004                                // SUM と AVG は、数字型の場合のみセットします。
    1005                                if( cntSum > 0 ) {
    1006                                        if( nf == null ) {
    1007                                                nf = NumberFormat.getInstance();
    1008                                                nf.setGroupingUsed( false );                                    // カンマ編集なし
    1009                                                nf.setMaximumFractionDigits(2);                                 // 最大小数部は２桁
    1010                                                nf.setMinimumFractionDigits(0);                                 // できれば、整数表示
    1011                                        }
    1012                                        setObject( "SUM." + keys[i],nf.format( sumNum ) );              // Double.toString( sumNum ) の代わり。
    1013                                        setObject( "AVG." + keys[i],nf.format( sumNum/cntSum ) );
    1014                                }
    1015                                else {
    1016                                        setObject( "SUM." + keys[i],nval( defaultVal , "" ) );
    1017                                        setObject( "AVG." + keys[i],nval( defaultVal , "" ) );
    1018                                }
    1019                        }
    1020                }
    1021                else {
    1022                        for( int i=0; i<keys.length; i++ ) {
    1023                                int clm = table.getColumnNo( keys[i] );
    1024                                setAttribute( keys[i],table.getValue( rowNo[0],clm ),action );
    1025                        }
    1026                }
    1027        }
    1028
    1029        /**
    1030         * DBTableModel の選択された値を取得します。
    1031         *
    1032         * 複数選択行が存在する場合は、先頭行を処理します。ただし、action="APPEND"の
    1033         * 場合は、separator属性で指定された文字を使用して、連結します。
    1034         *
    1035         * @og.rev 3.1.0.1 (2003/03/26) 新規作成
    1036         * @og.rev 3.5.6.5 (2004/08/09) ACT_APPEND 時の処理変更
    1037         * @og.rev 3.6.1.0 (2005/01/05) ACT_ALL_APPEND アクションの追加
    1038         * @og.rev 5.1.6.0 (2010/05/01) ALL_APPENDで選択行がない場合に処理されないバグを修正
    1039         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    1040         *
    1041         * @param       table   DBTableModelオブジェクト
    1042         * @param       key             キー
    1043         * @param       action  アクション
    1044         *
    1045         * @return      DBTableModelの選択された値
    1046         */
    1047        private String getTableAttribute( final DBTableModel table,final String key,final String action ) {
    1048                if( table == null ) {
    1049                        String errMsg = "table がセットされていません。"
    1050                                                + " command=" + command + " , action=" + action
    1051                                                + " , key=" + key ;                     // 5.1.8.0 (2010/07/01) errMsg 修正
    1052                        throw new HybsSystemException( errMsg );
    1053                }
    1054
    1055                if( key == null || key.length() == 0 ) {
    1056                        String errMsg = "key がセットされていません。"
    1057                                                + " command=" + command + " , action=" + action;                        // 5.1.8.0 (2010/07/01) errMsg 修正
    1058                        throw new HybsSystemException( errMsg );
    1059                }
    1060
    1061                int[] rowNo = getParameterRows();
    1062                // 5.1.6.0 (2010/05/01)
    1063                if( rowNo.length == 0 ) { return "" ; }                         // 5.6.4.3 (2013/05/24) tmpSelectedAll 属性を追加したので、0件判定が使える。
    1064
    1065                // 3.6.1.0 (2005/01/05) ACT_ALL_APPEND アクションの追加
    1066                int clm = table.getColumnNo( key );
    1067                if( ACT_APPEND.equals( action ) ) {
    1068                        StringBuilder val = new StringBuilder();
    1069                        val.append( table.getValue( rowNo[0],clm ) );
    1070                        for( int j=1; j<rowNo.length; j++ ) {
    1071                                val.append( separator );
    1072                                val.append( table.getValue( rowNo[j],clm ) );
    1073                        }
    1074                        return val.toString() ;
    1075                }
    1076                else {
    1077                        return actionExec( action,table.getValue( rowNo[0],clm ) );
    1078                }
    1079        }
    1080
    1081        /**
    1082         * 指定のスコープの内部キャッシュ情報に、DBTableModel の選択された値を登録します。
    1083         *
    1084         * これは、key で指定したカラムの値をキーとして、value で指定したカラムの値を
    1085         * value 値として設定します。
    1086         * setTableAttribute が、カラム(横持ち)データを処理するのに対して、
    1087         * ロウ(縦持ち)データを処理することが出来ます。
    1088         *
    1089         * @og.rev 3.1.0.1 (2003/03/26) 新規作成
    1090         * @og.rev 3.3.3.3 (2003/08/06) key 情報がデータの値になっていた。バグ修正。
    1091         * @og.rev 3.5.6.5 (2004/08/09) ACT_APPEND 時の処理変更
    1092         *
    1093         * @param table         DBTableModelオブジェクト
    1094         * @param key           キー
    1095         * @param value         値
    1096         * @param action        アクション
    1097         */
    1098        private void setKeyTableAttribute( final DBTableModel table,final String key,final String value,final String action ) {
    1099                if( table == null ) { return ; }
    1100
    1101                if( key == null || key.length() == 0 ) {
    1102                        String errMsg = "key がセットされていません。"
    1103                                                + " command=" + command + " , action=" + action
    1104                                                + " , value=" + value ;                 // 5.1.8.0 (2010/07/01) errMsg 修正
    1105                        throw new HybsSystemException( errMsg );
    1106                }
    1107
    1108                int[] rowNo = getParameterRows();
    1109                if( rowNo.length == 0 ) { return ; }
    1110
    1111                final int[] valClm ;
    1112                if( value == null || value.length() == 0 ) {
    1113                        String[] vals = table.getNames();
    1114                        valClm = new int[vals.length];
    1115                        for( int i=0; i<vals.length; i++ ) {
    1116                                valClm[i] = table.getColumnNo( vals[i] );
    1117                        }
    1118                }
    1119                else {
    1120                        valClm = new int[] { table.getColumnNo( value ) } ;
    1121                }
    1122
    1123        // 3.3.3.3 (2003/08/06) key 情報がデータの値になっていた。バグ修正。
    1124        //      3.5.6.5 (2004/08/09) ロジック変更
    1125                for( int j=0; j<rowNo.length; j++ ) {
    1126                        String rowKey = key + j ;
    1127                        if( ACT_APPEND.equals( action ) ) {
    1128                                StringBuilder val = new StringBuilder();
    1129                                val.append( table.getValue( rowNo[j],valClm[0] ) );
    1130                                for( int i=1; i<valClm.length; i++ ) {
    1131                                        val.append( separator );
    1132                                        val.append( table.getValue( rowNo[j],valClm[i] ) );
    1133                                }
    1134                                setObject( rowKey,val.toString() );
    1135                        }
    1136                        else {
    1137                                setAttribute( rowKey,table.getValue( rowNo[j],valClm[0] ),action );
    1138                        }
    1139                }
    1140        }
    1141
    1142        /**
    1143         * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を処理の対象とします。
    1144         *
    1145         * action="FIRST" 処理と、tmpSelectedAll 属性追加に伴う処理を、Override します。
    1146         *
    1147         * @og.rev 3.1.0.1 (2003/03/26) 新規作成
    1148         * @og.rev 4.0.0.0 (2005/01/31) メイン処理を、super class で対応
    1149         * @og.rev 3.8.0.4 (2005/08/08) action="FIRST" 機能の追加
    1150         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性の追加に伴い、全件選択状態のデータを作成します。
    1151         *
    1152         * @return      選択行の配列
    1153         */
    1154        @Override
    1155        protected int[] getParameterRows() {
    1156                final int[] rowNo ;
    1157                // 3.8.0.4 (2005/08/08) action="FIRST" 機能の追加
    1158                if( ACT_FIRST.equals( action ) ) {
    1159                        rowNo = new int[] { 0 };
    1160                }
    1161                // 5.6.4.3 (2013/05/24) tmpSelectedAll 属性の追加
    1162                else if( tmpSelectedAll ) {
    1163                        int rowCnt = table.getRowCount();
    1164                        rowNo = new int[ rowCnt ];
    1165                        for( int i=0; i<rowCnt; i++ ) {
    1166                                rowNo[i] = i;
    1167                        }
    1168                }
    1169                else {
    1170                        rowNo = super.getParameterRows() ;
    1171                }
    1172                return rowNo ;
    1173        }
    1174
    1175        /**
    1176         * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
    1177         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。
    1178         *
    1179         * @og.tag
    1180         * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に
    1181         * 渡す場合に、通常は、session を利用します。その場合の登録キーです。
    1182         * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、
    1183         * この tableId 属性を利用して、メモリ空間を分けます。
    1184         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。
    1185         *
    1186         * @param       id sessionに登録する時の ID
    1187         */
    1188        public void setTableId( final String id ) {
    1189                tableId   = nval( getRequestParameter( id ),tableId );
    1190        }
    1191
    1192        /**
    1193         * 【TAG】コマンド(SET,GET,REMOVE,SQL,SETTBL,GETTBL,KEYTBL,CLEAR,SETMEM)をセットします(初期値:SET)。
    1194         *
    1195         * @og.tag
    1196         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    1197         * フィールド定数値のいづれかを、指定できます。
    1198         * 何も設定されない、または、null の場合は、"SET" が初期値にセットされます。
    1199         *
    1200         * CLEAR 以外のすべての処理は、指定のスコープの内部キャッシュ情報に対して行われます。
    1201         * <table border="1" frame="box" rules="all" >
    1202         *   <caption>コマンド 一覧</caption>
    1203         *   <tr><th>command </th><th>名称          </th><th>機能</th></tr>
    1204         *   <tr><td>SET    </td><td>セット         </td><td>指定のキーに、value値を登録します。</td></tr>
    1205         *   <tr><td>GET    </td><td>ゲット         </td><td>指定のキーの値を画面に出力します。</td></tr>
    1206         *   <tr><td>REMOVE </td><td>リムーブ       </td><td>指定のキーの値を削除します。</td></tr>
    1207         *   <tr><td>CLEAR  </td><td>クリア         </td><td>セッション/アプリケーションスコープのキャッシュ情報をクリアします。</td></tr>
    1208         *   <tr><td>SQL    </td><td>ＳＱＬ         </td><td>指定のSQL文の実行結果を、カラム名をキーとして設定します。</td></tr>
    1209         *   <tr><td>SQLGET </td><td>ＳＱＬゲット   </td><td>指定のSQL文の実行結果を、画面に出力します。(2項目以降は無視されます)。</td></tr>
    1210         *   <tr><td>SETTBL </td><td>セットテーブル </td><td>指定のキーに、DBTableModel の選択されたカラム(横持ち)の値を登録します。</td></tr>
    1211         *   <tr><td>GETTBL </td><td>ゲットテーブル </td><td>指定のキーに、DBTableModel の選択されたカラム(横持ち)の値を画面に出力します。</td></tr>
    1212         *   <tr><td>KEYTBL </td><td>キーテーブル   </td><td>指定のキーに、DBTableModel の選択されたロウ(縦持ち)の値を登録します。</td></tr>
    1213         *   <tr><td>SETMEM </td><td>セットメモリ   </td><td>指定のキーに、value値を内部キャッシュに登録します。</td></tr>
    1214         * </table>
    1215         *
    1216         * @og.rev 3.1.0.1 (2003/03/26) 指定のコマンド以外は、エラーとするように変更。
    1217         * @og.rev 3.5.6.2 (2004/07/05) 文字列の連結にStringBuilderを使用します。
    1218         *
    1219         * @param       cmd コマンド(public static final 宣言されている文字列)
    1220         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ValueTag.CMD_GET">コマンド定数</a>
    1221         */
    1222        public void setCommand( final String cmd ) {
    1223                command = nval( getRequestParameter( cmd ),command ).toUpperCase(Locale.JAPAN);
    1224
    1225                if( !check( command, COMMAND_LIST ) ) {
    1226                        StringBuilder errMsg = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    1227                        errMsg.append( "指定のコマンドは実行できません。コマンドエラー" );
    1228                        errMsg.append( HybsSystem.CR );
    1229                        errMsg.append( "command=[" ).append( command ).append( "] " );
    1230                        errMsg.append( HybsSystem.CR );
    1231                        for( int i=0; i<COMMAND_LIST.length; i++ ) {
    1232                                errMsg.append( " | " );
    1233                                errMsg.append( COMMAND_LIST[i] );
    1234                        }
    1235                        errMsg.append( " | " );
    1236                        throw new HybsSystemException( errMsg.toString() );
    1237                }
    1238        }
    1239
    1240        /**
    1241         * 【TAG】アクション(UPPER,LOWER,MESSAGE,APPEND,ALL_APPEND,MAP,ALL_MAP,LIST,ALL_LIST,
    1242         *        DAY_WEEK,MERGE,FIRST,ROW_APPEND,REPLACE,SUBSTR,SPLIT,MAX_MIN,ALL_MAX_MIN,EXEC,CASE)をセットします。
    1243         *
    1244         * @og.tag
    1245         * アクションは,HTMLから(get/post)指定されますので,ACT_xxx で設定される
    1246         * フィールド定数値のいづれかを、指定できます。
    1247         * 無指定の場合は、なにもしません。
    1248         *
    1249         * <table border="1" frame="box" rules="all" >
    1250         *   <caption>アクション 一覧</caption>
    1251         *   <tr><th>action     </th><th>名称               </th><th>機能</th></tr>
    1252         *   <tr><td>UPPER      </td><td>アッパー(大文字化) </td><td>value値を大文字に変換します。</td></tr>
    1253         *   <tr><td>LOWER      </td><td>ローワー(小文字化) </td><td>value値を小文字に変換します。</td></tr>
    1254         *   <tr><td>MESSAGE    </td><td>メッセージ変換     </td><td>引数をメッセージリソースのキーとして、メッセージ変換します。</td></tr>
    1255         *   <tr><td>APPEND     </td><td>データアペンド     </td><td>複数リクエストや複数選択時に値を連結します。</td></tr>
    1256         *   <tr><td>ALL_APPEND </td><td>オールアペンド     </td><td>SETTBL,GETTBL 時に、チェック行以外の全行を対象に値の連結を行います。</td></tr>
    1257         *   <tr><td>MAP        </td><td>マップ             </td><td>検索結果やTableModelのkeyをキーに、valueｗを値に一括設定します。</td></tr>
    1258         *   <tr><td>ALL_MAP    </td><td>オールマップ       </td><td>全行を対象に検索結果やTableModelのkeyをキーに、valueｗを値に一括設定します。</td></tr>
    1259         *   <tr><td>LIST       </td><td>リスト             </td><td>複数リクエストや複数選択時に値をArrayListにセットします。</td></tr>
    1260         *   <tr><td>ALL_LIST   </td><td>オールリスト       </td><td>全行を対象に値をArrayListにセットします。</td></tr>
    1261         *   <tr><td>DAY_WEEK   </td><td>日付前方まるめ     </td><td>日付型文字列(YYYYMMDD) の値を、月曜日に変換します。</td></tr>
    1262         *   <tr><td>           </td><td>                   </td><td>指定日が日曜日の場合は、次の日(月曜日)に進めます。その他は、週始めに戻します。</td></tr>
    1263         *   <tr><td>MERGE      </td><td>データのマージ     </td><td>重複を除く、ユニークな値に、マージします。(カンマで分解、separatorで合成)</td></tr>
    1264         *   <tr><td>FIRST      </td><td>１件目取得         </td><td>最初の１件目を強制的に選択状態にして、処理を行います。</td></tr>
    1265         *   <tr><td>ROW_APPEND </td><td>検索結果の連結     </td><td>検索結果の行方向のデータを連結します。</td></tr>
    1266         *   <tr><td>REPLACE    </td><td>文字列置換         </td><td>value の値から、指定された正規表現(from)の部分文字列を、部分文字列(to)で置換します。</td></tr>
    1267         *   <tr><td>SUBSTR     </td><td>部分文字列         </td><td>value の値から、指定された(from)から(to)の部分文字列を作成します。</td></tr>
    1268         *   <tr><td>SPLIT      </td><td>文字列分割         </td><td>value の値から、指定されたseparatorで分割した文字列を作成します。(key+0〜連番)</td></tr>
    1269         *   <tr><td>MAX_MIN    </td><td>最大_最小値        </td><td>選択行のkeyのカラムの最小値,最大値を、MIN.キー、MAX.キー の値にセットします。※１</td></tr>
    1270         *   <tr><td>ALL_MAX_MIN</td><td>最大_最小値        </td><td>全行を対象にkeyのカラムの最小値,最大値を、MIN.キー、MAX.キー の値にセットします。※１</td></tr>
    1271         *   <tr><td>EXEC       </td><td>計算結果           </td><td>value またはBODY部の値を、JavaScriptで計算した結果をセットします。</td></tr>
    1272         *   <tr><td>CASE       </td><td>条件分岐           </td><td>fromVal="A:1 B:2 C:3 D:4" 形式の値を元に、value値(左辺)に一致する右辺をセットします。※２</td></tr>
    1273         * </table>
    1274         *
    1275         * ※１ MAX_MIN,ALL_MAX_MIN  については、DBTableModelのカラムのCLS_NAMEが、NUMBER,INTEGER,DECIMAL の場合は、数字型(double)に変換して比較します。
    1276         *    数字型(double)の場合だけ、合計(SUM.キー) と 平均(AVG.キー)計算も同時に行います。
    1277         *    それ以外の場合は、文字列比較を行います。（command="SETTBL" のみ）
    1278         *    command="SET" の場合は、数字型(double)として、value の値を、separator で分解したうえで、最大、最小、合計、平均 を計算し、
    1279         *    それぞれを、MIN.キー、MAX.キー、SUM.キー、AVG.キー 変数にセットします。
    1280         *    数字に変換できなかった場合は、エラーになります。
    1281         *    null は、無視され(平均を求める場合の母数としても無視)、すべてが nulll の場合は、ゼロ文字列("")になります。
    1282         *    ゼロ文字列("") の場合に、defaultVal 属性が設定されていると、defaultVal が設定されます。
    1283         * ※２ CASE は、fromVal="A:1 B:2 C:3 D:4" 形式の値に対して、コロン(:)で分解し、value値(左辺)が、一致する右辺を返します。
    1284         *    fromVal の値は、スペースで分割され、コロン(:)が存在する左辺(キー)と右辺(値)に分解し、value値とキーを比較し、
    1285         *    一致すれば、右辺の値を返します。
    1286         *    valueがnullの場合、defaultVal が設定されており、その値で、fromVal の値と比較します。
    1287         *    一致する値がなければ、元の value が返されます。
    1288         *
    1289         * @og.rev 3.1.0.1 (2003/03/26) 指定のアクション以外は、エラーとするように変更。
    1290         * @og.rev 3.5.6.2 (2004/07/05) 文字列の連結にStringBuilderを使用します。
    1291         * @og.rev 4.3.7.5 (2009/07/13) ACT_LIST、ACT_ALL_LIST アクションの追加(JavaDocのみ修正)
    1292         * @og.rev 5.6.4.3 (2013/05/24) ACTMAX_MIN アクションの追加(JavaDocのみ修正)
    1293         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加にともなう修正。action="ALL_xxx"は、tmpSelectedAll=true にします。
    1294         * @og.rev 5.7.7.2 (2014/06/20) EXEC と CASE アクションを追加
    1295         *
    1296         * @param       act アクション(public static final 宣言されている文字列)
    1297         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ValueTag.ACT_APPEND">アクション定数</a>
    1298         */
    1299        public void setAction( final String act ) {
    1300                action = nval( getRequestParameter( act ),action );
    1301
    1302                if( action != null && !check( action, ACTION_LIST ) ) {
    1303                        StringBuilder errMsg = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    1304                        errMsg.append( "指定のアクションは実行できません。アクションエラー" );
    1305                        errMsg.append( HybsSystem.CR );
    1306                        errMsg.append( "action=[" ).append( action ).append( "] " );
    1307                        errMsg.append( HybsSystem.CR );
    1308                        for( int i=0; i<ACTION_LIST.length; i++ ) {
    1309                                errMsg.append( " | " );
    1310                                errMsg.append( ACTION_LIST[i] );
    1311                        }
    1312                        errMsg.append( " | " );
    1313                        throw new HybsSystemException( errMsg.toString() );
    1314                }
    1315
    1316                // 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    1317                if( action != null && action.startsWith( "ALL_" ) ) {
    1318                        action      = action.substring( 4 );    // "ALL_" の４文字分削除
    1319                        tmpSelectedAll = true;
    1320                }
    1321        }
    1322
    1323        /**
    1324         * 【TAG】リクエスト情報 に登録するキーをセットします。
    1325         *
    1326         * @og.tag リクエスト情報 に登録するキーをセットします。
    1327         *
    1328         * @og.rev 3.0.1.3 (2003/03/11) キーを toUpperCase している箇所を削除
    1329         *
    1330         * @param       key1 リクエスト情報に登録するキー
    1331         */
    1332        public void setKey( final String key1 ) {
    1333                key = nval( getRequestParameter( key1 ),key ) ;
    1334                if( key == null ) {
    1335                        String errMsg = "key がセットされていません。"
    1336                                                + " command=" + command + " , action=" + action;                        // 5.1.8.0 (2010/07/01) errMsg 修正
    1337                        throw new HybsSystemException( errMsg );
    1338                }
    1339        }
    1340
    1341        /**
    1342         * 【TAG】リクエスト情報 に登録する値をセットします。
    1343         *
    1344         * @og.tag リクエスト情報 に登録する値をセットします。
    1345         *
    1346         * @og.rev 3.1.7.0 (2003/05/02) isNullSet 属性が true(初期値)のときは、リクエスト情報から値を取得。
    1347         * @og.rev 3.5.4.0 (2003/11/25) getRequestParameter( value ) メソッドを setValue に移動。
    1348         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    1349         *
    1350         * @param       val     リクエスト情報に登録する値
    1351         */
    1352        public void setValue( final String val ) {
    1353                inValue = val;          // 3.5.4.0 (2003/11/25) 入力変数も、キープしておく。
    1354                value = getRequestParameter( inValue );
    1355        }
    1356
    1357        /**
    1358         * 【TAG】value値がNULLの場合に、この初期値を設定します。
    1359         *
    1360         * @og.tag
    1361         * value値がNULLの場合に、この初期値をセットします。
    1362         *
    1363         * @param       val 初期値
    1364         */
    1365        public void setDefaultVal( final String val ) {
    1366                defaultVal = getRequestParameter( val );
    1367        }
    1368
    1369        /**
    1370         * 【廃止】value が NULL の時に、設定するかどうか[true/false]を指定します(初期値:true)。
    1371         *
    1372         * @og.tag
    1373         * true の場合は, null のときでもセットします。
    1374         * false の場合は, null のときは、既存の値を置き換えません。
    1375         * 初期値は、null のときでもセットするです。 ("true")
    1376         *
    1377         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    1378         *
    1379         * @param   flag NULL の時に設定するかどうか [true:設定する/それ以外:設定しない]
    1380         * @deprecated 5.1.8.0 (2010/07/01) 廃止。
    1381         */
    1382        @Deprecated public void setNullSet( final String flag ) {
    1383//              isNullSet = nval( getRequestParameter( flag ),isNullSet );
    1384        }
    1385
    1386        /**
    1387         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します。
    1388         *
    1389         * @og.tag Queryオブジェクトを作成する時のDB接続IDを指定します。
    1390         *
    1391         * @param       id データベース接続ID
    1392         */
    1393        public void setDbid( final String id ) {
    1394                dbid = nval( getRequestParameter( id ),dbid );
    1395        }
    1396
    1397        /**
    1398         * 【TAG】キャッシュする場合のスコープ(request,session)を指定します(初期値:request)。
    1399         *
    1400         * @og.tag
    1401         * "request","session" が指定できます。
    1402         * 初期値は、 "request" です。
    1403         *
    1404         * @param       scp     スコープ
    1405         */
    1406        @Override
    1407        public void setScope( final String scp ) {
    1408                scope = nval( getRequestParameter( scp ),scope );
    1409        }
    1410
    1411        /**
    1412         * 【TAG】DBTableModel から取得する場合のスコープ(request,session)を指定します(初期値:session)。
    1413         *
    1414         * @og.tag
    1415         * "request","session" が指定できます。
    1416         * 初期値は、 "session" です。
    1417         *
    1418         * @og.rev 5.1.2.0 (2010/01/01) DBTableModel の取得先のscope
    1419         *
    1420         * @param       scp     スコープ
    1421         */
    1422        public void setTblScope( final String scp ) {
    1423                tblScope = nval( getRequestParameter( scp ),tblScope );
    1424        }
    1425
    1426        /**
    1427         * 【TAG】マルチデータ(複数件検索)を使用するかどうか[true/false]を指定します(初期値:false)。
    1428         *
    1429         * @og.tag
    1430         * command="SQL" の場合に、複数行検索した結果を、キー＋行番号 というキーを作成して
    1431         * 値を設定するかどうかを指定します。
    1432         * false の場合は、従来どおり、検索カラム名がキーになります。
    1433         * 初期値は、false です。
    1434         *
    1435         * @og.rev 3.2.4.0 (2003/06/12) 新規追加
    1436         *
    1437         * @param   flag 複数件検索 [true:使用する/false:使用しない]
    1438         */
    1439        public void setUseMultiRows( final String flag ) {
    1440                useMultiRows = nval( getRequestParameter( flag ),useMultiRows );
    1441        }
    1442
    1443        /**
    1444         * 【TAG】各種アクションの文字列を連結/分解する項目区切り文字をセットします(初期値:",")。
    1445         *
    1446         * @og.tag
    1447         * 各種アクションに基づく処理において、文字列の区切りを指定するのに使用します。
    1448         * APPEND、ROW_APPEND 時には、文字列の連結に使用します。
    1449         * MERGE の場合は、カンマで分解後、このセパレータでMERGE処理を行い、再び、連結します。
    1450         * 初期値は、"," に設定されています。
    1451         *
    1452         * @og.rev 3.5.6.5 (2004/08/09) 新規追加
    1453         *
    1454         * @param   sepa 項目区切り文字(初期値:",")
    1455         */
    1456        public void setSeparator( final String sepa ) {
    1457                separator = nval( getRequestParameter( sepa ),separator );
    1458        }
    1459
    1460        /**
    1461         * 【TAG】リクエスト情報の HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか[true/false]を設定します
    1462         *              (初期値:USE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}])。
    1463         *
    1464         * @og.tag
    1465         * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。
    1466         * (&gt;&lt;) が含まれていたエラーにする(true)／かノーチェックか(false)を指定します。
    1467         * (初期値:システム定数のUSE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}])。
    1468         *
    1469         * @og.rev 5.1.7.0 (2010/06/01) 新規追加
    1470         *
    1471         * @param       flag    XSSチェック [true:する/false:しない]
    1472         * @see         org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK
    1473         */
    1474        public void setXssCheck( final String flag ) {
    1475                xssCheck = nval( getRequestParameter( flag ),xssCheck );
    1476        }
    1477
    1478        /**
    1479         * 【TAG】部分文字列置換の 置換え前の部分文字列(from)を指定します。
    1480         *
    1481         * @og.tag
    1482         * value の値から、指定された正規表現(from)に一致する、この文字列の各部分文字列に対し、
    1483         * 指定された文字列(to)で置換します。
    1484         * value.replaceAll( from, to ) という文法で処理します。
    1485         *
    1486         * @og.rev 5.2.2.0 (2010/11/01) 新規追加
    1487         *
    1488         * @param       from    置換え前の部分文字列
    1489         * @see         #setToVal(String)
    1490         */
    1491        public void setFromVal( final String from ) {
    1492                fromVal = nval( getRequestParameter( from ),fromVal );
    1493        }
    1494
    1495        /**
    1496         * 【TAG】部分文字列置換の 置換え後の部分文字列(to)を指定します。
    1497         *
    1498         * @og.tag
    1499         * value の値から、指定された正規表現(from)に一致する、この文字列の各部分文字列に対し、
    1500         * 指定された文字列(to)で置換します。
    1501         * value.replaceAll( from, to ) という文法で処理します。
    1502         *
    1503         * @og.rev 5.2.2.0 (2010/11/01) 新規追加
    1504         *
    1505         * @param       to      置換え後の部分文字列
    1506         * @see         #setFromVal(String)
    1507         */
    1508        public void setToVal( final String to ) {
    1509                toVal = nval( getRequestParameter( to ),toVal );
    1510        }
    1511
    1512        /**
    1513         * 【TAG】暗号化、複合化に利用する暗号化キーを指定します。
    1514         *
    1515         * @og.tag
    1516         * 暗号化キーをしています。
    1517         * 未設定の場合は、エンジンで用意されているキーを利用します。
    1518         * 暗号化キーは8の倍数の文字数が推奨されています。
    1519         *
    1520         * @og.rev 5.10.4.0 (2018/10/05) 新規追加
    1521         * @param cKey
    1522         */
    1523        public void setCryptKey( final String cKey ) {
    1524                cryptKey = nval( getRequestParameter( cKey ), cryptKey);
    1525        }
    1526
    1527        /**
    1528         * シリアライズ用のカスタムシリアライズ書き込みメソッド
    1529         *
    1530         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
    1531         * @serialData 一部のオブジェクトは、シリアライズされません。
    1532         *
    1533         * @param       strm    ObjectOutputStreamオブジェクト
    1534         * @throws IOException  入出力エラーが発生した場合
    1535         */
    1536        private void writeObject( final ObjectOutputStream strm ) throws IOException {
    1537                strm.defaultWriteObject();
    1538        }
    1539
    1540        /**
    1541         * シリアライズ用のカスタムシリアライズ読み込みメソッド
    1542         *
    1543         * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
    1544         *
    1545         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
    1546         * @serialData 一部のオブジェクトは、シリアライズされません。
    1547         *
    1548         * @param       strm    ObjectInputStreamオブジェクト
    1549         * @see #release2()
    1550         * @throws IOException  シリアライズに関する入出力エラーが発生した場合
    1551         * @throws ClassNotFoundException       クラスを見つけることができなかった場合
    1552         */
    1553        private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
    1554                strm.defaultReadObject();
    1555        }
    1556
    1557        /**
    1558         * このオブジェクトの文字列表現を返します。
    1559         * 基本的にデバッグ目的に使用します。
    1560         *
    1561         * @og.rev 4.3.4.0 (2008/12/01) PageContextのスコープをクラス変数としてアクセス
    1562         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    1563         *
    1564         * @return このクラスの文字列表現
    1565         */
    1566        @Override
    1567        public String toString() {
    1568                String rtnStr = org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
    1569                                .println( "VERSION"                     ,VERSION                )
    1570                                .println( "tableId"                     ,tableId                )
    1571                                .println( "command"                     ,command                )
    1572                                .println( "key"                         ,key                    )
    1573                                .println( "inValue"                     ,inValue                )
    1574                                .println( "value"                       ,value                  )
    1575                                .println( "defaultVal"          ,defaultVal             )
    1576                                .println( "action"                      ,action                 )
    1577                                .println( "dbid"                        ,dbid                   )
    1578                                .println( "scope"                       ,scope                  )
    1579                                .println( "separator"           ,separator              )
    1580                                .println( "useMultiRows"        ,useMultiRows   )
    1581                                .println( "COMMAND_LIST"        ,COMMAND_LIST   )
    1582                                .println( "ACTION_LIST"         ,ACTION_LIST    )
    1583                                .println( "Other..."    ,getAttributes().getAttribute() )
    1584                                .fixForm().toString() ;
    1585
    1586                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    1587                rtn.append( HybsSystem.CR ).append( "====================================" ).append( HybsSystem.CR );
    1588
    1589                rtn.append( "APPLICATION_SCOPE:" ).append( HybsSystem.CR );
    1590
    1591                Enumeration<String> ekeys = pageContext.getAttributeNamesInScope( PageContext.APPLICATION_SCOPE );        // 4.3.3.6 (2008/11/15) Generics警告対応
    1592                while ( ekeys.hasMoreElements() ) {
    1593                        String ekey = ekeys.nextElement();              // 4.3.3.6 (2008/11/15) Generics警告対応
    1594                        rtn.append( "  key=[" ).append( ekey ).append( "] " );
    1595                        rtn.append( "value=[" ).append( pageContext.getAttribute( ekey,PageContext.APPLICATION_SCOPE ) ).append( "]" );
    1596                        rtn.append( HybsSystem.CR );
    1597                }
    1598
    1599                rtn.append( "SESSION_SCOPE:" ).append( HybsSystem.CR );
    1600                ekeys = pageContext.getAttributeNamesInScope( PageContext.SESSION_SCOPE );
    1601                while ( ekeys.hasMoreElements() ) {
    1602                        String ekey = String.valueOf( ekeys.nextElement() );
    1603                        rtn.append( "  key=[" ).append( ekey ).append( "] " );
    1604                        rtn.append( "value=[" ).append( pageContext.getAttribute( ekey,PageContext.SESSION_SCOPE ) ).append( "]" );
    1605                        rtn.append( HybsSystem.CR );
    1606                }
    1607
    1608                rtn.append( "REQUEST_SCOPE:" ).append( HybsSystem.CR );
    1609                ekeys = pageContext.getAttributeNamesInScope( PageContext.REQUEST_SCOPE );
    1610                while ( ekeys.hasMoreElements() ) {
    1611                        String ekey = String.valueOf( ekeys.nextElement() );
    1612                        rtn.append( "  key=[" ).append( ekey ).append( "] " );
    1613                        rtn.append( "value=[" ).append( pageContext.getAttribute( ekey,PageContext.REQUEST_SCOPE ) ).append( "]" );
    1614                        rtn.append( HybsSystem.CR );
    1615                }
    1616
    1617                rtn.append( "PAGE_SCOPE:" ).append( HybsSystem.CR );
    1618                ekeys = pageContext.getAttributeNamesInScope( PageContext.PAGE_SCOPE );
    1619                while ( ekeys.hasMoreElements() ) {
    1620                        String ekey = String.valueOf( ekeys.nextElement() );
    1621                        rtn.append( "  key=[" ).append( ekey ).append( "] " );
    1622                        rtn.append( "value=[" ).append( pageContext.getAttribute( ekey,PageContext.PAGE_SCOPE ) ).append( "]" );
    1623                        rtn.append( HybsSystem.CR );
    1624                }
    1625                rtn.append( "====================================" ).append( HybsSystem.CR );
    1626
    1627                return rtnStr + rtn.toString();
    1628        }
    1629}