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