    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.system.OgBuilder ;                                  // 6.4.4.2 (2016/04/01)
    019import org.opengion.fukurou.system.DateSet;                                             // 6.4.2.0 (2016/01/29)
    020import static org.opengion.fukurou.util.StringUtil.nval;
    021import org.opengion.fukurou.security.HybsCryptography;                  // 5.9.6.3 (2016/03/18)
    022
    023import java.util.Calendar;
    024import java.util.Enumeration;
    025import java.util.LinkedHashSet;
    026import java.util.Locale;
    027import java.util.ArrayList;
    028import java.util.Set;
    029import java.util.Map;
    030import java.util.LinkedHashMap;                                                                 // 6.4.2.1 (2016/02/05)
    031import java.text.NumberFormat;                                                                  // 6.2.4.2 (2015/05/29)
    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.ToString;                                              // 6.8.5.0 (2018/01/09)
    045import org.opengion.fukurou.util.HybsDateUtil;                                  // 6.4.2.0 (2016/01/29)
    046import org.opengion.fukurou.util.StringUtil;
    047import org.opengion.fukurou.util.ArraySet;                                              // 6.4.3.4 (2016/03/11)
    048import org.opengion.fukurou.db.Transaction;
    049
    050/**
    051 * JSP上からキー、値を設定することにより、パラメータとして、値を
    052 * 取出し可能にするタグです。
    053 *
    054 * 通常のリクエスト情報と同じ扱いができます(優先順位は、リクエストが上位)。
    055 *
    056 * 設定した値は、{&#064;XXXX} 形式で 取り出すことができます。
    057 * また、command ="GET" で 直接画面に値を書き出すことも可能です。
    058 *
    059 * ※ このタグは、Transaction タグの対象です。
    060 *
    061 * &lt;style type="text/css" &gt;
    062 *   #valueJavaDoc th { vertical-align:top; margin:0px; padding:0px; }
    063 *   #valueJavaDoc td { text-align:center;  margin:0px; padding:0px; }
    064 *  .act {
    065 *      background-color: #ccffcc;
    066 *      height : 160px;
    067 *  }
    068 *  .cmd {
    069 *      background-color: #ffcccc;
    070 *      width  : 80px;
    071 *  }
    072 *  .arrow {
    073 *     border-top:  160px solid #ccffcc;
    074 *     border-left:  80px solid #ffcccc;
    075 *     position: absolute;
    076 *  }
    077 *  .actarw { margin-left:20px; position: absolute; }
    078 *  .cmdarw { margin-top:140px; position: absolute; }
    079 * &lt;/style&gt;
    080 *
    081 * @og.formSample
    082 * ●形式：&lt;og:value command="SET" key="ABC" value="123" /&gt;
    083 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    084 *
    085 * ●Tag定義：
    086 *   &lt;og:value
    087 *       command            【TAG】コマンド (SET,GET,REMOVE,CLEAR,SQL,SETTBL,GETTBL,KEYTBL,SETMEM,SQLGET,DEBUG)をセットします(初期値:SET)
    088 *       action             【TAG】アクション(UPPER,LOWER,MESSAGE,APPEND,ALL_APPEND,MAP,ALL_MAP,MAPOBJ,ALL_MAPOBJ,LIST,ALL_LIST,DAY_WEEK,
    089 *                                  MERGE,FIRST,ROW_APPEND,REPLACE,INDEX_OF,LASTINDEX_OF,SUBSTR,LENGTH,SPLIT,MAX_MIN,ALL_MAX_MIN,ADD,CASE,ESCAPE,
    090 *                                  URL_ENCODE,URL_ENCODE2,URL_DECODE,TRIM,MD5,TO_NUMBER,HMCSV,CRYPT_ENC,CRYPT_DEC,REQUEST)をセットします
    091 *                                  7.3.0.0 (2021/01/06) EXEC 廃止
    092 *       key                【TAG】パラメータ に登録するキーをセットします
    093 *       value              【TAG】パラメータ に登録する値をセットします
    094 *       defaultVal         【TAG】value値がNULLの場合に、この初期値を設定します
    095 *       separator          【TAG】各種アクションの文字列を連結/分解する項目区切り文字をセットします(初期値:",")
    096 *       useMultiRows       【TAG】マルチデータ(複数件検索)を使用するかどうか[true/false]を指定します(初期値:false)
    097 *       scope              【TAG】キャッシュする場合のスコープ(request,session)を指定します(初期値:request)
    098 *       tableId            【TAG】sessionから取得する DBTableModelオブジェクトの ID
    099 *       tblScope           【TAG】DBTableModel から取得する場合のスコープ(request,session)を指定します(初期値:session)
    100 *       dbid               【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します
    101 *       xssCheck           【TAG】パラメータの HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_XSS_CHECK[=true])
    102 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
    103 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
    104 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
    105 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
    106 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
    107 *       fromVal            【TAG】部分文字列置換の 置換え前の部分文字列(from)を指定します･･･HMCSVの開始時刻にも使用します
    108 *       toVal              【TAG】部分文字列置換の 置換え後の部分文字列(to)を指定します･･･HMCSVの終了時刻にも使用します
    109 *       skipVal            【TAG】HMCSVで使用する、ステップ時間を分で指定します(例：１時間=60 , ２時間=120 , 45分=45 など) 6.8.4.1 (2017/12/18)
    110 *       cryptKey           【TAG】暗号化と復号化で利用する、暗号化キーを指定します。
    111 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)  5.10.4.0 (2018/10/05)
    112 *   &gt;   ... Body ...
    113 *   &lt;/og:value&gt;
    114 *
    115 * 【廃止】5.1.8.0 (2010/07/01) 物理削除
    116 *  //   nullSet            【廃止】value が NULL の時に、設定するかどうか[true/false]を指定します(初期値:true)
    117 *
    118 * ●使用例
    119 *     ・ &lt;og:value command="SET" key="ABC" value="123" /&gt;
    120 *     ・ &lt;og:value command="SQL"&gt;SELECT 1 TEST FROM DUAL&lt;/og:value&gt;
    121 *     ・ &lt;og:value command="SET" key="DEF" value="{&#064;NOCOMMAND}" defaultVal="0000" /&gt;
    122 *     ・ &lt;og:value command="GET" key="NOKEY" defaultVal="NODATA" /&gt;
    123 *     ・ &lt;og:value command="SET" key="{&#064;ABC}4" value="TEST1234" /&gt;
    124 *     ・ &lt;og:value command="GET" key="ABC" /&gt;
    125 *     ・ &lt;og:value command="SET" action="LOWER" key="LOWERTEST" value="ABCDEF" /&gt;
    126 *     ・ &lt;og:value command="GET" key="LOWERTEST" /&gt;
    127 *     ・ &lt;og:value command="GET" action="UPPER" key="LOWERTEST" /&gt;
    128 *     ・ &lt;og:value command="REMOVE" key="ABC" /&gt;
    129 *
    130 * <table class="plain" id="valueJavaDoc">
    131 *   <caption>command 一覧と使用可能 action の対応表</caption>
    132 *   <tr>
    133 *       <th><span class="arrow">Key</span><span class="actarw">action</span><span class="cmdarw">command</span></th>
    134 *       <th class="act">UPPER<br>LOWER<br>MESSAGE<br>DAY_WEEK<br>MERGE<br>REPLACE<br>
    135 *                                              INDEX_OF<br>LASTINDEX_OF<br>SUBSTR<br>LENGTH<br>ADD<br>CASE<br>ESCAPE<br>URL_ENCODE<br>URL_ENCODE2<br>URL_DECODE<br>TRIM<br>MD5<br>TO_NUMBER</th>
    136 *       <th class="act">APPEND<br>ALL_APPEND</th>
    137 *       <th class="act">MAP<br>ALL_MAP<br>MAPOBJ<br>ALL_MAPOBJ<br>LIST<br>ALL_LIST</th>
    138 *       <th class="act">FIRST</th>
    139 *       <th class="act">ROW_APPEND</th>
    140 *       <th class="act">SPLIT<br>MAX_MIN<br>ALL_MAX_MIN</th>
    141 *       <th class="act">HMCSV</th>                                                                             <!-- 6.8.4.1 (2017/12/18) -->
    142 *   </tr>
    143 *   <tr><td class="cmd">SET    </td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>○</td><td>○</td></tr>
    144 *   <tr><td class="cmd">GET    </td><td>○</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>○</td></tr>
    145 *   <tr><td class="cmd">REMOVE </td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td></tr>
    146 *   <tr><td class="cmd">CLEAR  </td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td><td>×</td></tr>
    147 *   <tr><td class="cmd">SQL    </td><td>×</td><td>×</td><td>○</td><td>×</td><td>○</td><td>×</td><td>×</td></tr>
    148 *   <tr><td class="cmd">SETTBL </td><td>○</td><td>○</td><td>○</td><td>○</td><td>×</td><td>○</td><td>×</td></tr>
    149 *   <tr><td class="cmd">GETTBL </td><td>○</td><td>○</td><td>×</td><td>○</td><td>×</td><td>×</td><td>×</td></tr>
    150 *   <tr><td class="cmd">KEYTBL </td><td>○</td><td>○</td><td>×</td><td>○</td><td>×</td><td>○</td><td>×</td></tr>
    151 *   <tr><td class="cmd">SETMEM </td><td>○</td><td>○</td><td>×</td><td>×</td><td>×</td><td>○</td><td>×</td></tr>
    152 *   <tr><td class="cmd">SQLGET </td><td>×</td><td>×</td><td>×</td><td>×</td><td>○</td><td>×</td><td>×</td></tr>
    153 * </table>
    154 *
    155 * @og.group その他部品
    156 *
    157 * @version  4.0
    158 * @author   M.Endou
    159 * @since    JDK5.0,
    160 */
    161public class ValueTag extends CommonTagSupport {
    162        /** このプログラムのVERSION文字列を設定します。   {@value} */
    163        private static final String VERSION = "7.2.6.1 (2020/07/17)" ;
    164        private static final long serialVersionUID = 726120200717L ;
    165
    166        /** command 引数に渡す事の出来る コマンド  セット {@value} */
    167        public static final String CMD_SET              = "SET";
    168        /** command 引数に渡す事の出来る コマンド  ゲット {@value} */
    169        public static final String CMD_GET              = "GET";
    170        /** command 引数に渡す事の出来る コマンド  リムーブ {@value} */
    171        public static final String CMD_REMOVE   = "REMOVE";
    172        /** command 引数に渡す事の出来る コマンド  クリア {@value} */
    173        public static final String CMD_CLEAR    = "CLEAR";
    174        /** command 引数に渡す事の出来る コマンド  ＳＱＬ {@value} */
    175        public static final String CMD_SQL              = "SQL";
    176        /** command 引数に渡す事の出来る コマンド  セットテーブル {@value} */
    177        public static final String CMD_SETTBL   = "SETTBL";
    178        /** command 引数に渡す事の出来る コマンド  ゲットテーブル {@value} */
    179        public static final String CMD_GETTBL   = "GETTBL";
    180        /** command 引数に渡す事の出来る コマンド  キーテーブル {@value} */
    181        public static final String CMD_KEYTBL   = "KEYTBL";
    182        /** command 引数に渡す事の出来る コマンド  セットメモリ {@value} */
    183        public static final String CMD_SETMEM   = "SETMEM";                     // 3.7.1.0 (2005/04/15)
    184        /** command 引数に渡す事の出来る コマンド  ＳＱＬゲット {@value} */
    185        public static final String CMD_SQLGET   = "SQLGET";                     // 5.1.7.0 (2010/06/01) SQLGET対応
    186        /** command 引数に渡す事の出来る コマンド  デバッグ {@value} */
    187        public static final String CMD_DEBUG    = "DEBUG";                      // 6.7.7.2 (2017/04/14)
    188
    189        // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    190        private static final Set<String> COMMAND_SET = new ArraySet<>( CMD_SET , CMD_GET , CMD_REMOVE , CMD_SQL , CMD_SETTBL , CMD_GETTBL ,
    191                                                                                                                                   CMD_KEYTBL , CMD_CLEAR , CMD_SETMEM, CMD_SQLGET );
    192
    193        /** action 引数に渡す事の出来る アクション  アッパー(大文字化) {@value} */
    194        public static final String ACT_UPPER            = "UPPER" ;
    195        /** action 引数に渡す事の出来る アクション  ローワー(小文字化) {@value} */
    196        public static final String ACT_LOWER            = "LOWER" ;
    197        /** action 引数に渡す事の出来る アクション  メッセージ変換 {@value} */
    198        public static final String ACT_MESSAGE          = "MESSAGE" ;
    199        /** action 引数に渡す事の出来る アクション  データアペンド {@value} */
    200        public static final String ACT_APPEND           = "APPEND" ;
    201        /** action 引数に渡す事の出来る アクション  オールアペンド {@value} */
    202        public static final String ACT_ALL_APPEND       = "ALL_APPEND" ;                                // 3.6.1.0 (2005/01/05)
    203        /** action 引数に渡す事の出来る アクション  MAP {@value} */
    204        public static final String ACT_MAP                      = "MAP" ;                                               // 5.5.0.3 (2012/03/12)
    205        /** action 引数に渡す事の出来る アクション  ALL_MAP {@value} */
    206        public static final String ACT_ALL_MAP          = "ALL_MAP" ;                                   // 5.5.0.3 (2012/03/12)
    207        /** action 引数に渡す事の出来る アクション  MAP {@value} */
    208        public static final String ACT_MAPOBJ           = "MAPOBJ" ;                                    // 6.2.4.2 (2015/05/29)
    209        /** action 引数に渡す事の出来る アクション  ALL_MAP {@value} */
    210        public static final String ACT_ALL_MAPOBJ       = "ALL_MAPOBJ" ;                                // 6.2.4.2 (2015/05/29)
    211        /** action 引数に渡す事の出来る アクション  LIST {@value} */
    212        public static final String ACT_LIST                     = "LIST" ;                                              // 4.3.7.5 (2009/07/13)
    213        /** action 引数に渡す事の出来る アクション  ALL_LIST {@value} */
    214        public static final String ACT_ALL_LIST         = "ALL_LIST" ;                                  // 4.3.7.5 (2009/07/13)
    215        /** action 引数に渡す事の出来る アクション  日付前方まるめ {@value} */
    216        public static final String ACT_DAY_WEEK         = "DAY_WEEK" ;                                  // 3.7.1.0 (2005/04/15)
    217        /** action 引数に渡す事の出来る アクション  マージ {@value} */
    218        public static final String ACT_MERGE            = "MERGE" ;                                             // 3.7.1.1 (2005/05/23)
    219        /** action 引数に渡す事の出来る アクション  ファースト {@value} */
    220        public static final String ACT_FIRST            = "FIRST" ;                                             // 3.8.0.4 (2005/08/08)
    221        /** action 引数に渡す事の出来る アクション  縦横回転 {@value} */
    222        public static final String ACT_ROW_APPEND       = "ROW_APPEND" ;                                // 3.8.9.2 (2007/07/28)
    223        /** action 引数に渡す事の出来る アクション  文字列置換 {@value} */
    224        public static final String ACT_REPLACE          = "REPLACE" ;                                   // 5.2.2.0 (2010/11/01)
    225        /** action 引数に渡す事の出来る アクション  部分文字列 {@value} */
    226        public static final String ACT_SUBSTR           = "SUBSTR" ;                                    // 5.2.2.0 (2010/11/01)
    227        /** action 引数に渡す事の出来る アクション  文字数(char数) {@value} */
    228        public static final String ACT_LENGTH           = "LENGTH" ;                                    // 7.2.6.0 (2020/06/30)
    229        /** action 引数に渡す事の出来る アクション  INDEX_OF数 {@value} */
    230        public static final String ACT_INDEX_OF         = "INDEX_OF" ;                                  // 7.2.6.0 (2020/06/30)
    231        /** action 引数に渡す事の出来る アクション  LASTINDEX_OF数 {@value} */
    232        public static final String ACT_LASTINDEX_OF     = "LASTINDEX_OF" ;                              // 7.2.6.0 (2020/06/30)
    233        /** action 引数に渡す事の出来る アクション  文字列分割 {@value} */
    234        public static final String ACT_SPLIT            = "SPLIT" ;                                             // 5.2.2.0 (2010/11/01)
    235        /** action 引数に渡す事の出来る アクション  最大_最小値 {@value} */
    236        public static final String ACT_MAX_MIN          = "MAX_MIN" ;                                   // 5.6.4.3 (2013/05/24)
    237        /** action 引数に渡す事の出来る アクション  ALL_最大_最小値 {@value} */
    238        public static final String ACT_ALL_MAX_MIN      = "ALL_MAX_MIN" ;                               // 5.6.4.3 (2013/05/24)
    239        /** action 引数に渡す事の出来る アクション  計算処理結果 {@value} */
    240        public static final String ACT_EXEC                     = "EXEC" ;                                              // 5.7.7.2 (2014/06/20)
    241        /** action 引数に渡す事の出来る アクション  値をﾌﾟﾗｽする {@value} */
    242        public static final String ACT_ADD                      = "ADD" ;                                               // 7.3.0.0 (2021/01/06)
    243        /** action 引数に渡す事の出来る アクション  条件分岐 {@value} */
    244        public static final String ACT_CASE                     = "CASE" ;                                              // 5.7.7.2 (2014/06/20)
    245        /** action 引数に渡す事の出来る アクション  HTML上のエスケープ文字 {@value} */
    246        public static final String ACT_ESCAPE           = "ESCAPE" ;                                    // 6.3.5.0 (2015/08/08)
    247        /** action 引数に渡す事の出来る アクション  UTF-8 でURLエンコード {@value} */
    248        public static final String ACT_ENCODE           = "URL_ENCODE" ;                                        // 6.9.7.0 (2018/05/14)
    249        /** action 引数に渡す事の出来る アクション  UTF-8 で部分URLエンコード {@value} */
    250        public static final String ACT_ENCODE2          = "URL_ENCODE2" ;                                       // 6.9.7.0 (2018/05/14)
    251        /** action 引数に渡す事の出来る アクション  UTF-8 でURLデコード {@value} */
    252        public static final String ACT_DECODE           = "URL_DECODE" ;                                        // 6.9.7.0 (2018/05/14)
    253        /** action 引数に渡す事の出来る アクション  スペース削除 {@value} */
    254        public static final String ACT_TRIM                     = "TRIM" ;                                              // 6.4.1.2 (2016/01/22)
    255        /** action 引数に渡す事の出来る アクション  MD5 {@value} */
    256        public static final String ACT_MD5                      = "MD5" ;                                               // 5.9.6.3 (2016/03/18)
    257        /** action 引数に渡す事の出来る アクション  TO_NUMBER {@value} */
    258        public static final String ACT_TO_NUMBER        = "TO_NUMBER" ;                                 // 6.7.4.0 (2017/02/10)
    259        /** action 引数に渡す事の出来る アクション  HMCSV {@value} */
    260        public static final String ACT_HMCSV            = "HMCSV" ;                                             // 6.8.4.1 (2017/12/18)
    261        /** action 引数に渡す事の出来る アクション  CRYPT_ENC {@value} */
    262        public static final String ACT_CRYPT_ENC        = "CRYPT_ENC";                                  // 5.10.4.0 (2018/10/05)
    263        /** action 引数に渡す事の出来る アクション  CRYPT_DEC {@value} */
    264        public static final String ACT_CRYPT_DEC        = "CRYPT_DEC";                                  // 5.10.4.0 (2018/10/05)
    265        /** action 引数に渡す事の出来る アクション  REQUEST {@value} */
    266        public static final String ACT_REQUEST          = "REQUEST";                                    // 7.2.6.1 (2020/07/17)
    267
    268        /** action 引数に渡す事の出来る アクション リスト  */
    269        // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    270        // 6.8.4.1 (2017/12/18) ACT_HMCSV
    271        // 6.9.7.0 (2018/05/14) ACT_ENCODE , ACT_ENCODE2 , ACT_DECODE
    272        // 5.10.4.0 (2018/10/05) ACT_CRYPT_ENC, ACT_CRYPT_DEC
    273        // 7.2.6.0 (2020/06/30) ACT_LENGTH
    274        // 7.3.0.0 (2021/01/06) ACT_ADD , (ACT_EXECは基本廃止)
    275        private static final Set<String> ACTION_SET = new ArraySet<>(
    276                                ACT_UPPER , ACT_LOWER , ACT_MESSAGE , ACT_APPEND , ACT_ALL_APPEND ,
    277                                ACT_MAP , ACT_ALL_MAP , ACT_MAPOBJ , ACT_ALL_MAPOBJ , ACT_LIST, ACT_ALL_LIST ,
    278                                ACT_DAY_WEEK , ACT_MERGE , ACT_FIRST , ACT_ROW_APPEND , ACT_REPLACE  ,ACT_INDEX_OF ,ACT_LASTINDEX_OF, ACT_SUBSTR ,ACT_LENGTH ,
    279                                ACT_SPLIT , ACT_MAX_MIN , ACT_ALL_MAX_MIN , ACT_EXEC , ACT_CASE , ACT_ESCAPE , ACT_ENCODE , ACT_ENCODE2 , ACT_DECODE ,
    280                                ACT_TRIM , ACT_MD5 , ACT_TO_NUMBER , ACT_HMCSV, ACT_CRYPT_ENC, ACT_CRYPT_DEC, ACT_REQUEST , ACT_ADD
    281        );
    282
    283        /** 6.8.4.1 (2017/12/18) action="HMCSV" で、ループ制限します。 */
    284        public static final int MAX_CNT = 300;
    285
    286        private transient DBTableModel table;
    287
    288        private String          tableId         = HybsSystem.TBL_MDL_KEY;
    289        private String          command         = CMD_SET;
    290        private String          key                     ;
    291        private String          inValue         ;               // 3.5.4.0 (2003/11/25)
    292        private String          value           ;
    293        private String          defaultVal      ;
    294        private String          action          ;
    295        private String          dbid            ;                               // 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
    296        private String          scope           = "request";    // "request","session"
    297        private String          tblScope        = "session";    // 5.1.2.0 (2010/01/01) DBTableModel の取得先のscope
    298        private String          separator       = ",";                  // 項目区切り文字
    299        private boolean         useMultiRows ;                          // 3.2.4.0 (2003/06/12) マルチデータ(複数件検索)を使用するかしないか。初期値:使用せず
    300        private boolean         xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" ); // 5.1.7.0 (2010/06/01) XSS対策
    301
    302        private String  fromVal                 ;                                       // 5.2.2.0 (2010/11/01)
    303        private String  toVal                   ;                                       // 5.2.2.0 (2010/11/01)
    304        private String  skipVal                 ;                                       // 6.8.4.1 (2017/12/18)
    305        private String  cryptKey                ;                                       // 5.10.4.0 (2018/10/05) 暗号化キー
    306
    307        private boolean tmpSelectedAll  ;                                       // 5.6.4.3 (2013/05/24) action="ALL_xxx"を tmpSelectedAll="true" で内部処理します。
    308
    309        /**
    310         * デフォルトコンストラクター
    311         *
    312         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    313         */
    314        public ValueTag() { super(); }          // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    315
    316        /**
    317         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    318         *
    319         * @og.rev 3.1.7.0 (2003/05/02) isNullSet 属性が true(初期値)のときは、リクエスト情報から値を取得。
    320         * @og.rev 3.1.7.0 (2003/05/02) scope 属性を設定するタイミングを、早くする。
    321         * @og.rev 3.5.4.0 (2003/11/25) getRequestParameter( value ) メソッドを setValue に移動。
    322         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    323         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    324         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    325         * @og.rev 6.4.8.1 (2016/07/02) xssCheckを、doStartTag に移動
    326         *
    327         * @return      後続処理の指示
    328         */
    329        @Override
    330        public int doStartTag() {
    331                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    332                if( useTag() ) {
    333                        useXssCheck( xssCheck );                // 6.4.8.1 (2016/07/02)
    334
    335                        super.setScope( scope );                // デフォルトscope が "request" なので、再設定している。
    336
    337        //              if( isNullSet ) {
    338        //                      setUseValue( false );
    339        //              }
    340
    341                        // 5.1.7.0 (2010/06/01) SQLGET対応
    342                        if( CMD_SQL.equals( command ) || CMD_SET.equals( command ) || CMD_SQLGET.equals( command ) ) {
    343                                return EVAL_BODY_BUFFERED ;             // Body を評価する
    344                        }
    345                }
    346                return SKIP_BODY ;                              // Body を評価しない
    347        }
    348
    349        /**
    350         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
    351         *
    352         * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
    353         * @og.rev 3.6.0.8 (2004/11/19) エラー発生時に確実にリリースされるように try finally 追加
    354         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    355         * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
    356         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    357         * @og.rev 5.1.7.0 (2010/06/01) XSS解除対応
    358         * @og.rev 5.1.9.0 (2010/08/01) TransactionTag 対応。上位に TransactionTag があれば、そこからConnection をもらう。
    359         * @og.rev 5.2.1.0 (2010/10/01) command="SET" action="APPEND"でvalueをbody部に書いた場合に動作しないバグを修正
    360         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    361         * @og.rev 5.3.8.0 (2011/08/01) Transaction発生箇所でclose()
    362         * @og.rev 6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用したtry-with-resources構築に対応。
    363         * @og.rev 6.3.6.1 (2015/08/28) QueryFactory.close( Query ) 廃止。Queryはキャッシュしません。
    364         * @og.rev 6.4.8.1 (2016/07/02) xssCheckを、doStartTag に移動
    365         *
    366         * @return      後続処理の指示(SKIP_BODY)
    367         */
    368        @Override
    369        public int doAfterBody() {
    370                if( value == null || value.length() <= 0 ) {
    371                        // 5.1.7.0 (2010/06/01) XSS対策
    372
    373                        value = getBodyString();
    374                        // 5.2.1.0 (2010/10/01)
    375                        inValue = getBodyRawString();
    376
    377                        // 5.1.7.0 (2010/06/01) SQLGET対応
    378                        if( CMD_SQL.equals( command ) || CMD_SQLGET.equals( command ) ) {
    379                                // 6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用したtry-with-resources構築に対応。
    380                                try( Transaction tran = getTransaction() ) {
    381                                        final Query query = QueryFactory.newInstance();                 // 4.0.0 (2005/01/31)
    382                                        value = value.trim();
    383
    384                                        query.setConnection( tran.getConnection( dbid ) );              // 6.3.6.1 (2015/08/28)
    385                                        query.setResourceManager( getResource() );                              // 4.0.0 (2005/01/31)
    386                                        query.setStatement( value );
    387                                        query.execute();
    388
    389                                        table = query.getDBTableModel();
    390                                        tran.commit();                                                                                  // 6.3.6.1 (2015/08/28)
    391                                }       // 5.3.8.0 (2011/08/01) Transaction発生箇所でclose() (6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用)
    392                        }
    393                }
    394
    395                return SKIP_BODY ;
    396        }
    397
    398        /**
    399         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    400         *
    401         * @og.rev 3.1.0.1 (2003/03/26) DBTableModelの値をSET/GETできる command , action を追加。
    402         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    403         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    404         * @og.rev 3.1.5.0 (2003/04/22) DBTableModel が存在するときのみ実行するロジックになっていたバグ対応。
    405         * @og.rev 5.1.2.0 (2010/01/01) DBTableModel の取得先の tblScope を追加。
    406         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    407         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    408         *
    409         * @return      後続処理の指示
    410         */
    411        @Override
    412        public int doEndTag() {
    413                debugPrint();           // 4.0.0 (2005/02/28)
    414                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    415                if( useTag() ) {
    416                        if( check( command, COMMAND_SET ) ) {
    417                                if( CMD_SETTBL.equals( command ) ||
    418                                        CMD_GETTBL.equals( command ) ||
    419                                        CMD_KEYTBL.equals( command ) ) {
    420        //                                      table = (DBTableModel)getSessionAttribute( tableId );
    421                                                // 5.1.2.0 (2010/01/01) DBTableModel の取得先の tblScope を追加。
    422                                                if( "session".equals( tblScope ) ) { table = (DBTableModel) getSessionAttribute( tableId ); }
    423                                                else if( "request".equals( tblScope ) ) { table = (DBTableModel) getRequestAttribute( tableId ); }
    424                                                else {
    425                                                        final String errMsg = "このスコープはサポートされていません。[" + tblScope + "]";
    426                                                        throw new IllegalArgumentException( errMsg );
    427                                                }
    428                                }
    429                        }
    430
    431                        commandExec( command );
    432
    433                        // 5.1.7.0 (2010/06/01) SQLGET対応
    434                        if( CMD_GET.equals( command ) || CMD_GETTBL.equals( command ) || CMD_SQLGET.equals( command ) ) {
    435                                if( value != null ) { jspPrint( value ); }
    436                        }
    437                }
    438                return EVAL_PAGE ;
    439        }
    440
    441        /**
    442         * タグリブオブジェクトをリリースします。
    443         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    444         *
    445         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
    446         * @og.rev 3.1.0.1 (2003/03/26) DBTableModelの値をSET/GETできる command , action を追加。
    447         * @og.rev 3.1.0.1 (2003/03/26) query 属性を削除します。
    448         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    449         * @og.rev 3.2.4.0 (2003/06/12) マルチデータ(複数件検索)を使用するかしないか。
    450         * @og.rev 3.5.4.0 (2003/11/25) inValue 変数の追加
    451         * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
    452         * @og.rev 5.1.2.0 (2010/01/01) DBTableModel の取得先の tblScope を追加。
    453         * @og.rev 5.1.7.0 (2010/06/01) XSS解除対応
    454         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    455         * @og.rev 5.2.2.0 (2010/11/01) fromVal , toVal 属性 追加
    456         * @og.rev 5.6.4.3 (2013/05/24) parameter 属性は、未使用なので削除
    457         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    458         * @og.rev 6.8.4.1 (2017/12/18) skipVal 属性 追加
    459         * @og.rev 5.10.4.0 (2018/10/03) CRYPT追加
    460         *
    461         */
    462        @Override
    463        protected void release2() {
    464                super.release2();
    465                tableId         = HybsSystem.TBL_MDL_KEY;
    466                command         = CMD_SET;
    467                key                     = null;
    468                value           = null;
    469                defaultVal      = null;
    470                action          = null;
    471                table           = null;
    472                dbid            = null;
    473                scope           = "request";    // "request","session"
    474                tblScope        = "session";    // 5.1.2.0 (2010/01/01) DBTableModel の取得先のscope
    475                separator       = ",";
    476                useMultiRows = false;
    477                tmpSelectedAll  = false;        // 5.6.4.3 (2013/05/24)
    478                inValue         = null;                 // 3.5.4.0 (2003/11/25)
    479                xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );        // 5.1.7.0 (2010/06/01) XSS解除対応
    480                fromVal         = null;                 // 5.2.2.0 (2010/11/01)
    481                toVal           = null;                 // 5.2.2.0 (2010/11/01)
    482                skipVal         = null;                 // 6.8.4.1 (2017/12/18)
    483                cryptKey        = null;                 // 5.10.4.0 (2018/10/05)
    484        }
    485
    486        /**
    487         * コマンドを実行します。
    488         *
    489         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    490         * フィールド定数値のいづれかを、指定できます。
    491         * コマンドを登録すると同時に,実行も行ないます。
    492         *
    493         * @og.rev 3.1.0.1 (2003/03/26) command に、SETTBL / GETTBL / KEYTBL / CLEAR を追加。
    494         * @og.rev 3.1.0.1 (2003/03/26) query 属性を削除します。
    495         * @og.rev 3.1.7.0 (2003/05/02) scope 属性を設定するタイミングを、早くする。
    496         * @og.rev 3.7.1.0 (2005/04/15) command に、SETMEM を追加。
    497         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    498         * @og.rev 6.7.7.2 (2017/04/14) command に、DEBUG 追加
    499         *
    500         * @param       command コマンド (public static final 宣言されている文字列)
    501         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ValueTag.CMD_GET">コマンド定数</a>
    502         */
    503        private void commandExec( final String command ) {
    504
    505                if( CMD_SQL.equals( command ) ) {
    506                        setSQLAttribute( table );
    507                }
    508                else if( CMD_SQLGET.equals( command ) ) {
    509                        value = getSQLAttribute( table );
    510                }
    511                else if( CMD_SET.equals( command ) ) {
    512                        value = nval( value, defaultVal );
    513                        setAttribute( key,value,action );
    514                }
    515                else if( CMD_GET.equals( command ) ) {
    516                        value = getAttribute( key,action );
    517                }
    518                else if( CMD_REMOVE.equals( command ) ) {
    519                        removeAttribute( key );
    520                }
    521                else if( CMD_CLEAR.equals( command ) ) {
    522                        clearAttribute( key );
    523                }
    524                else if( CMD_SETTBL.equals( command ) ) {
    525                        setTableAttribute( table,key,action );
    526                }
    527                else if( CMD_GETTBL.equals( command ) ) {
    528                        value = getTableAttribute( table,key,action );
    529                }
    530                else if( CMD_KEYTBL.equals( command ) ) {
    531                        setKeyTableAttribute( table,key,value,action );
    532                }
    533                else if( CMD_SETMEM.equals( command ) ) {               // 3.7.1.0 (2005/04/15)
    534                        value = nval( value, defaultVal );
    535                        setAttribute( key,value,action );
    536                        setRequestCacheData( key,(String)getObject( key ) );
    537                }
    538                else if( CMD_DEBUG.equals( command ) ) {
    539                        value = scopeAttributePrint();                          // 6.7.7.2 (2017/04/14)
    540                }
    541        }
    542
    543        /**
    544         * アクションを実行します。
    545         *
    546         * コマンドは action 属性で指定します。
    547         * action コマンド が、 null の場合は、なにも実行しません。
    548         *
    549         * @og.rev 3.0.1.3 (2003/03/11) MESSAGE action を追加
    550         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    551         * @og.rev 3.7.1.0 (2005/04/15) action に、DAY_WEEK を追加。
    552         * @og.rev 3.7.1.1 (2005/05/23) action に、MERGE を追加。
    553         * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage ⇒ getResource().getLabel )
    554         * @og.rev 5.2.2.0 (2010/11/01) ACT_MERGE 時には、カンマで分解、separator で合成を行います。
    555         * @og.rev 5.2.2.0 (2010/11/01) ACT_REPLACE 処理を新規追加します。
    556         * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。
    557         * @og.rev 5.6.6.1 (2013/07/12) value が null の場合は、無視します。
    558         * @og.rev 5.7.7.2 (2014/06/20) EXEC と CASE アクションを追加
    559         * @og.rev 6.3.1.1 (2015/07/10) action="REPLACE" の、fromVal,toVal は、CSV形式で指定可能にする。
    560         * @og.rev 6.3.1.1 (2015/07/10) action="ESCAPE" 追加
    561         * @og.rev 6.3.5.0 (2015/08/08) action="ESCAPE" 追加
    562         * @og.rev 6.3.9.0 (2015/11/06) 文字列配列を toString() する。
    563         * @og.rev 6.4.1.2 (2016/01/22) TRIM アクションを追加。
    564         * @og.rev 6.4.2.0 (2016/01/29) HybsDateUtil.getCalendar( String ) を直接利用するように修正します。
    565         * @og.rev 5.9.6.3 (2016/02/18) MD5 アクションを追加
    566         * @og.rev 6.7.4.0 (2017/02/10) TO_NUMBER アクションを追加
    567         * @og.rev 6.8.4.1 (2017/12/18) HMCSV アクションを追加
    568         * @og.rev 6.9.1.0 (2018/02/26) HMCSV アクションに、MAX,MIN,HMF を追加
    569         * @og.rev 6.9.2.1 (2018/03/12) HybsDateUtil.getDateFormat の メソッド変更(引数の簡素化)
    570         * @og.rev 6.9.7.0 (2018/05/14) URL_ENCODE,URL_ENCODE2,URL_DECODE を追加
    571         * @og.rev 5.10.4.0 (2018/10/05) CRYPT追加
    572         * @og.rev 7.2.6.0 (2020/06/30) INDEX_OF ,LASTINDEX_OF, LENGTH追加
    573         * @og.rev 7.2.6.1 (2020/07/17) ACT_REQUEST追加
    574         * @og.rev 7.3.0.0 (2021/01/06) JavaScriptエンジンをNashornからGraalJSに移行(ただし、未対応)
    575         * @og.rev 7.3.0.0 (2021/01/06) ADDアクションを追加
    576         *
    577         * @param action        コマンド (public static final 宣言されている文字列)
    578         * @param value         旧の値
    579         *
    580         * @return      処理後の値
    581         */
    582        private String actionExec( final String action,final String value ) {
    583                String rtn = value;
    584
    585                // 5.6.6.1 (2013/07/12) value が null の場合は、無視します。
    586                if( action == null || value == null ) { return rtn; }
    587
    588                if( ACT_UPPER.equals( action ) ) {
    589                        // Localeを共通管理するようになった場合、String.toUpperCase( Locale locale )使用の事
    590                        rtn = value.toUpperCase(Locale.JAPAN);
    591                }
    592                else if( ACT_LOWER.equals( action ) ) {
    593                        // Localeを共通管理するようになった場合、String.toLowerCase( Locale locale )使用の事
    594                        rtn = value.toLowerCase(Locale.JAPAN);
    595                }
    596                else if( ACT_MESSAGE.equals( action ) ) {
    597                        // 引数をメッセージリソースのキーとして、メッセージ変換する。
    598                        rtn = getResource().getLabel( value );
    599                }
    600                else if( ACT_DAY_WEEK.equals( action ) ) {
    601                        // 日付型文字列(YYYYMMDD) の入力データを、開始日を月曜日にセットします。
    602                        // SUNDAY=1 , MONDAY=2 になります。月曜日との差だけ、前に戻します。
    603                        // 指定日が日曜日の場合は、次の日(月曜日)に進めます。
    604                        final Calendar ymd = HybsDateUtil.getCalendar( value );                         // 6.4.2.0 (2016/01/29)
    605                        final int shu = ymd.get( Calendar.DAY_OF_WEEK ) - Calendar.MONDAY ;
    606
    607                        if( shu != 0 ) { ymd.add( Calendar.DATE, -shu ); }
    608
    609                        rtn = DateSet.getDate( ymd.getTimeInMillis() , "yyyyMMdd" );            // 5.5.7.2 (2012/10/09) HybsDateUtil を利用
    610                }
    611                // 3.7.1.1 (2005/05/23)
    612                else if( ACT_MERGE.equals( action ) ) {
    613                        final Set<String> set = new LinkedHashSet<>();
    614                        // 引数をカンマで文字列配列に分解します。
    615                        final String[] vals = StringUtil.csv2Array( value );
    616                        // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    617                        for( final String str : vals ) {
    618                                if( str != null && str.length() > 0 ) {
    619                                        set.add( str );
    620                                }
    621                        }
    622//                      final String[] str = StringUtil.csv2Array( value );
    623//                      for( int i=0; i<str.length; i++ ) {
    624//                              if( str[i] != null && str[i].length() > 0 ) {
    625//                                      set.add( str[i] );
    626//                              }
    627//                      }
    628
    629                        // 分解後、マージ(Setで)されます。 登録順は、キープします。
    630                        rtn = StringUtil.iterator2line( set.iterator(),separator );     // 5.2.2.0 (2010/11/01) separator 使用
    631                }
    632                // 5.2.2.0 (2010/11/01) ACT_REPLACE 処理を新規追加
    633                else if( ACT_REPLACE.equals( action ) ) {
    634                        // value.replaceAll( from, to ) という文法で処理します。
    635                        // 6.0.2.5 (2014/10/31) null でないことがわかっている値の冗長な null チェックがあります。
    636                        if( fromVal != null && toVal != null ) {
    637                                // 6.3.1.1 (2015/07/10) CSV形式可能にする。
    638                                if( fromVal.indexOf( ',' ) < 0 ) {
    639                                        rtn = value.replaceAll( fromVal, toVal );
    640                                }
    641                                else {
    642                                        final String[] frmStr = fromVal.split( "," );
    643                                        final String[] toStr  = toVal.split( "," );
    644                                        if( frmStr.length == toStr.length ) {
    645                                                for( int i=0; i<frmStr.length; i++ ) {
    646                                                        rtn = rtn.replaceAll( frmStr[i], toStr[i] );
    647                                                }
    648                                        }
    649                                        else {
    650                                                final String errMsg = "REPLACE時の fromValのカンマの数が、toValの数と一致しません。"
    651                                                                                // 6.3.9.0 (2015/11/06) 文字列配列を toString() する。
    652                                                                                + CR + " fromVal=[" + String.join( ",",frmStr ) + "] , toVal=[" + toVal + "] , value=[" + value + "]";
    653                                                throw new HybsSystemException( errMsg );
    654                                        }
    655                                }
    656                        }
    657                }
    658                // 5.2.2.0 (2010/11/01) SUBSTR 処理を新規追加
    659                else if( ACT_SUBSTR.equals( action ) ) {
    660                        // value.substring( from, to ) という文法で処理します。
    661                        // 6.0.2.5 (2014/10/31) null でないことがわかっている値の冗長な null チェックがあります。
    662                                final int from = fromVal == null || fromVal.isEmpty() ? 0              : Integer.parseInt( fromVal );   // 6.4.2.1 (2016/02/05) PMD refactoring. Useless parentheses.
    663                                final int to   =   toVal == null || toVal.isEmpty()   ? value.length() : Integer.parseInt( toVal );             // 6.4.2.1 (2016/02/05) PMD refactoring. Useless parentheses.
    664
    665                                if(   from >= value.length() ) { rtn = ""; }
    666                                else if( to > value.length() ) { rtn = value.substring( from ); }
    667                                else {
    668                                        rtn = value.substring( from, to );
    669                                }
    670                }
    671                // 7.2.6.0 (2020/06/30) INDEX_OF ,LASTINDEX_OF, LENGTH追加
    672                else if( ACT_INDEX_OF.equals( action ) ) {
    673                        final int from = fromVal == null || fromVal.isEmpty() ? 0 : Integer.parseInt( fromVal );
    674                        rtn = String.valueOf( value.indexOf( separator,from ) );
    675                }
    676                // 7.2.6.0 (2020/06/30) INDEX_OF ,LASTINDEX_OF, LENGTH追加
    677                else if( ACT_LASTINDEX_OF.equals( action ) ) {
    678                        final int to = toVal == null || toVal.isEmpty() ? value.length() : Integer.parseInt( toVal );
    679                        rtn = String.valueOf( value.lastIndexOf( separator,to ) );
    680                }
    681                // 7.2.6.0 (2020/06/30) INDEX_OF ,LASTINDEX_OF, LENGTH追加
    682                else if( ACT_LENGTH.equals( action ) ) {
    683                        rtn = String.valueOf( value.length() );
    684                }
    685                // 5.7.7.2 (2014/06/20) CASE 処理を新規追加
    686                else if( ACT_CASE.equals( action ) ) {
    687                        // fromVal="A:1 B:2 C:3 D:4" 形式
    688                        if( fromVal != null && fromVal.length()>0 ) {
    689                                final String[] keys = StringUtil.csv2Array( fromVal , ' ' );
    690                                // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    691                                for( final String fkey : keys ) {
    692                                        final int idx = fkey.indexOf( ':' );
    693                                        if( idx >= 0 ) {                                                                        // 分解した値にコロン(:)がなければ、パス
    694                                                final String key = fkey.substring( 0,idx );             // 左辺(キー)
    695                                                if( value.equalsIgnoreCase( key ) ) {
    696                                                        rtn = fkey.substring( idx+1 );                          // 右辺(値)
    697                                                        break;
    698                                                }
    699                                        }
    700                                }
    701//                              for( int i=0; i<keys.length; i++ ) {
    702//                                      final int idx = keys[i].indexOf( ':' );
    703//                                      if( idx >= 0 ) {                                                                        // 分解した値にコロン(:)がなければ、パス
    704//                                              final String key = keys[i].substring( 0,idx );  // 左辺(キー)
    705//                                              if( value.equalsIgnoreCase( key ) ) {
    706//                                                      rtn = keys[i].substring( idx+1 );                       // 右辺(値)
    707//                                                      break;
    708//                                              }
    709//                                      }
    710//                              }
    711                        }
    712                }
    713                // 5.7.7.2 (2014/06/20) EXEC 処理を新規追加
    714                else if( ACT_EXEC.equals( action ) ) {
    715//                      final ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName( "JavaScript" );
    716                        ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName( "graal.js" );                // 7.3.0.0 (2021/01/06)
    717
    718                        if( jsEngine == null ) {
    719                                jsEngine = new ScriptEngineManager().getEngineByName( "nashorn" );              // 7.3.0.0 (2021/01/06)
    720                                if( jsEngine == null ) {
    721                                        final String errMsg = "ScriptEngine(Nashorn) は、廃止されました。" + CR
    722                                                                + " 別の方法に変更するか、GraalJSに移行してください。" + CR
    723                                                                + " command=" + command ;
    724                                        throw new HybsSystemException( errMsg );
    725                                }
    726                        }
    727
    728                        try {
    729                                final Object obj = jsEngine.eval( value );
    730                                rtn = String.valueOf( obj );
    731                        }
    732                        catch( final ScriptException ex ) {
    733                                final String errMsg = "JavaScript式のパースに失敗しました。[" + value + "]";
    734                                throw new HybsSystemException( errMsg , ex );
    735                        }
    736                }
    737                // 7.3.0.0 (2021/01/06) ADDアクションを追加
    738                else if( ACT_ADD.equals( action ) ) {
    739                        // defaultVal の 値と、(value またはBODY部の)値を、加算した結果をキー変数にセットします。
    740                        final int addVal = nval( defaultVal,0 ) + nval( value,0 );
    741                        rtn = String.valueOf( addVal );
    742                }
    743                // 6.3.5.0 (2015/08/08) action="ESCAPE" 追加
    744                else if( ACT_ESCAPE.equals( action ) ) {
    745                        rtn = StringUtil.htmlFilter( value );
    746                }
    747                // 6.9.7.0 (2018/05/14) action="URL_ENCODE" 追加
    748                else if( ACT_ENCODE.equals( action ) ) {
    749                        rtn = StringUtil.urlEncode( value );
    750                }
    751                // 6.9.7.0 (2018/05/14) action="URL_ENCODE" 追加
    752                else if( ACT_ENCODE2.equals( action ) ) {
    753                        rtn = StringUtil.urlEncode2( value );
    754                }
    755                // 6.9.7.0 (2018/05/14) action="URL_DECODE" 追加
    756                else if( ACT_DECODE.equals( action ) ) {
    757                        rtn = StringUtil.urlDecode( value );
    758                }
    759                // 6.4.1.2 (2016/01/22) TRIM アクションを追加。
    760                else if( ACT_TRIM.equals( action ) ) {
    761                        rtn = value.trim();
    762                }
    763                // 5.9.6.3 (2016/02/18)
    764                else if( ACT_MD5.equals( action ) ){
    765                        rtn = HybsCryptography.getMD5( value );
    766                }
    767                // 6.7.4.0 (2017/02/10)
    768                else if( ACT_TO_NUMBER.equals( action ) ){
    769                        final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    770                        for( int i=0; i<value.length(); i++ ) {
    771                                final char ch = value.charAt( i );
    772                                if( '-' == ch || '0'<=ch && ch<='9' ) {
    773                                        buf.append( ch );
    774                                }
    775                        }
    776                        rtn = buf.toString();
    777                }
    778                // 6.8.4.1 (2017/12/18)
    779                // 6.9.1.0 (2018/02/26) HMCSV アクションに、MAX,MIN,HMF を追加
    780                else if( ACT_HMCSV.equals( action ) && fromVal != null && fromVal.length()>0 ) {
    781                        final int fromNum = Integer.parseInt( StringUtil.deleteChar( fromVal , ':' ) );
    782                        final int toNum   = Integer.parseInt( StringUtil.deleteChar( toVal   , ':' ) );
    783
    784                        // value には、基準となる日付データ
    785                        final String fromS = HybsDateUtil.getDateFormat( "YMDHMS" , value, "HM" , fromNum );
    786                        final String toS   = HybsDateUtil.getDateFormat( "YMDHMS" , value, "HM" , toNum   );    // HM (時分形式の加算)
    787
    788                        final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    789                        buf.append( fromS );
    790                        final StringBuilder slbl = new StringBuilder( BUFFER_MIDDLE );  // 6.9.1.0 (2018/02/26) HMF を追加
    791//                      slbl.append( HybsDateUtil.getDateFormat( "HMF",fromS,null ) );  // null は、演算しない
    792                        slbl.append( HybsDateUtil.getDateFormat( "HMF",fromS ) );               // 6.9.2.1 (2018/03/12)
    793
    794                        final int skip = nval( skipVal , 60 );  // 初期値の間隔は、60分
    795                        int cnt = 1;
    796                        String timeS = fromS;
    797                        String lastS = timeS.substring( 0,8 );  // 日付部分の比較のための変数
    798                        while( timeS.compareTo( toS ) < 0 && cnt < MAX_CNT ) {          // 最大件数で制限しておきます。
    799                                timeS = HybsDateUtil.getDateFormat( "YMDHMS" , fromS , "MI" , skip*cnt );                       // MI (分の数値の加算)
    800                                cnt++;
    801
    802                                buf.append( separator ).append( timeS );                // 区切り文字で、連結
    803
    804                                if( lastS.equals( timeS.substring( 0,8 ) ) ) {  // 日付が同じ場合
    805//                                      slbl.append( separator ).append( HybsDateUtil.getDateFormat( "HMF",timeS,null ) );      // null は、演算しない
    806                                        slbl.append( separator ).append( HybsDateUtil.getDateFormat( "HMF",timeS ) );           // 6.9.2.1 (2018/03/12)
    807                                }
    808                                else {
    809//                                      slbl.append( separator ).append( HybsDateUtil.getDateFormat( "M/d HH:mm",timeS,null ) );        // null は、演算しない
    810                                        slbl.append( separator ).append( HybsDateUtil.getDateFormat( "M/d HH:mm",timeS ) );                     // 6.9.2.1 (2018/03/12)
    811                                }
    812                                lastS = timeS.substring( 0,8 ); // 日付部分の比較のための変数
    813                        }
    814                        rtn = buf.toString();
    815
    816                        if( cnt >= MAX_CNT ) {
    817                                final String errMsg = "valueタグで、action=\"HMCSV\" で、最大件数をオーバーしました。 MAX_CNT=[" + MAX_CNT + "]" + CR
    818                                                                + " fromVal=[" + fromVal + "] , toVal=[" + toVal + "] , skipVal=[" + skipVal + "] , value=[" + value + "]" + CR
    819                                                                + " rtn=[" + rtn + "]" ;
    820                                System.err.println( errMsg );
    821                        }
    822
    823                        // 6.9.1.0 (2018/02/26) MAX,MIN を追加
    824                        setObject( "MIN." + key , fromS );
    825                        setObject( "MAX." + key , toS   );
    826                        setObject( "HMF." + key , slbl.toString() );
    827                }
    828                // 6.9.1.0 (2018/02/26) HMCSV アクションで、from～to ではないケース
    829                // 6.9.8.0 (2018/05/28) FindBugs:null でないことがわかっている値の冗長な null チェック
    830//              else if( ACT_HMCSV.equals( action ) && value != null && value.contains( "," ) ){
    831                else if( ACT_HMCSV.equals( action ) && value.contains( "," ) ){         // valueは、nullチェック済み
    832                        final String[] ymdhms = StringUtil.csv2Array( value );
    833
    834                        final StringBuilder slbl = new StringBuilder( BUFFER_MIDDLE );  // 6.9.1.0 (2018/02/26) HMF を追加
    835
    836                        String lastS = ymdhms[0].substring( 0,8 );                      // 日付部分の比較のための変数
    837                        for( final String timeS : ymdhms ) {
    838                                if( lastS.equals( timeS.substring( 0,8 ) ) ) {  // 日付が同じ場合
    839//                                      slbl.append( separator ).append( HybsDateUtil.getDateFormat( "HMF",timeS,null ) );      // null は、演算しない
    840                                        slbl.append( separator ).append( HybsDateUtil.getDateFormat( "HMF",timeS ) );           // 6.9.2.1 (2018/03/12)
    841                                }
    842                                else {
    843//                                      slbl.append( separator ).append( HybsDateUtil.getDateFormat( "M/d HH:mm",timeS,null ) );        // null は、演算しない
    844                                        slbl.append( separator ).append( HybsDateUtil.getDateFormat( "M/d HH:mm",timeS ) );                     // 6.9.2.1 (2018/03/12)
    845                                }
    846                                lastS = timeS.substring( 0,8 ); // 日付部分の比較のための変数(前回の日付)
    847                        }
    848                        rtn = value;            // 元のvalue のまま、返します。
    849
    850                        // 6.9.1.0 (2018/02/26) MAX,MIN を追加
    851                        setObject( "MIN." + key , ymdhms[0] );
    852                        setObject( "MAX." + key , ymdhms[ymdhms.length-1] );
    853                        setObject( "HMF." + key , slbl.toString() );
    854                }
    855                // 5.10.4.0 (2018/10/05)
    856                else if( ACT_CRYPT_ENC.equals( action ) ) {
    857                        final HybsCryptography hc = new HybsCryptography(cryptKey);
    858                        rtn = hc.encrypt( value );
    859                }
    860                else if( ACT_CRYPT_DEC.equals( action ) ) {
    861                        final HybsCryptography hc = new HybsCryptography(cryptKey);
    862                        rtn = hc.decrypt( value );
    863                }
    864                // 7.2.6.1 (2020/07/17)
    865                else if( ACT_REQUEST.equals( action ) ) {
    866                        rtn = getRequestParameter( value );                     // setValue で変換された結果を、変換します。
    867                }
    868
    869                return rtn;
    870        }
    871
    872        /**
    873         * 指定のスコープの内部キャッシュ情報を、キーで登録します。
    874         *
    875         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    876         * @og.rev 3.5.4.0 (2003/11/25) APPENDアクションを有効にします。
    877         * @og.rev 3.5.6.5 (2004/08/09) APPEND時のセパレータを外部指定の変数を使用
    878         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    879         * @og.rev 5.2.2.0 (2010/11/01) ACT_SPLIT 追加
    880         * @og.rev 5.6.4.3 (2013/05/24) ACT_MAX_MIN アクションの追加
    881         * @og.rev 5.6.6.1 (2013/07/12) value が null の場合は、無視します。
    882         *
    883         * @param key           キー
    884         * @param value         値
    885         * @param action        アクション
    886         */
    887        private void setAttribute( final String key,final String value,final String action ) {
    888                if( key == null || key.isEmpty() ) {
    889                        final String errMsg = "key がセットされていません。"
    890                                                + " command=" + command + " , action=" + action
    891                                                + " , value=" + value ;                 // 5.1.8.0 (2010/07/01) errMsg 修正
    892                        throw new HybsSystemException( errMsg );
    893                }
    894
    895                // 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    896                // 5.6.6.1 (2013/07/12) value が null の場合は、無視します。
    897                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
    898                if( value == null ) {
    899                        setObject( key, null );                 // 5.6.6.1 (2013/07/12) value が null の場合
    900                }
    901                else {
    902                        if( ACT_APPEND.equals( action ) ) {
    903                                final String[] array = getRequestParameterValues( inValue );
    904                                setObject( key, StringUtil.array2line( array,separator ) );
    905                        }
    906                        // 5.2.2.0 (2010/11/01) ACT_SPLIT 追加
    907                        else if( ACT_SPLIT.equals( action ) )  {
    908                                final String[] array = value.split( separator );
    909                                setObject( key , array[0] );            // キー自体には、分割時の先頭の文字列を設定しておく。
    910                                for( int i=0; i<array.length; i++ ) {
    911                                        setObject( key + i , array[i] );
    912                                }
    913                        }
    914                        // 5.6.4.3 (2013/05/24) ACT_MAX_MIN アクションの追加
    915                        else if( ACT_MAX_MIN.equals( action ) )  {
    916                                final String[] array = value.split( separator );
    917
    918                                // command="SET" では、数字型としてのみ処理します。
    919                                double minNum = Double.MAX_VALUE ;
    920                                double maxNum = Double.MIN_VALUE ;
    921                                double sumNum = 0d ;
    922                                int    cntSum = 0;              // 平均計算に有効な件数
    923
    924                                for( int i=0; i<array.length; i++ ) {
    925                                        final String val = array[i].trim().replaceAll( ",","" );                // 数字型フォーマットのカンマを取り除く
    926                                        if( val.isEmpty() ) { continue; }               // ゼロ文字列の場合は、取り直し
    927
    928                                        final double tmp = Double.parseDouble( val );
    929                                        if( minNum > tmp ) { minNum = tmp; }
    930                                        if( maxNum < tmp ) { maxNum = tmp; }
    931                                        sumNum += tmp ;  cntSum++ ;
    932                                }
    933
    934                                // command="SET" の場合は、数字型の場合のみ使用します。
    935                                if( cntSum > 0 ) {
    936                                        final NumberFormat nf = NumberFormat.getInstance();
    937                                        nf.setGroupingUsed( false );                                    // カンマ編集なし
    938                                        nf.setMaximumFractionDigits(2);                                 // 最大小数部は２桁
    939                                        nf.setMinimumFractionDigits(0);                                 // できれば、整数表示
    940
    941                                        setObject( "MIN." + key,nf.format( minNum ) );          // Double.toString( minNum ) の代わり。
    942                                        setObject( "MAX." + key,nf.format( maxNum ) );
    943                                        setObject( "SUM." + key,nf.format( sumNum ) );
    944                                        setObject( "AVG." + key,nf.format( sumNum/cntSum ) );
    945                                }
    946                                else {
    947                                        setObject( "MIN." + key,nval( defaultVal , "" ) );
    948                                        setObject( "MAX." + key,nval( defaultVal , "" ) );
    949                                        setObject( "SUM." + key,nval( defaultVal , "" ) );
    950                                        setObject( "AVG." + key,nval( defaultVal , "" ) );
    951                                }
    952                        }
    953                        else {
    954                                setObject( key, actionExec( action,value ) );
    955                        }
    956                }
    957        }
    958
    959        /**
    960         * 指定のスコープの内部キャッシュ情報を、キーで取得します。
    961         *
    962         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    963         *
    964         * @param key           キー
    965         * @param action        アクション
    966         *
    967         * @return      キーに対する内部キャッシュ情報
    968         */
    969        private String getAttribute( final String key,final String action ) {
    970                if( key == null || key.isEmpty() ) {
    971                        final String errMsg = "key がセットされていません。"
    972                                                + " command=" + command + " , action=" + action;        // 5.1.8.0 (2010/07/01) errMsg 修正
    973                        throw new HybsSystemException( errMsg );
    974                }
    975
    976                String rtn = defaultVal;
    977                final Object obj = pageContext.findAttribute( key );
    978                if( obj != null ) { rtn = obj.toString(); }
    979
    980                return actionExec( action,rtn );
    981        }
    982
    983        /**
    984         * 指定のスコープの内部キャッシュ情報を削除します。
    985         *
    986         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    987         *
    988         * @param key           キー
    989         */
    990        private void removeAttribute( final String key ) {
    991                if( key == null || key.isEmpty() ) {
    992                        final String errMsg = "key がセットされていません。"
    993                                                + " command=" + command ;                       // 5.1.8.0 (2010/07/01) errMsg 修正
    994                        throw new HybsSystemException( errMsg );
    995                }
    996                removeObject( key );
    997        }
    998
    999        /**
    1000         * セッション/アプリケーションスコープのキャッシュ情報をクリアします。
    1001         *
    1002         * このクリアは、キーの前方一致で、大文字小文字の区別をせずにクリアします。
    1003         * また、キーが null の場合は、"X_" で始めるもの以外のすべての値をクリアします。
    1004         * また、Ｗｅｂエンジン内部で使用しているキーは、ここではクリアできません。
    1005         *
    1006         * @og.rev 3.1.0.1 (2003/03/26) クリアコマンドの追加。
    1007         * @og.rev 4.3.4.0 (2008/12/01) PageContextのスコープをクラス変数としてアクセス
    1008         *
    1009         * @param key           キー
    1010         */
    1011        private void clearAttribute( final String key ) {
    1012
    1013                String lowKey = null;
    1014                if( key != null ) { lowKey = key.toLowerCase(Locale.JAPAN); }
    1015
    1016                Enumeration<String> ekeys = pageContext.getAttributeNamesInScope( PageContext.APPLICATION_SCOPE );              // 4.3.3.6 (2008/11/15) Generics警告対応
    1017                while( ekeys.hasMoreElements() ) {
    1018                        final String ekey = ekeys.nextElement().toLowerCase(Locale.JAPAN);              // 4.3.3.6 (2008/11/15) Generics警告対応
    1019                        if( ! ekey.startsWith( "h_") && ! ekey.startsWith( "x_") &&                             // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
    1020                                ( lowKey == null || ekey.startsWith( key ) ) ) {
    1021                                        pageContext.removeAttribute( ekey, PageContext.APPLICATION_SCOPE ) ;
    1022                        }
    1023                }
    1024
    1025                ekeys = pageContext.getAttributeNamesInScope( PageContext.SESSION_SCOPE );
    1026                while( ekeys.hasMoreElements() ) {
    1027                        final String ekey = String.valueOf( ekeys.nextElement() ).toLowerCase(Locale.JAPAN);
    1028                        if( ! ekey.startsWith( "h_") && ! ekey.startsWith( "x_") &&                             // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
    1029                                ( lowKey == null || ekey.startsWith( key ) ) ) {
    1030                                        pageContext.removeAttribute( ekey, PageContext.SESSION_SCOPE ) ;
    1031                        }
    1032                }
    1033        }
    1034
    1035        /**
    1036         * 指定のスコープの内部キャッシュ情報を、指定のSQL文より作成します。
    1037         *
    1038         * @og.rev 3.1.0.1 (2003/03/26) 引数を与えて処理する様に変更する。
    1039         * @og.rev 3.2.4.0 (2003/06/12) マルチデータ(複数件検索)を使用するかしないか。
    1040         * @og.rev 3.8.6.0 (2006/08/07) nullSet="true"(初期値)の時は、検索結果がゼロ件時に "" をセットする。
    1041         * @og.rev 3.8.9.2 (2007/07/28) action="ROW_APPEND" 追加
    1042         * @og.rev 4.3.7.5 (2009/07/13) ACT_LIST、ACT_ALL_LIST アクションの追加
    1043         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    1044         * @og.rev 5.5.0.3 (2012/03/12) ACT_MAP アクションの追加
    1045         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    1046         * @og.rev 6.2.4.2 (2015/05/29) ACT_MAPOBJ アクションの追加
    1047         * @og.rev 6.2.6.0 (2015/06/19) キーの判定に、isEmpty() が漏れていた。
    1048         * @og.rev 6.4.2.1 (2016/02/05) ACT_MAPOBJ アクションのMapを、TreeMap から LinkedHashMap に変更。
    1049         * @og.rev 6.4.4.2 (2016/04/01) StringBuilderの代わりに、OgBuilderを使用する。
    1050         * @og.rev 6.9.0.2 (2018/02/13) ACT_MAP,(ACT_ALL_MAP) で、第３カラム以降も、ｷｰ + '_番号(1～)' で、ｷｰを作成します。
    1051         * @og.rev 7.2.6.1 (2020/07/17) ACT_REQUEST追加
    1052         *
    1053         * @param table DBTableModelオブジェクト
    1054         */
    1055        private void setSQLAttribute( final DBTableModel table ) {
    1056                if( table == null ) {           // 3.8.6.0 (2006/08/07)
    1057                        return;
    1058                }
    1059
    1060                final int clmCnt = table.getColumnCount();
    1061                final int rowCnt = table.getRowCount();
    1062                String sqlkey ;
    1063                String sqlval ;
    1064                String sufix = "";
    1065
    1066                if( ACT_ROW_APPEND.equals( action ) ) {
    1067                        final OgBuilder buf = new OgBuilder();
    1068                        for( int clmNo=0; clmNo<clmCnt; clmNo++ ) {
    1069                                // 6.4.4.2 (2016/04/01)
    1070                                final int clm = clmNo;                  // ラムダ式の引数に使えるのは、final変数のみ。
    1071                                buf.clear();
    1072                                buf.appendRoop( 0,rowCnt,separator
    1073                                                                        , row -> table.getValue( row, clm ) );
    1074                                sqlkey = table.getColumnName( clm );
    1075                                setObject( sqlkey , buf.toString() );
    1076                        }
    1077                }
    1078                // 4.3.7.5 (2009/07/13) ACT_LIST、ACT_ALL_LIST アクションの追加
    1079                else if( ACT_LIST.equals( action ) ) {
    1080                        for( int clm=0; clm<clmCnt; clm++ ) {
    1081                                final ArrayList<String> list = new ArrayList<>();
    1082                                for( int row=0; row<rowCnt; row++ ) {
    1083                                        sqlval = table.getValue( row, clm );
    1084                                        list.add( sqlval );
    1085                                }
    1086                                sqlkey = table.getColumnName( clm );
    1087                                setObject( sqlkey , list );
    1088                        }
    1089                }
    1090                // 5.5.0.3 (2012/03/12) ACT_MAP アクションの追加
    1091                else if( ACT_MAP.equals( action )  ) {
    1092                        if( clmCnt < 2 ) {
    1093                                final String errMsg = "action=MAP 時には、カラムは、２つ以上必要です。カラム数=[" + clmCnt + "]";
    1094                                throw new IllegalArgumentException( errMsg );
    1095                        }
    1096                        for( int row=0; row<rowCnt; row++ ) {
    1097                                sqlkey = table.getValue( row, 0 );                      // 0番目カラムがキー
    1098                                sqlval = table.getValue( row, 1 );                      // 1番目カラムが値
    1099                                setObject( sqlkey , sqlval );
    1100
    1101                                // 6.9.0.2 (2018/02/13) ACT_MAP,(ACT_ALL_MAP) で、第３カラム以降も、ｷｰ + '_番号(1～)' で、ｷｰを作成します。
    1102                                for( int clm=2; clm<clmCnt; clm++ ) {
    1103                                        final String keyN = sqlkey + "_" + (clm-1);             // 第３カラムは、ｷｰ + '_1' になります。
    1104                                        sqlval = table.getValue( row, clm );                    // N番目カラムの値
    1105                                        setObject( keyN , sqlval );
    1106                                }
    1107                        }
    1108                }
    1109                // 6.2.4.2 (2015/05/29) ACT_MAPOBJ アクションの追加
    1110                else if( ACT_MAPOBJ.equals( action )  ) {
    1111                        if( clmCnt < 2 ) {
    1112                                final String errMsg = "action=MAPOBJ 時には、カラムは、２つ以上必要です。カラム数=[" + clmCnt + "]";
    1113                                throw new IllegalArgumentException( errMsg );
    1114                        }
    1115                        if( key == null || key.isEmpty() ) {                    // 6.2.6.0 (2015/06/19)
    1116                                key = table.getColumnName( 0 );                         // key が指定されていない場合は、最初のカラム名
    1117                        }
    1118                        final Map<String,String> mapObj = new LinkedHashMap<>();        // 6.4.2.1 (2016/02/05)
    1119
    1120                        for( int row=0; row<rowCnt; row++ ) {
    1121                                sqlkey = table.getValue( row, 0 );                      // 0番目カラムがMapのキー
    1122                                sqlval = table.getValue( row, 1 );                      // 1番目カラムがMapの値
    1123                                mapObj.put( sqlkey,sqlval );
    1124                        }
    1125                        setObject( key , mapObj );
    1126                }
    1127                // 7.2.6.1 (2020/07/17) SQL処理なので、ループで判断させずにactionで分けておきます。
    1128                else if( ACT_REQUEST.equals( action ) ) {
    1129                        for( int row=0; row<rowCnt; row++ ) {
    1130                                if( useMultiRows ) { sufix = String.valueOf( row ) ; }
    1131                                for( int clm=0; clm<clmCnt; clm++ ) {
    1132                                        sqlkey = table.getColumnName( clm );
    1133                                        sqlval = table.getValue( row, clm );
    1134                                        sqlval = getRequestParameter( sqlval );                 // SQLで取得した値を、変換します。
    1135                                        setObject( sqlkey + sufix, sqlval );
    1136                                }
    1137                                if( ! useMultiRows ) { break; }
    1138                        }
    1139                }
    1140                else {
    1141                        // 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    1142                        if( rowCnt == 0 ) {
    1143                                if( useMultiRows ) { sufix = "0" ; }
    1144                                for( int clm=0; clm<clmCnt; clm++ ) {
    1145                                        sqlkey = table.getColumnName( clm );
    1146                                        sqlval = "";
    1147                                        setObject( sqlkey + sufix, sqlval );
    1148                                }
    1149                        }
    1150                        else {
    1151                                for( int row=0; row<rowCnt; row++ ) {
    1152                                        if( useMultiRows ) { sufix = String.valueOf( row ) ; }
    1153                                        for( int clm=0; clm<clmCnt; clm++ ) {
    1154                                                sqlkey = table.getColumnName( clm );
    1155                                                sqlval = table.getValue( row, clm );
    1156                                                setObject( sqlkey + sufix, sqlval );
    1157                                        }
    1158                                        if( ! useMultiRows ) { break; }
    1159                                }
    1160                        }
    1161                }
    1162        }
    1163
    1164        /**
    1165         * 指定のSQL文の結果を文字列として画面に出力します。
    1166         * 画面に出力される項目は、1項目だけで2項目以降は無視されます。
    1167         *
    1168         * @og.rev 5.1.7.0 (2010/06/01) SQLGET対応
    1169         * @og.rev 6.4.4.2 (2016/04/01) StringBuilderの代わりに、OgBuilderを使用する。
    1170         *
    1171         * @param table DBTableModelオブジェクト
    1172         *
    1173         * @return SQL文の結果文字列
    1174         */
    1175        private String getSQLAttribute( final DBTableModel table ) {
    1176                if( table == null ) {           // 3.8.6.0 (2006/08/07)
    1177                        return "";
    1178                }
    1179
    1180                final int rowCnt = table.getRowCount();
    1181                final String rtn;
    1182                if( ACT_ROW_APPEND.equals( action ) ) {
    1183                        // 6.4.4.2 (2016/04/01)
    1184                        rtn = new OgBuilder()
    1185                                        .appendRoop( 0,rowCnt,separator
    1186                                                                        , row -> table.getValue( row, 0 ) )
    1187                                        .toString();
    1188                }
    1189                else if( rowCnt == 0 ) {
    1190                        rtn = "";
    1191                }
    1192                else {
    1193                        rtn = table.getValue( 0, 0 );
    1194                }
    1195
    1196                return rtn;
    1197        }
    1198
    1199        /**
    1200         * 指定のスコープの内部キャッシュ情報に、DBTableModel の選択された値を登録します。
    1201         *
    1202         * 複数選択行が存在する場合は、先頭行を処理します。ただし、action="APPEND"の
    1203         * 場合は、separator属性で指定された文字を使用して、連結します。
    1204         *
    1205         * @og.rev 3.1.0.1 (2003/03/26) 新規作成
    1206         * @og.rev 3.5.6.5 (2004/08/09) ACT_APPEND 時の処理変更
    1207         * @og.rev 3.6.1.0 (2005/01/05) ACT_ALL_APPEND アクションの追加
    1208         * @og.rev 4.3.7.5 (2009/07/13) ACT_LIST、ACT_ALL_LIST アクションの追加
    1209         * @og.rev 5.1.6.0 (2010/05/01) ALL_APPENDで選択行がない場合に処理されないバグを修正
    1210         * @og.rev 5.5.0.3 (2012/03/12) ACT_MAP アクションの追加
    1211         * @og.rev 5.6.4.3 (2013/05/24) ACT_MAX_MIN,ACT_ALL_MAX_MIN アクションの追加
    1212         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    1213         * @og.rev 6.2.4.2 (2015/05/29) ACT_MAPOBJ アクションの追加
    1214         * @og.rev 6.4.2.1 (2016/02/05) ACT_MAPOBJ アクションのMapを、TreeMap から LinkedHashMap に変更。
    1215         * @og.rev 6.4.4.2 (2016/04/01) StringBuilderの代わりに、OgBuilderを使用する。
    1216         * @og.rev 6.4.4.2 (2016/04/01) contains 判定を行う新しいメソッドを使用します。
    1217         * @og.rev 6.4.6.0 (2016/05/27) isNumber , isDate 追加。
    1218         *
    1219         * @param table         DBTableModelオブジェクト
    1220         * @param key           キー
    1221         * @param action        アクション
    1222         */
    1223        private void setTableAttribute( final DBTableModel table,final String key,final String action ) {
    1224                if( table == null || table.getRowCount() == 0 || table.getColumnCount() == 0 ) { return ; }
    1225
    1226                final int[] rowNo = getParameterRows();
    1227                // 5.1.6.0 (2010/05/01)
    1228                if( rowNo.length == 0 ) { return; }                             // 5.6.4.3 (2013/05/24) tmpSelectedAll 属性を追加したので、0件判定が使える。
    1229
    1230                final String[] keys ;
    1231                if( key == null || key.isEmpty() ) {
    1232                        keys = table.getNames();
    1233                }
    1234                else {
    1235                        keys = new String[] { key } ;
    1236                }
    1237
    1238                // 5.6.4.3 (2013/05/24) tmpSelectedAll で、ロジックの共通化
    1239                if( ACT_APPEND.equals( action ) ) {
    1240                        final OgBuilder buf = new OgBuilder();
    1241                        // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    1242                        for( final String ky : keys ) {
    1243                                final int clm = table.getColumnNo( ky );
    1244//                      for( int i=0; i<keys.length; i++ ) {
    1245//                              final int clm = table.getColumnNo( keys[i] );
    1246                                // 6.4.4.2 (2016/04/01)
    1247                                buf.clear();
    1248                                buf.appendRoop( 0,rowNo.length,separator
    1249                                                                        , j -> table.getValue( rowNo[j],clm ) );
    1250                                setObject( ky,buf.toString() );
    1251//                              setObject( keys[i],buf.toString() );
    1252                        }
    1253                }
    1254
    1255                // 5.5.0.3 (2012/03/12) ACT_MAP アクションの追加
    1256                else if( ACT_MAP.equals( action ) ) {
    1257                        int keyClm = table.getColumnNo( key   ,false );
    1258                        int valClm = table.getColumnNo( value ,false );
    1259
    1260                        if( keyClm < 0 ) { keyClm = 0; }        // キーとなるカラムが指定されていない場合は、最初のカラム
    1261                        if( valClm < 0 ) { valClm = 1; }        // 値となるカラムが指定されていない場合は、２番目のカラム
    1262
    1263                        // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    1264                        for( final int row : rowNo ) {
    1265                                final String mapkey = table.getValue( row, keyClm );
    1266                                final String mapval = table.getValue( row, valClm );
    1267                                setObject( mapkey , mapval );
    1268                        }
    1269//                      for( int j=0; j<rowNo.length; j++ ) {
    1270//                              final String mapkey = table.getValue( rowNo[j], keyClm );
    1271//                              final String mapval = table.getValue( rowNo[j], valClm );
    1272//                              setObject( mapkey , mapval );
    1273//                      }
    1274                }
    1275
    1276                // 6.2.4.2 (2015/05/29) ACT_MAPOBJ アクションの追加
    1277                else if( ACT_MAPOBJ.equals( action )  ) {
    1278                        int keyClm = table.getColumnNo( key   ,false );
    1279                        int valClm = table.getColumnNo( value ,false );
    1280
    1281                        if( keyClm < 0 ) { keyClm = 0; }        // キーとなるカラムが指定されていない場合は、最初のカラム
    1282                        if( valClm < 0 ) { valClm = 1; }        // 値となるカラムが指定されていない場合は、２番目のカラム
    1283
    1284                        final Map<String,String> mapObj = new LinkedHashMap<>();        // 6.4.2.1 (2016/02/05)
    1285                        // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    1286                        for( final int row : rowNo ) {
    1287                                final String mapkey = table.getValue( row, keyClm );
    1288                                final String mapval = table.getValue( row, valClm );
    1289                                mapObj.put( mapkey,mapval );
    1290                        }
    1291//                      for( int j=0; j<rowNo.length; j++ ) {
    1292//                              final String mapkey = table.getValue( rowNo[j], keyClm );
    1293//                              final String mapval = table.getValue( rowNo[j], valClm );
    1294//                              mapObj.put( mapkey,mapval );
    1295//                      }
    1296                        setObject( key , mapObj );
    1297                }
    1298
    1299                // 4.3.7.5 (2009/07/13) ACT_LIST アクションの追加
    1300                else if( ACT_LIST.equals( action ) ) {
    1301                        // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    1302                        for( final String ky : keys ) {
    1303                                final int clm = table.getColumnNo( ky );
    1304//                      for( int i=0; i<keys.length; i++ ) {
    1305//                              final int clm = table.getColumnNo( keys[i] );
    1306                                final ArrayList<String> list = new ArrayList<>();
    1307                                // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    1308                                for( final int row : rowNo ) {
    1309                                        list.add( table.getValue( row,clm ) );
    1310                                }
    1311//                              for( int j=0; j<rowNo.length; j++ ) {
    1312//                                      list.add( table.getValue( rowNo[j],clm ) );
    1313//                              }
    1314                                setObject( key,list );
    1315//                              setObject( keys[i],list );
    1316                        }
    1317                }
    1318
    1319                // 5.6.4.3 (2013/05/24) ACT_MAX_MIN アクションの追加
    1320                else if( ACT_MAX_MIN.equals( action ) ) {
    1321                        NumberFormat nf = null;
    1322                        // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    1323                        for( final String ky : keys ) {
    1324                                final int clm = table.getColumnNo( ky );
    1325//                      for( int i=0; i<keys.length; i++ ) {
    1326//                              final int clm = table.getColumnNo( keys[i] );
    1327                                final DBColumn clmObj = table.getDBColumn( clm );
    1328                                // 6.4.4.2 (2016/04/01) contains 判定を行う新しいメソッドを使用します。
    1329                                final boolean numFlag = clmObj.isNumberType();          // 6.4.6.0 (2016/05/27) 数字型:true
    1330
    1331                                String minVal = null ;
    1332                                String maxVal = null ;
    1333                                double minNum = Double.MAX_VALUE ;
    1334                                double maxNum = Double.MIN_VALUE ;
    1335                                double sumNum = 0d ;
    1336                                int    cntSum = 0;              // 平均計算に有効な件数
    1337
    1338                                // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    1339                                for( final int row : rowNo ) {
    1340                                        final String val = table.getValue( row,clm );
    1341//                              for( int j=0; j<rowNo.length; j++ ) {
    1342//                                      final String val = table.getValue( rowNo[j],clm );
    1343                                        if( val != null && val.length() > 0 ) {
    1344                                                // 数字として比較
    1345                                                if( numFlag ) {
    1346                                                        final double tmp = Double.parseDouble( val );
    1347                                                        if( minNum > tmp ) { minNum = tmp; minVal = val; }
    1348                                                        if( maxNum < tmp ) { maxNum = tmp; maxVal = val; }
    1349                                                        sumNum += tmp ;  cntSum++ ;
    1350                                                }
    1351                                                else {
    1352                                                        // 文字列として比較
    1353                                                        if( minVal == null || minVal.compareTo( val ) > 0 ) { minVal = val; }   // 最初のデータは、必ずセットする。
    1354                                                        if( maxVal == null || maxVal.compareTo( val ) < 0 ) { maxVal = val; }   // 最初のデータは、必ずセットする。
    1355                                                }
    1356                                        }
    1357                                }
    1358                                if( minVal == null ) { minVal = nval( defaultVal , "" ); }              // 最後まで値が決まらなければ、""(空文字列) にする。
    1359                                if( maxVal == null ) { maxVal = nval( defaultVal , "" ); }              // 最後まで値が決まらなければ、""(空文字列) にする。
    1360                                setObject( "MIN." + ky,minVal );
    1361                                setObject( "MAX." + ky,maxVal );
    1362//                              setObject( "MIN." + keys[i],minVal );
    1363//                              setObject( "MAX." + keys[i],maxVal );
    1364
    1365                                // SUM と AVG は、数字型の場合のみセットします。
    1366                                if( cntSum > 0 ) {
    1367                                        if( nf == null ) {
    1368                                                nf = NumberFormat.getInstance();
    1369                                                nf.setGroupingUsed( false );                                    // カンマ編集なし
    1370                                                nf.setMaximumFractionDigits(2);                                 // 最大小数部は２桁
    1371                                                nf.setMinimumFractionDigits(0);                                 // できれば、整数表示
    1372                                        }
    1373                                        setObject( "SUM." + ky,nf.format( sumNum ) );           // Double.toString( sumNum ) の代わり。
    1374                                        setObject( "AVG." + ky,nf.format( sumNum/cntSum ) );
    1375//                                      setObject( "SUM." + keys[i],nf.format( sumNum ) );              // Double.toString( sumNum ) の代わり。
    1376//                                      setObject( "AVG." + keys[i],nf.format( sumNum/cntSum ) );
    1377                                }
    1378                                else {
    1379                                        setObject( "SUM." + ky,nval( defaultVal , "" ) );
    1380                                        setObject( "AVG." + ky,nval( defaultVal , "" ) );
    1381//                                      setObject( "SUM." + keys[i],nval( defaultVal , "" ) );
    1382//                                      setObject( "AVG." + keys[i],nval( defaultVal , "" ) );
    1383                                }
    1384                        }
    1385                }
    1386                else {
    1387                        // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    1388                        for( final String ky : keys ) {
    1389                                final int clm = table.getColumnNo( ky );
    1390                                setAttribute( key,table.getValue( rowNo[0],clm ),action );
    1391                        }
    1392//                      for( int i=0; i<keys.length; i++ ) {
    1393//                              final int clm = table.getColumnNo( keys[i] );
    1394//                              setAttribute( keys[i],table.getValue( rowNo[0],clm ),action );
    1395//                      }
    1396                }
    1397        }
    1398
    1399        /**
    1400         * DBTableModel の選択された値を取得します。
    1401         *
    1402         * 複数選択行が存在する場合は、先頭行を処理します。ただし、action="APPEND"の
    1403         * 場合は、separator属性で指定された文字を使用して、連結します。
    1404         *
    1405         * @og.rev 3.1.0.1 (2003/03/26) 新規作成
    1406         * @og.rev 3.5.6.5 (2004/08/09) ACT_APPEND 時の処理変更
    1407         * @og.rev 3.6.1.0 (2005/01/05) ACT_ALL_APPEND アクションの追加
    1408         * @og.rev 5.1.6.0 (2010/05/01) ALL_APPENDで選択行がない場合に処理されないバグを修正
    1409         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    1410         * @og.rev 6.4.4.2 (2016/04/01) StringBuilderの代わりに、OgBuilderを使用する。
    1411         *
    1412         * @param       table   DBTableModelオブジェクト
    1413         * @param       key             キー
    1414         * @param       action  アクション
    1415         *
    1416         * @return      DBTableModelの選択された値
    1417         */
    1418        private String getTableAttribute( final DBTableModel table,final String key,final String action ) {
    1419                if( table == null ) {
    1420                        final String errMsg = "table がセットされていません。"
    1421                                                + " command=" + command + " , action=" + action
    1422                                                + " , key=" + key ;                     // 5.1.8.0 (2010/07/01) errMsg 修正
    1423                        throw new HybsSystemException( errMsg );
    1424                }
    1425
    1426                if( key == null || key.isEmpty() ) {
    1427                        final String errMsg = "key がセットされていません。"
    1428                                                + " command=" + command + " , action=" + action;                        // 5.1.8.0 (2010/07/01) errMsg 修正
    1429                        throw new HybsSystemException( errMsg );
    1430                }
    1431
    1432                final int[] rowNo = getParameterRows();
    1433                // 5.1.6.0 (2010/05/01)
    1434                if( rowNo.length == 0 ) { return "" ; }                         // 5.6.4.3 (2013/05/24) tmpSelectedAll 属性を追加したので、0件判定が使える。
    1435
    1436                // 3.6.1.0 (2005/01/05) ACT_ALL_APPEND アクションの追加
    1437                final int clm = table.getColumnNo( key );
    1438                if( ACT_APPEND.equals( action ) ) {
    1439                        // 6.4.4.2 (2016/04/01)
    1440                        return new OgBuilder()
    1441                                        .appendRoop( 0,rowNo.length,separator
    1442                                                                        , j -> table.getValue( rowNo[j],clm ) )
    1443                                        .toString();
    1444                }
    1445                else {
    1446                        return actionExec( action,table.getValue( rowNo[0],clm ) );
    1447                }
    1448        }
    1449
    1450        /**
    1451         * 指定のスコープの内部キャッシュ情報に、DBTableModel の選択された値を登録します。
    1452         *
    1453         * これは、key で指定したカラムの値をキーとして、value で指定したカラムの値を
    1454         * value 値として設定します。
    1455         * setTableAttribute が、カラム(横持ち)データを処理するのに対して、
    1456         * ロウ(縦持ち)データを処理することが出来ます。
    1457         *
    1458         * @og.rev 3.1.0.1 (2003/03/26) 新規作成
    1459         * @og.rev 3.3.3.3 (2003/08/06) key 情報がデータの値になっていた。バグ修正。
    1460         * @og.rev 3.5.6.5 (2004/08/09) ACT_APPEND 時の処理変更
    1461         * @og.rev 6.4.4.2 (2016/04/01) StringBuilderの代わりに、OgBuilderを使用する。
    1462         *
    1463         * @param table         DBTableModelオブジェクト
    1464         * @param key           キー
    1465         * @param value         値
    1466         * @param action        アクション
    1467         */
    1468        private void setKeyTableAttribute( final DBTableModel table,final String key,final String value,final String action ) {
    1469                if( table == null ) { return ; }
    1470
    1471                if( key == null || key.isEmpty() ) {
    1472                        final String errMsg = "key がセットされていません。"
    1473                                                + " command=" + command + " , action=" + action
    1474                                                + " , value=" + value ;                 // 5.1.8.0 (2010/07/01) errMsg 修正
    1475                        throw new HybsSystemException( errMsg );
    1476                }
    1477
    1478                final int[] rowNo = getParameterRows();
    1479                if( rowNo.length == 0 ) { return ; }
    1480
    1481                final int[] valClm ;
    1482                if( value == null || value.isEmpty() ) {
    1483                        final String[] vals = table.getNames();
    1484                        valClm = new int[vals.length];
    1485                        for( int i=0; i<vals.length; i++ ) {
    1486                                valClm[i] = table.getColumnNo( vals[i] );
    1487                        }
    1488                }
    1489                else {
    1490                        valClm = new int[] { table.getColumnNo( value ) } ;
    1491                }
    1492
    1493                // 6.4.4.2 (2016/04/01)
    1494                final OgBuilder buf = new OgBuilder();
    1495                for( int j=0; j<rowNo.length; j++ ) {
    1496                        final String rowKey = key + j ;
    1497                        final int rNo = rowNo[j];
    1498                        if( ACT_APPEND.equals( action ) ) {
    1499                                buf.clear();
    1500                                buf.appendRoop( 0,valClm.length,separator
    1501                                                                        , i -> table.getValue( rNo,valClm[i] ) );
    1502                                setObject( rowKey,buf.toString() );
    1503                        }
    1504                        else {
    1505                                setAttribute( rowKey,table.getValue( rNo,valClm[0] ),action );
    1506                        }
    1507                }
    1508        }
    1509
    1510        /**
    1511         * 指定のスコープに登録されているパラメータ（アトリビュート）を返します。
    1512         *
    1513         * 従来は、debug="true" で出力していましたが、情報量が多すぎるため、
    1514         * それぞれ指定することが出来るようにします。
    1515         *
    1516         * @og.rev 6.7.7.2 (2017/04/14) command に、DEBUG 追加
    1517         *
    1518         * @return      scopeに応じた値
    1519         */
    1520        private String scopeAttributePrint() {
    1521                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
    1522                        .append( "====================================" ).append( CR );
    1523
    1524                if( "application".equals( scope ) ) {
    1525                        rtn.append( "APPLICATION_SCOPE:" ).append( CR );
    1526
    1527                        final Enumeration<String> ekeys = pageContext.getAttributeNamesInScope( PageContext.APPLICATION_SCOPE );        // 4.3.3.6 (2008/11/15) Generics警告対応
    1528                        while( ekeys.hasMoreElements() ) {
    1529                                final String ekey = ekeys.nextElement();                // 4.3.3.6 (2008/11/15) Generics警告対応
    1530                                // 6.0.2.5 (2014/10/31) char を append する。
    1531                                rtn.append( "  key=[" ).append( ekey )
    1532                                        .append( "] value=[" )
    1533                                        .append( pageContext.getAttribute( ekey,PageContext.APPLICATION_SCOPE ) )
    1534                                        .append( ']' ).append( CR );
    1535                        }
    1536                }
    1537
    1538                if( "session".equals( scope ) ) {
    1539                        rtn.append( "SESSION_SCOPE:" ).append( CR );
    1540                        final Enumeration<String> ekeys = pageContext.getAttributeNamesInScope( PageContext.SESSION_SCOPE );
    1541                        while( ekeys.hasMoreElements() ) {
    1542                                final String ekey = String.valueOf( ekeys.nextElement() );
    1543                                // 6.0.2.5 (2014/10/31) char を append する。
    1544                                rtn.append( "  key=[" ).append( ekey )
    1545                                        .append( "] value=[" )
    1546                                        .append( pageContext.getAttribute( ekey,PageContext.SESSION_SCOPE ) )
    1547                                        .append( ']' ).append( CR );
    1548                        }
    1549                }
    1550
    1551                if( "request".equals( scope ) ) {
    1552                        rtn.append( "REQUEST_SCOPE:" ).append( CR );
    1553                        final Enumeration<String> ekeys = pageContext.getAttributeNamesInScope( PageContext.REQUEST_SCOPE );
    1554                        while( ekeys.hasMoreElements() ) {
    1555                                final String ekey = String.valueOf( ekeys.nextElement() );
    1556                                // 6.0.2.5 (2014/10/31) char を append する。
    1557                                rtn.append( "  key=[" ).append( ekey )
    1558                                        .append( "] value=[" )
    1559                                        .append( pageContext.getAttribute( ekey,PageContext.REQUEST_SCOPE ) )
    1560                                        .append( ']' ).append( CR );
    1561                        }
    1562                }
    1563
    1564                if( "page".equals( scope ) ) {
    1565                        rtn.append( "PAGE_SCOPE:" ).append( CR );
    1566                        final Enumeration<String> ekeys = pageContext.getAttributeNamesInScope( PageContext.PAGE_SCOPE );
    1567                        while( ekeys.hasMoreElements() ) {
    1568                                final String ekey = String.valueOf( ekeys.nextElement() );
    1569                                // 6.0.2.5 (2014/10/31) char を append する。
    1570                                rtn.append( "  key=[" ).append( ekey )
    1571                                        .append( "] value=[" )
    1572                                        .append( pageContext.getAttribute( ekey,PageContext.PAGE_SCOPE ) )
    1573                                        .append( ']' ).append( CR );
    1574                        }
    1575                }
    1576
    1577                rtn.append( "====================================" ).append( CR );
    1578
    1579                return rtn.toString();
    1580        }
    1581
    1582        /**
    1583         * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を処理の対象とします。
    1584         *
    1585         * action="FIRST" 処理と、tmpSelectedAll 属性追加に伴う処理を、Override します。
    1586         *
    1587         * @og.rev 3.1.0.1 (2003/03/26) 新規作成
    1588         * @og.rev 4.0.0.0 (2005/01/31) メイン処理を、super class で対応
    1589         * @og.rev 3.8.0.4 (2005/08/08) action="FIRST" 機能の追加
    1590         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性の追加に伴い、全件選択状態のデータを作成します。
    1591         *
    1592         * @return      選択行の配列
    1593         * @og.rtnNotNull
    1594         */
    1595        @Override
    1596        protected int[] getParameterRows() {
    1597                final int[] rowNo ;
    1598                // 3.8.0.4 (2005/08/08) action="FIRST" 機能の追加
    1599                if( ACT_FIRST.equals( action ) ) {
    1600                        rowNo = new int[] { 0 };
    1601                }
    1602                // 5.6.4.3 (2013/05/24) tmpSelectedAll 属性の追加
    1603                else if( tmpSelectedAll ) {
    1604                        final int rowCnt = table.getRowCount();
    1605                        rowNo = new int[ rowCnt ];
    1606                        for( int i=0; i<rowCnt; i++ ) {
    1607                                rowNo[i] = i;
    1608                        }
    1609                }
    1610                else {
    1611                        rowNo = super.getParameterRows() ;
    1612                }
    1613                return rowNo ;
    1614        }
    1615
    1616        /**
    1617         * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
    1618         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    1619         *
    1620         * @og.tag
    1621         * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に
    1622         * 渡す場合に、通常は、session を利用します。その場合の登録キーです。
    1623         * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、
    1624         * この tableId 属性を利用して、メモリ空間を分けます。
    1625         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    1626         *
    1627         * @param       id テーブルID (sessionに登録する時のID)
    1628         */
    1629        public void setTableId( final String id ) {
    1630                tableId   = nval( getRequestParameter( id ),tableId );
    1631        }
    1632
    1633        /**
    1634         * 【TAG】コマンド (SET,GET,REMOVE,SQL,SETTBL,GETTBL,KEYTBL,CLEAR,SETMEM)をセットします(初期値:SET)。
    1635         *
    1636         * @og.tag
    1637         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    1638         * フィールド定数値のいづれかを、指定できます。
    1639         * 何も設定されない、または、null の場合は、"SET" が初期値にセットされます。
    1640         *
    1641         * CLEAR 以外のすべての処理は、指定のスコープの内部キャッシュ情報に対して行われます。
    1642         * <table class="plain">
    1643         *   <caption>コマンド 一覧</caption>
    1644         *   <tr><th>command </th><th>名称          </th><th>機能</th></tr>
    1645         *   <tr><td>SET    </td><td>セット         </td><td>指定のキーに、value値を登録します。</td></tr>
    1646         *   <tr><td>GET    </td><td>ゲット         </td><td>指定のキーの値を画面に出力します。</td></tr>
    1647         *   <tr><td>REMOVE </td><td>リムーブ       </td><td>指定のキーの値を削除します。</td></tr>
    1648         *   <tr><td>CLEAR  </td><td>クリア         </td><td>セッション/アプリケーションスコープのキャッシュ情報をクリアします。</td></tr>
    1649         *   <tr><td>SQL    </td><td>ＳＱＬ         </td><td>指定のSQL文の実行結果を、カラム名をキーとして設定します。(useMultiRows="false" 時は、最初のデータを使用)</td></tr>
    1650         *   <tr><td>SQLGET </td><td>ＳＱＬゲット   </td><td>指定のSQL文の実行結果を、画面に出力します。(2項目以降は無視されます)。</td></tr>
    1651         *   <tr><td>SETTBL </td><td>セットテーブル </td><td>指定のキーに、DBTableModel の選択されたカラム(横持ち)の値を登録します。</td></tr>
    1652         *   <tr><td>GETTBL </td><td>ゲットテーブル </td><td>指定のキーに、DBTableModel の選択されたカラム(横持ち)の値を画面に出力します。</td></tr>
    1653         *   <tr><td>KEYTBL </td><td>キーテーブル   </td><td>指定のキーに、DBTableModel の選択されたロウ(縦持ち)の値を登録します。</td></tr>
    1654         *   <tr><td>SETMEM </td><td>セットメモリ   </td><td>指定のキーに、value値を内部キャッシュに登録します。</td></tr>
    1655         *   <tr><td>DEBUG  </td><td>デバッグ       </td><td>指定のスコープに登録されているパラメータ（アトリビュート）を返します。</td></tr>
    1656         * </table>
    1657         *
    1658         * @og.rev 3.1.0.1 (2003/03/26) 指定のコマンド以外は、エラーとするように変更。
    1659         * @og.rev 3.5.6.2 (2004/07/05) 文字列の連結にStringBuilderを使用します。
    1660         * @og.rev 6.3.4.0 (2015/08/01) Arrays.toString から String.join に置き換え。
    1661         * @og.rev 6.7.7.2 (2017/04/14) command に、DEBUG 追加
    1662         *
    1663         * @param       cmd コマンド (public static final 宣言されている文字列)
    1664         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ValueTag.CMD_GET">コマンド定数</a>
    1665         */
    1666        public void setCommand( final String cmd ) {
    1667                command = nval( getRequestParameter( cmd ),command ).toUpperCase(Locale.JAPAN);
    1668
    1669                if( !check( command, COMMAND_SET ) ) {
    1670                        final String errMsg = "指定のコマンドは実行できません。コマンドエラー" + CR
    1671                                                                + "command=[" + command + "] "                                                  + CR
    1672                                                                + "commandList=[" + String.join( ", " , COMMAND_SET ) + "]" ;
    1673                        throw new HybsSystemException( errMsg );
    1674                }
    1675        }
    1676
    1677        /**
    1678         * 【TAG】アクション(UPPER,LOWER,MESSAGE,APPEND,ALL_APPEND,MAP,ALL_MAP,MAPOBJ,ALL_MAPOBJ,LIST,ALL_LIST,DAY_WEEK,
    1679         *        MERGE,FIRST,ROW_APPEND,REPLACE,INDEX_OF,LASTINDEX_OF,SUBSTR,LENGTH,SPLIT,MAX_MIN,ALL_MAX_MIN,EXEC,CASE,ESCAPE,TRIM,MD5)をセットします。
    1680         *
    1681         * @og.tag
    1682         * アクションは,HTMLから(get/post)指定されますので,ACT_xxx で設定される
    1683         * フィールド定数値のいづれかを、指定できます。
    1684         * 無指定の場合は、なにもしません。
    1685         *
    1686         * <table class="plain">
    1687         *   <caption>アクション 一覧</caption>
    1688         *   <tr><th>action      </th><th>名称                    </th><th>機能</th></tr>
    1689         *   <tr><td>UPPER       </td><td>アッパー(大文字化)      </td><td>value値を大文字に変換します。</td></tr>
    1690         *   <tr><td>LOWER       </td><td>ローワー(小文字化)      </td><td>value値を小文字に変換します。</td></tr>
    1691         *   <tr><td>MESSAGE     </td><td>メッセージ変換          </td><td>引数をメッセージリソースのキーとして、メッセージ変換します。</td></tr>
    1692         *   <tr><td>APPEND      </td><td>データアペンド          </td><td>複数リクエストや複数選択時に値を連結します。</td></tr>
    1693         *   <tr><td>ALL_APPEND  </td><td>オールアペンド          </td><td>SETTBL,GETTBL 時に、チェック行以外の全行を対象に値の連結を行います。</td></tr>
    1694         *   <tr><td>MAP         </td><td>マップ                  </td><td>検索結果やTableModelのkeyをキーに、valueを値に一括設定します。</td></tr>
    1695         *   <tr><td>ALL_MAP     </td><td>オールマップ            </td><td>全行を対象に検索結果やTableModelのkeyをキーに、valueを値に一括設定します。</td></tr>
    1696         *   <tr><td>MAPOBJ      </td><td>マップオブジェクト      </td><td>検索結果やTableModelのkeyに、キーと値のMapを設定します。6.2.4.2 (2015/05/29)</td></tr>
    1697         *   <tr><td>ALL_MAPOBJ  </td><td>オールマップオブジェクト</td><td>全行を対象に検索結果やTableModelのkeyに、キーと値のMapを設定します。6.2.4.2 (2015/05/29)</td></tr>
    1698         *   <tr><td>LIST        </td><td>リスト                  </td><td>複数リクエストや複数選択時に値をArrayListにセットします。4.3.7.5 (2009/07/13)</td></tr>
    1699         *   <tr><td>ALL_LIST    </td><td>オールリスト            </td><td>全行を対象に値をArrayListにセットします。4.3.7.5 (2009/07/13)</td></tr>
    1700         *   <tr><td>DAY_WEEK    </td><td>日付前方まるめ          </td><td>日付型文字列(YYYYMMDD) の値を、月曜日に変換します。</td></tr>
    1701         *   <tr><td>            </td><td>                        </td><td>指定日が日曜日の場合は、次の日(月曜日)に進めます。その他は、週始めに戻します。</td></tr>
    1702         *   <tr><td>MERGE       </td><td>データのマージ          </td><td>重複を除く、ユニークな値に、マージします。(カンマで分解、separatorで合成)</td></tr>
    1703         *   <tr><td>FIRST       </td><td>１件目取得              </td><td>最初の１件目を強制的に選択状態にして、処理を行います。</td></tr>
    1704         *   <tr><td>ROW_APPEND  </td><td>検索結果の連結          </td><td>検索結果の行方向のデータを連結します。</td></tr>
    1705         *   <tr><td>REPLACE     </td><td>文字列置換              </td><td>value の値から、指定された正規表現(from)の部分文字列を、部分文字列(to)で置換します。</td></tr>
    1706         *   <tr><td>INDEX_OF    </td><td>最初に出現する位置      </td><td>value の値から、指定された(separator)が、fromVal以降に最初に出現する位置。</td></tr>
    1707         *   <tr><td>LASTINDEX_OF</td><td>最後に出現する位置      </td><td>value の値から、指定された(separator)が、toVal以前に最後に出現する位置。</td></tr>
    1708         *   <tr><td>SUBSTR      </td><td>部分文字列              </td><td>value の値から、指定された(fromVal)から(toVal)の部分文字列を作成します。</td></tr>
    1709         *   <tr><td>LENGTH      </td><td>文字数(char数)          </td><td>value の文字数(char数)をカウントします。</td></tr>
    1710         *   <tr><td>SPLIT       </td><td>文字列分割              </td><td>value の値から、指定されたseparatorで分割した文字列を作成します。(key+0～連番)</td></tr>
    1711         *   <tr><td>MAX_MIN     </td><td>最大_最小値             </td><td>選択行のkeyのカラムの最小値,最大値を、MIN.キー、MAX.キー の値にセットします。 5.6.4.3 (2013/05/24) ※１</td></tr>
    1712         *   <tr><td>ALL_MAX_MIN </td><td>最大_最小値             </td><td>全行を対象にkeyのカラムの最小値,最大値を、MIN.キー、MAX.キー の値にセットします。 5.6.4.3 (2013/05/24) ※１</td></tr>
    1713         *   <tr><td>EXEC 廃止   </td><td>計算結果                </td><td>【廃止】value またはBODY部の値を、JavaScriptで計算した結果をセットします。7.3.0.0 (2021/01/06)</td></tr>
    1714         *   <tr><td>ADD         </td><td>計算結果                </td><td>defaultVal の 値と、(value またはBODY部の)値を、加算した結果をキー変数にセットします。7.3.0.0 (2021/01/06)</td></tr>
    1715         *   <tr><td>CASE        </td><td>条件分岐                </td><td>fromVal="A:1 B:2 C:3 D:4" 形式の値を元に、value値(左辺)に一致する右辺をセットします。 5.7.7.2 (2014/06/20) ※２</td></tr>
    1716         *   <tr><td>ESCAPE      </td><td>エスケープ文字          </td><td>HTML上のエスケープ文字(&amp;lt;,&amp;gt;,&amp;quot;,&amp;apos;,&amp;amp;)を変換します。</td></tr>
    1717         *   <tr><td>URL_ENCODE  </td><td>URLエンコード           </td><td>UTF-8 で、URLエンコードを行います。</td></tr>
    1718         *   <tr><td>URL_ENCODE2 </td><td>ASCII以外の文字のURLエンコード</td><td>UTF-8 で、ASCII以外の文字の、URLエンコードします。</td></tr>
    1719         *   <tr><td>URL_DECODE  </td><td>URLデコード             </td><td>UTF-8 でURLエンコードされた文字列をデコードします。</td></tr>
    1720         *   <tr><td>TRIM        </td><td>スペース削除            </td><td>両端空白文字(スペース、タブ、改行等)を削除します。6.4.1.2 (2016/01/22)</td></tr>
    1721         *   <tr><td>MD5         </td><td>MD5変換                 </td><td>値をMD5変換します。</td></tr>
    1722         *   <tr><td>TO_NUMBER   </td><td>数値変換                </td><td>値から、数値以外の文字を削除します。例えば、日付、金額など、区切り記号等を削除します。6.7.4.0 (2017/02/10)</td></tr>
    1723         *   <tr><td>HMCSV       </td><td>日付の加算              </td><td>ステップ時間を分で指定します(例：１時間=60 , ２時間=120 , 45分=45 など)。valueには、初期日付(YMD形式)を設定します。6.8.4.1 (2017/12/18)</td></tr>
    1724         *   <tr><td>CRYPT_ENC   </td><td>暗号化変換              </td><td>HybsCryptographyによる暗号化を行います。暗号化キーは、cryptKey 属性で指定します。5.10.4.0 (2018/10/05)</td></tr>
    1725         *   <tr><td>CRYPT_DEC   </td><td>暗号化復号              </td><td>HybsCryptographyによる復号化を行います。復号化キーは、cryptKey 属性で指定します。5.10.4.0 (2018/10/05)</td></tr>
    1726         *   <tr><td>REQUEST     </td><td>ﾘｸｴｽﾄ変数変換           </td><td>SQLなどで直接取得したﾃﾞｰﾀを、ﾘｸｴｽﾄ変換({&#064;XXXX}変換)します。7.2.6.1 (2020/07/17)</td></tr>
    1727         * </table>
    1728         *
    1729         * ※１ MAX_MIN,ALL_MAX_MIN  については、DBTableModelのカラムのCLS_NAMEが、NUMBER,INTEGER,DECIMAL の場合は、数字型(double)に変換して比較します。
    1730         *    数字型(double)の場合だけ、合計(SUM.キー) と 平均(AVG.キー)計算も同時に行います。
    1731         *    それ以外の場合は、文字列比較を行います。（command="SETTBL" のみ）
    1732         *    command="SET" の場合は、数字型(double)として、value の値を、separator で分解したうえで、最大、最小、合計、平均 を計算し、
    1733         *    それぞれを、MIN.キー、MAX.キー、SUM.キー、AVG.キー 変数にセットします。
    1734         *    数字に変換できなかった場合は、エラーになります。
    1735         *    null は、無視され(平均を求める場合の母数としても無視)、すべてが nulll の場合は、ゼロ文字列("")になります。
    1736         *    ゼロ文字列("") の場合に、defaultVal 属性が設定されていると、defaultVal が設定されます。
    1737         * ※２ CASE は、fromVal="A:1 B:2 C:3 D:4" 形式の値に対して、コロン(:)で分解し、value値(左辺)が、一致する右辺を返します。
    1738         *    fromVal の値は、スペースで分割され、コロン(:)が存在する左辺(キー)と右辺(値)に分解し、value値とキーを比較し、
    1739         *    一致すれば、右辺の値を返します。
    1740         *    valueがnullの場合、defaultVal が設定されており、その値で、fromVal の値と比較します。
    1741         *    一致する値がなければ、元の value が返されます。
    1742         * ※３ 6.9.0.2 (2018/02/13)
    1743         *    command="SQL"のMAP,ALL_MAP で、select key,val from TABLE のように、ｷｰと値のみのMapを作成していましたが、
    1744         *    第３引数以降も、Mapを作成するようにします。
    1745         *    具体的には、select key,val,val1,val2,val3 ･･･ from TABLE とすると、key,val の関係は、従来どおりで、
    1746         *    val1 は、key + '_1' , val2 は、key + '_2' ･･･ という風に登録します。
    1747         * ※４ 6.9.1.0 (2018/02/26)
    1748         *    HMCSV アクションを実行すると、MIN(fromValの日付),MAX(toValの日付),HMF(日付の時:分ラベル) を追加します。
    1749         *    fromVal,toVal を指定せず、valueに、CSV形式の日付ﾃﾞｰﾀを渡した場合は、MIN,MAX,HMF のみ求めます。
    1750         * ※５ 7.2.6.0 (2020/06/30)
    1751         *    INDEX_OF( value.indexOf(separator,fromVal); )は、検索対象の部分文字列をseparatorに、検索開始位置のインデックスをfromVal にセットします。
    1752         *    LASTINDEX_OF( value.lastIndexOf​(separator,toVal); )は、検索対象の部分文字列をseparatorに、検索開始位置のインデックスをtoVal にセットします。(fromValではないことを注意)
    1753         *
    1754         * @og.rev 3.1.0.1 (2003/03/26) 指定のアクション以外は、エラーとするように変更。
    1755         * @og.rev 3.5.6.2 (2004/07/05) 文字列の連結にStringBuilderを使用します。
    1756         * @og.rev 4.3.7.5 (2009/07/13) ACT_LIST、ACT_ALL_LIST アクションの追加(JavaDocのみ修正)
    1757         * @og.rev 5.6.4.3 (2013/05/24) ACT_MAX_MIN アクションの追加(JavaDocのみ修正)
    1758         * @og.rev 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加にともなう修正。action="ALL_xxx"は、tmpSelectedAll=true にします。
    1759         * @og.rev 5.7.7.2 (2014/06/20) EXEC と CASE アクションを追加
    1760         * @og.rev 6.2.4.2 (2015/05/29) MAPOBJ , ALL_MAPOBJ アクションの追加
    1761         * @og.rev 6.3.4.0 (2015/08/01) Arrays.toString から String.join に置き換え。
    1762         * @og.rev 6.4.1.2 (2016/01/22) TRIM アクションを追加。
    1763         * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    1764         * @og.rev 6.7.4.0 (2017/02/10) TO_NUMBER アクションを追加。
    1765         * @og.rev 6.8.4.1 (2017/12/18) HMCSV アクションを追加
    1766         *
    1767         * @param       act アクション (public static final 宣言されている文字列)
    1768         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ValueTag.ACT_APPEND">アクション定数</a>
    1769         */
    1770        public void setAction( final String act ) {
    1771                action = nval( getRequestParameter( act ),action );
    1772
    1773                if( action != null && !check( action, ACTION_SET ) ) {
    1774                        final String errMsg = "指定のアクションは実行できません。アクションエラー"       + CR
    1775                                                                + "action=[" + action + "] "                                                    + CR
    1776                                                                + "actionList=[" + String.join( ", " , ACTION_SET ) + "]" ;
    1777                        throw new HybsSystemException( errMsg );
    1778                }
    1779
    1780                // 5.6.4.3 (2013/05/24) tmpSelectedAll 属性追加。action="ALL_xxx"を tmpSelectedAll="true" に置き換えます。
    1781                if( action != null && action.startsWith( "ALL_" ) ) {
    1782                        action      = action.substring( 4 );    // "ALL_" の４文字分削除
    1783                        tmpSelectedAll = true;
    1784                }
    1785        }
    1786
    1787        /**
    1788         * 【TAG】パラメータ に登録するキーをセットします。
    1789         *
    1790         * @og.tag パラメータ に登録するキーをセットします。
    1791         *
    1792         * @og.rev 3.0.1.3 (2003/03/11) キーを toUpperCase している箇所を削除
    1793         * @og.rev 6.2.6.0 (2015/06/19) キーのnull判定は行わない。(個別のメソッド内で実施している。)
    1794         *
    1795         * @param       key1 登録キー
    1796         */
    1797        public void setKey( final String key1 ) {
    1798                key = nval( getRequestParameter( key1 ),key ) ;
    1799        }
    1800
    1801        /**
    1802         * 【TAG】パラメータ に登録する値をセットします。
    1803         *
    1804         * @og.tag パラメータ に登録する値をセットします。
    1805         *
    1806         * @og.rev 3.1.7.0 (2003/05/02) isNullSet 属性が true(初期値)のときは、リクエスト情報から値を取得。
    1807         * @og.rev 3.5.4.0 (2003/11/25) getRequestParameter( value ) メソッドを setValue に移動。
    1808         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    1809         *
    1810         * @param       val     登録値
    1811         */
    1812        public void setValue( final String val ) {
    1813                inValue = val;          // 3.5.4.0 (2003/11/25) 入力変数も、キープしておく。
    1814                value = getRequestParameter( inValue );
    1815        }
    1816
    1817        /**
    1818         * 【TAG】value属性に値がセットされていないとき使用する、初期値を指定します。
    1819         *
    1820         * @og.tag
    1821         * value属性に値がセットされていないときに、この初期値を使用します。
    1822         *
    1823         * @param       val 初期値
    1824         */
    1825        public void setDefaultVal( final String val ) {
    1826                defaultVal = getRequestParameter( val );
    1827        }
    1828
    1829//      /**
    1830//       * 【廃止】value が NULL の時に、設定するかどうか[true/false]を指定します(初期値:true)。
    1831//       *
    1832//       * @og.tag
    1833//       * true の場合は, null のときでもセットします。
    1834//       * false の場合は, null のときは、既存の値を置き換えません。
    1835//       * 初期値は、null のときでもセットするです。 ("true")
    1836//       *
    1837//       * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    1838//       * @og.rev 6.9.5.0 (2018/04/23) 物理的に廃止
    1839//       *
    1840//       * @param   flag NULL時設定有無 [true:設定する/それ以外:設定しない]
    1841//       * @deprecated 5.1.8.0 (2010/07/01) 廃止。
    1842//       */
    1843//      @Deprecated public void setNullSet( final String flag ) {
    1844//              // 廃止予定
    1845//      }
    1846
    1847        /**
    1848         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します。
    1849         *
    1850         * @og.tag Queryオブジェクトを作成する時のDB接続IDを指定します。
    1851         *
    1852         * @param       id データベース接続ID
    1853         */
    1854        public void setDbid( final String id ) {
    1855                dbid = nval( getRequestParameter( id ),dbid );
    1856        }
    1857
    1858        /**
    1859         * 【TAG】キャッシュする場合のスコープ(request,session)を指定します(初期値:request)。
    1860         *
    1861         * @og.tag
    1862         * "request","session" が指定できます。
    1863         * 初期値は、 "request" です。
    1864         *
    1865         * @param       scp     スコープ
    1866         */
    1867        @Override
    1868        public void setScope( final String scp ) {
    1869                scope = nval( getRequestParameter( scp ),scope );
    1870        }
    1871
    1872        /**
    1873         * 【TAG】DBTableModel から取得する場合のスコープ(request,session)を指定します(初期値:session)。
    1874         *
    1875         * @og.tag
    1876         * "request","session" が指定できます。
    1877         * 初期値は、 "session" です。
    1878         *
    1879         * @og.rev 5.1.2.0 (2010/01/01) DBTableModel の取得先のscope
    1880         *
    1881         * @param       scp     スコープ
    1882         */
    1883        public void setTblScope( final String scp ) {
    1884                tblScope = nval( getRequestParameter( scp ),tblScope );
    1885        }
    1886
    1887        /**
    1888         * 【TAG】マルチデータ(複数件検索)を使用するかどうか[true/false]を指定します(初期値:false)。
    1889         *
    1890         * @og.tag
    1891         * command="SQL" の場合に、複数行検索した結果を、キー＋行番号 というキーを作成して
    1892         * 値を設定するかどうかを指定します。
    1893         * false の場合は、従来どおり、検索カラム名がキーになります。
    1894         * 初期値は、false です。
    1895         *
    1896         * @og.rev 3.2.4.0 (2003/06/12) 新規追加
    1897         *
    1898         * @param   flag 複数件検索 [true:使用する/false:使用しない]
    1899         */
    1900        public void setUseMultiRows( final String flag ) {
    1901                useMultiRows = nval( getRequestParameter( flag ),useMultiRows );
    1902        }
    1903
    1904        /**
    1905         * 【TAG】各種アクションの文字列を連結/分解する項目区切り文字をセットします(初期値:",")。
    1906         *
    1907         * @og.tag
    1908         * 各種アクションに基づく処理において、文字列の区切りを指定するのに使用します。
    1909         * APPEND、ROW_APPEND 時には、文字列の連結に使用します。
    1910         * MERGE の場合は、カンマで分解後、このセパレータでMERGE処理を行い、再び、連結します。
    1911         * 初期値は、"," に設定されています。
    1912         *
    1913         * @og.rev 3.5.6.5 (2004/08/09) 新規追加
    1914         *
    1915         * @param   sepa 項目区切り文字 (初期値:",")
    1916         */
    1917        public void setSeparator( final String sepa ) {
    1918                separator = nval( getRequestParameter( sepa ),separator );
    1919        }
    1920
    1921        /**
    1922         * 【TAG】パラメータの HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか[true/false]を設定します
    1923         *              (初期値:USE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。
    1924         *
    1925         * @og.tag
    1926         * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。
    1927         * (&gt;&lt;) が含まれていたエラーにする(true)／かノーチェックか(false)を指定します。
    1928         * (初期値:システム定数のUSE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。
    1929         *
    1930         * @og.rev 5.1.7.0 (2010/06/01) 新規追加
    1931         *
    1932         * @param       flag    XSSチェック [true:する/false:しない]
    1933         * @see         org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK
    1934         */
    1935        public void setXssCheck( final String flag ) {
    1936                xssCheck = nval( getRequestParameter( flag ),xssCheck );
    1937        }
    1938
    1939        /**
    1940         * 【TAG】部分文字列置換の 置換え前の部分文字列(from)を指定します。
    1941         *
    1942         * @og.tag
    1943         * value の値から、指定された正規表現(from)に一致する、この文字列の各部分文字列に対し、
    1944         * 指定された文字列(to)で置換します。
    1945         * value.replaceAll( from, to ) という文法で処理します。
    1946         *
    1947         * ※ action="CASE" 時は、fromVal="A:1 B:2 C:3 D:4" 形式で指定可能です。
    1948         * ※ action="SUBSTR" 時は、fromVal は、数字 のみ設定可能です。
    1949         * ※ action="REPLACE" 時は、fromVal は、CSV形式で、複数のリプレースキーを指定できます。。
    1950         *            例: @1,@2,@3・・
    1951         *
    1952         * @og.rev 5.2.2.0 (2010/11/01) 新規追加
    1953         *
    1954         * @param       from    置換え前の部分文字列
    1955         * @see         #setToVal(String)
    1956         */
    1957        public void setFromVal( final String from ) {
    1958                fromVal = nval( getRequestParameter( from ),fromVal );
    1959        }
    1960
    1961        /**
    1962         * 【TAG】部分文字列置換の 置換え後の部分文字列(to)を指定します。
    1963         *
    1964         * @og.tag
    1965         * value の値から、指定された正規表現(from)に一致する、この文字列の各部分文字列に対し、
    1966         * 指定された文字列(to)で置換します。
    1967         * value.replaceAll( from, to ) という文法で処理します。
    1968         *
    1969         * ※ action="SUBSTR" 時は、toVal は、数字 のみ設定可能です。
    1970         * ※ action="REPLACE" 時は、toVal は、CSV形式で、複数の置換え後の文字列を指定できます。。
    1971         *            例: VLA1,VAL2,VAL・・
    1972         *
    1973         * @og.rev 5.2.2.0 (2010/11/01) 新規追加
    1974         *
    1975         * @param       to      置換え後の部分文字列
    1976         * @see         #setFromVal(String)
    1977         */
    1978        public void setToVal( final String to ) {
    1979                toVal = nval( getRequestParameter( to ),toVal );
    1980        }
    1981
    1982        /**
    1983         * 【TAG】HMCSVで使用する、ステップ時間を分で指定します(例：１時間=60 , ２時間=120 , 45分=45 など)。
    1984         *
    1985         * @og.tag
    1986         * fromVal と、toVal を組み合わせて、使用します。
    1987         * action="HMCSV" で、時刻のCSVリストを作成するのに使用します。
    1988         * 例えば、value="20171213" fromVal="0600" toVal="1000" skipVal="45" とすると、
    1989         * 201712130600,201712130645,201712130730,201712130815,201712130900,201712130945 という文字列を作成します。
    1990         * デフォルトは、60分(１時間)です。
    1991         * skipVal には、マイナスやゼロは、指定できません。
    1992         *
    1993         * @og.rev 6.8.4.1 (2017/12/18) skipVal 属性 追加
    1994         *
    1995         * @param       skip    HMCSVで使用する、ステップ時間を分で指定
    1996         */
    1997        public void setSkipVal( final String skip ) {
    1998                skipVal = nval( getRequestParameter( skip ),skipVal );
    1999                if( !StringUtil.isNull( skipVal ) ) {
    2000                        final char ch = skipVal.charAt(0);
    2001                        if( ch == '-' || ch == '0' ) {
    2002                                final String errMsg = "skipVal属性には、マイナスやゼロは、指定できません。"
    2003                                                        + " skipVal=[" + skipVal + "]" + CR ;
    2004                                throw new HybsSystemException( errMsg );
    2005                        }
    2006                }
    2007        }
    2008
    2009        /**
    2010         * 【TAG】暗号化、復号化に利用する暗号化キーを指定します。
    2011         *
    2012         * @og.tag
    2013         * 暗号化キーをしています。
    2014         * 未設定の場合は、エンジンで用意されているキーを利用します。
    2015         * 暗号化キーは8の倍数の文字数が推奨されています。
    2016         *
    2017         * @og.rev 5.10.4.0 (2018/10/05) 新規追加
    2018         *
    2019         * @param cKey  暗号化キー
    2020         */
    2021        public void setCryptKey( final String cKey ) {
    2022                cryptKey = nval( getRequestParameter( cKey ), cryptKey);
    2023        }
    2024
    2025        /**
    2026         * このオブジェクトの文字列表現を返します。
    2027         * 基本的にデバッグ目的に使用します。
    2028         *
    2029         * @og.rev 4.3.4.0 (2008/12/01) PageContextのスコープをクラス変数としてアクセス
    2030         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止
    2031         * @og.rev 6.7.7.2 (2017/04/14) 属性の追加と、各スコープ変数の表示廃止
    2032         *
    2033         * @return このクラスの文字列表現
    2034         * @og.rtnNotNull
    2035         */
    2036        @Override
    2037        public String toString() {
    2038                return ToString.title( this.getClass().getName() )
    2039                                .println( "VERSION"                     ,VERSION                )
    2040                                .println( "tableId"                     ,tableId                )
    2041                                .println( "command"                     ,command                )
    2042                                .println( "action"                      ,action                 )
    2043                                .println( "key"                         ,key                    )
    2044                                .println( "inValue"                     ,inValue                )
    2045                                .println( "value"                       ,value                  )
    2046                                .println( "defaultVal"          ,defaultVal             )
    2047                                .println( "dbid"                        ,dbid                   )
    2048                                .println( "scope"                       ,scope                  )
    2049                                .println( "tblScope"            ,tblScope               )                               // 6.7.7.2 (2017/04/14)
    2050                                .println( "separator"           ,separator              )
    2051                                .println( "useMultiRows"        ,useMultiRows   )
    2052                                .println( "xssCheck"            ,xssCheck               )                               // 6.7.7.2 (2017/04/14)
    2053                                .println( "fromVal"                     ,fromVal                )                               // 6.7.7.2 (2017/04/14)
    2054                                .println( "toVal"                       ,toVal                  )                               // 6.7.7.2 (2017/04/14)
    2055                                .println( "skipVal"                     ,skipVal                )                               // 6.8.4.1 (2017/12/18)
    2056                                .println( "tmpSelectedAll"      ,tmpSelectedAll )                               // 6.7.7.2 (2017/04/14)
    2057                                .println( "Other..."    ,getAttributes().getAttribute() )
    2058                                .fixForm().toString() ;
    2059        }
    2060}