    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.hayabusa.common.HybsSystem;
    019import org.opengion.hayabusa.common.HybsSystemException;
    020import org.opengion.hayabusa.db.DBColumn;
    021import org.opengion.hayabusa.db.DBEventColumn;
    022import org.opengion.hayabusa.db.DBLastSql;
    023import org.opengion.hayabusa.db.DBTableModel;
    024import org.opengion.hayabusa.resource.GUIInfo;
    025import org.opengion.hayabusa.resource.LabelInterface;
    026import org.opengion.hayabusa.resource.ResourceFactory;
    027import org.opengion.hayabusa.resource.ResourceManager;
    028import org.opengion.hayabusa.resource.UserInfo;
    029
    030import static org.opengion.fukurou.util.StringUtil.nval;
    031import org.opengion.fukurou.system.DateSet;                                                                             // 6.4.2.0 (2016/01/29)
    032import org.opengion.fukurou.system.BuildNumber;                                                                 // 6.4.2.0 (2016/01/29) hayabusa.common.BuildNumber → fukurou.system.BuildNumber に移動
    033import org.opengion.fukurou.system.HybsConst;                                                                   // 6.1.0.0 (2014/12/26)
    034import org.opengion.fukurou.system.MsgUtil;                                                                             // 6.4.3.2 (2016/02/19)
    035// import org.opengion.fukurou.system.OgRuntimeException;                                               // 6.9.2.1 (2018/03/12)
    036import org.opengion.fukurou.util.Attributes;
    037import org.opengion.fukurou.util.StringUtil;
    038import org.opengion.fukurou.util.HybsDateUtil;
    039import org.opengion.fukurou.util.ToString;                                                                              // 6.1.1.0 (2015/01/17)
    040import org.opengion.fukurou.db.DBFunctionName;
    041import org.opengion.fukurou.db.ApplicationInfo;
    042import org.opengion.fukurou.db.Transaction;                                                                             // 6.3.6.1 (2015/08/28)
    043import org.opengion.fukurou.db.TransactionReal;                                                                 // 6.3.6.1 (2015/08/28)
    044
    045import java.io.IOException;
    046import java.io.ObjectInputStream;
    047import java.net.InetAddress;
    048import java.net.UnknownHostException;
    049import java.util.Arrays;
    050import java.util.Collections;
    051import java.util.Enumeration;
    052import java.util.HashMap;
    053import java.util.Locale;
    054import java.util.Map;
    055import java.util.LinkedHashMap;                                                                                                 // 6.2.5.1 (2015/06/12)
    056import java.util.Set;                                                                                                                   // 6.4.3.4 (2016/03/11)
    057import java.util.Scanner;                                                                                                               // 5.1010.1 (2019/04/05)
    058
    059import jakarta.servlet.ServletContext;
    060import jakarta.servlet.ServletRequest;
    061import jakarta.servlet.http.Cookie;
    062import jakarta.servlet.http.HttpServletRequest;
    063import jakarta.servlet.http.HttpServletResponse;
    064import jakarta.servlet.http.HttpSession;
    065import jakarta.servlet.jsp.JspWriter;
    066import jakarta.servlet.jsp.tagext.BodyContent;
    067import jakarta.servlet.jsp.tagext.BodyTagSupport;
    068import jakarta.servlet.jsp.tagext.TryCatchFinally;
    069
    070/**
    071 * TagSupport から継承されたｻﾌﾞｸﾗｽです｡
    072 *
    073 * 汎用属性 のsetterﾒｿｯﾄﾞと、Attributes ｵﾌﾞｼﾞｪｸﾄを持っています｡
    074 * それ以外に、{&#064;XXXX} 変数の対応と、lang属性のﾒｿｯﾄﾞも用意しています｡
    075 *
    076 * language 属性は、個々のﾘｿｰｽのﾛｹｰﾙを指定できます｡
    077 * 通常は、ﾕｰｻﾞｰ情報の lang 属性をﾃﾞﾌｫﾙﾄで使用し、ｾｯﾄされていない場合は、
    078 * ﾘｸｴｽﾄ情報のﾛｹｰﾙから取得します｡
    079 *
    080 * 以下に、このﾒｿｯﾄﾞ内で定義される属性を記述します｡
    081 *
    082 *       language           【TAG】ﾀｸﾞ内部で使用する言語ｺｰﾄﾞ[ja/en/zh/…]を指定します
    083 *       lbl                【TAG】ﾗﾍﾞﾙﾘｿｰｽのﾗﾍﾞﾙIDを指定します
    084 *       debug              【TAG】ﾃﾞﾊﾞｯｸﾞ情報を出力するかどうか[true/false]を指定します (初期値:false)
    085 *       caseKey            【TAG】このﾀｸﾞ自体を利用するかどうかの条件ｷｰを指定します (初期値:null)
    086 *       caseVal            【TAG】このﾀｸﾞ自体を利用するかどうかの条件値を指定します (初期値:null)
    087 *       caseNN             【TAG】指定の値が、null/ｾﾞﾛ文字列 でない場合(Not Null=NN)は、このﾀｸﾞは使用されます (初期値:判定しない)
    088 *       caseNull           【TAG】指定の値が、null/ｾﾞﾛ文字列 の場合は、このﾀｸﾞは使用されます (初期値:判定しない)
    089 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このﾀｸﾞは使用されます (初期値:判定しない)
    090 *       scope              【TAG】ｷｬｯｼｭする場合のｽｺｰﾌﾟ(request,session)を指定します (初期値:session)
    091 *
    092 * 各属性は、{&#064;XXXX} 変数が使用できます｡
    093 * これは、ServletRequest から、XXXX をｷｰに値を取出し、この変数に割り当てます｡
    094 * つまり、このXXXXをｷｰにﾘｸｴｽﾄすれば、この変数に値をｾｯﾄすることができます｡
    095 *
    096 * http://localhost/query.jsp?KEY1=VLA1&amp;KEY2=VAL2
    097 *
    098 * のようなﾘｸｴｽﾄで、{&#064;KEY1} とすれば、VAL1 がｾｯﾄされます｡
    099 *
    100 * このﾀｸﾞは、ﾗﾍﾞﾙ部分と入力ﾌｨｰﾙﾄﾞ部分がﾃｰﾌﾞﾙﾀｸﾞの&lt;td&gt;により左右に分割されます｡
    101 * HTML 表示時は、前後に&lt;tr&gt;ﾀｸﾞで囲って整形できます｡
    102 *
    103 * @og.group 画面制御
    104 *
    105 * @version  4.0
    106 * @author   Kazuhiko Hasegawa
    107 * @since    JDK5.0,
    108 */
    109class CommonTagSupport extends BodyTagSupport implements TryCatchFinally {
    110        /** このﾌﾟﾛｸﾞﾗﾑのVERSION文字列を設定します。 {@value} */
    111        private static final String VERSION = "8.2.0.2 (2022/06/24)" ;
    112        private static final long serialVersionUID = 820220220624L ;
    113
    114        /** ｼｽﾃﾑの改行ｺｰﾄﾞを設定します。*/
    115        protected static final String CR                = HybsConst.CR;                                         // 6.1.0.0 (2014/12/26) refactoring
    116        /** HTMLの改行ｺｰﾄﾞ(&lt;br /&gt; + CR)を設定します。*/
    117        protected static final String BR                = HybsConst.BR;                                         // 6.1.0.0 (2014/12/26) refactoring
    118        /** StringBilderなどの初期値を設定します。   {@value} */
    119        protected static final int BUFFER_MIDDLE = HybsConst.BUFFER_MIDDLE;                     // 6.1.0.0 (2014/12/26) refactoring
    120
    121        private transient Attributes            attri           = new Attributes();
    122        private transient ResourceManager       resource        ;
    123        private transient UserInfo                      userInfo        ;
    124        private transient GUIInfo                       guiInfo         ;
    125        private transient HttpSession           session         ;
    126        private transient ServletRequest        request         ;
    127        /** 6.4.3.1 (2016/02/12) 取得元の HashMap を ConcurrentHashMap に置き換え。 */
    128        private transient Map<String,String[]>  requestCache;                                           // 3.5.6.2 (2004/07/05)
    129        private transient LabelInterface        msglbl          ;                                                       // 4.0.0 (2005/01/31)
    130
    131        private String          language        ;
    132        private boolean         debugFlag       ;                                                                                       // 3.5.5.3 (2004/04/09)
    133        private boolean         isReqNull       ;
    134        private boolean         quotCheck       ;                                                                                       // 4.0.0 (2005/08/31)
    135        private String          scope           = "session";                                                            // "request","page","session","application"
    136        // 3.1.7.0 (2003/05/02) value値の使用可否を指定する、useValue 属性を追加。
    137        private Long            startTransaction;                                                                               // 3.6.0.8 (2004/11/19)
    138        private int[]           rowNo           ;                                                                                       // 4.0.0 (2005/01/31)
    139        private boolean         xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );        // 5.0.0.2 (2009/09/15)
    140        private boolean         useTrans        ;                                                                                       // 5.1.6.0 (2010/05/01)
    141
    142        private String          caseKey         ;                                                                                       // 5.2.2.0 (2010/11/01) 新規追加
    143        private String          caseVal         ;                                                                                       // 5.2.2.0 (2010/11/01) 新規追加
    144        private boolean         caseNN          = true;                                                                         // 5.6.7.0 (2013/07/27) 新規追加
    145        private boolean         caseNull        = true;                                                                         // 5.6.8.0 (2013/09/06) 新規追加
    146        private boolean         caseIf          = true;                                                                         // 6.2.6.0 (2015/06/19) 新規追加
    147
    148        private boolean         isSanitized     ;                                                                                       // 5.7.4.2 (2014/03/20) 新規追加
    149
    150        /**
    151         * Taglibの開始ﾀｸﾞが見つかったときに処理する doStartTag() を ｵｰﾊﾞｰﾗｲﾄﾞします｡
    152         *
    153         * @return      後続処理の指示(SKIP_BODY)
    154         */
    155        @Override
    156        public int doStartTag() {
    157                return SKIP_BODY ;                                                                                                              // Body を評価しない
    158        //      return( EVAL_BODY_INCLUDE );                                                                                    // Body ｲﾝｸﾙｰﾄﾞ( extends TagSupport 時)
    159        //      return EVAL_BODY_BUFFERED ;                                                                                             // Body を評価する｡( extends BodyTagSupport 時)
    160        }
    161
    162        /**
    163         * Taglibのﾀｸﾞ本体を処理する doAfterBody() を ｵｰﾊﾞｰﾗｲﾄﾞします｡
    164         *
    165         * @return      後続処理の指示(SKIP_BODY)
    166         */
    167        @Override
    168        public int doAfterBody() {
    169                return SKIP_BODY ;                                                                                                              // Body を評価しない
    170        //      return( EVAL_BODY_AGAIN );                                                                                              // Body を再評価( extends TagSupport 時)
    171        //      return EVAL_BODY_BUFFERED ;                                                                                             // Body を再評価( extends BodyTagSupport 時)
    172        }
    173
    174        /**
    175         * Taglibの終了ﾀｸﾞが見つかったときに処理する doEndTag() を ｵｰﾊﾞｰﾗｲﾄﾞします｡
    176         *
    177         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応｡release2() を doEndTag()で呼ぶ｡
    178         *
    179         * @return      後続処理の指示
    180         */
    181        @Override
    182        public int doEndTag() {
    183                debugPrint();                                                                                                                   // 4.0.0 (2005/02/28)
    184
    185                return EVAL_PAGE ;                                                                                                              // ﾍﾟｰｼﾞの残りを評価する｡( extends TagSupport 時)
    186        //      return(SKIP_PAGE);                                                                                                              // ﾍﾟｰｼﾞの残りの処理を行わない｡
    187        }
    188
    189        /**
    190         * ﾀｸﾞの処理中(ｾｯﾀｰﾒｿｯﾄﾞを除く)の例外を全て受け取ります｡
    191         *
    192         * ﾀｸﾞの中のﾎﾞﾃﾞｨ部の評価中、または Tag.doStartTag(), Tag.doEndTag(),
    193         * IterationTag.doAfterBody(), BodyTag.doInitBody() のいずれもの
    194         * ﾒｿｯﾄﾞの中で、Throwableが投げられたときに呼出されます｡
    195         *
    196         * このﾒｿｯﾄﾞはｾｯﾀｰﾒｿｯﾄﾞの中でThrowableが起きた場合は呼出されません｡
    197         *
    198         * @og.rev 3.5.0.0 (2003/09/17) TryCatchFinally ｲﾝﾀｰﾌｪｰｽを適用｡
    199         * @og.rev 6.8.5.0 (2018/01/09) ﾀｸﾞﾘﾌﾞで発生したｴﾗｰを、session に登録しておきます｡
    200         * @og.rev 6.9.2.1 (2018/03/12) ﾀｸﾞﾘﾌﾞで発生したｴﾗｰを、session に登録する処理を一旦廃止
    201         * @og.rev 7.0.6.4 (2019/11/29) HybsSystemException を throw するように変更します｡
    202         *
    203         * @param       th      このﾀｸﾞを通過してきたThrowableな例外
    204         */
    205        @Override       // TryCatchFinally
    206        public void doCatch( final Throwable th ) throws Throwable {
    207//              // 6.8.5.0 (2018/01/09) ※ なぜか、うまく使えていません。
    208//              final Throwable cause = (Throwable)getSessionAttribute( "CommonTagThrowable" );
    209//
    210//              if( cause != null ) {
    211//                      th.addSuppressed( cause );
    212//              }
    213//
    214//              setSessionAttribute( "CommonTagThrowable" , th );
    215
    216//              throw th;
    217
    218                if( th instanceof HybsSystemException ) {
    219                        throw th;
    220                }
    221                else {
    222                        throw new HybsSystemException( th );                                                            // 7.0.6.4 (2019/11/29)
    223                }
    224        }
    225
    226        /**
    227         * ﾀｸﾞの処理毎の、doEndTag()の後で呼出されます｡
    228         *
    229         * Tag,IterationTag,BodyTagを実装した全てのｸﾗｽの doEndTag()の後で呼出されます｡
    230         * このﾒｿｯﾄﾞはﾀｸﾞのﾎﾞﾃﾞｨ部や Tag.doStartTag(), Tag.doEndTag(), IterationTag.doAfterBody(),
    231         * BodyTag.doInitBody()のすべてのﾒｿｯﾄﾞで例外が発生した後でも呼出されます｡
    232         *
    233         * このﾒｿｯﾄﾞはｾｯﾀｰﾒｿｯﾄﾞの中でThrowableが起きた場合は呼出されません｡
    234         *
    235         * このﾒｿｯﾄﾞからは例外を投げるべきではありません｡
    236         * このﾒｿｯﾄﾞは呼び出し毎のﾃﾞｰﾀの整合性をとることとﾘｿｰｽ管理の
    237         * 動作をさせることを意図しています｡
    238         *
    239         * @og.rev 3.5.0.0 (2003/09/17) TryCatchFinally ｲﾝﾀｰﾌｪｰｽを適用｡
    240         */
    241        @Override       // TryCatchFinally
    242        public void doFinally() {
    243                release2();
    244        }
    245
    246        /**
    247         * ﾀｸﾞﾘﾌﾞｵﾌﾞｼﾞｪｸﾄをﾘﾘｰｽします｡
    248         * ｷｬｯｼｭされて再利用されるので、ﾌｨｰﾙﾄﾞの初期設定を行います｡
    249         *
    250         * @og.rev 2.0.0.4 (2002/09/27) ｶｽﾀﾑﾀｸﾞの release() ﾒｿｯﾄﾞを追加
    251         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応｡release2() を doEndTag()で呼ぶ｡
    252         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応｡HybsRequestWrapper 廃止｡直接 Mapでｷｬｯｼｭする｡
    253         * @og.rev 3.1.3.0 (2003/04/10) ｴﾝｺｰﾄﾞ情報の取得を廃止する｡
    254         * @og.rev 3.1.7.0 (2003/05/02) value値の使用可否を指定する、useValue 属性を追加｡
    255         * @og.rev 3.5.5.3 (2004/04/09) debugFlag を String ではなく、boolean 型に変更
    256         * @og.rev 3.6.0.8 (2004/11/19) startTransaction 属性を追加
    257         * @og.rev 3.8.0.2 (2005/07/11) rightNow 属性を追加
    258         * @og.rev 5.0.0.2 (2009/09/15) XSS対応
    259         * @og.rev 5.1.6.0 (2010/05/01) DBLastSQL周りの実装見直し
    260         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性廃止にともなう、useValue 属性廃止
    261         * @og.rev 5.2.2.0 (2010/11/01) caseKey,caseVal 属性の追加
    262         * @og.rev 5.3.2.0 (2011/02/01) paramNames 属性の追加
    263         * @og.rev 5.6.7.0 (2013/07/27) caseNN 属性の追加
    264         * @og.rev 5.6.8.0 (2013/09/06) caseNull 属性の追加
    265         * @og.rev 5.7.4.1 (2014/03/14) rightNow 属性の廃止
    266         * @og.rev 5.7.4.1 (2014/03/14) isSanitized 属性の追加
    267         * @og.rev 6.2.6.0 (2015/06/19) caseIf 属性の追加
    268         */
    269        protected void release2() {
    270                language                        = null;
    271                attri                           = new Attributes();
    272                resource                        = null;
    273                debugFlag                       = false;                                                                                        // 3.5.5.3 (2004/04/09)
    274                userInfo                        = null;
    275                guiInfo                         = null;
    276                session                         = null;
    277                request                         = null;
    278                isReqNull                       = false;
    279                scope                           = "session";                                                                            // "request","page","session","application"
    280                requestCache            = null;
    281                startTransaction        = null;                                                                                         // 3.6.0.8 (2004/11/19)
    282                rowNo                           = null;                                                                                         // 4.0.0 (2005/01/31)
    283                msglbl                          = null;                                                                                         // 4.0.0 (2005/01/31)
    284                quotCheck                       = false;                                                                                        // 4.0.0 (2005/08/31)
    285                xssCheck                        = HybsSystem.sysBool( "USE_XSS_CHECK" );                        // 5.0.0.2 (2009/09/15)
    286                useTrans                        = false;                                                                                        // 5.1.6.0 (2010/05/01)
    287                caseKey                         = null;                                                                                         // 5.2.2.0 (2010/11/01)
    288                caseVal                         = null;                                                                                         // 5.2.2.0 (2010/11/01)
    289                caseNN                          = true;                                                                                         // 5.6.7.0 (2013/07/27) 新規追加
    290                caseNull                        = true;                                                                                         // 5.6.8.0 (2013/09/06) 新規追加
    291                caseIf                          = true;                                                                                         // 6.2.6.0 (2015/06/19) 新規追加
    292                isSanitized                     = false;                                                                                        // 5.7.4.2 (2014/03/20) 新規追加。一応入れておくが都度、初期化しています。
    293        }
    294
    295        /**
    296         * 【TAG】ﾀｸﾞ内部で使用する言語ｺｰﾄﾞ[ja/en/zh/…]を指定します｡
    297         *
    298         * @og.tag
    299         * この言語ｺｰﾄﾞに基づいて、表示のﾗﾍﾞﾙをﾘｿｰｽから作成します｡
    300         *
    301         * @param       lang    言語ｺｰﾄﾞ [ja/en/zh/…]
    302         * @see         #getLanguage()
    303         */
    304        public void setLanguage( final String lang ) {
    305                language = getRequestParameter( lang );
    306        }
    307
    308        /**
    309         * 言語ｺｰﾄﾞ[ja/en/zh/…]を取得します｡
    310         *
    311         * 言語ｺｰﾄﾞがｾｯﾄされている場合は、設定値を優先します｡
    312         * 設定されていない場合は、ﾛｸﾞｲﾝﾕｰｻﾞｰの持つLANG属性を、それが null の場合は、
    313         * 実行環境のﾘｸｴｽﾄの言語を返します｡
    314         *
    315         * @og.rev 2.1.1.0 (2002/11/08) ｾｯｼｮﾝ情報から取得できない場合に、ｸﾗｲｱﾝﾄの
    316         *                      ﾘｸｴｽﾄ情報のﾛｹｰﾙから取得する処理を追加
    317         * @og.rev 2.2.0.0 (2002/12/17) ｾｯｼｮﾝ情報から取得するのではなく、ﾕｰｻﾞｰ情報より
    318         *                      取得するように変更｡そこにない場合は、ﾘｸｴｽﾄ情報の
    319         *                      ﾛｹｰﾙから取得する
    320         * @og.rev 6.0.2.5 (2014/10/31) 初期ｴﾗｰ発生時は、ﾕｰｻﾞｰも取得できないので、null でも返す｡
    321         * @og.rev 6.4.3.2 (2016/02/19) なにも取得できない場合は、"ja" を返すように変更｡
    322         *
    323         * @return      言語ｺｰﾄﾞ[ja/en/zh/…]
    324         * @see         #setLanguage( String )
    325         */
    326        protected String getLanguage() {
    327                // 6.0.2.5 (2014/10/31) 初期ｴﾗｰ発生時は、ﾕｰｻﾞｰも取得できないので、null でも返す｡
    328                try {
    329                        if( language == null ) {
    330                                language = getUser().getLang();
    331                                if( language == null ) {
    332                                        language = getRequest().getLocale().getLanguage();
    333                                }
    334                        }
    335                }
    336                catch( final RuntimeException ex ) {
    337                        final String errMsg = "言語ｺｰﾄﾞを取得できませんでした。"
    338                                                + ex.getMessage() ;
    339                        System.err.println( errMsg );
    340                }
    341
    342                // 6.4.3.2 (2016/02/19) なにも取得できない場合は、"ja" を返すように変更。
    343                return language == null ? "ja" : language ;
    344        }
    345
    346        /**
    347         * 【TAG】ﾗﾍﾞﾙﾘｿｰｽのﾗﾍﾞﾙIDを指定します｡
    348         *
    349         * @og.tag
    350         * ﾗﾍﾞﾙを変更するときに、lbl属性を使います｡
    351         *
    352         * ﾗﾍﾞﾙID は、所定の language に基づく ResourceManager の
    353         * getLabelData( id ) を呼び出し、その結果のLabelInterfaceを使用します｡
    354         * getMsglbl() で取り出せます｡
    355         * ﾗﾍﾞﾙとﾒｯｾｰｼﾞは統一されました｡
    356         *
    357         * @og.rev 4.0.0.0 (2005/01/31) label 変数は、生ﾃﾞｰﾀを保管するように変更｡
    358         *
    359         * @param       lbl     ﾗﾍﾞﾙID
    360         * @see         #getMsglbl()
    361         */
    362        public void setLbl( final String lbl ) {
    363                msglbl = (LabelInterface)getResource().getLabelData( getRequestParameter( lbl ) ) ;             // 4.0.0 (2005/01/31)
    364        }
    365
    366        /**
    367         * 【TAG】ﾃﾞﾊﾞｯｸﾞ情報を出力するかどうか[true/false]を指定します(初期値:false)｡
    368         *
    369         * @og.tag
    370         * ﾃﾞﾊﾞｯｸﾞ情報を [true:出力する/false:しない]を指定します｡
    371         * 出力形式自体は、個々のﾀｸﾞによって異なります｡
    372         *
    373         * @og.rev 3.5.5.3 (2004/04/09) debugFlag を String ではなく、boolean 型に変更
    374         *
    375         * @param       flag    ﾃﾞﾊﾞｯｸﾞ出力 [true:する/それ以外:しない]
    376         */
    377        public void setDebug( final String flag ) {
    378                debugFlag = nval( getRequestParameter( flag ),debugFlag );
    379        }
    380
    381        /**
    382         * 【TAG】ｷｬｯｼｭする場合のｽｺｰﾌﾟ[request/page/session/application]を指定します(初期値:session)｡
    383         *
    384         * @og.tag
    385         * "request","page","session","application" が指定できます｡
    386         * JSPのｽｺｰﾌﾟは｢変数の有効範囲｣を表すもので、ﾌﾚｰﾑﾜｰｸ上では、
    387         * 主にﾃｰﾌﾞﾙﾓﾃﾞﾙを管理するｽｺｰﾌﾟを指します｡
    388         *
    389         * <table class="plain">
    390         *   <caption>ﾃｰﾌﾞﾙﾓﾃﾞﾙを管理するｽｺｰﾌﾟ変数の有効範囲</caption>
    391         *   <tr><th>ｽｺｰﾌﾟ      </th><th>変数の有効範囲</th><th>説明</th></tr>
    392         *   <tr><td>page               </td><td>JSPﾍﾟｰｼﾞ内</td>
    393         *       <td>そのJSPﾍﾟｰｼﾞ内のみで有効です｡ﾌﾚｰﾑﾜｰｸ的には、JSPﾍﾟｰｼﾞにまたがる処理が多いため、ほとんど使う機会はありません｡</td></tr>
    394         *   <tr><td>request    </td><td>HTTPﾘｸｴｽﾄ</td>
    395         *       <td>ﾘｸｴｽﾄの一連の処理期間中に有効な変数で、ﾒﾓﾘに多くの情報を残したくない場合に利用します｡検索系やﾎﾟｯﾌﾟｱｯﾌﾟのJSP画面等に利用します｡</td></tr>
    396         *   <tr><td>session    </td><td>HTTPｾｯｼｮﾝ</td>
    397         *       <td>初期設定されているｽｺｰﾌﾟで、ﾛｸﾞｲﾝﾕｰｻﾞｰ単位にﾛｸﾞｱｳﾄまで保持されます｡
    398         *           内部的には、同じｷｰﾜｰﾄﾞ（tableId）で管理しているため、検索都度、破棄されます｡
    399         *           （ｶﾞｰﾍﾞｼﾞｺﾚｸｼｮﾝにて破棄されるのを待ちます｡）</td></tr>
    400         *   <tr><td>application</td><td>Webｱﾌﾟﾘｹｰｼｮﾝ</td>
    401         *       <td>ﾕｰｻﾞｰ間で共有する場合のｽｺｰﾌﾟになります｡JSP画面の開発では、まず使うことはありません｡</td></tr>
    402         * </table>
    403         *
    404         * @param       scp     ｽｺｰﾌﾟ [request/page/session/application]
    405         * @see         #getScope()
    406         */
    407        public void setScope( final String scp ) {
    408                scope = nval( getRequestParameter( scp ),scope );
    409        }
    410
    411        /**
    412         * ｷｬｯｼｭする場合のｽｺｰﾌﾟ[request/page/session/application]を返します｡
    413         *
    414         * "request","page","session","application" があります｡
    415         *
    416         * @og.rev 3.5.5.8 (2004/05/20) 新規追加
    417         *
    418         * @return      ｽｺｰﾌﾟ [request/page/session/application]
    419         * @see         #setScope( String )
    420         */
    421        public String getScope() {
    422                return scope ;
    423        }
    424
    425        /**
    426         * 【TAG】このﾀｸﾞ自体を利用するかどうかの条件ｷｰを指定します(初期値:null)｡
    427         *
    428         * @og.tag
    429         * caseKey.matches( caseVal ) の値が、true の場合は、このﾀｸﾞは使用されます｡
    430         * false の場合は、このﾀｸﾞは使用されません｡
    431         *
    432         * caseKey , caseVal ともに null の場合は、true です｡どちらかが 非null の場合は、
    433         * もう片方も 非null で且つcaseKey.matches( caseVal ) が成立する必要があります｡
    434         * この属性は、caseKey , caseVal , caseNN , caseNull , caseIf とともに useTag() の判定で使用されます｡
    435         *
    436         * @og.rev 5.2.2.0 (2010/11/01) 新規追加
    437         * @og.rev 5.6.3.3 (2013/04/19) 条件変更のためのｺﾒﾝﾄ修正
    438         *
    439         * @param       ckey    条件ｷｰ (何も指定されない場合は使用すると判断)
    440         * @see         #setCaseVal( String )
    441         * @see         #useTag()
    442         */
    443        public void setCaseKey( final String ckey ) {
    444                caseKey = nval( getRequestParameter( ckey ),caseKey );
    445        }
    446
    447        /**
    448         * 【TAG】このﾀｸﾞ自体を利用するかどうかの条件値を指定します(初期値:null)｡
    449         *
    450         * @og.tag
    451         * caseKey.matches( caseVal ) の値が true の場合は、このﾀｸﾞは使用されます｡
    452         * false の場合は、このﾀｸﾞは使用されません｡
    453         *
    454         * caseKey , caseVal ともに null の場合は、true です｡どちらかが 非null の場合は、
    455         * もう片方も 非null で且つcaseKey.matches( caseVal ) が成立する必要があります｡
    456         * この属性は、caseKey , caseVal , caseNN , caseNull , caseIf とともに useTag() の判定で使用されます｡
    457         *
    458         * @og.rev 5.2.2.0 (2010/11/01) 新規追加
    459         * @og.rev 5.6.3.3 (2013/04/19) 条件変更のためのｺﾒﾝﾄ修正
    460         *
    461         * @param       cval    条件値 (何も指定されない場合は使用すると判断)
    462         * @see         #setCaseKey( String )
    463         * @see         #useTag()
    464         */
    465        public void setCaseVal( final String cval ) {
    466                caseVal = nval( getRequestParameter( cval ),caseVal );
    467        }
    468
    469        /**
    470         * 【TAG】このﾀｸﾞ自体を利用するかどうかの条件として、NotNullかどうか判定します(初期値:判定しない)｡
    471         *
    472         * @og.tag
    473         * この値が、null/ｾﾞﾛ文字列 でない場合(Not Null=NN)はこのﾀｸﾞは使用されます｡
    474         * null/ｾﾞﾛ文字列 の場合は、このﾀｸﾞは使用されません｡
    475         * 何も指定しない場合は、使用されます｡
    476         * caseNull と逆の動きをします｡
    477         * {&#064;XXXX} で指定した場合は、値が設定されなければ使用されません｡
    478         *
    479         * この属性は、caseKey , caseVal , caseNN , caseNull , caseIf とともに useTag() の判定で使用されます｡
    480         *
    481         * @og.rev 5.6.7.0 (2013/07/27) 新規追加
    482         *
    483         * @param       cnn     NotNull判定値 (何も指定されない場合は使用すると判断)
    484         * @see         #setCaseVal( String )
    485         * @see         #useTag()
    486         */
    487        public void setCaseNN( final String cnn ) {
    488                final String tempNN = nval( getRequestParameter( cnn ),null );
    489
    490                caseNN = tempNN != null && !tempNN.isEmpty() ;
    491        }
    492
    493        /**
    494         * 【TAG】このﾀｸﾞ自体を利用するかどうかの条件として、Nullかどうか判定します(初期値:判定しない)｡
    495         *
    496         * @og.tag
    497         * この値が、null/ｾﾞﾛ文字列 の場合はこのﾀｸﾞは使用されます｡
    498         * null/ｾﾞﾛ文字列 でない場合は、このﾀｸﾞは使用されません｡
    499         * 何も指定しない場合は、使用されます｡
    500         * caseNN と逆の動きをします｡
    501         * {&#064;XXXX} で指定した場合は、値が設定されていなければ使用されます｡
    502         *
    503         * この属性は、caseKey , caseVal , caseNN , caseNull , caseIf とともに useTag() の判定で使用されます｡
    504         *
    505         * @og.rev 5.6.8.0 (2013/09/06) 新規追加
    506         *
    507         * @param       cnul    Null判定値 (何も指定されない場合は使用すると判断)
    508         * @see         #setCaseVal( String )
    509         * @see         #useTag()
    510         */
    511        public void setCaseNull( final String cnul ) {
    512                final String tempNull = nval( getRequestParameter( cnul ),null );
    513
    514                caseNull = tempNull == null || tempNull.isEmpty() ;
    515        }
    516
    517        /**
    518         * 【TAG】このﾀｸﾞ自体を利用するかどうかの条件としてtrue/TRUEかどうか判定します(初期値:判定しない)｡
    519         *
    520         * @og.tag
    521         * この値が、true/TRUE文字列 の場合はこのﾀｸﾞは使用されます｡
    522         * それ以外の場合は、このﾀｸﾞは使用されません｡
    523         * {&#064;XXXX} を指定した場合は、null/ｾﾞﾛ文字列でも使用しないと判定されますので、ご注意ください｡
    524         *
    525         * 7.0.1.1 (2018/10/22)
    526         *  引数の先頭に、'!' を記述した場合、false/FALSE 判定を行います｡
    527         *  ﾊﾟｰｽ後の値が、"true" か、"!false" の場合のみ、条件成立となります｡
    528         *
    529         *  "!{&#064;XXXX}" 指定の場合、null/ｾﾞﾛ文字列の場合は、"!" だけになり、使用されません
    530         *  これは、caseIfの反転ではありません｡
    531         *
    532         * この属性は、caseKey , caseVal , caseNN , caseNull , caseIf とともに useTag() の判定で使用されます｡
    533         *
    534         * @og.rev 6.2.6.0 (2015/06/19) caseIf 属性の追加
    535         * @og.rev 7.0.1.1 (2018/10/22) 属性に、'!' を使用できるようにします｡
    536         *
    537         * @param       cif     true/TRUE判定 (null/ｾﾞﾛ文字列場合のは使用しないと判定)
    538         * @see         #setCaseVal( String )
    539         * @see         #useTag()
    540         */
    541        public void setCaseIf( final String cif ) {
    542                // ※ 引数がnullの場合は、false。  nvl( flag,caseIf ) ではないので注意
    543//              caseIf = "true".equalsIgnoreCase( getRequestParameter( cif ) );
    544                final String flag = getRequestParameter( cif );         // null,ゼロ文字列もありうる。
    545                caseIf = "true".equalsIgnoreCase( flag ) || "!false".equalsIgnoreCase( flag );
    546        }
    547
    548        /**
    549         * このﾀｸﾞ自体を利用するかどうかの条件判定を行います｡
    550         *
    551         * caseNN &amp;&amp; caseNull &amp;&amp; caseIf &amp;&amp;
    552         *    ( (caseKey == null &amp;&amp; caseVal == null) ||
    553         *      (caseKey != null &amp;&amp; caseVal != null &amp;&amp; caseKey.matches( caseVal )))
    554         * の結果を返します｡
    555         *
    556         * これは、ﾀｸﾞ本体に、条件式を登録できる機能です｡必要なﾀｸﾞには、tld ﾌｧｲﾙで、
    557         * caseKey 、caseVal 、caseNN 、caseNull属性が使用できるように、設定します｡
    558         * 各ﾀｸﾞを、equals ﾀｸﾞで括る方法では、ｿｰｽの見通しが悪くなるため、
    559         * ある程度ﾀｸﾞ自身に判定機能を設けることで対応できるようにしました｡
    560         * ただ、本来、JSP 側にﾛｼﾞｯｸを持ち込むのはよくないので、利用に関しては、
    561         * 慎重にお願いします｡
    562         *
    563         * @og.rev 5.2.2.0 (2010/11/01) 新規追加
    564         * @og.rev 5.6.3.3 (2013/04/19) 条件変更(caseKey と caseVal が 両方とも null の場合のみ true)
    565         * @og.rev 5.6.7.0 (2013/07/27) caseNN 属性追加｡先のcaseKey、caseVal 条件と、AND 結合になります｡
    566         * @og.rev 5.6.8.0 (2013/09/06) caseNull 属性追加｡先の条件と、AND 結合になります｡
    567         * @og.rev 6.2.6.0 (2015/06/19) caseIf 属性の追加
    568         *
    569         * @return      このﾀｸﾞ自体を利用するかどうか(true:利用する/false:利用しない)
    570         * @see         #setCaseVal( String )
    571         * @see         #setCaseKey( String )
    572         * @see         #setCaseNN( String )
    573         * @see         #setCaseIf( String )
    574         */
    575        protected boolean useTag() {
    576//              return caseNN && caseNull && caseIf &&
    577//                                      ( (caseKey == null && caseVal == null) ||
    578//                                        (caseKey != null && caseVal != null && caseKey.matches( caseVal ))) ;
    579                return caseNN && caseNull && caseIf &&                                                                  // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
    580                                        ( caseKey == null && caseVal == null ||
    581                                          caseKey != null && caseVal != null && caseKey.matches( caseVal ) ) ;
    582        }
    583
    584        /**
    585         * (通常は使いません)ﾀｸﾞで処理される処理がﾒｲﾝとなるﾄﾗﾝｻﾞｸｼｮﾝ処理かどうかを指定します(初期値:false)｡
    586         *
    587         * この値は、ﾌｧｲﾙﾀﾞｳﾝﾛｰﾄﾞ処理に影響します｡この値がtrueに指定された時にcommitされたDBTableModelが
    588         * ﾌｧｲﾙﾀﾞｳﾝﾛｰﾄﾞの対象の表になります｡
    589         *
    590         * このﾊﾟﾗﾒｰﾀｰは、通常、各ﾀｸﾞにより実装され、ﾕｰｻﾞｰが指定する必要はありません｡
    591         * 但し、1つのJSP内でDBTableModelが複数生成される場合に、前に処理したDBTableModelについてﾌｧｲﾙﾀﾞｳﾝﾛｰﾄﾞをさせたい
    592         * 場合は、後ろでDBTableModelを生成するﾀｸﾞで、明示的にこの値をfalseに指定することで、ﾌｧｲﾙﾀﾞｳﾝﾛｰﾄﾞ処理の対象から
    593         * 除外することができます｡
    594         *
    595         * @og.rev 5.1.6.0 (2010/05/01) 新規作成
    596         *
    597         * @param       flag    ﾒｲﾝﾄﾗﾝｻﾞｸｼｮﾝ処理かどうか [true:ﾒｲﾝ/false:その他]
    598         */
    599        protected void useMainTrans( final boolean flag ) {
    600                useTrans = flag;
    601        }
    602
    603        /**
    604         * ﾒｯｾｰｼﾞﾗﾍﾞﾙ(msglbl)を取得します｡
    605         *
    606         * ﾒｯｾｰｼﾞﾗﾍﾞﾙは、lbl属性で登録された値を、
    607         * それぞれのﾘｿｰｽに応じて各言語に変換した結果を格納しています｡
    608         *
    609         * @og.rev 4.0.0.0 (2005/01/31) msglbl は、LabelInterface ｵﾌﾞｼﾞｪｸﾄを利用
    610         *
    611         * @return      ﾒｯｾｰｼﾞﾗﾍﾞﾙ
    612         * @see         #setLbl( String )
    613         */
    614        protected String getMsglbl() {
    615                String rtn = null;
    616
    617                if( msglbl != null ) { rtn = msglbl.getLabel(); }
    618
    619                return rtn ;
    620        }
    621
    622        /**
    623         * ﾒｯｾｰｼﾞﾗﾍﾞﾙ(msglbl)のﾁｯﾌﾟｽ表記を取得します｡
    624         *
    625         * ﾒｯｾｰｼﾞﾗﾍﾞﾙは、lbl属性で登録された値を、
    626         * それぞれのﾘｿｰｽに応じて各言語に変換した結果を格納しています｡
    627         * 別途、title属性を指定している場合は、置き換えます｡
    628         *
    629         * @og.rev 4.0.0.0 (2005/01/31) msglbl は、LabelInterface ｵﾌﾞｼﾞｪｸﾄを利用
    630         *
    631         * @return      ﾒｯｾｰｼﾞﾗﾍﾞﾙ
    632         */
    633        protected String getLongLabel() {
    634                String rtn = null;
    635
    636                if( msglbl != null ) {
    637                        rtn = msglbl.getLongLabel( get( "title" ) );
    638                }
    639
    640                return rtn ;
    641        }
    642
    643        /**
    644         * ﾒｯｾｰｼﾞﾗﾍﾞﾙ(LabelInterface)を取得します｡
    645         *
    646         * ﾒｯｾｰｼﾞﾗﾍﾞﾙは、lbl属性で登録された値を、
    647         * それぞれのﾘｿｰｽに応じて各言語に変換した結果を格納しています｡
    648         *
    649         * @return      ﾒｯｾｰｼﾞﾗﾍﾞﾙ
    650         */
    651        protected LabelInterface getLabelInterface() {
    652                return msglbl ;
    653        }
    654
    655        /**
    656         * ResourceManager を取得します｡
    657         *
    658         * ﾍﾟｰｼﾞｽｺｰﾌﾟ にｾｯﾄされた ResourceManager があれば、それを、
    659         * なければ、language 属性よりﾃﾞﾌｫﾙﾄ ResourceManager を構築します｡
    660         * LOCAL_RES_KEY で管理される ResourceManager は、LocalResourceTag で
    661         * 登録されたﾘｿｰｽです｡これは、ﾛｰｶﾙﾘｿｰｽ情報として、使用されます｡
    662         *
    663         * @return      ResourceManagerｵﾌﾞｼﾞｪｸﾄ
    664         */
    665        protected ResourceManager getResource() {
    666                if( resource == null ) {
    667                        resource = (ResourceManager)pageContext.getAttribute( HybsSystem.LOCAL_RES_KEY );
    668                        if( resource == null ) {
    669                                resource = ResourceFactory.newInstance( getLanguage() );
    670                        }
    671                }
    672                return resource;
    673        }
    674
    675        /**
    676         * ﾃﾞﾊﾞｯｸﾞ情報を出力するかどうか[true:する/false:しない]を取得します｡
    677         *
    678         * setDebug( String )で登録します｡
    679         * 初期値は、false です｡
    680         *
    681         * @og.rev 3.5.5.3 (2004/04/09) getDebug() から、ﾒｿｯﾄﾞ名変更
    682         *
    683         * @return      ﾃﾞﾊﾞｯｸﾞ出力 [true:する/false:しない]
    684         */
    685        protected boolean isDebug() {
    686                return debugFlag ;
    687        }
    688
    689        /**
    690         * ﾗﾍﾞﾙ文字列を返します｡
    691         *
    692         * これは、{&#064;LBL.XXXX %Y} 引数処理をおこなうための、ｻﾎﾟｰﾄﾒｿｯﾄﾞです｡
    693         * 引数は、"XXXX %Y" という状態で受け取ります｡(LBL. ははずした形)
    694         * ﾗﾍﾞﾙには、通常のﾗﾍﾞﾙ(Label)以外に、Short,Tips,Description,RawShortLabel の情報を持っています｡
    695         * {&#064;LBL.XXXX %Y} の Y に、L(ﾗﾍﾞﾙ長),S(ﾗﾍﾞﾙ短),R(生ﾗﾍﾞﾙ短),B(ｺｰﾄﾞ長),C(ｺｰﾄﾞ短),D(概要説明),T(ﾂｰﾙﾁｯﾌﾟ)
    696         * を指定することで、それぞれの状態を取得することが可能になります｡
    697         * Y を指定しない場合({&#064;LBL.XXXX}) は、'L' が指定された場合と同じ効果があります｡
    698         * Y は、先頭文字１文字で判断していますので、{&#064;LBL.XXXX %Short}と記述できます｡
    699         * Y 引数には、&#064;で始まるﾘｸｴｽﾄ引数が指定できます｡例えば、{&#064;LBL.XXXX &#064;ZZ}
    700         * とすると、ZZ のﾘｸｴｽﾄ引数の値が Y に適用されます｡
    701         * ﾗﾍﾞﾙｷｰそのものをﾊﾟﾗﾒｰﾀ化することが出来ます｡
    702         * これは、{&#064;LBL.&#064;XXXX}という形式になります｡引数は、先の説明と同じです｡
    703         * この場合は、XXXX をｷｰにﾘｸｴｽﾄ引数の値が、ﾗﾍﾞﾙﾘｿｰｽのｷｰになります｡
    704         *
    705         * @og.rev 4.0.0.0 (2007/10/17) ﾒｯｾｰｼﾞﾘｿｰｽ統合に伴い、{&#064;LBL.XXXX Y}⇒{&#064;LBL.XXXX %Y}
    706         * @og.rev 5.4.0.1 (2011/11/01) ﾗﾍﾞﾙ形式('L','S','T','D') に、R(RawShortLabel) を追加
    707         * @og.rev 5.5.7.2 (2012/10/09) ﾗﾍﾞﾙ形式('L','S','T','D','R') に、C(CodeData) を追加
    708         * @og.rev 7.2.9.0 (2020/10/12) ﾗﾍﾞﾙ形式('L','S','T','D','R','C') 処理を、ﾒｿｯﾄﾞに変更(null時はｷｰを返す)
    709         * @og.rev 7.2.9.0 (2020/10/12) getRawShortLabelで、null時は key を返します｡
    710         * @og.rev 8.1.2.1 (2022/03/25) ﾗﾍﾞﾙ形式に B(ｺｰﾄﾞ長) 追加
    711         *
    712         * @param       lbl ﾗﾍﾞﾙのｷｰ
    713         *
    714         * @return      ﾗﾍﾞﾙ文字列
    715         */
    716        protected String getLabel( final String lbl ) {
    717
    718                String key = lbl ;
    719                String val = null;
    720
    721                final int spc = lbl.indexOf( ' ' );             // " " があるかどうか
    722                if( spc > 0 ) {
    723                        key = lbl.substring( 0,spc );
    724                        if( key.charAt(0) == '@' ) { key = getRequestValue( key.substring( 1 ) ); }
    725
    726                        // リクエスト引数が指定された場合
    727                        char ch  = lbl.length() > spc+1 ? lbl.toUpperCase( Locale.JAPAN ).charAt( spc+1 ) : ' ';        // Label,Short,Tips,Description
    728                        char ch2 = lbl.length() > spc+2 ? lbl.toUpperCase( Locale.JAPAN ).charAt( spc+2 ) : ' ';        // Label,Short,Tips,Description
    729                        if( ch == '@' ) {
    730                                final String tmp = getRequestValue( lbl.substring( spc+2 ) );
    731                                if( tmp != null && tmp.length() > 0 ) {
    732                                        ch  = tmp.toUpperCase( Locale.JAPAN ).charAt(0);
    733                                        ch2 = tmp.length() > 1 ? tmp.toUpperCase( Locale.JAPAN ).charAt( 1 ) : ' ';
    734                                }
    735                        }
    736                        // 4.0.0.0 (2007/10/19)
    737                        if( ch == '%' ) {
    738                                switch( ch2 ) {
    739                                        case 'L': val = getResource().getLabel( key ); break;
    740//                                      case 'S': val = getResource().getLabelData( key ).getShortLabel(); break;
    741//                                      case 'T': val = getResource().getLabelData( key ).getLongLabel(); break;
    742//                                      case 'D': val = getResource().getLabelData( key ).getDescription(); break;
    743//                                      case 'R': val = getResource().getLabelData( key ).getRawShortLabel(); break;    // 5.4.0.1 (2011/11/01)
    744//                                      case 'C': val = getResource().getLabelData( key + "." + getRequestValue( key ) ).getShortLabel(); break;        // 5.5.7.2 (2012/10/09)
    745                                        // 7.2.9.0 (2020/10/12) ﾗﾍﾞﾙ形式('L','S','T','D','R','C') 処理を、ﾒｿｯﾄﾞに変更(null時はｷｰを返す)
    746                                        case 'S': val = getResource().getShortLabel(    key ); break;
    747//                                      case 'R': val = getResource().getRawShortLabel( key ); break;           // 5.4.0.1 (2011/11/01)
    748                                        case 'R': val = getResource().getRawShortLabel( key,true ); break;      // 7.2.9.0 (2020/10/12)
    749                                        case 'B': val = getResource().getLabel( key + "." + getRequestValue( key ) ); break;            // 8.1.2.1 (2022/03/25)
    750                                        case 'C': val = getResource().getShortLabel( key + "." + getRequestValue( key ) ); break;       // 5.5.7.2 (2012/10/09)
    751                                        case 'D': val = getResource().getDescription(   key ); break;
    752                                        case 'T': val = getResource().getLongLabel(     key ); break;
    753                                        default : break;
    754                                }
    755                        }
    756                        else if( ch != ' ' ) {
    757                                String[] msgVals = StringUtil.csv2Array( lbl.substring( spc+1 ),' ' );
    758                                for( int i=0; i<msgVals.length; i++ ) {
    759                                        // ﾘｸｴｽﾄ文字ﾊﾟﾗﾒｰﾀ時の処理｡その他は、ﾗﾍﾞﾙ文字は処理不要｡
    760                                        if( StringUtil.startsChar( msgVals[i] , '@' ) ) {                       // 6.4.1.1 (2016/01/16) １文字 String.startsWith
    761                                                msgVals[i] = getRequestValue( msgVals[i].substring( 1 ) );
    762                                        }
    763                                }
    764                                val = getResource().getLabel( key,msgVals );
    765                        }
    766                }
    767                else {
    768                        if( key.charAt(0) == '@' ) { key = getRequestValue( key.substring( 1 ) ); }
    769                }
    770
    771                if( val == null ) { val = getResource().getLabel( key ); }
    772                return val;
    773        }
    774
    775        /**
    776         * DBColumn ｵﾌﾞｼﾞｪｸﾄを返します｡
    777         *
    778         * これは、ｷｰを元に DBColumnｵﾌﾞｼﾞｪｸﾄをｶﾗﾑﾘｿｰｽの
    779         * 定義ﾌｧｲﾙより取得して、ﾘｿｰｽﾏﾈｰｼﾞｬで管理します｡
    780         *
    781         * @param       key     ｵﾌﾞｼﾞｪｸﾄのｷｰ
    782         * @return      DBColumnｵﾌﾞｼﾞｪｸﾄ
    783         */
    784        protected DBColumn getDBColumn( final String key ) {
    785                return getResource().makeDBColumn( key ) ;
    786        }
    787
    788        /**
    789         * 内部の Attributes ｵﾌﾞｼﾞｪｸﾄに、属性値をｾｯﾄします｡
    790         *
    791         * 同じｷｰの値が登録されていた場合は、置き換えられます｡
    792         *
    793         * @param       key             ｷｰ
    794         * @param       value   属性値
    795         * @see         #add( String , String )
    796         */
    797        protected void set( final String key, final String value ) {
    798                attri.set( key,value );
    799        }
    800
    801        /**
    802         * 内部の Attributes ｵﾌﾞｼﾞｪｸﾄに、属性値を追加します｡
    803         *
    804         * ここでは、すでに同じｷｰが登録されている場合は、その値に、
    805         * 標準ｾﾊﾟﾚｰﾀ(ｽﾍﾟｰｽ)を追加して、文字列結合します｡
    806         * たとえば、class 属性などは、値をｽﾍﾟｰｽで追加する事で、
    807         * CSS で処理することができます｡
    808         *
    809         * @og.rev 4.0.0.0 (2007/05/18) 新規追加
    810         *
    811         * @param       key             ｷｰ
    812         * @param       value   属性値
    813         * @see         #add( String , String , String )
    814         * @see         #set( String , String )
    815         */
    816        protected void add( final String key, final String value ) {
    817                attri.add( key,value );
    818        }
    819
    820        /**
    821         * 内部の Attributes ｵﾌﾞｼﾞｪｸﾄに、属性値を追加します｡
    822         *
    823         * ここでは、すでに同じｷｰが登録されている場合は、その値に、
    824         * 引数のｾﾊﾟﾚｰﾀを追加して、文字列結合します｡
    825         *
    826         * @og.rev 3.5.0.0 (2003/09/17) 新規追加
    827         * @og.rev 3.5.5.9 (2004/06/07) ｾﾊﾟﾚｰﾀ引数付きのﾒｿｯﾄﾞに変更
    828         *
    829         * @param       key             ｷｰ
    830         * @param       value   属性値
    831         * @param       sepa    ｾﾊﾟﾚｰﾀ
    832         * @see         #add( String , String )
    833         */
    834        protected void add( final String key, final String value, final String sepa ) {
    835                attri.add( key,value,sepa );
    836        }
    837
    838        /**
    839         * 内部の Attributes ｵﾌﾞｼﾞｪｸﾄから、属性値を取得します｡
    840         *
    841         * @param       key     ｷｰ
    842         * @return      属性値
    843         * @see         #set( String , String )
    844         */
    845        protected String get( final String key ) {
    846                return attri.get( key );
    847        }
    848
    849        /**
    850         * 属性ｵﾌﾞｼﾞｪｸﾄの取得｡
    851         *
    852         * Attributes ｵﾌﾞｼﾞｪｸﾄを取得します｡
    853         *
    854         * @return      Attributesｵﾌﾞｼﾞｪｸﾄ
    855         */
    856        protected Attributes getAttributes() {
    857                return attri;
    858        }
    859
    860        /**
    861         * {&#064;XXXX} 形式の文字列から XXXX をｷｰとして ServletRequest から getParameter で値を取り出します｡
    862         *
    863         * 他の文字列に混在した {&#064;XXXX} 文字を変換可能です｡
    864         * ただし、処理の簡素化のため、上記形式以外は変換いたしません｡
    865         * ｴﾗｰ例)× { &#064;XXXX }、{&#064; XXXX }、{&#064;XXXX&#064;yyyy}、{&#064;XXXX{&#064;yyyy}}
    866         * また、"{&#064;" を通常の記述で使うことは無いと考え、ｴｽｹｰﾌﾟも用意して
    867         * いません｡よって、"{&#064;" のﾊﾟﾀｰﾝが見つかって,"}" で閉じられていない
    868         * 場合は,ｴﾗｰとして、HybsSystemException を throw します｡
    869         *
    870         * @og.rev 3.8.0.4 (2005/08/08) {} の処理方法見直し｡連続処理、単体処理を可能にします｡
    871         *
    872         * @param       key     ﾘｸｴｽﾄのｷｰ
    873         * @return      ﾘｸｴｽﾄの値
    874         * @og.rtnNotNull
    875         */
    876        protected String getRequestParameter( final String key ) {
    877                isReqNull = false;
    878
    879                if( key == null ) { isReqNull = true; return ""; }
    880                int index = key.indexOf( "{@" );
    881                if( index < 0 ) { return key; }
    882
    883                // 変数が "{@XXXX}" の場合を優先的に検索。
    884                // これにより多くのﾊﾟﾀｰﾝで、StringTokenizer による
    885                // 文字列操作を行う必要がなくなります｡
    886                if( index == 0 &&
    887                        key.indexOf( '}' ) == key.lastIndexOf( '}' ) &&                                         // 6.4.2.1 (2016/02/05) PMD refactoring. Useless parentheses.
    888                        key.charAt(key.length()-1) == '}' ) {
    889                                return getRequestValue( key.substring( 2,key.length()-1 ) );
    890                }
    891
    892                // 3.8.0.4 (2005/08/08) {} の処理方法見直し。連続処理、単体処理を可能にします。
    893                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
    894                int start = 0;
    895                while( index >= 0 ) {
    896                        final int end = key.indexOf( '}',index );
    897                        if( end < 0 ) {
    898                                final String errMsg = "{@ と } との対応関係がずれています。" + CR
    899                                                        + "key=[" + key + "] : index=" + index ;
    900                                throw new HybsSystemException( errMsg );
    901                        }
    902
    903                        // {@ より前方の文字列を追加
    904                        if( index > 0 ) { rtn.append( key.substring( start,index ) ); }
    905
    906                        // {@XXXX} の XXXX部分を処理
    907                        final String val = getRequestValue( key.substring( index+2,end ) );
    908                        if( val != null ) { rtn.append( val ); }
    909
    910                        start = end+1 ;
    911                        index = key.indexOf( "{@",start );
    912                }
    913                rtn.append( key.substring( start ) );
    914
    915                return rtn.toString();
    916        }
    917
    918        /**
    919         * {&#064;XXX.YYYY} 形式の文字列から値を取得します｡
    920         * 予約語のみ処理をし、それ以外は{&#064;xxx}のままとします｡
    921         *
    922         * 他の文字列に混在した {&#064;XXXX} 文字を変換可能です｡
    923         * ただし、処理の簡素化のため、上記形式以外は変換いたしません｡
    924         * ｴﾗｰ例）× { &#064;XXXX }、{&#064; XXXX }、{&#064;XXXX&#064;yyyy}、{&#064;XXXX{&#064;yyyy}}
    925         * また、"{&#064;" を通常の記述で使うことは無いと考え、ｴｽｹｰﾌﾟも用意して
    926         * いません｡よって、"{&#064;" のﾊﾟﾀｰﾝが見つかって,"}" で閉じられていない
    927         * 場合は,ｴﾗｰとして、HybsSystemException を throw します｡
    928         *
    929         * @og.rev 5.5.4.0 (2012/07/02) 新規作成
    930         *
    931         * @param       key     ﾘｸｴｽﾄのｷｰ
    932         * @return      ﾘｸｴｽﾄの値
    933         * @og.rtnNotNull
    934         */
    935        protected String getReservedParameter( final String key ) {
    936                isReqNull = false;
    937
    938                if( key == null ) { isReqNull = true; return ""; }
    939                int index = key.indexOf( "{@" );
    940                if( index < 0 ) { return key; }
    941
    942                // 変数が "{@XXXX}" の場合を優先的に検索｡
    943                // これにより多くのﾊﾟﾀｰﾝで、StringTokenizer による
    944                // 文字列操作を行う必要がなくなります｡
    945                if( index == 0 &&
    946                        key.indexOf( '}' ) == key.lastIndexOf( '}' ) &&                                         // 6.4.2.1 (2016/02/05) PMD refactoring. Useless parentheses.
    947                        key.charAt(key.length()-1) == '}' ) {                                                           // 6.4.2.1 (2016/02/05) PMD refactoring. Useless parentheses.
    948                                return getReservedValue( key.substring( 2,key.length()-1 ) );
    949                }
    950
    951                // 3.8.0.4 (2005/08/08) {} の処理方法見直し。連続処理、単体処理を可能にします。
    952                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
    953                int start = 0;
    954                while( index >= 0 ) {
    955                        final int end = key.indexOf( '}',index );
    956                        if( end < 0 ) {
    957                                final String errMsg = "{@ と } との対応関係がずれています。" + CR
    958                                                        + "key=[" + key + "] : index=" + index ;
    959                                throw new HybsSystemException( errMsg );
    960                        }
    961
    962                        // {@ より前方の文字列を追加
    963                        if( index > 0 ) { rtn.append( key.substring( start,index ) ); }
    964
    965                        // {@XXXX} の XXXX部分を処理
    966                        final String val = getReservedValue( key.substring( index+2,end ) );
    967                        if( val != null ) { rtn.append( val ); }
    968
    969                        start = end+1 ;
    970                        index = key.indexOf( "{@",start );
    971                }
    972                rtn.append( key.substring( start ) );
    973
    974                return rtn.toString();
    975        }
    976
    977        /**
    978         * {&#064;XXXX} 形式の文字列から XXXX をｷｰとして ServletRequest から getParameterValues で値を取り出します｡
    979         *
    980         * これは、複数(配列)でﾘｸｴｽﾄを取り出すことが可能です｡
    981         * そのため、他の文字列に混在させて変換することができません｡
    982         * "{&#064;XXXX}" 形式 からのみの変換となります｡
    983         *
    984         * @og.rev 3.6.0.0 (2004/09/22) ｷｰがnull のときにnullではなく長さ０の配列を返します｡
    985         *
    986         * @param       key     ﾘｸｴｽﾄのｷｰ
    987         * @return      ﾘｸｴｽﾄの値
    988         * @og.rtnNotNull
    989         */
    990        protected String[] getRequestParameterValues( final String key ) {
    991                if( key == null ) { return new String[0]; }             // 3.6.0.0 (2004/09/22)
    992                final int index = key.indexOf( "{@" );
    993                if( index < 0 ) { return StringUtil.csv2Array( key ); }
    994
    995                if( index == 0 && key.charAt( key.length()-1 ) == '}' ) {
    996                        return getRequestValues( key.substring( 2,key.length()-1 ) );
    997                }
    998
    999                final String errMsg = "引数の形式が異なります。 [" + key + "]" ;
    1000                throw new HybsSystemException( errMsg );
    1001        }
    1002
    1003        /**
    1004         * 引数 inStr が、引数 check のSetの中に存在すれば、 true を、存在しなければ、false を返します｡
    1005         *
    1006         * check は、 String配列 を、inStr は、null でも構いません｡
    1007         * ※ 6.3.5.0 (2015/08/08) 大文字小文字の区別廃止｡
    1008         *
    1009         * @og.rev 2.1.0.3 (2002/11/08) 文字列配列を引数に取るﾒｿｯﾄﾞを追加
    1010         * @og.rev 6.3.5.0 (2015/08/08) forﾙｰﾌﾟの変更と、大文字小文字の区別廃止
    1011         * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます｡
    1012         *
    1013         * @param       inStr   ﾁｪｯｸする文字列
    1014         * @param       chkSet  ﾁｪｯｸ用の文字列Set
    1015         * @return      存在する true ／ 存在しない false
    1016         */
    1017        protected boolean check( final String inStr, final Set<String> chkSet ) {
    1018                return inStr != null && chkSet != null && chkSet.contains( inStr );
    1019        }
    1020
    1021        /**
    1022         * ﾕｰｻﾞｰｵﾌﾞｼﾞｪｸﾄが持っている内部情報を取得します｡
    1023         *
    1024         * これは、UserInfo#getAttribute( String ) で取得される情報です｡
    1025         * ﾕｰｻﾞｰﾊﾟﾗﾒｰﾀとは異なります｡
    1026         *
    1027         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 getUser() を使用するように変更
    1028         *
    1029         * @param       user    ﾕｰｻﾞｰ情報を取り出すｷｰ
    1030         *
    1031         * @return      ﾕｰｻﾞｰ情報文字列
    1032         */
    1033        protected String getUserInfo( final String user ) {
    1034                if( user == null ) { return null; }
    1035
    1036                String key = user ;
    1037                if( key.charAt(0) == '@' ) {
    1038                        key = getRequestValue( key.substring( 1 ) );
    1039                }
    1040
    1041                return getUser().getAttribute( key );
    1042        }
    1043
    1044        /**
    1045         * ﾕｰｻﾞｰｵﾌﾞｼﾞｪｸﾄが持っているEditの内部情報を取得します｡
    1046         *
    1047         * これは、UserInfo#getSelectedEdit( String ) で取得される情報です｡
    1048         * ﾕｰｻﾞｰﾊﾟﾗﾒｰﾀとは異なります｡
    1049         *
    1050         * @og.rev 5.8.2.3 (2014/12/27) 新規作成
    1051         *
    1052         * @param       guikey 取り出す画面ID
    1053         *
    1054         * @return      ﾕｰｻﾞｰ情報文字列
    1055         */
    1056        protected String getUserEditInfo( final String guikey ) {
    1057                if( guikey == null ) { return null; }
    1058
    1059                String key = guikey ;
    1060                if( key.charAt(0) == '@' ) {
    1061                        key = getRequestValue( key.substring( 1 ) );
    1062                }
    1063
    1064        // * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。
    1065        //      final DBEditConfigManager dbConfMgr = getUser().getEditConfigManager();         // 6.4.5.0 (2016/04/08)
    1066        //      return dbConfMgr.getSelectedEdit( key );
    1067                return getUser().getSelectedEdit( key );
    1068        }
    1069
    1070        /**
    1071         * ﾕｰｻﾞｰ情報を設定します｡
    1072         *
    1073         * 初めての場合は、session 登録項目 の HybsSystem#USERINFO_KEY ｷｰ の値で
    1074         * 取得します｡
    1075         * save属性は、GE20(ﾕｰｻﾞｰ定数)に情報を保存するかどうかを指定します｡
    1076         *
    1077         * @og.rev 2.1.1.4 (2002/11/25) ﾕｰｻﾞｰ情報をｾｯﾄするﾒｿｯﾄﾞを追加
    1078         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 getUser() を使用するように変更
    1079         * @og.rev 4.3.4.0 (2008/12/01) GE20(ﾕｰｻﾞｰ定数)へ登録するかのﾌﾗｸﾞを追加
    1080         *
    1081         * @param       key             ﾕｰｻﾞｰ情報をｾｯﾄするｷｰ
    1082         * @param       value   ﾕｰｻﾞｰ情報文字列
    1083         * @param       save    情報保存 [true:保存/false:保存しない]
    1084         */
    1085        protected void setUserInfo( final String key,final String value, final boolean save ) {
    1086                if( key != null ) {
    1087                        getUser().setAttribute( key, value, save );
    1088                }
    1089        }
    1090
    1091        /**
    1092         * ﾕｰｻﾞｰ情報ｵﾌﾞｼﾞｪｸﾄを取得します｡
    1093         *
    1094         * 初めての場合は、session 登録項目 の HybsSystem#USERINFO_KEY ｷｰ の値で
    1095         * 取得します｡
    1096         *
    1097         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 新規追加
    1098         * @og.rev 3.6.0.0 (2004/09/17) private ⇒ protected 化します｡
    1099         *
    1100         * @return      ﾕｰｻﾞｰ情報ｵﾌﾞｼﾞｪｸﾄ
    1101         * @og.rtnNotNull
    1102         */
    1103        protected UserInfo getUser() {
    1104                if( userInfo == null ) {
    1105                        userInfo = (UserInfo)getSessionAttribute( HybsSystem.USERINFO_KEY );
    1106                }
    1107                if( userInfo == null ) {
    1108                        final String errMsg = "ﾕｰｻﾞｰｵﾌﾞｼﾞｪｸﾄが存在しません。";
    1109                        throw new HybsSystemException( errMsg );
    1110                }
    1111                return userInfo ;
    1112        }
    1113
    1114        /**
    1115         * 画面情報(GUIInfo)を取得します｡
    1116         *
    1117         * これは、session 登録項目 の HybsSystem#GUIMAP_KEY ｷｰ の値で
    1118         * 登録された MAP を取り出し、そこから取得します｡
    1119         * 画面情報は、ﾛｸﾞｲﾝﾕｰｻﾞｰ毎に個別に持っています｡
    1120         *
    1121         * @og.rev 4.0.0.0 (2005/01/31) GUIInfo が存在しない場合も処理を続けます｡
    1122         *
    1123         * @param       gamenId 画面ID
    1124         * @return      画面情報(GUIInfo)
    1125         */
    1126        protected GUIInfo getGUIInfo( final String gamenId ) {
    1127                return getUser().getGUIInfo( gamenId );
    1128        }
    1129
    1130        /**
    1131         * 画面情報(GUIInfo)の属性値を取得します｡
    1132         *
    1133         * これは、{&#064;GUI.XXXX ID} 引数処理をおこなうための、ｻﾎﾟｰﾄﾒｿｯﾄﾞです｡
    1134         * 引数は、"XXXX ID" という状態で受け取ります｡(GUI. ははずした形)
    1135         * XXXXには、画面情報(GUIInfo)の属性ｷｰを指定します｡IDが指定されない場合は、
    1136         * 実行中の自分自身の画面が指定されたことになります｡
    1137         * これは、session 登録項目 の HybsSystem#GUIINFO_KEY ｷｰ の値で取得します｡
    1138         * この値は,画面が呼び出される毎に毎回設定されており、ﾘｸｴｽﾄ毎に
    1139         * 所得し直す必要があります｡
    1140         *
    1141         * ID に、画面IDを指定した場合は、&#064; 指定によるﾘｸｴｽﾄ引数の値を適用できます｡
    1142         * {&#064;GUI.&#064;XXXX ID} や、{&#064;GUI.XXXX &#064;ID} です｡(同時指定も可能)
    1143         *
    1144         * @og.rev 3.6.0.6 (2004/10/22) GUIInfo が存在しない場合も処理を続けます｡
    1145         * @og.rev 4.0.0.0 (2004/11/30) 画面ID引数や、ﾘｸｴｽﾄ引数の使用を可能にします｡
    1146         * @og.rev 5.9.32.2 (2018/05/18) ｴﾗｰ表示変更
    1147         * @og.rev 5.10.12.3 (2019/06/21) ｴﾗｰ表示変更
    1148         *
    1149         * @param       attkey  画面情報を取り出すｷｰ
    1150         * @return      画面情報文字列
    1151         */
    1152        protected String getGUIInfoAttri( final String attkey ) {
    1153                if( attkey == null ) { return null; }
    1154
    1155                String  key = attkey ;
    1156                final GUIInfo gui ;
    1157
    1158                final int spc = key.indexOf( ' ' );                                                                             // " " があるかどうか
    1159                if( spc > 0 ) {
    1160                        key = attkey.substring( 0,spc );
    1161                        String id = attkey.substring( spc+1 );
    1162                        if( StringUtil.startsChar( id , '@' ) ) {                                                       // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    1163                                id = getRequestValue( id.substring( 1 ) );
    1164                        }
    1165                        gui = getUser().getGUIInfo( id );
    1166                }
    1167                else {
    1168                        if( guiInfo == null ) {
    1169                                guiInfo = (GUIInfo)getSessionAttribute( HybsSystem.GUIINFO_KEY );
    1170                        }
    1171                        gui = guiInfo;
    1172                }
    1173//              if( gui == null ) { return "Not Found[" + attkey + "]"; }
    1174//              if( gui == null ) { return "Not Found(" + attkey + ")"; }                               // 5.9.32.2 (2018/05/18) []で囲むとﾃｰﾌﾞﾙﾓﾃﾞﾙで予期せぬｴﾗｰになるため変更
    1175                if( gui == null ) { return "NotFound_" + attkey ; }                                             // 5.10.12.3 (2019/06/21) URLで確実に使える文字のみで構成しておく
    1176                if( StringUtil.startsChar( key , '@' ) ) {                                                              // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    1177                        key = getRequestValue( key.substring( 1 ) );
    1178                }
    1179
    1180                return gui.getAttribute( key );
    1181        }
    1182
    1183        /**
    1184         * {&#064;NVL.XXX 値} で、XXXが NULLの場合、値を返します｡
    1185         *
    1186         * ORACLE等の COALESCE ( expr_list ) 処理に近い結果を返します｡
    1187         * NVL ( expr1 , expr2 ) は、expr1 が NULL の場合、expr2 を返しますが、
    1188         * COALESCE は、第一引数が NULLなら、次の引数、それも NULL なら、さらに次と
    1189         * 引数ﾘｽﾄを順次処理していきます｡
    1190         * それと同じく、XXX が NULL なら、その次･･と順次評価していき、NULL でない
    1191         * 値が返ってきたところで、その値を返します｡
    1192         * これは、{&#064;NVL.XXX &#064;YYY ZZZ ･･･} 形式を処理します｡
    1193         * これは、ﾊﾟﾗﾒｰﾀ XXX が NULLの場合、次の値を使います｡(&#064;YYY)
    1194         * &#064;YYY は、YYY ﾊﾟﾗﾒｰﾀの事で、これも NULL の場合は、ZZZ を使います｡
    1195         * 最後まで NULL の場合は、 ｾﾞﾛ文字列が返されます｡
    1196         *
    1197         * @og.rev 5.6.4.0 (2013/05/02) 新規追加
    1198         * @og.rev 6.9.3.0 (2018/03/26) ﾊﾟﾗﾒｰﾀ処理で、ﾀﾞﾌﾞﾙｸｵｰﾄ内は分解しない
    1199         * @og.rev 6.9.3.1 (2018/04/02) ﾊﾟﾗﾒｰﾀ処理で、ﾀﾞﾌﾞﾙｸｵｰﾄ内は分解しない･･の処理漏れ追加
    1200         * @og.rev 7.2.9.1 (2020/10/23) protected → private に変更
    1201         *
    1202         * @param       attkey  NVL情報を取り出すﾊﾟﾗﾒｰﾀ
    1203         *
    1204         * @return      NULL以外の値が出てくるまで、順次評価した結果
    1205         */
    1206//      protected String getNVLAttri( final String attkey ) {
    1207        private String getNVLAttri( final String attkey ) {
    1208                if( attkey == null ) { return null; }
    1209
    1210                final String[] keys = StringUtil.csv2Array( attkey,' ' );                               // ﾀﾞﾌﾞﾙｸｵｰﾄ内は分解しない｡
    1211//              final String[] keys = attkey.split( " " );                                                              // ｽﾍﾟｰｽで、ﾊﾟﾗﾒｰﾀを分解する｡
    1212                String val = getRequestValue( keys[0] );                                                                // 第一ﾊﾟﾗﾒｰﾀは、そのままのｷｰで検索
    1213
    1214                // val が null の間は、ﾁｪｯｸする｡
    1215                if( val == null || val.isEmpty() ) {
    1216                        for( int i=1; i<keys.length; i++ ) {
    1217                                val = keys[i];
    1218                                // 先頭が @ の場合は、ﾘｸｴｽﾄ変数のｷｰとして、値を判定
    1219                                if( StringUtil.startsChar( val , '@' ) ) {                                              // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    1220                                        if( val.indexOf( ' ' ) > 0 ) {                                                          // 6.9.3.1 (2018/04/02) 空白を含む場合は、ﾀﾞﾌﾞﾙｸｵｰﾄ内の処理
    1221                                                val = getReservedValue( val.substring( 1 ) );                   // 6.9.3.0 (2018/03/26) もう一度変数処理
    1222                                        }
    1223                                        else {
    1224                                                val = getRequestValue( val.substring( 1 ) );                    // 6.9.3.1 (2018/04/02) 一旦元に戻す｡
    1225                                        }
    1226//                                      val = getRequestValue( val.substring( 1 ) );
    1227//                                      val = getReservedValue( val.substring( 1 ) );                           // 6.9.3.0 (2018/03/26) もう一度変数処理
    1228                                }
    1229                                if( val != null && val.length() > 0 ) { break; }
    1230                        }
    1231                }
    1232
    1233                if( val == null ) { val = ""; }                                                                                 // NULL の場合は、ｾﾞﾛ文字列を返す。
    1234
    1235                return val;
    1236        }
    1237
    1238        /**
    1239         * {&#064;REP.XXX 置換元 置換先} で、XXX の文字列変換した値を返します｡
    1240         *
    1241         * XXX に対して、置換元文字列を置換先文字列で置換します｡
    1242         * これは、{&#064;REP.XXX &#064;YYY ZZZ} 形式を処理します｡
    1243         * これは、ﾊﾟﾗﾒｰﾀ XXX が NULLの場合、NULLを返します｡
    1244         * &#064;YYY は、YYY ﾊﾟﾗﾒｰﾀの事で、これが NULL の場合は、XXX を返します｡
    1245         *
    1246         * ※ ｸｫｰﾃｨｼｮﾝ(')を含む処理と、元々が IN 引数に、'AA,BB,CC' などの文字列処理を
    1247         *    行う( 'AA,'BB,'CC' ) のが目的だったので、引数なしの場合は、上記変換を行う｡
    1248         *
    1249         * @og.rev 8.0.0.0 (2021/09/30) REP.XXXX を追加します｡
    1250         *
    1251         * @param       attkey  文字列置換ﾊﾟﾗﾒｰﾀ
    1252         * @return      XXX 値の第一引数と第二引数を置換した値
    1253         */
    1254        private String getREPAttri( final String attkey ) {
    1255                if( attkey == null ) { return null; }
    1256
    1257                final String[] keys = StringUtil.csv2Array( attkey,' ' );                               // ﾀﾞﾌﾞﾙｸｵｰﾄ内は分解しない｡
    1258                String val = getRequestValue( keys[0] );                                                                // 第一ﾊﾟﾗﾒｰﾀは、そのままのｷｰで検索
    1259
    1260                if( val == null ) { val = ""; }                                                                                 // NULL の場合は、ｾﾞﾛ文字列を返す｡
    1261                if( keys.length < 3 ) {                                                                                                 // 引数が少ない場合は、"," を"','" に変換する。
    1262                        return val.replace( ",","','" );
    1263                }
    1264
    1265                // 置換元 文字列の取得
    1266                String key1 = keys[1];
    1267                // 先頭が @ の場合は、ﾘｸｴｽﾄ変数のｷｰとして、値を判定
    1268                if( StringUtil.startsChar( key1 , '@' ) ) {
    1269                        key1 = getRequestValue( key1.substring( 1 ) );                                          // @ を削除して、値の取得
    1270                }
    1271                if( key1 == null || key1.isEmpty() ) {
    1272                        return val;                                                                                                                     // 置換元が null か空文字列の場合は、置換しない
    1273                }
    1274
    1275                // 置換先 文字列の取得
    1276                String key2 = keys[2];
    1277                // 先頭が @ の場合は、ﾘｸｴｽﾄ変数のｷｰとして、値を判定
    1278                if( StringUtil.startsChar( key2 , '@' ) ) {
    1279                        key2 = getRequestValue( key2.substring( 1 ) );                                          // @ を削除して、値の取得
    1280                }
    1281                if( key2 == null )  {
    1282                        key2 = "";                                                                                                                      // 置換先が null か空文字列の場合は、削除になる。
    1283                }
    1284
    1285                return val.replace( key1,key2 );
    1286        }
    1287
    1288        /**
    1289         * {&#064;NN.XXX 値} で、XXXが NOT_NULLの場合、値を返します｡
    1290         *
    1291         * 値が存在した場合に、別の値に変更する動作になります｡
    1292         * 引数が、NULLの場合は、NULLなので、例えばある値が設定されれば、
    1293         * "true" を返すとか、"checked" を返すなどの処理が考えられます｡
    1294         * 値をｾｯﾄしなかった場合は、処理を行いません｡
    1295         *
    1296         * @og.rev 7.2.9.1 (2020/10/23) 新規追加
    1297         *
    1298         * @param       attkey  NOT_NULL情報を取り出すﾊﾟﾗﾒｰﾀ
    1299         * @return      NOT_NULLの場合、値を返します｡
    1300         */
    1301        private String getNNAttri( final String attkey ) {
    1302                if( attkey == null ) { return null; }                                                                   // 継続処理をさせるため、nullを返しておきます｡
    1303
    1304                String val = "" ;                                                                                                               // 不正なﾊﾟﾗﾒｰﾀやｷｰが NULLの場合の初期値
    1305
    1306                final int spc = attkey.indexOf( ' ' );                                                                  // " " があるかどうか
    1307                if( spc > 0 ) {                                                                                                                 // 値ﾊﾟﾗﾒｰﾀが存在するときのみ処理を行う｡
    1308                        String key = attkey.substring( 0,spc );
    1309                        if( StringUtil.startsChar( key , '@' ) ) {
    1310                                key = getRequestValue( key.substring( 1 ) );
    1311                        }
    1312                        key = getRequestValue( key );
    1313
    1314                        if( key != null && !key.isEmpty() ) {                                                           // key が NOT NULL の場合のみ、処理を行う。
    1315                                // 値を求める。
    1316                                val = attkey.substring( spc+1 );
    1317                                if( StringUtil.startsChar( id , '@' ) ) {                                               // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    1318                                        val = getRequestValue( id.substring( 1 ) );
    1319                                }
    1320                        }
    1321                }
    1322
    1323                return val;
    1324        }
    1325
    1326        /**
    1327         * {&#064;VALS.XXX ｱﾄﾞﾚｽ ｾﾊﾟﾚｰﾀ} で、XXXをｾﾊﾟﾚｰﾀで分解して、ｱﾄﾞﾚｽの値を返します｡
    1328         *
    1329         * ｾﾊﾟﾚｰﾀ の初期値は、,(ｶﾝﾏ)です｡
    1330         * XXX は、変数のｷｰﾜｰﾄﾞになります｡
    1331         *
    1332         * @og.rev 7.2.3.1 (2020/04/17) 新規追加
    1333         * @og.rev 7.2.9.1 (2020/10/23) protected → private に変更
    1334         *
    1335         * @param       attkey  VALS情報を取り出すﾊﾟﾗﾒｰﾀ
    1336         *
    1337         * @return      指定の変数をｾﾊﾟﾚｰﾀで分割してｱﾄﾞﾚｽ番目の文字列を取り出す｡
    1338         */
    1339//      protected String getValsAttri( final String attkey ) {
    1340        private String getValsAttri( final String attkey ) {
    1341                if( attkey == null ) { return null; }
    1342
    1343                final String[] keys = StringUtil.csv2Array( attkey,' ' );                               // ﾀﾞﾌﾞﾙｸｵｰﾄ内は分解しない｡
    1344                String val = getRequestValue( keys[0] );                                                                // 第一ﾊﾟﾗﾒｰﾀは、そのままのｷｰで検索
    1345
    1346                if( val == null || val.isEmpty() ) {
    1347                        val = "";                                                                                                                       // NULL の場合は、ｾﾞﾛ文字列を返す｡
    1348                }
    1349                else {
    1350                        final int      adrs = keys.length > 1 ? Integer.parseInt( keys[1] ) : 0 ;       // ｱﾄﾞﾚｽを取り出す
    1351                        final String   sep  = keys.length > 2 ? keys[2] : "," ;                         // 区切り文字列
    1352                        final String[] vals = val.split( sep );
    1353
    1354                        val = vals[adrs];
    1355                }
    1356
    1357                return val;
    1358        }
    1359
    1360        /**
    1361         * {&#064;SUBSTR.XXX 開始ｲﾝﾃﾞｯｸｽ 終了ｲﾝﾃﾞｯｸｽ} で、XXXの部分文字列を取り出します｡
    1362         *
    1363         * 終了ｲﾝﾃﾞｯｸｽを指定しない場合は、最後までです｡
    1364         * 開始ｲﾝﾃﾞｯｸｽ(この値を含む)から、終了ｲﾝﾃﾞｯｸｽ(この値を含まない)を切り出します｡
    1365         * ｲﾝﾃﾞｯｸｽは、文字数です｡
    1366         *
    1367         * @og.rev 7.2.3.1 (2020/04/17) 新規追加
    1368         * @og.rev 7.2.9.1 (2020/10/23) protected → private に変更
    1369         *
    1370         * @param       attkey  SUBSTR情報を取り出すﾊﾟﾗﾒｰﾀ
    1371         * @return      XXXの部分文字列
    1372         */
    1373//      protected String getSubstrAttri( final String attkey ) {
    1374        private String getSubstrAttri( final String attkey ) {
    1375                if( attkey == null ) { return null; }
    1376
    1377                final String[] keys = StringUtil.csv2Array( attkey,' ' );                               // ﾀﾞﾌﾞﾙｸｵｰﾄ内は分解しない｡
    1378
    1379                final String val = getAtmarkVas( keys[0],true );                                                        // ｷｰﾜｰﾄﾞをﾘｸｴｽﾄから処理する
    1380                final String ad1 = keys.length > 1 ? getAtmarkVas( keys[1],false ) : "" ;       // ｷｰﾜｰﾄﾞは、@が無ければそのままの値
    1381                final String ad2 = keys.length > 2 ? getAtmarkVas( keys[2],false ) : "" ;       // ｷｰﾜｰﾄﾞは、@が無ければそのままの値
    1382
    1383                final int id1 = ad1.isEmpty() ? 0                               : Integer.parseInt( ad1 );
    1384                final int id2 = ad2.isEmpty() ? val.length()    : Integer.parseInt( ad2 );
    1385
    1386                if( id1 < id2 && val.length() > id1 && val.length() >= id2 ) {
    1387                        return val.substring( id1,id2 );
    1388                }
    1389
    1390                return val;
    1391        }
    1392
    1393        /**
    1394         * {&#064;LAST.XXX} で、XXXが 最後に使われた値を返します｡
    1395         *
    1396         * XXX は、command="NEW" でｾｯﾄされたﾘｸｴｽﾄ値です｡通常、{&#064;MEM.XXX} は
    1397         * 画面単位に、既存のｷｬｯｼｭから値を取り出しますが、{&#064;LAST.XXX} は、
    1398         * 画面に関係なく、ﾕｰｻﾞｰ単位に管理しています｡
    1399         * また、値は、ﾃﾞｰﾀﾍﾞｰｽ(GE20)に保管されますので、次回ﾛｸﾞｲﾝ時にも有効です｡
    1400         * この処理が呼び出されたときに、ﾘｸｴｽﾄ変数に、XXXX が存在した場合は、そちらを優先に
    1401         * 使います｡その場合は、command に関係なく、値を設定しておきます｡
    1402         *
    1403         * command="NEW"の場合のﾘｸｴｽﾄ変数の値の設定は、RequestCacheTag で行います｡
    1404         *
    1405         * ※ ﾃﾞｰﾀﾍﾞｰｽには、画面ｱｸｾｽ情報のｾｰﾌﾞ時に行われます｡
    1406         * valueﾀｸﾞのsave属性の様に、ﾘｱﾙﾀｲﾑではありませんので、Tomcatが
    1407         * 異常終了した場合は、ｾｰﾌﾞされません｡
    1408         *
    1409         * @og.rev 5.6.8.1 (2013/09/13) 新規追加
    1410         * @og.rev 7.2.9.1 (2020/10/23) protected → private に変更
    1411         *
    1412         * @param       attkey  最後に使われた値をを取り出すﾊﾟﾗﾒｰﾀ
    1413         * @return      XXXが 最後に使われた値
    1414         * @see         org.opengion.hayabusa.taglib.RequestCacheTag#commandExec( String ,ServletRequest )
    1415         * @see         org.opengion.hayabusa.resource.UserInfo#getLastRequestValue( String )
    1416         */
    1417//      protected String getLASTAttri( final String attkey ) {
    1418        private String getLASTAttri( final String attkey ) {
    1419                if( attkey == null ) { return null; }
    1420
    1421                // 最新のﾘｸｴｽﾄ変数をﾁｪｯｸ
    1422                final String[] vals = getRequest().getParameterValues( attkey );
    1423
    1424                String val = null;
    1425                if( vals == null ) {
    1426                        val = getUser().getLastRequestValue( attkey );                                          // なければ、取得
    1427                }
    1428                else {
    1429                        for( int i=0; i<vals.length; i++ ) {
    1430                                val = vals[i];
    1431                                if( ! "0".equals( val ) ) { break; }                                                    // ﾁｪｯｸﾎﾞｯｸｽ対応
    1432                        }
    1433                        getUser().setLastRequestValue( attkey,val );                                            // あれば、最新の値をｾｯﾄ
    1434                }
    1435
    1436                return val ;
    1437        }
    1438
    1439        /**
    1440         * {&#064;SUMR.XXX} で、XXXの 複数ﾘｸｴｽﾄ時の値を合算します｡
    1441         *
    1442         * 同一ｷｰのﾘｸｴｽﾄ変数に、複数のﾊﾟﾗﾒｰﾀが
    1443         * 設定された場合、その値を合計します｡
    1444         * 数値変換できない場合は、ｶﾝﾏで連結します｡
    1445         * 通常は、edior="BITBOX" などで、数値の合計を求めるために使われます｡
    1446         *
    1447         * @og.rev 6.2.2.4 (2015/04/24) SUM追加
    1448         * @og.rev 6.2.3.0 (2015/05/01) CSV形式の作成を、String#join( CharSequence , CharSequence... )を使用｡
    1449         * @og.rev 7.2.0.0 (2020/02/14) SUMはValueTagとﾀﾞﾌﾞるため、SUMR とします｡
    1450         * @og.rev 7.2.9.1 (2020/10/23) protected → private に変更
    1451         *
    1452         * @param       attkey  最後に使われた値をを取り出すﾊﾟﾗﾒｰﾀ
    1453         * @return      XXXの 複数ﾘｸｴｽﾄ時の値を合算
    1454         */
    1455//      protected String getSumRequestValue( final String attkey ) {
    1456        private String getSumRequestValue( final String attkey ) {
    1457                if( attkey == null ) { return null; }
    1458
    1459                // 最新のﾘｸｴｽﾄ変数をﾁｪｯｸ
    1460                final String[] vals = getRequestValues( attkey );
    1461
    1462                String rtn = "";
    1463                if( vals != null && vals.length > 0 ) {
    1464                        try {
    1465                                int sum = 0;
    1466                                for( int i=0; i<vals.length; i++ ) {
    1467                                        final String val = vals[i];
    1468                                        if( val != null && !val.isEmpty() ) {
    1469                                                sum += Integer.parseInt( val );
    1470                                        }
    1471                                }
    1472                                rtn = String.valueOf( sum );                                                                    // 最後までｴﾗｰがなかった場合｡
    1473                        }
    1474                        catch( final NumberFormatException ex ) {
    1475                                // 数値変換ｴﾗｰ時は、文字列連結します｡
    1476                                // 6.2.3.0 (2015/05/01) CSV形式の作成を、String#join( CharSequence , CharSequence... )を使用｡
    1477                                rtn = String.join( "," , vals ) ;
    1478                        }
    1479                }
    1480
    1481                return rtn ;
    1482        }
    1483
    1484        /**
    1485         * {&#064;REQ.XXX} で、XXXの ﾘｸｴｽﾄｵﾌﾞｼﾞｪｸﾄのﾒｿｯﾄﾞの値を取得します｡
    1486         *
    1487         * HttpServletRequest のﾒｿｯﾄﾞを実行します｡
    1488         * それ以外に、ROWCOUNT というｷｰﾜｰﾄﾞで、選択された行数を返します｡
    1489         *
    1490         * 通常のﾘｸｴｽﾄの値以外にRestAPIで利用される場合のあるX-HTTP-Method-Overrideと、
    1491         * POSTﾃﾞｰﾀのBodyの値（JSONを変数名を指定せずに送信する場合がある）についても
    1492         * 取得できるようにしておきます｡
    1493         *
    1494         * <table class="plain">
    1495         *   <caption>{&#064;REQ.XXX}の説明</caption>
    1496         *   <tr><th>KEY</th><th>VALUE</th></tr>
    1497         *   <tr><td>ROWCOUNT           </td><td style="white-space: normal">ﾁｪｯｸされた件数</td></tr>
    1498         *   <tr><td>RequestURL         </td><td style="white-space: normal">request.getRequestURL()</td></tr>
    1499         *   <tr><td>AuthType           </td><td style="white-space: normal">request.getAuthType()</td></tr>
    1500         *   <tr><td>ContextPath        </td><td style="white-space: normal">request.getContextPath()</td></tr>
    1501         *   <tr><td>Method             </td><td style="white-space: normal">request.getMethod()</td></tr>
    1502         *   <tr><td>PathInfo           </td><td style="white-space: normal">request.getPathInfo()</td></tr>
    1503         *   <tr><td>PathTranslated     </td><td style="white-space: normal">request.getPathTranslated()</td></tr>
    1504         *   <tr><td>QueryString        </td><td style="white-space: normal">request.getQueryString()</td></tr>
    1505         *   <tr><td>RemoteUser         </td><td style="white-space: normal">request.getRemoteUser()</td></tr>
    1506         *   <tr><td>RequestURI         </td><td style="white-space: normal">request.getRequestURI()</td></tr>
    1507         *   <tr><td>ServletPath        </td><td style="white-space: normal">request.getServletPath()</td></tr>
    1508         *   <tr><td>RemoteAddr         </td><td style="white-space: normal">request.getRemoteAddr()</td></tr>
    1509         *   <tr><td>RemoteHost         </td><td style="white-space: normal">request.getRemoteHost()</td></tr>
    1510         *   <tr><td>Scheme             </td><td style="white-space: normal">request.getScheme()</td></tr>
    1511         *   <tr><td>ServerName         </td><td style="white-space: normal">request.getServerName()</td></tr>
    1512         *   <tr><td>ServerPort         </td><td style="white-space: normal">request.getServerPort()</td></tr>
    1513         *   <tr><td>MethodOverride     </td><td style="white-space: normal">X-HTTP-Method-Override</td></tr>
    1514         *   <tr><td>PostData           </td><td style="white-space: normal">request.getInputStream()</td></tr>
    1515         *   <tr><td>JSPID              </td><td style="white-space: normal">JSPﾌｧｲﾙ名</td></tr>
    1516         * </table>
    1517         *
    1518         * @og.rev 6.4.7.0 (2016/06/03) REQ追加
    1519         * @og.rev 5.10.10.0 (2019/03/29) MethodOverride追加
    1520         * @og.rev 7.0.4.1 (2019/06/10) {&#064;REQ.JSPID}追加
    1521         * @og.rev 5.10.10.1 (2019/04/05) BodyData追加
    1522         *
    1523         * @param       attkey  最後に使われた値を取り出すﾊﾟﾗﾒｰﾀ
    1524         * @return      XXXに対応したﾘｸｴｽﾄﾒｿｯﾄﾞの実行結果
    1525         */
    1526        protected String getRequestMethod( final String attkey ) {
    1527                if( attkey == null ) { return null; }
    1528
    1529                final HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
    1530
    1531                String rtn = "";
    1532
    1533                if(      "ROWCOUNT"                     .equalsIgnoreCase( attkey ) ) {
    1534                        final String[] vals = req.getParameterValues( HybsSystem.ROW_SEL_KEY );
    1535                        rtn = vals == null ? "0" : String.valueOf( vals.length );
    1536                }
    1537                else if( "RequestURL"           .equalsIgnoreCase( attkey ) ) { rtn = req.getRequestURL().toString();                   }
    1538                else if( "AuthType"                     .equalsIgnoreCase( attkey ) ) { rtn = req.getAuthType();                                                }
    1539                else if( "ContextPath"          .equalsIgnoreCase( attkey ) ) { rtn = req.getContextPath();                                             }
    1540                else if( "Method"                       .equalsIgnoreCase( attkey ) ) { rtn = req.getMethod();                                                  }
    1541                else if( "PathInfo"                     .equalsIgnoreCase( attkey ) ) { rtn = req.getPathInfo();                                                }
    1542                else if( "PathTranslated"       .equalsIgnoreCase( attkey ) ) { rtn = req.getPathTranslated();                                  }
    1543                else if( "QueryString"          .equalsIgnoreCase( attkey ) ) { rtn = req.getQueryString();                                             }
    1544                else if( "RemoteUser"           .equalsIgnoreCase( attkey ) ) { rtn = req.getRemoteUser();                                              }
    1545                else if( "RequestURI"           .equalsIgnoreCase( attkey ) ) { rtn = req.getRequestURI();                                              }
    1546                else if( "ServletPath"          .equalsIgnoreCase( attkey ) ) { rtn = req.getServletPath();                                             }
    1547                else if( "RemoteAddr"           .equalsIgnoreCase( attkey ) ) { rtn = req.getRemoteAddr();                                              }
    1548                else if( "RemoteHost"           .equalsIgnoreCase( attkey ) ) { rtn = req.getRemoteHost();                                              }
    1549                else if( "Scheme"                       .equalsIgnoreCase( attkey ) ) { rtn = req.getScheme();                                                  }
    1550                else if( "ServerName"           .equalsIgnoreCase( attkey ) ) { rtn = req.getServerName();                                              }
    1551                else if( "ServerPort"           .equalsIgnoreCase( attkey ) ) { rtn = String.valueOf( req.getServerPort() );    }
    1552                else if( "MethodOverride"       .equalsIgnoreCase( attkey ) ) { rtn = String.valueOf( req.getHeader("X-HTTP-Method-Override") ); }      //5.10.10.0 (2019/03/29)
    1553                else if( "ContentType"          .equalsIgnoreCase( attkey ) ) { rtn = String.valueOf( req.getHeader("Content-Type") ); }                        //5.10.10.1 (2019/04/05)
    1554                else if( "PostData"                     .equalsIgnoreCase( attkey ) ) {                                                                                                                                         //5.10.10.1 (2019/04/05)
    1555                        try( Scanner sc = new Scanner(req.getInputStream(), "UTF-8").useDelimiter("\\A"); ){
    1556                                rtn = sc.hasNext() ? sc.next() : "";
    1557                        }catch( final IOException ie ) {
    1558                                System.out.println(ie);
    1559                                rtn="";
    1560                        }
    1561                }
    1562                // 7.0.4.1 (2019/06/10) {&#064;REQ.JSPID}追加
    1563                else if( "JSPID"                        .equalsIgnoreCase( attkey ) ) {
    1564                        rtn = req.getRequestURI();
    1565                        final int ad = rtn.lastIndexOf( '/' );
    1566                        if( ad >= 0 ) {
    1567                                rtn = rtn.substring( ad+1 );
    1568                        }
    1569                }
    1570                // ﾕｰｻﾞｰｴｰｼﾞｪﾝﾄを取得します｡8.0.0.1 (2021/10/08)
    1571                else if( "userAgent"    .equalsIgnoreCase( attkey ) ) { rtn = String.valueOf( req.getHeader("user-agent") ); }
    1572
    1573                if( rtn == null ) { rtn = ""; }
    1574
    1575                return rtn ;
    1576        }
    1577
    1578        /**
    1579         * 予約語に関する情報の文字列を取得します｡
    1580         *
    1581         * @og.rev 5.5.4.0 (2012/07/02) 予約語部分のみ分離
    1582         * @og.rev 5.6.4.0 (2013/05/02) NVL 追加
    1583         * @og.rev 5.6.8.1 (2013/09/13) LAST 追加
    1584         * @og.rev 5.8.2.3 (2014/12/27) USEREDIT追加
    1585         * @og.rev 6.2.2.4 (2015/04/24) SUM追加
    1586         * @og.rev 6.4.7.0 (2016/06/03) REQ追加
    1587         * @og.rev 6.5.0.0 (2016/09/30)) VAL追加｡value値とﾘｸｴｽﾄ変数では、ﾘｸｴｽﾄ変数が上位なので、value値を取り出したい場合に使用します｡
    1588         * @og.rev 6.7.7.0 (2017/03/31) applicationｽｺｰﾌﾟの文字列を取得します｡
    1589         * @og.rev 6.7.7.2 (2017/04/14) VAL に、&#064; 付きのﾊﾟﾗﾒｰﾀを使えるようにします｡
    1590         * @og.rev 5.9.26.1 (2017/11/10) JSON追加｡JSON化するのではなく、JSONﾀｲﾌﾟのｴｽｹｰﾌﾟ処理をする｡
    1591         * @og.rev 7.0.5.0 (2019/09/09) 追加 ENV.で環境変数の値を取得できるようにします｡
    1592         * @og.rev 7.2.0.0 (2020/02/14) SUMはValueTagとﾀﾞﾌﾞるため、SUMR とします｡
    1593         * @og.rev 7.2.3.1 (2020/04/17) System.getenv → HybsConst.getenv 変更(ｻｰﾋﾞｽ化対応) , VALS 追加 , SUBSTR 追加
    1594         * @og.rev 7.2.9.1 (2020/10/23) NN 追加、if処理を少しだけ分割します｡
    1595         * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(DataRole.java廃止)
    1596         * @og.rev 8.0.0.0 (2021/09/30) TBL.XXXX を設定します｡(TBL.CLMS,TBL.LBLS,TBL.SLBLS,TBL.COLS,TBL.ROWS)
    1597         * @og.rev 8.0.0.0 (2021/09/30) REP.XXXX を追加します｡
    1598         *
    1599         * @param       key     ｷｰ
    1600         * @return      ﾘｸｴｽﾄ情報の文字列
    1601         * @og.rtnNotNull
    1602         */
    1603        protected String getReservedValue( final String key ) {
    1604                if( key == null ) { isReqNull = true; return ""; }                                              // 3.4.0.3 (2003/09/10)
    1605
    1606                String rtn = null;
    1607                final int adrs = key.indexOf( '.' );
    1608
    1609                if( adrs > 0 ) {
    1610                        final String subKey = key.substring( adrs+1 );
    1611                        if( adrs == 2 ) {
    1612                                // 4.0.0.0 (2007/06/12) DB.XXXX は、直接取り出すように変更します。
    1613                                if( key.startsWith( "DB." ) ) {
    1614                                        rtn = (String)getRequestAttribute( key );                                       // ※ 取り出しは、key で
    1615                                }
    1616                                // 7.2.9.1 (2020/10/23)  NN 追加
    1617                                else if( key.startsWith( "NN." ) ) {
    1618                                        rtn = getNNAttri( subKey );
    1619                                }
    1620                        }
    1621                        else if( adrs == 3 ) {
    1622                                // 3.8.0.2 (2005/07/11) MSG.XXXX で、ﾒｯｾｰｼﾞﾘｿｰｽの値を取得できるように追加｡
    1623                                // 3.8.0.2 (2005/07/11) LBL.XXXX で、ﾗﾍﾞﾙﾘｿｰｽの値を取得できるように追加｡
    1624                                if( key.startsWith( "LBL." ) ) {
    1625                                        rtn = getLabel( subKey );
    1626                                }
    1627                                else if( key.startsWith( "SYS." ) ) {
    1628                                        rtn = sys( subKey );            // 3.5.6.6 (2004/08/23)
    1629                                }
    1630                                // 3.4.0.3 (2003/09/10) MEM.XXXX で、REQUEST_CACHE の値を取得できるように修正。
    1631                                else if( key.startsWith( "MEM." ) ) {
    1632                                        // 3.5.4.7 (2004/02/06) getRequestCacheData を使用するように修正
    1633                                        rtn = getRequestCacheData( subKey );
    1634                                }
    1635                                // 5.6.4.0 (2013/05/02) NVL 追加
    1636                                else if( key.startsWith( "NVL." ) ) {
    1637                                        rtn = getNVLAttri( subKey );
    1638                                }
    1639                                // 8.0.0.0 (2021/09/30) REP.XXXX を追加します。
    1640                                else if( key.startsWith( "REP." ) ) {
    1641                                        rtn = getREPAttri( subKey );
    1642                                }
    1643                                // 6.5.0.0 (2016/09/30)) VAL追加
    1644                                else if( key.startsWith( "VAL." ) ) {
    1645                                        // 6.7.7.2 (2017/04/14) VAL に、&#064; 付きのﾊﾟﾗﾒｰﾀを使えるようにします｡
    1646                                        if( subKey != null && !subKey.isEmpty() && subKey.charAt(0) == '@' ) {
    1647                                                final String tmpKey = getRequestValue( subKey.substring( 1 ) );
    1648                                                rtn = (String)getRequestAttribute( tmpKey );
    1649                                        }
    1650                                        else {
    1651                                                rtn = (String)getRequestAttribute( subKey );                    // ※ 取り出しは、subKey で
    1652                                        }
    1653                                }
    1654                                // 6.4.7.0 (2016/06/03) REQ追加
    1655                                else if( key.startsWith( "REQ." ) ) {
    1656                                        rtn = getRequestMethod( subKey );
    1657                                }
    1658                                else if( key.startsWith( "GUI." ) ) {
    1659                                        rtn = getGUIInfoAttri( subKey );                                                        // 4.0.0 (2005/01/31)
    1660                                }
    1661                                // 6.7.7.0 (2017/03/31) applicationｽｺｰﾌﾟの文字列を取得します｡
    1662                                else if( key.startsWith( "APP." ) ) {
    1663                                        rtn = String.valueOf( getContextAttribute( subKey ) );
    1664                                }
    1665                                // 4.3.7.0 (2009/06/01) DB関数名の取得
    1666                                else if( key.startsWith( "DBF." ) ) {
    1667                                        rtn = getDBFunctionName( subKey );
    1668                                }
    1669                                // 5.5.1.3 (2012/04/09) ｴｽｹｰﾌﾟ変換
    1670                                else if( key.startsWith( "ESC." ) ) {
    1671                                        rtn = StringUtil.htmlFilter( getRequestValue(subKey,false) );
    1672                                }
    1673                                // 4.4.0.0 (2009/08/02) ﾃﾞｰﾀﾛｰﾙに基づく条件式の取得 7.4.4.0 (2021/06/30) Delete
    1674        //                      else if( key.startsWith( "SEC." ) ) {
    1675        //                              rtn = getDataCondition( subKey );
    1676        //                      }
    1677                                // 5.3.9.0 (2011/09/01) URLｴﾝｺｰﾄﾞ変換
    1678                                else if( key.startsWith( "URL." ) ) {
    1679                                        rtn = StringUtil.urlEncode( getRequestValue( subKey ) );
    1680                                }
    1681                                // 7.0.5.0 (2019/09/09) 追加 ENV.で環境変数の値を取得できるようにします。
    1682                                else if( key.startsWith( "ENV." ) ) {
    1683        //                              rtn = System.getenv( subKey );
    1684                                        rtn = HybsConst.getenv( subKey );                                                       // 7.2.3.1 (2020/04/17)
    1685                                }
    1686                                // 8.0.0.0 (2021/09/30) TBL.XXXX は、直接取り出すように変更します。(TBL.CLMS,TBL.LBLS,TBL.SLBLS,TBL.COLS,TBL.ROWS)
    1687                                else if( key.startsWith( "TBL." ) ) {
    1688                                        rtn = (String)getRequestAttribute( key );                                       // ※ 取り出しは、key で
    1689                                }
    1690                        }
    1691                        else if( adrs == 4 ) {
    1692                                // 3.8.0.2 (2005/07/11) DATE.XXXX で、日付関係の値を取得できるように追加。
    1693                                if( key.startsWith( "DATE." ) ) {
    1694                                        rtn = getDateFormat( subKey );
    1695                                }
    1696                                else if( key.startsWith( "USER." ) ) {
    1697                                        rtn = getUserInfo( subKey );
    1698                                }
    1699                                // 5.6.8.1 (2013/09/13) LAST 追加
    1700                                else if( key.startsWith( "LAST." ) ) {
    1701                                        rtn = getLASTAttri( subKey );
    1702                                }
    1703                                // 4.3.6.0 (2009/04/01) ﾒｰﾙﾓｼﾞｭｰﾙ用の予約語
    1704                                else if( key.startsWith( "MAIL." ) ) {
    1705                                        rtn = ( String )getSessionAttribute( key );
    1706                                }
    1707                                // 6.2.2.4 (2015/04/24) SUM追加
    1708                                // 7.2.0.0 (2020/02/14) SUMはValueTagとﾀﾞﾌﾞるため、SUMR とします｡
    1709                                // 他に、MIN,MAX,HMF,AVG も、ValueTagで使用中なので注意すること｡
    1710        //                      else if( key.startsWith( "SUM." ) ) {
    1711                                else if( key.startsWith( "SUMR." ) ) {
    1712                                        rtn = getSumRequestValue( subKey );
    1713                                }
    1714                                // 5.9.26.1 (2017/11/10) 追加 JSONﾀｲﾌﾟのｴｽｹｰﾌﾟを行う(JSONにするわけではない）
    1715                                else if( key.startsWith( "JSON." ) ) {
    1716                                        rtn = StringUtil.jsonFilter( getRequestValue(subKey) );
    1717                                }
    1718                                // 7.2.3.1 (2020/04/17) VALS 追加
    1719                                else if( key.startsWith( "VALS." ) ) {
    1720                                        rtn = getValsAttri( subKey );
    1721                                }
    1722                                // 3.8.0.1 (2005/06/17) NVAR.XXXX で、getUnicodeEscape 変換() を行います｡
    1723                                // NVAR. を取り除いた XXXX で再度、ﾘｸｴｽﾄ値を取得し、それを Escape変換します｡
    1724                                else if( key.startsWith( "NVAR." ) ) {
    1725                                        rtn = StringUtil.getUnicodeEscape( getRequestValue( subKey ) );
    1726                                }
    1727                        }
    1728                        else if( adrs > 5 ) {
    1729                                // 7.2.3.1 (2020/04/17) SUBSTR 追加
    1730                                if( key.startsWith( "SUBSTR." ) ) {
    1731                                        rtn = getSubstrAttri( subKey );
    1732                                }
    1733                                else if( key.startsWith( "USEREDIT." ) ) {
    1734                                        rtn = getUserEditInfo( subKey );                                                        // 5.8.2.3 (2014/12/27)
    1735                                }
    1736                                else if( key.startsWith( "SESSION." ) ) {                                               // 3.5.5.3 (2004/04/09)
    1737                                        rtn = String.valueOf( getSessionAttribute( subKey ) );
    1738                                }
    1739                        }
    1740                        // 7.2.9.1 (2020/10/23) 処理されなかった場合は、そのままｷｰとして使用する｡
    1741                        if( rtn == null ) {
    1742                                rtn = (String)getRequestAttribute( key );                                               // ※ 取り出しは、key で
    1743                        }
    1744//                      // 6.3.5.0 (2015/08/08) CHART.TAG は、直接取り出すように変更します。
    1745//                      else { // 4.0.0.0 (2007/11/16)
    1746//                              rtn = (String)getRequestAttribute( key );                                               // ※ 取り出しは、key で
    1747//                      }
    1748                }
    1749                // 予約語以外は括弧を付けて書き戻します。
    1750                else{
    1751                        rtn = "{@" + key + "}";
    1752                }
    1753                return rtn;
    1754        }
    1755
    1756        /**
    1757         * ﾘｸｴｽﾄ情報の文字列を取得します｡
    1758         *
    1759         * @og.rev 5.0.0.2 (2009/09/15) XSS対策
    1760         *
    1761         * @param       key     ｷｰ
    1762         * @return      ﾘｸｴｽﾄ情報の文字列
    1763         */
    1764        protected String getRequestValue( final String key ) {
    1765                return getRequestValue( key, xssCheck);
    1766        }
    1767
    1768        /**
    1769         * ﾘｸｴｽﾄ情報の文字列を取得します｡
    1770         *
    1771         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 ｴﾝｺｰﾄﾞの取得方法変更
    1772         * @og.rev 3.0.0.0 (2002/12/25) StringUtil#changeString 廃止
    1773         * @og.rev 3.0.0.0 (2002/12/25) ValueTag追加の為、指定の scope の Attributeより取得
    1774         * @og.rev 3.1.0.1 (2003/03/26) Valueﾀｸﾞの値と、request情報の値の所得優先順位を、request が優先されるように変更｡
    1775         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応｡HybsRequestWrapper 廃止｡直接 Mapでｷｬｯｼｭする｡
    1776         * @og.rev 3.1.5.0 (2003/04/22) SYS.XXXX で、ｼｽﾃﾑﾊﾟﾗﾒｰﾀ の値を取得できるように修正｡
    1777         * @og.rev 3.1.7.0 (2003/05/02) ﾘｸｴｽﾄ情報の取得順序を、Request、ｷｬｯｼｭ、Value の順に変更｡
    1778         * @og.rev 3.1.7.0 (2003/05/02) value値の使用可否を指定する、useValue 属性を追加｡
    1779         * @og.rev 3.4.0.3 (2003/09/10) MEM.XXXX で、REQUEST_CACHE の値を取得できるように修正｡
    1780         * @og.rev 3.5.4.7 (2004/02/06) getRequestCacheData を使用するように修正
    1781         * @og.rev 3.5.5.3 (2004/04/09) {&#064;SESSION.XXXX} で、session.getAttribute( "XXXX" ) の値を取得するように修正
    1782         * @og.rev 3.5.6.6 (2004/08/23) SYS.XXXX の処理を getSystemParameter( String key ) ﾒｿｯﾄﾞへ移動
    1783         * @og.rev 3.8.0.1 (2005/06/17) NVAR.XXXX で、getUnicodeEscape 変換() を行います｡
    1784         * @og.rev 3.8.0.2 (2005/07/11) MSG.XXXX , LBL.XXXX の処理を追加
    1785         * @og.rev 3.8.0.2 (2005/07/11) ﾁｪｯｸﾎﾞｯｸｽ対応で、重複ﾘｸｴｽﾄに対応させます｡
    1786         * @og.rev 3.8.8.8 (2007/05/11) 重複ﾘｸｴｽﾄ処理の場所を移動｡ﾘｸｴｽﾄのみ対象とする｡
    1787         * @og.rev 4.0.0.0 (2005/08/31) quotCheck によるＳＱＬｲﾝｼﾞｪｸｼｮﾝ対策
    1788         * @og.rev 4.0.0.0 (2005/08/31) getSystemParameter を sys に名称変更
    1789         * @og.rev 4.0.0.0 (2007/04/02) Valueﾀｸﾞの値と、ｷｬｯｼｭでは、Valueﾀｸﾞの値を優先するように変更
    1790         * @og.rev 4.0.0.0 (2007/11/16) "."付きのﾊﾟﾗﾒｰﾀのｴﾗｰ処理をなくし、getRequestAttributeで取得する｡
    1791         * @og.rev 4.3.0.0 (2008/07/04) DB.XXXX は、必ずStringｵﾌﾞｼﾞｪｸﾄとし、String.valueOf しない｡
    1792         * @og.rev 4.3.6.0 (2009/04/01) ﾒｰﾙﾓｼﾞｭｰﾙ用の予約語MAIL.XXXXの取得対応
    1793         * @og.rev 4.4.0.0 (2009/08/02) ﾃﾞｰﾀﾛｰﾙ対応(SEC.xxxの取得対応)
    1794         * @og.rev 5.0.0.2 (2009/09/15) XSS対策用にﾒｿｯﾄﾞにﾌﾗｸﾞを追加
    1795         * @og.rev 5.1.8.0 (2010/07/01) isNullSet 属性 廃止にともなう、useValue 属性廃止
    1796         * @og.rev 5.3.9.0 (2011/09/01) URL.XXXX処理を追加
    1797         * @og.rev 5.5.1.3 (2012/04/09) ESC.XXXX処理を追加
    1798         * @og.rev 5.5.4.0 (2012/07/01) 予約語の処理を分離
    1799         * @og.rev 5.7.4.2 (2014/03/20) ｻﾆﾀｲｽﾞ処理は、getSanitizedBodyString() ではなく、ここで行います｡
    1800         * @og.rev 5.9.25.2 (2017/10/27) xssCheck及びquotCheckのｴﾗｰﾒｯｾｰｼﾞをﾗﾍﾞﾙﾘｿｰｽ化
    1801         *
    1802         * @param       key                     ｷｰ
    1803         * @param       xssCheckFlg     XSS対策用[true:行う/false:行わない]
    1804         *
    1805         * @return      ﾘｸｴｽﾄ情報の文字列
    1806         * @og.rtnNotNull
    1807         */
    1808        protected String getRequestValue( final String key, final boolean xssCheckFlg ) {
    1809                if( key == null ) { isReqNull = true; return ""; }                                              // 3.4.0.3 (2003/09/10)
    1810
    1811                String rtn ;
    1812                final int adrs = key.indexOf( '.' );
    1813
    1814                if( adrs > 0 ) {
    1815                        rtn = getReservedValue( key );                                                                          // 5.5.4.0 (2012/07/02)
    1816                }
    1817                else {
    1818                        rtn = getRequest().getParameter( key );
    1819
    1820                        // 5.7.4.2 (2014/03/20) ｻﾆﾀｲｽﾞ処理は、getSanitizedBodyString() ではなく、ここで行います｡
    1821                        // 6.0.0.1 (2014/04/25) These nested if statements could be combined
    1822                        if( isSanitized && rtn != null && rtn.indexOf( '[' ) >= 0 ) {
    1823                                rtn = rtn.replace( "[", "\\]\\" );
    1824                        }
    1825
    1826                        // 5.0.0.2 (2009/09/15) tagCheck によるthan signﾁｪｯｸ Parameterのみにかけるためこの位置
    1827                        if( rtn != null && rtn.length() > 0 && xssCheckFlg && ( rtn.indexOf( '<' ) >= 0 || rtn.indexOf( '>' ) >= 0 ) ) {
    1828
    1829                                // 5.9.25.2 (2017/10/27)
    1830                                getResource();
    1831                                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    1832                                        .append( resource.getLabel( "ERR0048.1" ) ).append( CR )
    1833                                        .append( resource.getLabel( "ERR0048.2",new String[] { key,rtn,getTagName() } ) ).append( CR );
    1834
    1835                                throw new HybsSystemException( buf.toString() );
    1836                        }
    1837
    1838                        // 3.8.8.8 (2007/05/11) 重複ﾘｸｴｽﾄ処理の場所を移動｡ﾘｸｴｽﾄのみ対象とする｡
    1839                        // 3.8.0.2 (2005/07/11) ﾁｪｯｸﾎﾞｯｸｽ対応で、重複ﾘｸｴｽﾄに対応させます｡
    1840                        // {@XXXX} で、値が"0"の場合、複数ﾘｸｴｽﾄを確認して、"1"が含まれていれば、"1"とします｡
    1841                        if( "0".equals(rtn) ) {
    1842                                final boolean backFlag = isReqNull ;
    1843                                final String[] vals = getRequestValues( key );
    1844                                if( vals != null && vals.length > 1 ) {
    1845                                        for( int i=0; i<vals.length; i++ ) {
    1846                                                if( "1".equals( vals[i] ) ) { rtn = "1"; break; }
    1847                                        }
    1848                                }
    1849                                isReqNull = backFlag;                                                                                   // 3.8.8.8 (2007/05/11) getRequestValues での NULLセット解除
    1850                        }
    1851
    1852                        // 3.1.0.1 (2003/03/26) Valueﾀｸﾞの値と、request情報の値の取得優先順位を、
    1853                        // request が優先されるように変更｡
    1854                        if( ( rtn == null || rtn.isEmpty() ) && requestCache != null ) {
    1855                                final String[] str = requestCache.get( key );
    1856                                if( str != null && str.length > 0 ) {
    1857                                        rtn = str[0];
    1858                                }
    1859                        }
    1860                        // 5.1.8.0 (2010/07/01) isNullSet 属性 廃止にともなう、useValue 属性廃止
    1861                        if( rtn == null || rtn.isEmpty() ) {
    1862                                final Object obj = pageContext.findAttribute( key );
    1863                                if( obj != null ) {
    1864                                        rtn = obj.toString();
    1865                                }
    1866                        }
    1867                }
    1868                if( rtn == null || rtn.isEmpty() ) {
    1869                        isReqNull = true;
    1870                        rtn    = "";
    1871                }
    1872                // 4.0.0 (2005/08/31) quotCheck によるSQLｲﾝｼﾞｪｸｼｮﾝ対策
    1873//              else if( quotCheck && rtn.indexOf( '\'' ) >= 0 && !key.startsWith( "SEC." ) ) { // 6.0.2.5 (2014/10/31) refactoring
    1874                else if( quotCheck && rtn.indexOf( '\'' ) >= 0 && !key.startsWith( "REP." ) ) { // 7.4.4.0 (2021/06/30) Delete SEC." 廃止
    1875
    1876                        // 5.9.25.2 (2017/10/27)
    1877                        getResource();
    1878                        final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    1879                                .append( resource.getLabel( "ERR0049.1" ) ).append( CR )
    1880                                .append( resource.getLabel( "ERR0049.2",new String[] { key,rtn,getTagName() } ) ).append( CR );
    1881
    1882                        throw new HybsSystemException( buf.toString() );
    1883                }
    1884
    1885                return rtn ;
    1886        }
    1887
    1888        /**
    1889         * ﾘｸｴｽﾄ情報の文字列を取得します｡
    1890         *
    1891         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 ｴﾝｺｰﾄﾞの取得方法変更
    1892         * @og.rev 3.0.0.0 (2002/12/25) StringUtil#changeString 廃止
    1893         * @og.rev 3.1.8.0 (2003/05/16) RequestCache ﾃﾞｰﾀをﾘｸｴｽﾄ配列情報にも適用する｡
    1894         * @og.rev 5.3.8.0 (2011/08/01) Attribute等からも値が取得できるようにする｡
    1895         * @og.rev 8.2.0.2 (2022/06/24) must と mustAny の複数選択対応
    1896         *
    1897         * @param       key     ｷｰ
    1898         * @return      ﾘｸｴｽﾄ情報の文字列
    1899         */
    1900        protected String[] getRequestValues( final String key ) {
    1901                String[] rtn = getRequest().getParameterValues( key );
    1902
    1903                // 3.1.8.0 (2003/05/16) RequestCache ﾃﾞｰﾀをﾘｸｴｽﾄ配列情報にも適用する｡
    1904                if( ( rtn == null || rtn.length == 0 ) && requestCache != null ) {
    1905                        rtn =requestCache.get( key );
    1906                }
    1907
    1908                // 8.2.0.2 (2022/06/24) must と mustAny の複数選択対応
    1909                if( rtn == null || rtn.length == 0 ) {
    1910                        final Object obj = getRequestAttribute( key );
    1911                        if( obj instanceof String[] ) {
    1912                                rtn = (String[])obj;
    1913                        }
    1914                }
    1915
    1916                // 5.3.8.0 (2011/08/01) Attribute等からも値が取得できるようにする｡
    1917                if( rtn == null || rtn.length == 0 ) {
    1918                        final String tmp = getRequestValue( key );
    1919                        if( tmp != null && tmp.length() > 0 ) {
    1920                                rtn = new String[]{ tmp };
    1921                        }
    1922                }
    1923
    1924                if( rtn == null || rtn.length == 0 ) { isReqNull = true; }
    1925                return rtn ;
    1926        }
    1927
    1928        /**
    1929         * ﾘｸｴｽﾄ情報の文字列のｷｰ集合を取得します｡
    1930         *
    1931         * @og.rev 5.3.2.0 (2011/02/01) ﾊﾟﾗﾒｰﾀｰの外部指定対応
    1932         *
    1933         * @return      ﾘｸｴｽﾄ情報の文字列のｷｰ集合
    1934         */
    1935        protected Enumeration<?> getParameterNames() {                                                          // 4.3.3.6 (2008/11/15) Generics警告対応
    1936                final String[] names = (String[])getRequestAttribute( HybsSystem.PARAM_NAMES_KEY );
    1937                return names == null ? getRequest().getParameterNames() : Collections.enumeration( Arrays.asList( names ) ) ;
    1938        }
    1939
    1940        /**
    1941         * ﾘｸｴｽﾄ情報の文字列のｷｰ集合をｾｯﾄします｡
    1942         *
    1943         * @og.rev 5.3.2.0 (2011/02/01) ﾊﾟﾗﾒｰﾀｰの外部指定対応
    1944         *
    1945         * @param       names   ﾘｸｴｽﾄ情報の文字列のｷｰ配列(可変長引数)
    1946         */
    1947        protected void setParameterNames( final String... names ) {
    1948                setRequestAttribute( HybsSystem.PARAM_NAMES_KEY, names );
    1949        }
    1950
    1951        /**
    1952         * ﾘｸｴｽﾄ情報の文字列に NULL が存在していたかどうかを取得します｡
    1953         *
    1954         * これは、getRequestParameter( String ) の呼出し毎に設定されます｡
    1955         * つまり、上記ﾒｿｯﾄﾞの実行直後の値を取り出す必要があります｡
    1956         * NULL が含まれていた(true)／含まれていなかった｡(false)
    1957         *
    1958         * @return      NULLが含まれていた(true)／含まれていなかった｡(false)
    1959         */
    1960        protected boolean isNull() {
    1961                return isReqNull;
    1962        }
    1963
    1964        /**
    1965         * ｾｯｼｮﾝに登録されているｵﾌﾞｼﾞｪｸﾄを取得します｡
    1966         *
    1967         * @param       key     ｷｰ
    1968         * @return      ｾｯｼｮﾝに登録されているｵﾌﾞｼﾞｪｸﾄ
    1969         */
    1970        protected Object getSessionAttribute( final String key ) {
    1971                if( session == null ) { session = pageContext.getSession(); }
    1972                return session.getAttribute( key );
    1973        }
    1974
    1975        /**
    1976         * ｾｯｼｮﾝに 指定のｷｰでｵﾌﾞｼﾞｪｸﾄをｾｯﾄします｡
    1977         *
    1978         * @param       key             ｷｰ
    1979         * @param       object  ｾｯｼｮﾝに登録するｵﾌﾞｼﾞｪｸﾄ
    1980         */
    1981        protected void setSessionAttribute( final String key ,final Object object ) {
    1982                if( session == null ) { session = pageContext.getSession(); }
    1983                session.setAttribute( key,object );
    1984        }
    1985
    1986        /**
    1987         * ｾｯｼｮﾝに指定のｷｰで登録されているｵﾌﾞｼﾞｪｸﾄを 削除します｡
    1988         *
    1989         * @param       key     ｷｰ
    1990         */
    1991        protected void removeSessionAttribute( final String key ) {
    1992                if( session == null ) { session = pageContext.getSession(); }
    1993                session.removeAttribute( key );
    1994        }
    1995
    1996        /**
    1997         * ﾘｸｴｽﾄに登録されているｵﾌﾞｼﾞｪｸﾄを取得します｡
    1998         *
    1999         * @param       key     ｷｰ
    2000         *
    2001         * @return      ﾘｸｴｽﾄﾝに登録されているｵﾌﾞｼﾞｪｸﾄ
    2002         */
    2003        protected Object getRequestAttribute( final String key ) {
    2004                return getRequest().getAttribute( key );
    2005        }
    2006
    2007        /**
    2008         * ﾘｸｴｽﾄに 指定のｷｰでｵﾌﾞｼﾞｪｸﾄをｾｯﾄします｡
    2009         *
    2010         * @param       key             ｷｰ
    2011         * @param       object  ﾘｸｴｽﾄに登録するｵﾌﾞｼﾞｪｸﾄ
    2012         */
    2013        protected void setRequestAttribute( final String key ,final Object object ) {
    2014                getRequest().setAttribute( key,object );
    2015        }
    2016
    2017        /**
    2018         * ﾘｸｴｽﾄに指定のｷｰで登録されているｵﾌﾞｼﾞｪｸﾄを削除します｡
    2019         *
    2020         * @param       key     ｷｰ
    2021         */
    2022        protected void removeRequestAttribute( final String key ) {
    2023                getRequest().removeAttribute( key );
    2024        }
    2025
    2026        /**
    2027         * ｺﾝﾃｷｽﾄ(application)に登録されているｵﾌﾞｼﾞｪｸﾄを取得します｡
    2028         *
    2029         * scope属性に、"application" が指定された場合に、実行されます｡
    2030         *
    2031         * @og.rev 3.0.0.0 (2002/12/25) scope="application" 指定の追加
    2032         *
    2033         * @param       key     ｷｰ
    2034         * @return      ｺﾝﾃｷｽﾄ(application)に登録されているｵﾌﾞｼﾞｪｸﾄ
    2035         */
    2036        protected Object getContextAttribute( final String key ) {
    2037                final ServletContext application = pageContext.getServletContext();
    2038                return application.getAttribute( key );
    2039        }
    2040
    2041        /**
    2042         * ｺﾝﾃｷｽﾄ(application)指定のｷｰでｵﾌﾞｼﾞｪｸﾄをｾｯﾄします｡
    2043         *
    2044         * scope属性に、"application" が指定された場合に、実行されます｡
    2045         *
    2046         * @og.rev 3.0.0.0 (2002/12/25) scope="application" 指定の追加
    2047         *
    2048         * @param       key     ｷｰ
    2049         * @param       object ｺﾝﾃｷｽﾄ(application)に登録するｵﾌﾞｼﾞｪｸﾄ
    2050         */
    2051        protected void setContextAttribute( final String key ,final Object object ) {
    2052                final ServletContext application = pageContext.getServletContext();
    2053                application.setAttribute( key,object );
    2054        }
    2055
    2056        /**
    2057         * ｺﾝﾃｷｽﾄ(application)指定のｷｰで登録されているｵﾌﾞｼﾞｪｸﾄを 削除します｡
    2058         *
    2059         * scope属性に、"application" が指定された場合に、実行されます｡
    2060         *
    2061         * @og.rev 3.0.0.0 (2002/12/25) scope="application" 指定の追加
    2062         *
    2063         * @param       key     ｷｰ
    2064         */
    2065        protected void removeContextAttribute( final String key ) {
    2066                final ServletContext application = pageContext.getServletContext();
    2067                application.removeAttribute( key );
    2068        }
    2069
    2070        /**
    2071         * ｱﾌﾟﾘｹｰｼｮﾝｻｰﾊﾞｰのｺﾝﾃｷｽﾄﾊﾟｽのURLを返します｡
    2072         *
    2073         * @return      ｺﾝﾃｷｽﾄﾊﾟｽ
    2074         */
    2075        protected String getContextPath() {
    2076                return ((HttpServletRequest)getRequest()).getContextPath();
    2077        }
    2078
    2079        /**
    2080         * ｽｺｰﾌﾟに応じて登録されているｵﾌﾞｼﾞｪｸﾄを取得します｡
    2081         *
    2082         * @og.rev 3.0.0.0 (2002/12/25) scope="application" 指定の追加
    2083         * @og.rev 6.7.7.0 (2017/03/31) scope="application" つづり間違い訂正
    2084         *
    2085         * @param       key     ｷｰ
    2086         * @return      ｽｺｰﾌﾟに応じて登録されているｵﾌﾞｼﾞｪｸﾄ
    2087         */
    2088        protected Object getObject( final String key ) {
    2089                if(      "session".equals( scope )              ) { return getSessionAttribute( key ); }
    2090                else if( "request".equals( scope )              ) { return getRequestAttribute( key ); }
    2091                else if( "application".equals( scope )  ) { return getContextAttribute( key ); }                // 6.7.7.0 (2017/03/31)
    2092                else {
    2093                        final String errMsg = "このｽｺｰﾌﾟはｻﾎﾟｰﾄされていません。[" + scope + "]";
    2094                        throw new IllegalArgumentException( errMsg );
    2095                }
    2096        }
    2097
    2098        /**
    2099         * ｽｺｰﾌﾟに応じて登録されているｵﾌﾞｼﾞｪｸﾄを指定のｷｰでｾｯﾄします｡
    2100         *
    2101         * @og.rev 3.0.0.0 (2002/12/25) scope="application" 指定の追加
    2102         *
    2103         * @param       key             ｷｰ
    2104         * @param       object  ﾘｸｴｽﾄに登録するｵﾌﾞｼﾞｪｸﾄ
    2105         * @see         #setObject( String ,Object ,String )
    2106         */
    2107        protected void setObject( final String key ,final Object object ) {
    2108                setObject( key,object,scope );
    2109        }
    2110
    2111        /**
    2112         * ｽｺｰﾌﾟに応じて登録されているｵﾌﾞｼﾞｪｸﾄを指定のｷｰでｾｯﾄします｡
    2113         *
    2114         * 引数にｽｺｰﾌﾟを指定します｡ｽｺｰﾌﾟが null の場合は、ｵﾘｼﾞﾅﾙの
    2115         * ｽｺｰﾌﾟを使用します｡
    2116         *
    2117         * @og.rev 5.2.2.0 (2010/11/01) 新規追加
    2118         * @og.rev 6.7.7.0 (2017/03/31) scope="application" つづり間違い訂正
    2119         *
    2120         * @param       key             ｷｰ
    2121         * @param       object  ﾘｸｴｽﾄに登録するｵﾌﾞｼﾞｪｸﾄ
    2122         * @param       scp             ｽｺｰﾌﾟ
    2123         * @see         #setObject( String ,Object )
    2124         */
    2125        protected void setObject( final String key ,final Object object ,final String scp ) {
    2126                final String inScp = (scp == null) ? scope : scp ;
    2127
    2128                if(      "session".equals( inScp        ) ) { setSessionAttribute( key,object ); }
    2129                else if( "request".equals( inScp        ) ) { setRequestAttribute( key,object ); }
    2130                else if( "application".equals( inScp ) ) { setContextAttribute( key,object ); } // 6.7.7.0 (2017/03/31)
    2131                else {
    2132                        final String errMsg = "このｽｺｰﾌﾟはｻﾎﾟｰﾄされていません。[" + inScp + "]";
    2133                        throw new IllegalArgumentException( errMsg );
    2134                }
    2135        }
    2136
    2137        /**
    2138         * ｽｺｰﾌﾟに応じて登録されているｵﾌﾞｼﾞｪｸﾄを指定のｷｰで削除します｡
    2139         *
    2140         * @og.rev 3.0.0.0 (2002/12/25) scope="application" 指定の追加
    2141         * @og.rev 6.7.7.0 (2017/03/31) scope="application" つづり間違い訂正
    2142         *
    2143         * @param       key     ｷｰ
    2144         */
    2145        protected void removeObject( final String key ) {
    2146                if( "session".equals( scope ) ) { removeSessionAttribute( key ); }
    2147                else if( "request".equals( scope ) ) { removeRequestAttribute( key ); }
    2148                else if( "application".equals( scope ) ) { removeContextAttribute( key ); }     // 6.7.7.0 (2017/03/31)
    2149                else {
    2150                        final String errMsg = "このｽｺｰﾌﾟはｻﾎﾟｰﾄされていません。[" + scope + "]";
    2151                        throw new IllegalArgumentException( errMsg );
    2152                }
    2153        }
    2154
    2155        /**
    2156         * ﾘｸｴｽﾄｵﾌﾞｼﾞｪｸﾄを取得します｡
    2157         *
    2158         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 ｴﾝｺｰﾄﾞの取得方法変更
    2159         * @og.rev 2.2.0.0 (2002/12/17) 文字化け対策 setCharacterEncoding が効いていないので削除
    2160         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応｡HybsRequestWrapper 廃止｡直接 Mapでｷｬｯｼｭする｡
    2161         * @og.rev 3.4.0.3 (2003/09/10) 冗長な個所や、無意味な個所を、等価な内容のﾛｼﾞｯｸに置き換える｡
    2162         * @og.rev 3.5.5.0 (2004/03/12) command=RESET 時にも、ｷｬｯｼｭを取り出すように変更します｡
    2163         *
    2164         * @return      ﾘｸｴｽﾄｵﾌﾞｼﾞｪｸﾄ
    2165         */
    2166        @SuppressWarnings(value={"unchecked"})
    2167        protected ServletRequest getRequest() {
    2168                if( request == null ) {
    2169                        request = pageContext.getRequest();
    2170                        // ﾘｸｴｽﾄｷｬｯｼｭ機能
    2171                        final String cmd =request.getParameter( "command" );
    2172                        if( "RENEW".equals( cmd ) || "RESET".equals( cmd ) ) {                          // 3.5.5.0
    2173                                requestCache = (Map<String,String[]>)getSessionAttribute( HybsSystem.REQ_CACHE_KEY );
    2174                        }
    2175                }
    2176                return request;
    2177        }
    2178
    2179        /**
    2180         * BodyContent ｵﾌﾞｼﾞｪｸﾄを取得して、ﾎﾞﾃﾞｨの内容を取得します｡
    2181         *
    2182         * 処理としては、getRequestParameter() によるﾊﾟﾗﾒｰﾀ処理も含みます｡
    2183         * このﾒｿｯﾄﾞは、必ず doAfterBody() から呼び出してください｡それ以外(例えば、
    2184         * doEndTag()等)では、すでに Body情報が破棄/再利用されている可能性があり、
    2185         * 正常に動作しなくなる可能性があります｡
    2186         *
    2187         * @og.rev 3.1.1.0 (2003/03/28) BodyContent ｵﾌﾞｼﾞｪｸﾄを取得して、ﾎﾞﾃﾞｨの内容を取得する処理を追加
    2188         * @og.rev 6.3.1.1 (2015/07/10) BodyString,BodyRawStringは、CommonTagSupport で、trim() します｡
    2189         *
    2190         * @return      ﾎﾞﾃﾞｨ文字列
    2191         */
    2192        protected String getBodyString() {
    2193                final BodyContent body = getBodyContent();
    2194                return getRequestParameter( body.getString().trim() );                                  // 6.3.1.1 (2015/07/10)
    2195        }
    2196
    2197        /**
    2198         * BodyContent ｵﾌﾞｼﾞｪｸﾄを取得して、ﾎﾞﾃﾞｨの内容を取得します｡
    2199         *
    2200         * {&#064;XXXX}を変換しない生のBODY文を返します
    2201         *
    2202         * @og.rev 4.3.6.0 (2009/04/01) 新規作成
    2203         * @og.rev 6.3.1.1 (2015/07/10) BodyString,BodyRawStringは、CommonTagSupport で、trim() します｡
    2204         *
    2205         * @return      ﾎﾞﾃﾞｨ文字列
    2206         */
    2207        protected String getBodyRawString() {
    2208                final BodyContent body = getBodyContent();
    2209                return body.getString().trim();                                                                                 // 6.3.1.1 (2015/07/10)
    2210        }
    2211
    2212        /**
    2213         * BodyContent ｵﾌﾞｼﾞｪｸﾄを取得して、ﾎﾞﾃﾞｨの内容を取得します｡
    2214         *
    2215         * {&#064;XXXX}の変換を行いますが、その変換結果に、"["が含まれる場合は、
    2216         * "\\]\\"に変換して、ﾌｫｰﾏｯﾄ処理されないようにｻﾆﾀｲｽﾞします｡
    2217         *
    2218         * @og.rev 5.1.7.0 (2010/06/01) 新規作成
    2219         * @og.rev 5.7.4.2 (2014/03/20) ｻﾆﾀｲｽﾞ処理を、標準の処理で行う｡
    2220         *
    2221         * @return      ﾎﾞﾃﾞｨ文字列
    2222         */
    2223        protected String getSanitizedBodyString() {
    2224                isSanitized = true;
    2225                final String rtn = getBodyString();
    2226                isSanitized = false;                                                                                                    // 一連の処理の中だけ、有効とします。
    2227
    2228                return rtn;
    2229        }
    2230
    2231        /**
    2232         * JspWriter を使用した画面出力です。
    2233         *
    2234         * @param       msg     画面に出力する文字列
    2235         */
    2236        protected void jspPrint( final String msg ) {
    2237                if( msg == null ) { return ; }
    2238                try {
    2239                        final JspWriter out = pageContext.getOut();
    2240                        out.print( msg );
    2241                } catch( final IOException ex ) {
    2242                        final String errMsg = "画面出力時の PageContext の取得時にｴﾗｰが発生しました。"
    2243                                                        + ex.getMessage();                                                                      // 5.1.8.0 (2010/07/01) errMsg 修正
    2244                        throw new HybsSystemException( errMsg,ex );                                                     // 3.5.5.4 (2004/04/15) 引数の並び順変更
    2245                }
    2246        }
    2247
    2248        /**
    2249         * ﾃﾞﾊﾞｯｸﾞ用の文字列を JspWriter を使用して画面に出力します｡
    2250         * 引数を単に画面に表示するだけです｡
    2251         *
    2252         * @og.rev 8.0.2.0 (2021/11/30) 検索実行前に、SQL文字をdebugPrint出来るように修正｡
    2253         *
    2254         * @param       msg     表示する文字列
    2255         */
    2256        protected void debugPrint( final String msg ) {
    2257                if( debugFlag ) {
    2258                        try {
    2259                                final JspWriter out = pageContext.getOut();
    2260                                out.println( "<pre>" );
    2261                                out.println( msg );
    2262                                out.println( "</pre>" );
    2263                        } catch( final IOException ex ) {
    2264                                final String errMsg = "ﾃﾞﾊﾞｯｸﾞ画面出力時の PageContext の取得時にｴﾗｰが発生しました。"
    2265                                                        + ex.getMessage();
    2266                                throw new HybsSystemException( errMsg,ex );
    2267                        }
    2268                }
    2269        }
    2270
    2271        /**
    2272         * ﾃﾞﾊﾞｯｸﾞ用の文字列を JspWriter を使用して画面に出力します｡
    2273         * このﾒｿｯﾄﾞは、debugFlag=true の場合のみ動作します｡
    2274         *
    2275         * 出力内容は，各ｵﾌﾞｼﾞｪｸﾄの toString() 文字列です｡
    2276         *
    2277         * @og.rev 4.0.0.0 (2005/02/28) debugFlag の条件式を追加｡
    2278         * @og.rev 4.0.0.0 (2005/02/28) ｸｲｯｸﾘﾌｧﾚﾝｽへのﾘﾝｸを追加｡
    2279         */
    2280        protected void debugPrint() {
    2281                if( debugFlag ) {
    2282                        try {
    2283                                final JspWriter out = pageContext.getOut();
    2284                                out.println( getDocumentLink() );                                                               // 4.0.0 (2005/02/28)
    2285                                out.println( "<pre>" );
    2286                                out.println( toString() );
    2287                                out.println( "</pre>" );
    2288                        } catch( final IOException ex ) {
    2289                                final String errMsg = "ﾃﾞﾊﾞｯｸﾞ画面出力時の PageContext の取得時にｴﾗｰが発生しました。"
    2290                                                        + ex.getMessage();                                                                      // 5.1.8.0 (2010/07/01) errMsg 修正
    2291                                throw new HybsSystemException( errMsg,ex );                                             // 3.5.5.4 (2004/04/15) 引数の並び順変更
    2292                        }
    2293                }
    2294        }
    2295
    2296        /**
    2297         * GAMENID付のﾘｸｴｽﾄｷｬｯｼｭ情報を取り出します｡
    2298         *
    2299         * @og.rev 3.5.4.7 (2004/02/06) 新規作成
    2300         *
    2301         * @param       key     ﾘｸｴｽﾄｷｬｯｼｭのｷｰ情報
    2302         * @return      ﾘｸｴｽﾄ情報(存在しない場合は、null)
    2303         */
    2304        protected String getRequestCacheData( final String key ) {
    2305                String rtn = null;
    2306
    2307                final String memKey = HybsSystem.REQ_CACHE_KEY + getGUIInfoAttri( "KEY" );      // 4.0.0 (2005/01/31)
    2308                final Map<?,?> mem = (Map<?,?>)getSessionAttribute( memKey );                           // 4.3.3.6 (2008/11/15) Generics警告対応
    2309
    2310                if( mem != null ) {
    2311                        final String[] vals = (String[])mem.get( key );
    2312                        if( vals != null && vals.length > 0 ) {
    2313                                rtn = vals[0];
    2314                        }
    2315                }
    2316                return rtn ;
    2317        }
    2318
    2319        /**
    2320         * GAMENID付のﾘｸｴｽﾄｷｬｯｼｭ情報を取り出します｡
    2321         *
    2322         * @og.rev 3.5.4.7 (2004/02/06) 新規作成
    2323         *
    2324         * @param       key             ﾘｸｴｽﾄｷｬｯｼｭのｷｰ情報
    2325         * @param       value   ﾘｸｴｽﾄｷｬｯｼｭに登録する値
    2326         */
    2327        protected void setRequestCacheData( final String key,final String value ) {
    2328                final String[] vals = new String[] { value } ;
    2329
    2330                final String memKey = HybsSystem.REQ_CACHE_KEY + getGUIInfoAttri( "KEY" );      // 4.0.0 (2005/01/31)
    2331                @SuppressWarnings(value={"unchecked"})
    2332                final Map<String,String[]> mem = (Map<String,String[]>)getSessionAttribute( memKey );
    2333                if( mem != null ) {
    2334                        mem.put( key,vals );
    2335                }
    2336        }
    2337
    2338        /**
    2339         * CSV形式引数(CSV引数)を配列に分解して返します｡
    2340         *
    2341         * CSV形式引数(CSV引数)で複数指定されたﾘｸｴｽﾄﾊﾟﾗﾒｰﾀを
    2342         * 文字列配列に分解して、返します｡
    2343         * 引数は、{&#064;XXXX} 変数も使用できます｡
    2344         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します｡
    2345         * こうしないとﾃﾞｰﾀ自身にｶﾝﾏを持っている場合に分解をﾐｽる為です｡
    2346         *
    2347         * @og.rev 3.5.6.2 (2004/07/05) 新規作成
    2348         *
    2349         * @param       csvKey  引数(CSV形式)
    2350         * @return      配列に分解されたﾘｸｴｽﾄﾊﾟﾗﾒｰﾀ値
    2351         */
    2352        protected String[] getCSVParameter( final String csvKey ) {
    2353                final String[] keys = StringUtil.csv2Array( csvKey );                                   // ﾀﾞﾌﾞﾙｸｵｰﾄ内は分解しない。
    2354                String[] vals = new String[keys.length];
    2355                for( int i=0; i<keys.length; i++ ) {
    2356                        vals[i] = getRequestParameter( keys[i] ) ;
    2357                }
    2358                return vals ;
    2359        }
    2360
    2361        /**
    2362         * CSV形式のkeys,vals引数(CSV引数)を配列に分解して返します｡
    2363         *
    2364         * CSV形式引数(CSV引数)で複数指定されたﾘｸｴｽﾄﾊﾟﾗﾒｰﾀを
    2365         * 文字列配列に分解して、返します｡
    2366         * 引数は、{&#064;XXXX} 変数も使用できます｡
    2367         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します｡
    2368         * こうしないとﾃﾞｰﾀ自身にｶﾝﾏを持っている場合に分解をﾐｽる為です｡
    2369         *
    2370         * ※ これは、keys,vals を同時に処理します｡keys を分解後、ｶﾝﾏがあれば、
    2371         *    vals も 再度、CSV分解します｡
    2372         *
    2373         * @og.rev 6.2.5.1 (2015/06/12) CSV形式のkeys,vals引数(CSV引数)対応｡新規作成｡
    2374         *
    2375         * @param       csvKey  引数(CSV形式)
    2376         * @param       csvVal  引数(CSV形式)
    2377         * @return      Mapにｾｯﾄされたﾘｸｴｽﾄﾊﾟﾗﾒｰﾀ値
    2378         * @see         #getCSVParameter( String )
    2379         */
    2380        protected Map<String,String> getCSVParameter( final String csvKey , final String csvVal ) {
    2381                final String[] keys = StringUtil.csv2Array( csvKey );                                   // ﾀﾞﾌﾞﾙｸｵｰﾄ内は分解しない｡
    2382                final String[] vals = StringUtil.csv2Array( csvVal );                                   // ﾀﾞﾌﾞﾙｸｵｰﾄ内は分解しない｡
    2383
    2384                if( keys.length != vals.length ) {
    2385                        final String errMsg = "ｷｰとﾊﾞﾘｭｰの個数が異なります。" + CR
    2386                                                + " keys.length=[" + keys.length + "]  vals.length=[" + vals.length + "]" + CR
    2387                                                + " keys=" + csvKey  + CR
    2388                                                + " vals=" + csvVal ;
    2389                        throw new HybsSystemException( errMsg );
    2390                }
    2391
    2392                final Map<String,String> kvMap = new LinkedHashMap<>();                                 // keys,valsの登録順は残しておきます。
    2393
    2394                for( int i=0; i<keys.length; i++ ) {
    2395                        final String key1 = getRequestParameter( keys[i] ) ;                            // ※ rtnNotNull
    2396                        String val1 = getRequestParameter( vals[i] ) ;
    2397                        if( key1.isEmpty() ) { continue; }                                                                      // ｷｰに関しては、何か値が必要｡
    2398
    2399                        if( key1.contains( "," ) ) {                                                                            // ｷｰにｶﾝﾏが含まれるとき
    2400                                final String[] keys2 = StringUtil.csv2Array( key1 );
    2401                                final String[] vals2 = StringUtil.csv2Array( val1 );
    2402
    2403                                // keys 分解の個別の個数ﾁｪｯｸ
    2404                                if( keys2.length != vals2.length ) {
    2405                                        final String errMsg = "部分ｷｰと部分ﾊﾞﾘｭｰの個数が異なります。" + CR
    2406                                                                + " keys2.length=[" + keys2.length + "]  vals2.length=[" + vals2.length + "]" + CR
    2407                                                                + " orgKey=" + csvKey  + CR
    2408                                                                + " orgVal=" + csvVal  + CR
    2409                                                                + " keys2=" + key1 + CR
    2410                                                                + " vals2=" + val1 ;
    2411                                        throw new HybsSystemException( errMsg );
    2412                                }
    2413
    2414                                for( int j=0; j<keys2.length; j++ ) {
    2415                                        if( keys2[j] != null && !keys2[j].isEmpty() && vals2[j] != null ) {
    2416                                                kvMap.put( keys2[j] , vals2[j] );
    2417                                        }
    2418                                }
    2419                        }
    2420                        else {
    2421                                // val にｶﾝﾏが含まれる場合は、前後に、ﾀﾞﾌﾞﾙｸｵｰﾄを追加する｡
    2422                                if( val1.contains( "," ) ) { val1 = '"' + val1 + '"' ; }
    2423                                kvMap.put( key1 , val1 );
    2424                        }
    2425                }
    2426
    2427                return kvMap ;
    2428        }
    2429
    2430        /**
    2431         * ｼｽﾃﾑ変数 {&#064;SYS.XXXX} に対する値の取得を行います｡
    2432         *
    2433         * 本来は、ｼｽﾃﾑﾊﾟﾗﾒｰﾀ の値を取得できますが、
    2434         * ｼｽﾃﾑ的な共有値も取得できるように機能追加しています｡
    2435         * また、ﾕｰｻﾞｰ個別にｼｽﾃﾑﾊﾟﾗﾒｰﾀを変更できます｡この取得は、
    2436         * ｼｽﾃﾑﾊﾟﾗﾒｰﾀとして取得します｡(値はﾕｰｻﾞｰ個別値を返します｡)
    2437         * ここで、引数に、&#064;変数が使用できます｡具体的には、{&#064;SYS.&#064;XXXX}
    2438         * で、&#064;XXXX をﾘｸｴｽﾄ変数から取得した値を利用します｡
    2439         * この中で、&#064;GUIID だけが、さらに特殊で、実行中の画面IDを割り当てます｡
    2440         * この &#064;GUIID は、ここまでの文字列を画面IDに置き換えるとともに、それ以降の
    2441         * 文字列を、画面IDに連結させます｡
    2442         * {&#064;SYS.&#064;GUIID_XXXX} ⇒ 画面ID_XXXX 文字列で、ｼｽﾃﾑﾊﾟﾗﾒｰﾀ の値を取得します｡
    2443         *
    2444         *  SERVER_NAME     このTomcatが実行しているｻｰﾊﾞｰ名       localhost 等
    2445         *  SERVER_URL      Portも含むURLｱﾄﾞﾚｽ                    http://localhost:8823/
    2446         *  CONTEXT_URL     実行しているｺﾝﾃｷｽﾄのURLｱﾄﾞﾚｽ          http://localhost:8823/dbdef2/
    2447         *  REAL_PATH       / ﾙｰﾄに対応する物理ﾃﾞｨﾚｸﾄﾘ            d:/webapps/dbdef2/ 等
    2448         *  CONTEXT_NAME    ｺﾝﾃｷｽﾄ名(webapps 直下の仮想ﾌｫﾙﾀﾞ名)   dbdef 等
    2449         *  COOKIE          ｸｯｷｰ取得
    2450         *  DATE            YMDH とほぼ同じですが、'yyyy/MM/dd HH:mm:ss' の形式で取得できます｡
    2451         *  HOSTNAME        IPﾄﾞﾚｽ ｽﾍﾟｰｽ区切りで指定したIPｱﾄﾞﾚｽからﾎｽﾄ名を逆引きします(5.6.6.2 (2013/07/19))
    2452         *  任意            ｼｽﾃﾑﾊﾟﾗﾒｰﾀ(GE12)の値を取得
    2453         *    &#064;GUIID_XXXX  既存の画面IDに、_XXXX を追加した文字列
    2454         *    &#064;XXXX        XXXX でﾘｸｴｽﾄ変数から取得した文字列
    2455         *    XXXX              XXXX の文字列
    2456         *  PRINTER         ｻｰﾊﾞｰのﾌﾟﾘﾝﾀｰ一覧(6.2.6.0 (2015/06/19))
    2457         *
    2458         * @og.rev 3.5.6.6 (2004/08/23) 新規作成
    2459         * @og.rev 3.7.0.3 (2005/03/01) ｸｯｷｰ取得機能を追加
    2460         * @og.rev 4.0.0.0 (2005/11/30) ﾕｰｻﾞｰﾊﾟﾗﾒｰﾀは、ｼｽﾃﾑﾊﾟﾗﾒｰﾀとして取得します｡
    2461         * @og.rev 5.1.6.0 (2010/05/01) ｼｽﾃﾑﾊﾟﾗﾒｰﾀに、&#064;GUIID という特殊ﾊﾟﾗﾒｰﾀが使用できるように対応します｡
    2462         * @og.rev 5.6.6.2 (2013/07/19) SYS.HOSTNAMEに対応します｡
    2463         * @og.rev 6.2.6.0 (2015/06/19) PRINTERに対応します｡
    2464         * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します｡
    2465         * @og.rev 6.9.5.0 (2018/04/23) うまく動いていないようなので、廃止
    2466         *
    2467         * @param       key     {&#064;SYS.XXXX}のXXXX部分の文字列(ｷｰ)
    2468         * @return      ｷｰに対する値｡なければ、null
    2469         */
    2470        protected String sys( final String key ) {
    2471                final String rtn;
    2472
    2473                if( key.startsWith( "COOKIE." ) ) {                                                                             // 3.7.0.3 (2005/03/01)
    2474                        rtn = getCookie( key.substring( "COOKIE.".length() ) );
    2475                }
    2476                else if( key.startsWith( "DATE" ) ) {
    2477                        final int idx = key.indexOf( ' ' );
    2478                        if( idx >= 0 ) {
    2479                                rtn = DateSet.getDate( key.substring( idx+1 ) );                                // 6.4.2.0 (2016/01/29)
    2480                        }
    2481                        else {
    2482                                rtn = HybsSystem.getDate();
    2483                        }
    2484                }
    2485                else if( key.startsWith( "HOSTNAME" ) ) {                                                               // 5.6.6.2 (2013/07/19)
    2486                        final int idx = key.indexOf( ' ' );
    2487                        if( idx >= 0 ) {
    2488                                final String key2 = key.substring( idx+1 ) ;
    2489                                if( StringUtil.startsChar( key2 , '@' ) ) {                                             // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    2490                                        rtn = getHostName( getRequestValue( key2.substring( 1 ) ) );
    2491                                }
    2492                                else{
    2493                                        rtn = getHostName( key2 );
    2494                                }
    2495                        }
    2496                        else{
    2497                                rtn = getUser().getParameter( key );
    2498                        }
    2499                }
    2500//              // 6.9.5.0 (2018/04/23) うまく動いていないようなので、廃止
    2501//              // 5.1.6.0 (2010/05/01) {@SYS.@GUIID_XXXX} ﾊﾟﾗﾒｰﾀ対応
    2502//              else if( key.startsWith( "@GUIID" ) ) {
    2503//                      final String key2 = getGUIInfoAttri( "ID" ) +  key.substring( "@GUIID".length() );
    2504//                      rtn = getUser().getParameter( key2 );
    2505//              }
    2506                // 6.2.6.0 (2015/06/19) PRINTERに対応します。
    2507                else if( key.startsWith( "PRINTER" ) ) {
    2508                        rtn = HybsSystem.getPrinter();
    2509                }
    2510                // 5.1.6.0 (2010/05/01) {@SYS.@XXXX} ﾊﾟﾗﾒｰﾀ対応
    2511                else if( StringUtil.startsChar( key , '@' ) ) {                                                 // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    2512                        final String key2 = getRequestValue( key.substring( 1 ) );
    2513                        rtn = getUser().getParameter( key2 );
    2514                }
    2515                else {
    2516                        rtn = getUser().getParameter( key );
    2517                }
    2518
    2519                return rtn ;
    2520        }
    2521
    2522        /**
    2523         * ｼｽﾃﾑﾊﾟﾗﾒｰﾀの値を、boolean 型に変換して返します｡
    2524         *
    2525         * 本来は、ｼｽﾃﾑﾊﾟﾗﾒｰﾀ の値を取得できますが、
    2526         * ｼｽﾃﾑ的な共有値も取得できるように機能追加しています｡
    2527         * また、ﾕｰｻﾞｰ個別にｼｽﾃﾑﾊﾟﾗﾒｰﾀを変更できます｡この取得は、
    2528         * ｼｽﾃﾑﾊﾟﾗﾒｰﾀとして取得します｡(値はﾕｰｻﾞｰ個別値を返します｡)
    2529         *
    2530         * @og.rev 4.0.0.0 (2005/11/30) 新規追加
    2531         *
    2532         * @param       key     ｼｽﾃﾑ設定ｷｰ
    2533         * @return      ｼｽﾃﾑ設定値(boolean型)
    2534         */
    2535        protected boolean sysBool( final String key ) {
    2536                return Boolean.parseBoolean( sys( key ) );              // 6.1.0.0 (2014/12/26) refactoring
    2537        }
    2538
    2539        /**
    2540         * ｼｽﾃﾑﾊﾟﾗﾒｰﾀの値を、int 型に変換して返します｡
    2541         *
    2542         * 本来は、ｼｽﾃﾑﾊﾟﾗﾒｰﾀ の値を取得できますが、
    2543         * ｼｽﾃﾑ的な共有値も取得できるように機能追加しています｡
    2544         * また、ﾕｰｻﾞｰ個別にｼｽﾃﾑﾊﾟﾗﾒｰﾀを変更できます｡この取得は、
    2545         * ｼｽﾃﾑﾊﾟﾗﾒｰﾀとして取得します｡(値はﾕｰｻﾞｰ個別値を返します｡)
    2546         *
    2547         * ※ ｼｽﾃﾑﾊﾟﾗﾒｰﾀの値が数字でない場合、HybsSystemException が throw されます｡
    2548         * ※ ｷｰの値が nullの場合、HybsSystemException が throw されます｡
    2549         *
    2550         * @og.rev 4.0.0.0 (2005/11/30) 新規追加
    2551         *
    2552         * @param       key     ｼｽﾃﾑ設定ｷｰ
    2553         * @return      ｼｽﾃﾑ設定値(int型)
    2554         */
    2555        protected int sysInt( final String key ) {
    2556                String tmp = null;
    2557                int rtn ;
    2558                try {
    2559                        tmp = sys( key );
    2560                        rtn = Integer.parseInt( tmp );
    2561                }
    2562                catch( final NumberFormatException ex ) {
    2563                        final String errMsg = "ｼｽﾃﾑﾊﾟﾗﾒｰﾀの値が数字ではありません。" + CR
    2564                                        + "  Resource key=[" + key + "] val=[" + tmp + "]"  ;
    2565                        throw new HybsSystemException( errMsg,ex );                                                     // 3.5.5.4 (2004/04/15) 引数の並び順変更
    2566                }
    2567                catch( final IllegalArgumentException ex ) {
    2568                        final String errMsg = "ｷｰの値が null です。key=[" + key + "] val=[" + tmp + "]";
    2569                        throw new HybsSystemException( errMsg,ex );                                                     // 3.5.5.4 (2004/04/15) 引数の並び順変更
    2570                }
    2571
    2572                return rtn;
    2573        }
    2574
    2575        /**
    2576         * Transactionｵﾌﾞｼﾞｪｸﾄを取得します｡
    2577         * これは、自身のﾀｸﾞの親ﾀｸﾞ（囲われているﾀｸﾞ）から、TransactionTag を
    2578         * 見つけて、すでに、Transactionｵﾌﾞｼﾞｪｸﾄが作成済みなら、そのｵﾌﾞｼﾞｪｸﾄを
    2579         * そうでないなら、新規に作成して返します｡
    2580         *
    2581         * Transactionｵﾌﾞｼﾞｪｸﾄは、AutoCloseableｲﾝﾀﾌｪｰｽを実装しているため、
    2582         * try-with-resources構築を使用することが可能です｡
    2583         *
    2584         * @og.rev 6.3.6.1 (2015/08/28) Transactionｵﾌﾞｼﾞｪｸﾄの取得方法変更｡
    2585         *
    2586         * @return      Transactionｵﾌﾞｼﾞｪｸﾄ
    2587         */
    2588        protected Transaction getTransaction() {
    2589                final TransactionTag tranTag = (TransactionTag)findAncestorWithClass( this,TransactionTag.class );
    2590
    2591                return tranTag == null  ? new TransactionReal( getApplicationInfo() )
    2592                                                                : tranTag.getTranObj();
    2593        }
    2594
    2595        /**
    2596         * session に、処理開始時刻を設定します｡
    2597         * これは、DBTableModel を登録する場合に、一連の処理が連続であるかどうかを
    2598         * 判断する時に使用します｡
    2599         * 処理が一連でない(start 時のﾀｲﾑｽﾀﾝﾌﾟが書き換えられている)場合は、
    2600         * DBTableModel の登録処理を行いません｡
    2601         * なお、判断処理を行うのは、scope が session の場合のみです｡
    2602         * 判定は、commitTableObject( String ,DBTableModel ) で行います｡
    2603         *
    2604         * @og.rev 3.6.0.8 (2004/11/19) 新規追加
    2605         * @og.rev 4.3.0.0 (2008/07/04) fileUD 対応｡
    2606         * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は、DBTableModelが新規作成された処理でのみ行う｡
    2607         *
    2608         * @param       tableId ｷｰ
    2609         * @see         #commitTableObject( String ,DBTableModel )
    2610         */
    2611        protected void startQueryTransaction( final String tableId ) {
    2612                if( "session".equals( scope ) ) {
    2613                        startTransaction = Long.valueOf( System.currentTimeMillis() );
    2614                        setSessionAttribute( tableId+"_TRANSACTION", startTransaction );
    2615                }
    2616
    2617                // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し
    2618                if( useTrans ) {
    2619                        // 4.3.0.0 (2008/07/04) fileUD 対応
    2620                        removeSessionAttribute( HybsSystem.DB_LAST_SQL_KEY );                           // 無条件削除
    2621                }
    2622        }
    2623
    2624        /**
    2625         * ｽｺｰﾌﾟに応じて登録されている DBTableModel を指定のｷｰでｾｯﾄします｡
    2626         * これは、startQueryTransaction( String ) でｾｯｼｮﾝに登録した処理開始時刻と、
    2627         * このｵﾌﾞｼﾞｪｸﾄ自身が持っている(ｾｯｼｮﾝに登録した開始時刻そのもの)を
    2628         * 比較し、異なる場合は、DBTableModel の登録を行いません｡
    2629         * これにより、検索処理の開始順にしか登録しないようなﾛｼﾞｯｸを入れています｡
    2630         * 検索処理時間が掛かるSQLを実行した場合、先に検索した結果があとから登録される
    2631         * ｹｰｽがあるためです｡
    2632         * また、判断処理を行うのは、scope が session の場合のみです｡
    2633         *
    2634         * @og.rev 3.6.0.8 (2004/11/19) 新規追加
    2635         * @og.rev 3.8.1.1 (2005/11/21) ExcelOut の整合性を取る為の仕掛け
    2636         * @og.rev 4.3.0.0 (2008/07/04) fileUD 対応｡
    2637         * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は、DBTableModelが新規作成された処理でのみ行う｡
    2638         * @og.rev 8.0.0.0 (2021/09/30) TBL.XXXX を設定します｡(TBL.CLMS,TBL.LBLS,TBL.SLBLS,TBL.COLS,TBL.ROWS)
    2639         *
    2640         * @param       tableId ｷｰ
    2641         * @param       table   登録するDBTableModelｵﾌﾞｼﾞｪｸﾄ
    2642         * @return      正常に登録(true) / 一連でないため登録していない(false)
    2643         * @see         #startQueryTransaction( String )
    2644         */
    2645        protected boolean commitTableObject( final String tableId ,final DBTableModel table ) {
    2646                // 登録しないケースをピックアップします。
    2647                if( "session".equals( scope ) ) {
    2648                        final String key = tableId+"_TRANSACTION";
    2649                        final Long endTime = (Long)getSessionAttribute( key );
    2650                        removeSessionAttribute( key );
    2651                        if( endTime == null ||
    2652                                startTransaction == null ||
    2653                                endTime.compareTo( startTransaction ) != 0 ) {
    2654                                        final String msg = "CommonTagSupport Query処理が割り込まれました。DBTableModel は登録しません。"
    2655                                                                + "[" + getUser().getUserID() + "],"
    2656                                                                + "[" + getGUIInfoAttri( "KEY" ) + "]"                  // 4.0.0 (2005/01/31)
    2657                                                                + "[" + startTransaction + "]"                                  // 4.0.0 (2005/01/31)
    2658                                                                + "[" + endTime + "]";                                                  // 4.0.0 (2005/01/31)
    2659                                        System.out.println( msg );
    2660                                        return false;
    2661                        }
    2662                        // 3.8.1.1 (2005/11/21) ExcelOut の整合性を取る為の仕掛け
    2663                        if( table != null && HybsSystem.TBL_MDL_KEY.equals( tableId ) ) {
    2664                                final String consisKey = table.getConsistencyKey();
    2665                                setSessionAttribute( HybsSystem.TBL_MDL_CONKEY,consisKey );
    2666                        }
    2667                }
    2668
    2669                // 4.3.0.0 (2008/07/04) fileUD 対応
    2670                // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し
    2671                if( useTrans && table != null ) {
    2672                        final String guikey = getGUIInfoAttri( "KEY" );
    2673                        final DBLastSql lastSql = new DBLastSql( scope,guikey,table.isOverflow(),tableId );
    2674                        setSessionAttribute( HybsSystem.DB_LAST_SQL_KEY,lastSql );
    2675                }
    2676
    2677                setObject( tableId,table );
    2678
    2679                // 8.0.0.0 (2021/09/30) TBL.XXXX を設定します。(TBL.CLMS,TBL.LBLS,TBL.SLBLS,TBL.COLS,TBL.ROWS)
    2680                if( table != null ) {
    2681                        final StringBuilder clms = new StringBuilder( BUFFER_MIDDLE );
    2682                        final StringBuilder lbls = new StringBuilder( BUFFER_MIDDLE );
    2683                        final StringBuilder slbls = new StringBuilder( BUFFER_MIDDLE );
    2684                        for( final DBColumn clm : table.getDBColumns() ) {
    2685                                clms.append( clm.getName() ).append( ',' );                                                                     // ｶﾗﾑ名
    2686                                lbls.append( StringUtil.tagCut( clm.getLabel() ) ).append( ',' );                       // ﾗﾍﾞﾙ名
    2687                                slbls.append( StringUtil.tagCut( clm.getShortLabel() ) ).append( ',' );         // ﾗﾍﾞﾙ名(名前(短))
    2688                        }
    2689
    2690                        // 最後のｶﾝﾏを除外します。
    2691                        clms.setLength( clms.length()-1 );
    2692                        lbls.setLength( lbls.length()-1 );
    2693                        slbls.setLength( slbls.length()-1 );
    2694
    2695                        setRequestAttribute( "TBL.CLMS" , clms.toString() );
    2696                        setRequestAttribute( "TBL.LBLS" , lbls.toString() );
    2697                        setRequestAttribute( "TBL.SLBLS", slbls.toString() );
    2698                        setRequestAttribute( "TBL.COLS" , String.valueOf( table.getColumnCount() ) );   // ｶﾗﾑの数
    2699                        setRequestAttribute( "TBL.ROWS" , String.valueOf( table.getRowCount() ) );              // 行数(={@DB.COUNT})
    2700                }
    2701
    2702                return true;
    2703        }
    2704
    2705        /**
    2706         * 表示ﾃﾞｰﾀの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行番号の
    2707         * 配列を返します｡
    2708         * 配列情報は、行番号でｿｰﾄされて返されます｡
    2709         * なにも選ばれていない場合は、ｻｲｽﾞ０の配列を返します｡
    2710         *
    2711         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    2712         * @og.rev 6.3.9.1 (2015/11/27) 内部処理が、長さが0の配列を返すように変更されたので、その対応｡
    2713         *
    2714         * @return      (選ばれていない場合は、ｻｲｽﾞ０の配列を返す)
    2715         * @og.rtnNotNull
    2716         */
    2717        protected int[] getParameterRows() {
    2718                if( rowNo != null ) { return rowNo; }
    2719
    2720                // 6.3.9.1 (2015/11/27) org.opengion.hayabusa.servlet.MultipartRequest#getIntParameters(String) が、
    2721                // 存在しない場合、長さが0の配列を返すことにしたので、同じﾛｼﾞｯｸに変更しておきます｡
    2722                rowNo = (int[])getRequestAttribute( HybsSystem.ROW_SEL_KEY );
    2723                if( rowNo != null && rowNo.length > 0 ) { return rowNo; }
    2724
    2725                final String[] selected = getRequestValues( HybsSystem.ROW_SEL_KEY ) ;
    2726
    2727                // 6.3.9.1 (2015/11/27) ﾗﾑﾀﾞ式で書き直します｡
    2728                return selected == null || selected.length == 0
    2729                                        ? new int[0]
    2730                                        : Arrays.stream( selected )
    2731                                                        .filter( str -> str != null && !str.isEmpty() )
    2732                                                        .mapToInt( Integer::parseInt )
    2733                                                        .sorted()
    2734                                                        .toArray();
    2735        }
    2736
    2737        /**
    2738         * 表示ﾃﾞｰﾀの HybsSystem.ROW_SEL_KEY に対して、選ばれた 行番号の
    2739         * 配列を設定します｡
    2740         * ここで設定した選択配列は、getParameterRows() ﾒｿｯﾄﾞで取得する場合、優先されます｡
    2741         *
    2742         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    2743         *
    2744         * @param       rowNo   行番号配列(可変長引数)
    2745         */
    2746        protected void setParameterRows( final int... rowNo ) {
    2747                setRequestAttribute(  HybsSystem.ROW_SEL_KEY , rowNo );
    2748        }
    2749
    2750        /**
    2751         * 指定のｸｯｷｰをｾｯﾄします｡
    2752         * これは、従来，各Taglibﾊﾟｯｹｰｼﾞで使用していました、ErrorMessage ｵﾌﾞｼﾞｪｸﾄを、
    2753         * HTMLﾃｰﾌﾞﾙ形式で表示する為に、DBUtilｸﾗｽや、ViewFormｸﾗｽなど、複数のｸﾗｽを
    2754         * 複雑に組み合わせて使用していましたが、一つの static ﾒｿｯﾄﾞにまとめたものです｡
    2755         *
    2756         * @og.rev 3.7.0.3 (2005/03/01) 新規登録
    2757         *
    2758         * @param       key             ｸｯｷｰのｷｰ
    2759         * @param       value   ｸｯｷｰの設定値
    2760         * @param       maxage  最長存続期間を秒単位で設定 (負の値は Cookie を保存しない、 0 なら Cookie を削除する)
    2761         */
    2762        protected void setCookie( final String key,final String value,final int maxage ) {
    2763                final HttpServletResponse res = (HttpServletResponse)pageContext.getResponse();
    2764                final Cookie ck = new Cookie( key, value );
    2765                ck.setMaxAge( maxage );                                                                                                 // 有効秒
    2766                res.addCookie( ck );
    2767        }
    2768
    2769        /**
    2770         * 指定のｸｯｷｰを取得します｡
    2771         * 見つからない場合は、null を返します｡
    2772         *
    2773         * @og.rev 3.7.0.3 (2005/03/01) 新規登録
    2774         *
    2775         * @param       key     ｸｯｷｰのｷｰ
    2776         * @return      ｸｯｷｰの設定値
    2777         */
    2778        protected String getCookie( final String key ) {
    2779                final HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
    2780                final Cookie[] cks = req.getCookies();
    2781
    2782                String val = null;
    2783                for( int i=0; i<cks.length; i++ ) {
    2784                        final Cookie ck = cks[i];
    2785                        if( ck.getName().equals( key ) ) {
    2786                                val = ck.getValue();
    2787                                break;
    2788                        }
    2789                }
    2790                return val ;
    2791        }
    2792
    2793        /**
    2794         * ﾘｸｴｽﾄ情報の ｼﾝｸﾞﾙｸｫｰﾄ(') 存在ﾁｪｯｸを実施するかどうか[true/false]を設定します
    2795         *              (初期値:USE_SQL_INJECTION_CHECK[={@og.value SystemData#USE_SQL_INJECTION_CHECK}])｡
    2796         *
    2797         * SQLｲﾝｼﾞｪｸｼｮﾝ対策の一つとして、暫定的ではありますが、SQLのﾊﾟﾗﾒｰﾀに
    2798         * 渡す文字列にｼﾝｸﾞﾙｸｫｰﾄ(') を許さない設定にすれば、ある程度は防止できます｡
    2799         * 数字ﾀｲﾌﾟの引数には、 or 5=5 などのｼﾝｸﾞﾙｸｫｰﾄを使用しないｺｰﾄﾞを埋めても、
    2800         * 数字ﾁｪｯｸで検出可能です｡文字ﾀｲﾌﾟの場合は、必ず (')をはずして、
    2801         * ' or 'A' like 'A のような形式になる為、(')ﾁｪｯｸだけでも有効です｡
    2802         * (') が含まれていたｴﾗｰにする(true)／かﾉｰﾁｪｯｸか(false)を指定します｡
    2803         * (初期値:ｼｽﾃﾑ定数のUSE_SQL_INJECTION_CHECK[={@og.value SystemData#USE_SQL_INJECTION_CHECK}])｡
    2804         *
    2805         * @og.rev 4.0.0.0 (2005/08/31) 新規追加
    2806         *
    2807         * @param       flag    ｼﾝｸﾞﾙｸｫｰﾄﾁｪｯｸ  [true:する/:falseしない]
    2808         * @see         org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK
    2809         */
    2810        protected void useQuotCheck( final boolean flag ) {
    2811                quotCheck = flag;
    2812        }
    2813
    2814        /**
    2815         * ﾘｸｴｽﾄ情報の HTMLTag開始/終了文字(&gt;&lt;) 存在ﾁｪｯｸを実施するかどうか[true/false]を設定します
    2816         *    (初期値:USE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])｡
    2817         *
    2818         * ｸﾛｽｻｲﾄｽｸﾘﾌﾟﾃｨﾝｸﾞ(XSS)対策の一環としてless/greater than signについてのﾁｪｯｸを行います｡
    2819         * (&gt;&lt;) が含まれていたｴﾗｰにする(true)／かﾉｰﾁｪｯｸか(false)を指定します｡
    2820         * 現在の実装としてはﾘｸｴｽﾄﾊﾟﾗﾒｰﾀのみﾁｪｯｸして、attributesに対しては行いません｡
    2821         * (初期値:ｼｽﾃﾑ定数のUSE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])｡
    2822         *
    2823         * @og.rev 5.0.0.2 (2009/09/15) 新規追加
    2824         *
    2825         * @param       flag    XSSﾁｪｯｸ [true:する/false:しない]
    2826         * @see         org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK
    2827         */
    2828        protected void useXssCheck( final boolean flag ) {
    2829                xssCheck = flag;
    2830        }
    2831
    2832        /**
    2833         * 日付関係の情報を簡易的に取り出す処理を行います｡
    2834         *
    2835         * これは、{&#064;DATE.XXXX AA BB CC} 引数処理をおこなうための、ｻﾎﾟｰﾄﾒｿｯﾄﾞです｡
    2836         * XXXX は結果のﾌｫｰﾏｯﾄ、AA が基準時刻で省略した場合は、現在時刻が利用されます｡
    2837         * BB 引数は、日付についての加減算処理を行うためのｺﾏﾝﾄﾞです｡
    2838         * CC 引数は、BB引数のｺﾏﾝﾄﾞに付属するﾊﾟﾗﾒｰﾀです｡加減算処理の数値を指定できます｡
    2839         * AA,BB,CC 引数については、先頭に、@ を付ける事で、ﾘｸｴｽﾄ変数が使用できます｡
    2840         *
    2841         * 引数は、"XXXX AA BB CC" という状態で受け取ります｡(DATE. ははずした形)
    2842         * 第一引数(key) "XXXX" は、日付処理を行うﾌｫｰﾏｯﾄの予約語になっています｡
    2843         * ･Y4     ：4文字の年ﾃﾞｰﾀ(yyyy)を扱います｡
    2844         * ･YMD    ：8文字の4-2-2年月日ﾃﾞｰﾀ(yyyyMMdd)を扱います｡
    2845         * ･Y2MD   ：6文字の2-2-2年月日ﾃﾞｰﾀ(yyMMdd)を扱います｡
    2846         * ･YM     ：6文字の4-2年月ﾃﾞｰﾀ(yyyyMM)を扱います｡
    2847         * ･HMS    ：6文字の2-2-2時分秒ﾃﾞｰﾀ(HHmmss)を扱います｡
    2848         * ･HM     ：4文字の2-2時分ﾃﾞｰﾀ(HHmm)を扱います｡6.7.4.1 (2017/02/17)
    2849         * ･YMDHMS ：1４文字の4-2-2-2-2-2年月日時分秒ﾃﾞｰﾀ(yyyyMMddHHmmss)を扱います｡
    2850         * ･EEE    ：曜日をﾃﾞﾌｫﾙﾄﾛｹｰﾙで表示します｡
    2851         *
    2852         * F付きは、ﾌｫｰﾏｯﾄされた日付を返します｡
    2853         * ･YMDF   ：10文字の日付表現(yyyy/MM/dd)を扱います｡
    2854         * ･Y2MDF  ：8文字の日付表現(yy/MM/dd)を扱います｡
    2855         * ･YMF    ：7文字の日付表現(yyyy/MM)を扱います｡
    2856         * ･HMSF   ：8文字の時刻表現(HH:mm:ss)を扱います｡
    2857         * ･HMF    ：5文字の時刻表現(HH:mm)を扱います｡6.7.4.1 (2017/02/17)
    2858         * ･YMDHMSF：19文字の日付表現(yyyy/MM/dd HH:mm:ss)を扱います｡
    2859         * ･MDF    ：5文字の月日表現(MM/dd)を扱います｡
    2860         * ･MDEF   ：5文字＋曜日の月日表現(MM/dd(EEE))を扱います｡
    2861         * ･MDHMF  ：11文字の月日時分表現(MM/dd HH:mm)を扱います｡ (7.0.0.1 (2018/10/09) 追加)
    2862         * ･MD2F   ：漢字の月日表現(MM月dd日)を扱います｡(5.5.5.2 追加)
    2863         * ･HM2F   ：漢字の時分表現(HH時mm分)を扱います｡(7.0.0.1 (2018/10/09) 追加)
    2864         * ･MDHM2F ：漢字の月日時分表現(MM月dd日 HH時mm分)を扱います｡(7.0.0.1 (2018/10/09) 追加)
    2865         * ･GYMDF  ：和暦の年月日表現(GGGGyyyy年MM月dd日)を扱います｡
    2866         * ･G2YMDF ：和暦の日付表現(Gyyyy/MM/dd)を扱います｡
    2867         * ･GYMF   ：和暦の年月表現(GGGGyyyy年MM月)を扱います｡
    2868         * ･GYF    ：和暦の年表現(GGGGyyyy)を扱います｡
    2869         *
    2870         * ･DIFF   ：日付の差分を求めます｡(7.0.1.1 (2018/10/22) 追加)
    2871         *               AA - BB を求め、CCの数値で単位を指定します｡
    2872         *
    2873         * なお、上記以外のﾌｫｰﾏｯﾄを指定する場合は、XXXX部分に直接記述できます｡(5.5.5.2 追加)
    2874         * ただし、ｽﾍﾟｰｽで分解するため、ﾌｫｰﾏｯﾄにｽﾍﾟｰｽを含む場合は、ﾀﾞﾌﾞﾙｺｰﾃｰｼｮﾝ等で
    2875         * くくる等の処理が必要です｡基本的には、自由ﾌｫｰﾏｯﾄは、ｴﾗｰﾁｪｯｸがない為、使わないでください｡
    2876         *
    2877         * 第二引数 AA は、基準となる日付を、yyyyMMdd形式で指定します｡nullの場合は、現在日時を使用します｡
    2878         * 指定できる日付は、yyyyMMdd形式を推奨しますが、'/' , '-' , ' ' , ':' を削除して使います｡
    2879         * 6桁の場合は、yyyyMM + 01 とし、8ｹﾀの場合は、yyyyMMdd とし、14ｹﾀ以上の場合は、前半14文字を
    2880         * yyyyMMddHHmmss として処理します｡それ以外の桁数の場合は、ｴﾗｰになります｡
    2881         * たとえば、"2012/09/05 16:52:36" のようなﾌｫｰﾏｯﾄﾃﾞｰﾀの場合、'/' , '-' , ' ' , ':' を削除して
    2882         * "20120905165236" に変換後、日付ｵﾌﾞｼﾞｪｸﾄに変換されます｡
    2883         *
    2884         * AA には、数字で始まる(20050701など)実日付と&#064;で始まるﾊﾟﾗﾒｰﾀが使用できます｡
    2885         * &#064;AA と記述することで、{&#064;AA}で指定する場合と同様のﾘｸｴｽﾄﾊﾟﾗﾒｰﾀが使用できます｡
    2886         * このﾊﾟﾗﾒｰﾀの値の解析結果が、null の場合は、現在時刻が使用されます｡
    2887         * 数字以外の場合は、省略されたと判断して、ｺﾏﾝﾄﾞ（BB引数）として使用されます｡
    2888         *
    2889         * BB 引数は、日付についての加減算処理を行います｡
    2890         * 省略すると、なにも加減算処理を行いません｡
    2891         * この引数もﾊﾟﾗﾒｰﾀ(&#064;BB)指定で、ﾘｸｴｽﾄﾊﾟﾗﾒｰﾀが使用できます｡
    2892         * 加減算処理のﾊﾟﾗﾒｰﾀが使用できるのは、"H" , "D" , "M" の１文字ﾊﾟﾗﾒｰﾀの場合のみです｡
    2893         * それ以外のｺﾏﾝﾄﾞで、加減算処理する場合は、独立した CC 引数 を使用してください｡
    2894         * ･SY :当年の最初の日付にｾｯﾄします｡(当年1月1日)｡CC引数は、-N:N年前、0:当年(=SY)、N:N年後 6.9.2.1 (2018/03/12)
    2895         * ･SD :当月の最初の日付にｾｯﾄします｡(当月1日)｡CC引数は、-N:N月前、0:当月(=SD)、N:N月後、-1:BSD と同じ、1:ASD と同じ
    2896         * ･SW :日付処理の週初め(月曜日)にｾｯﾄします｡日付は当日より前に移動します｡CC引数は、-N:N週前、0:今週(=SW)、N:N週後
    2897         * ･SH :指定の最初の時にｾｯﾄします｡(分秒を0000にする)｡CC引数は、時の倍数(4と指定すれば、4時間単位に前に戻る) 6.7.4.1 (2017/02/17)
    2898         * ･SM :指定の最初の分にｾｯﾄします｡(秒を00にする)｡CC引数は、分の倍数(15と指定すれば、15分単位に前に戻る) 6.7.4.1 (2017/02/17)
    2899         * ･SS :指定の最初の秒にｾｯﾄします｡CC引数は、秒の倍数(15と指定すれば、15秒単位に前に戻る) 6.7.4.1 (2017/02/17)
    2900         * ･EY :当年の最後の日付にｾｯﾄします｡(当年年末)｡CC引数は、-N:N年前、0:当年(=EY)、N:N年後 6.9.2.1 (2018/03/12)
    2901         * ･ED :当月の最後の日付にｾｯﾄします｡(当月月末)｡CC引数は、-N:N月前、0:当月(=ED)、N:N月後、-1:BED と同じ、1:AED と同じ
    2902         * ･EW :日付処理の週末(日曜日)にｾｯﾄします｡日付は当日より後ろに移動します｡CC引数は、-N:N週前、0:今週(=EW)、N:N週後
    2903         * ･EH :指定の次の時にｾｯﾄします｡(分秒を0000にした次の時)｡CC引数は、時の倍数(4と指定すれば、4時間単位に前に進む) 6.7.4.1 (2017/02/17)
    2904         * ･EM :指定の次の分にｾｯﾄします｡(秒を00にした次の分)｡CC引数は、分の倍数(15と指定すれば、15分単位に前に進む) 6.7.4.1 (2017/02/17)
    2905         * ･ES :指定の次の秒にｾｯﾄします｡CC引数は、秒の倍数(15と指定すれば、15秒単位に前に進む) 6.7.4.1 (2017/02/17)
    2906         * ･M1 ～ MXXX :月を指定の分だけ進めます｡M1なら翌月、M6 なら半年後
    2907         * ･D1 ～ DXXX :日を指定の分だけ進めます｡D1なら翌日、D200 なら200日後
    2908         * ･H1 ～ HXXX :時を指定の分だけ進めます｡H1なら1時間後、H24 なら24時間後(5.5.5.6 (2012/08/31) 追加)
    2909         * ･MI  :分を指定の分だけ進めます｡第四引数(intC) で、時間を指定します｡(6.8.4.1 (2017/12/18) 追加)
    2910         * ･YMD :CC 引数のYMD表記の日付を加減算します｡6.8.4.1 (2017/12/18) 追加
    2911         * ･HM  :CC 引数のHM表記の時刻を加減算します｡6.8.4.1 (2017/12/18) 追加
    2912         * ･NO  :AA 引数がnullの場合、現在時刻ではなく空文字列にします｡  7.0.1.3 (2018/11/12) 追加
    2913         * ･(有閑)BSD :先月の最初の日付にｾｯﾄします｡(先月1日)(5.5.5.2 追加)｡SD -1 と同等
    2914         * ･(有閑)BED :先月の最後の日付にｾｯﾄします｡(先月月末)(5.5.5.2 追加)｡ED -1 と同等
    2915         * ･(有閑)ASD :翌月の最初の日付にｾｯﾄします｡(翌月1日)(5.5.5.2 追加)｡SD 1  と同等
    2916         * ･(有閑)AED :翌月の最後の日付にｾｯﾄします｡(翌月月末)(5.5.5.2 追加)｡ED 1  と同等
    2917         *
    2918         * 7.0.1.1 (2018/10/22)
    2919         *   DATE.DIFF の場合、BB 引数は、日付ﾃﾞｰﾀになります｡AA-BB の関係です｡
    2920         *
    2921         * CC 引数は、特別な処理で、BB 引数に対して、加算、減算のための数字を指定できます｡(5.7.4.1 (2014/03/14) 追加)
    2922         * 従来は、BB 引数が、"H" , "D" , "M" の 1文字ﾊﾟﾗﾒｰﾀの場合のみ利用可能でした｡
    2923         * これは、"H15" と指定するのと、"H" "15" と指定するのと同じ意味になります｡
    2924         * 異なるのは、CC 引数も、(&#064;CC)指定で、ﾘｸｴｽﾄﾊﾟﾗﾒｰﾀが使用できます｡
    2925         * 従来は、文字列として結合された状態でしか、BB 引数を渡せませんでしたが、この、CC 引数の
    2926         * 追加で、日付の加減算を、ﾊﾟﾗﾒｰﾀ指定できるようになります｡
    2927         * 数字以外の文字が指定されたり、ﾊﾟﾗﾒｰﾀの解析結果が NULL の場合には、BB引数自体も無視されます｡
    2928         * 注意点は、各 BB 引数に応じて、数字の意味が異なるという事です｡
    2929         *
    2930         * HXXX,DXXX,MXXX 形式に、CC 引数を付けた場合は、XXX にさらに加算されます｡
    2931         * prmB に、数字を使用した場合、(ｺﾏﾝﾄﾞでない場合)にも、CC 引数は、加算されます｡
    2932         *
    2933         * 7.0.1.1 (2018/10/22)
    2934         *   DATE.DIFF の場合、CC 引数は、差分の単位を指定するｷｰﾜｰﾄﾞになります｡AA-BB の結果を、
    2935         *   1:年 2:月 3:日 4:時 5:分 6:秒 に換算 して返します｡端数は切り捨てで整数で返します｡
    2936         *
    2937         * @og.rev 3.8.0.2 (2005/07/11) 新規追加
    2938         * @og.rev 5.4.0.1 (2011/11/01) 日付処理の機能追加(BB 引数に、ﾘｸｴｽﾄﾊﾟﾗﾒｰﾀ対応)
    2939         * @og.rev 5.5.0.2 (2012/03/09) 和暦対応
    2940         * @og.rev 5.5.5.2 (2012/08/18) XXXXﾌｫｰﾏｯﾄ追加、自由ﾌｫｰﾏｯﾄ対応、BB引数追加、/,-削除機能追加、SM,EM廃止
    2941         * @og.rev 5.5.5.6 (2012/08/31) H1 ～ HXXX 追加｡時間の加算を指定できる｡
    2942         * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します｡
    2943         * @og.rev 5.5.8.2 (2012/11/09) prmA の判定に、null と ｾﾞﾛ文字列を判定する｡
    2944         * @og.rev 5.6.0.1 (2013/01/11) 5.5.7.2でyyyyMMddしか取っていないため、HHmmssを追加します
    2945         * @og.rev 5.7.4.1 (2014/03/14) AA 引数の@解析後のｺﾏﾝﾄﾞ判定方法を、８ｹﾀ以下から先頭が数字以外に変更します｡
    2946         * @og.rev 5.7.4.1 (2014/03/14) CC 引数を、"H" , "D" , "M" 以外でも使用できるように拡張します｡
    2947         *
    2948         * @param       value   ﾊﾟﾗﾒｰﾀ
    2949         * @return      ﾒｯｾｰｼﾞ情報
    2950         * @see         org.opengion.fukurou.util.HybsDateUtil#getDateFormat( String,String,String,int )
    2951         */
    2952        protected String getDateFormat( final String value ) {
    2953                // {@DATE.XXXX AA BB CC} を分割
    2954                final String[] vals = StringUtil.csv2Array( value,' ' );                // ダブルクオート内は保持される。
    2955
    2956                final String key = vals[0] ;
    2957
    2958                // 5.7.4.1 (2014/03/14) 初期化時に、vals を設定しておきます。
    2959                String prmA = vals.length >= 2 ? vals[1] : null ;
    2960                String prmB = vals.length >= 3 ? vals[2] : null ;
    2961                String prmC = vals.length >= 4 ? vals[vals.length-1] : null ;           // 互換性。最後の値が、CC引数
    2962
    2963                if( StringUtil.startsChar( prmA , '@' ) ) {                                                     // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    2964                        prmA = getRequestValue( prmA.substring(1) );
    2965                }
    2966
    2967                if( StringUtil.startsChar( prmB , '@' ) ) {                                                     // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    2968                        prmB = getRequestValue( prmB.substring(1) );
    2969                }
    2970
    2971                if( StringUtil.startsChar( prmC , '@' ) ) {                                                     // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    2972                        prmC = getRequestValue( prmC.substring(1) );
    2973                }
    2974
    2975                // 5.7.4.1 (2014/03/14) AA 引数の@解析後のｺﾏﾝﾄﾞ判定方法を、８ｹﾀ以下から先頭が数字以外に変更します｡
    2976                if( prmA != null && prmA.length() > 0 ) {
    2977                        final char chA = prmA.charAt(0);
    2978                        // 先頭が、数字以外の場合は、ｺﾏﾝﾄﾞなので、一つずつずらす｡
    2979                        if( chA < '0' || chA > '9' ) {
    2980                                prmC = prmB;
    2981                                prmB = prmA;
    2982                                prmA = null;
    2983                        }
    2984                }
    2985
    2986                // 5.7.4.1 (2014/03/14) CC 引数を、"H" , "D" , "M" 以外でも使用できるように拡張します。
    2987                int intC = 0;
    2988                if( prmC != null && prmC.length() > 0 ) {
    2989                        try {
    2990                                intC = Integer.parseInt( prmC );
    2991                        }
    2992                        catch( final NumberFormatException ex ) {
    2993                                final String errMsg = "CC引数が数字ではありません。value=[" + value + "]"
    2994                                                                + ex.getMessage() ;
    2995                                System.err.println( errMsg );
    2996                        }
    2997                }
    2998
    2999                // prmA が null か、isEmpty() の場合は、現在時刻が使用される。
    3000                return HybsDateUtil.getDateFormat( key,prmA,prmB,intC );                                // 5.7.4.1 (2014/03/14) CC 引数を拡張します。
    3001        }
    3002
    3003        /**
    3004         * debug や ｴﾗｰ時に参考にする、ｸｲｯｸﾘﾌｧﾚﾝｽへのﾘﾝｸを作成します｡
    3005         * ﾘﾝｸを行うﾀｸﾞの名称は、getTagName() ﾒｿｯﾄﾞより取得します｡
    3006         *
    3007         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    3008         * @og.rev 4.2.1.0 (2008/04/11) URLを相対ﾊﾟｽに変更
    3009         * @og.rev 6.2.1.0 (2015/03/13) ｸｲｯｸﾘﾌｧﾚﾝｽへのﾘﾝｸが相対ﾊﾟｽでは、common/gamen 以下から使えない｡
    3010         * @og.rev 6.3.1.1 (2015/07/10) ｸｲｯｸﾘﾌｧﾚﾝｽは、documents.html ではなく、quickReference.html です｡
    3011         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"／＞" 止めを、"＞" に変更します)｡
    3012         *
    3013         * @return      ｸｲｯｸﾘﾌｧﾚﾝｽへのﾘﾝｸ
    3014         * @og.rtnNotNull
    3015         * @see         #getTagName()
    3016         */
    3017        protected String getDocumentLink() {
    3018                final String name = getTagName();
    3019
    3020        //      try {
    3021        //              Field fld = getClass().getDeclaredField( "VERSION" ) ;
    3022        //              version = (String)fld.get( null );
    3023        //      }
    3024        //      catch( final Exception ex ) {
    3025        //              version = ex.toString();
    3026        //      }
    3027
    3028                // org.opengion.hayabusa.taglib.AbcdTag というｸﾗｽ名より、abcd を取り出す｡
    3029                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    3030//                      .append( "<br /><a href=\"" )
    3031                        .append( "<br><a href=\"" )                                                                                     // 7.0.1.0 (2018/10/15)
    3032                        .append( HybsSystem.sys( "JSP" ) )                                                                      // 6.2.1.0 (2015/03/13) 追加
    3033                        .append( "/common/quickReference.html#VAL_" )                                           // 6.3.1.1 (2015/07/10) ﾘﾝｸ先間違い
    3034                        .append( name )
    3035                        .append( "\" target=\"_brank\" >ｸｲｯｸﾘﾌｧﾚﾝｽ[" )
    3036                        .append( name )
    3037                        .append( "] " )
    3038                        .append( BuildNumber.ENGINE_INFO )                                                                      // 6.3.1.1 (2015/07/10) ENGINE_INFO の追加
    3039                //      .append( version )
    3040                        .append( "</a>" ).append( BR );
    3041
    3042                return buf.toString();
    3043        }
    3044
    3045        /**
    3046         * ﾀｸﾞの名称を返します｡
    3047         * これは、debug や ｴﾗｰ時に参考にする、ｸｲｯｸﾘﾌｧﾚﾝｽへのﾘﾝｸを作成する場合に
    3048         * 使用します｡
    3049         * 通常は、org.opengion.hayabusa.taglib.AbcdTag という自分自身のｸﾗｽ名より、
    3050         * abcd の部分を取り出し、返します｡
    3051         * ｸﾗｽ名とﾀｸﾞ名が、上記変換ﾙｰﾙと異なる場合は、このﾒｿｯﾄﾞを
    3052         * 使用して、直接 abcd の部分に相当する文字列を返すようにしてください｡
    3053         *
    3054         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    3055         *
    3056         * @return      ﾀｸﾞの名称
    3057         * @og.rtnNotNull
    3058         * @see #getDocumentLink()
    3059         */
    3060        protected String getTagName() {
    3061                final String name = getClass().getName();
    3062                final int adrs = name.lastIndexOf('.');
    3063
    3064                // org.opengion.hayabusa.taglib.AbcdTag というクラス名より、abcd を取り出す。
    3065                return name.substring( adrs+1,adrs+2 ).toLowerCase(Locale.JAPAN)
    3066                                + name.substring( adrs+2,name.length()-3 ) ;
    3067        }
    3068
    3069        /**
    3070         * ﾘｸｴｽﾄに対して、画面遷移なしﾓｰﾄﾞを有効にします[true/false]｡
    3071         * この情報は画面IDをｷｰにｾｯｼｮﾝに保存されるため、
    3072         * 各ﾀｸﾞで共有することができます｡
    3073         *
    3074         * @og.rev 4.3.3.0 (2008/10/01) 新規作成
    3075         * @og.rev 4.3.8.0 (2009/08/01) ﾘｸｴｽﾄからｾｯｼｮﾝに変更(名称も変更)
    3076         * @og.rev 5.1.3.0 (2010/02/01) noTransition、ajaxSubmitのｺﾝﾄﾛｰﾙは、requestで行う｡
    3077         *
    3078         * @param       flag    画面遷移なしﾓｰﾄﾞ [true:有効/false:無効]
    3079         */
    3080        protected void setNoTransitionRequest( final boolean flag ) {
    3081                setRequestAttribute( HybsSystem.NO_TRANSITION_MODE_KEY, String.valueOf( flag ));
    3082        }
    3083
    3084        /**
    3085         * ﾘｸｴｽﾄで画面遷移なしﾓｰﾄﾞが有効になっているかを返します｡
    3086         * この情報はｾｯｼｮﾝから画面IDをｷｰに取得します｡
    3087         * ｾｯｼｮﾝに情報が設定されていない(#setNoTransition()が呼ばれていない)場合は、
    3088         * falseを返します｡
    3089         *
    3090         * @og.rev 4.3.3.0 (2008/10/01) 新規作成
    3091         * @og.rev 4.3.8.0 (2009/08/01) ﾘｸｴｽﾄからｾｯｼｮﾝに変更
    3092         * @og.rev 5.1.3.0 (2010/02/01) noTransition、ajaxSubmitのｺﾝﾄﾛｰﾙは、requestで行う｡
    3093         *
    3094         * @return      画面遷移なしﾓｰﾄﾞが有効
    3095         */
    3096        protected boolean isNoTransitionRequest() {
    3097                return nval( (String)getRequestAttribute( HybsSystem.NO_TRANSITION_MODE_KEY ), false );
    3098        }
    3099
    3100        /**
    3101         * ﾘｸｴｽﾄに対して、AjaxSubmitﾓｰﾄﾞを使用するかどうか指定します[true/false]｡
    3102         * この情報は画面IDをｷｰにｾｯｼｮﾝに保存されるため、
    3103         * 各ﾀｸﾞで共有することができます｡
    3104         *
    3105         * @og.rev 4.3.8.0 (2009/08/01) 新規作成
    3106         * @og.rev 5.1.3.0 (2010/02/01) noTransition、ajaxSubmitのｺﾝﾄﾛｰﾙは、requestで行う｡
    3107         *
    3108         * @param       flag    AjaxSubmitﾓｰﾄﾞ [true:使用する/false:使用しない]
    3109         */
    3110        protected void setAjaxSubmitRequest( final boolean flag ) {
    3111                setRequestAttribute( HybsSystem.USE_AJAX_SUBMIT_KEY, String.valueOf( flag ));
    3112        }
    3113
    3114        /**
    3115         * ﾘｸｴｽﾄでAjaxSubmitﾓｰﾄﾞが有効になっているかを返します｡
    3116         * この情報はｾｯｼｮﾝから画面IDをｷｰに取得します｡
    3117         * ｾｯｼｮﾝに情報が設定されていない(#setNoTransition()が呼ばれていない)場合は、
    3118         * falseを返します｡
    3119         *
    3120         * @og.rev 4.3.8.0 (2009/08/01) 新規作成
    3121         * @og.rev 5.1.3.0 (2010/02/01) noTransition、ajaxSubmitのｺﾝﾄﾛｰﾙは、requestで行う｡
    3122         *
    3123         * @return      AjaxSubmitﾓｰﾄﾞが有効
    3124         */
    3125        protected boolean isAjaxSubmitRequest() {
    3126                return nval( (String)getRequestAttribute( HybsSystem.USE_AJAX_SUBMIT_KEY ), false );
    3127        }
    3128
    3129        /**
    3130         * ｼﾘｱﾗｲｽﾞ用のｶｽﾀﾑｼﾘｱﾗｲｽﾞ読み込みﾒｿｯﾄﾞ
    3131         *
    3132         * ここでは、transient 宣言された内部変数の内、初期化が必要なﾌｨｰﾙﾄﾞのみ設定します｡
    3133         *
    3134         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
    3135         * @serialData 一部のｵﾌﾞｼﾞｪｸﾄは、ｼﾘｱﾗｲｽﾞされません｡
    3136         *
    3137         * @param       strm    ObjectInputStreamｵﾌﾞｼﾞｪｸﾄ
    3138         * @see #release2()
    3139         */
    3140        private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
    3141                strm.defaultReadObject();
    3142                attri = new Attributes();
    3143        }
    3144
    3145        /**
    3146         * ｱｸｾｽﾛｸﾞ取得の為,ApplicationInfoｵﾌﾞｼﾞｪｸﾄを返します｡
    3147         * 見つからない場合は、null が返ります｡(暫定対応)
    3148         *
    3149         * @og.rev 3.8.7.0 (2006/12/15) 新規追加
    3150         *
    3151         * @return      ｱｸｾｽﾛｸﾞ取得の為の管理ｵﾌﾞｼﾞｪｸﾄ
    3152         */
    3153        protected ApplicationInfo getApplicationInfo() {
    3154                final String gamenId = getGUIInfoAttri( "KEY" );
    3155                final String jspId   = (String)getSessionAttribute( "JSPID" );
    3156
    3157                return getUser().getApplicationInfo( gamenId,jspId );
    3158        }
    3159
    3160        /**
    3161         * ｲﾍﾞﾝﾄｶﾗﾑの実行に必要なｶﾗﾑ情報をﾏｯﾌﾟに登録します｡
    3162         *
    3163         * @og.rev 5.1.7.0 (2010/06/01) 動的ﾌﾟﾙﾀﾞｳﾝ実装見直し
    3164         * @og.rev 6.3.3.0 (2015/07/25) eventValue 追加
    3165         *
    3166         * @param       col     DBｶﾗﾑ
    3167         */
    3168        protected void addEventColumn( final DBColumn col ) {
    3169                addEventColumn( col.getName(), col.getEventColumn(), col.getEventValue(), col.getEventURL()
    3170                                                , col.getRenderer(), col.getEditor(), col.getRawRendParam(), col.getRawEditParam() );
    3171        }
    3172
    3173        /**
    3174         * ｲﾍﾞﾝﾄｶﾗﾑの実行に必要なｶﾗﾑ情報をﾏｯﾌﾟに登録します｡
    3175         *
    3176         * @og.rev 5.1.7.0 (2010/06/01) 動的ﾌﾟﾙﾀﾞｳﾝ実装見直し
    3177         * @og.rev 6.3.3.0 (2015/07/25) eventValue 追加
    3178         *
    3179         * @param       name            ｶﾗﾑ名
    3180         * @param       evCol           ｲﾍﾞﾝﾄｶﾗﾑ名
    3181         * @param       evVal           子ｶﾗﾑの値SQL
    3182         * @param       url                     ｲﾍﾞﾝﾄURL
    3183         * @param       renderer        ｶﾗﾑのﾚﾝﾃﾞﾗｰ
    3184         * @param       editor          ｶﾗﾑのｴﾃﾞｨﾀｰ
    3185         * @param       rendParam       ｶﾗﾑの表示ﾊﾟﾗﾒｰﾀｰ
    3186         * @param       editParam       ｶﾗﾑの編集ﾊﾟﾗﾒｰﾀｰ
    3187         */
    3188        protected void addEventColumn( final String name, final String evCol , final String evVal, final String url,
    3189                                                final String renderer, final String editor, final String rendParam, final String editParam ) {
    3190                if( evCol == null || evCol.isEmpty() ){ return; }
    3191
    3192                String key = (String)getRequestAttribute( HybsSystem.USE_EVENT_COLUMN_KEY );
    3193                if( key == null || key.isEmpty() ) {
    3194                        key = HybsSystem.USE_EVENT_COLUMN_KEY + System.currentTimeMillis();
    3195                        setRequestAttribute( HybsSystem.USE_EVENT_COLUMN_KEY, key );
    3196                }
    3197
    3198                @SuppressWarnings(value={"unchecked"})
    3199                Map<String, DBEventColumn> evColMap = (Map<String, DBEventColumn>)( getSessionAttribute( key ) );
    3200                if( evColMap == null ){
    3201                        evColMap = new HashMap<>();
    3202                }
    3203                if( evColMap.get( name ) == null ) {
    3204                        evColMap.put( name, new DBEventColumn( name, evCol, evVal, url, renderer, editor, rendParam, editParam ) );     // 6.3.3.0 (2015/07/25)
    3205                }
    3206                setSessionAttribute( key, evColMap );
    3207        }
    3208
    3209        /**
    3210         * 各ﾃﾞｰﾀﾍﾞｰｽに対応するﾌｧﾝｸｼｮﾝ名を返します｡
    3211         *
    3212         * @og.rev 4.3.7.0 (2009/06/01) 新規作成
    3213         * @og.rev 5.1.4.0 (2010/03/01) ﾃﾞｰﾀﾍﾞｰｽ名 でなく、DBID 名で検索するようにします｡
    3214         *
    3215         * @param       key     ﾌｧﾝｸｼｮﾝ名(定義文字)
    3216         * @return      実ﾌｧﾝｸｼｮﾝ名
    3217         */
    3218        protected String getDBFunctionName( final String key ) {
    3219                final int idx = key.indexOf( ' ' );
    3220                String func = null;
    3221                String dbid = null;
    3222                if( idx >= 0 ) {
    3223                        func = key.substring( 0, idx );
    3224                        dbid = key.substring( idx+1, key.length() );
    3225                        if( StringUtil.startsChar( dbid , '@' ) ) { dbid = getRequestValue( dbid.substring( 1 ) ); }    // 6.2.0.0 (2015/02/27) １文字 String.startsWith
    3226                }
    3227                else {
    3228                        func = key;
    3229                }
    3230                // 5.1.4.0 (2010/03/01) データベース名 でなく、DBID 名で検索する。
    3231                return DBFunctionName.getFunctionName( func, dbid );
    3232        }
    3233
    3234        // /**
    3235        // * ﾃﾞｰﾀﾛｰﾙの設定に基づき、ｷｰ(ｶﾗﾑ名)に対応する条件式を返します｡
    3236        // *
    3237        // * @og.rev 4.4.0.0 (2009/08/02) 新規作成
    3238        // * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(DataRole.java廃止)
    3239        // *
    3240        // * @param             key     ｶﾗﾑ名
    3241        // * @return    条件式
    3242        // */
    3243        // 7.4.4.0 (2021/06/30) Delete
    3244        // protected String getDataCondition( final String key ) {
    3245        //      return getUser().getDataCondition( key );
    3246        // }
    3247
    3248        /**
    3249         * 与えたIPｱﾄﾞﾚｽからﾎｽﾄ名を取得して返します｡
    3250         * 取得できなかった場合は空文字を返します｡
    3251         * IPｱﾄﾞﾚｽが解決できない場合や、ｾｷｭﾘﾃｨﾏﾈｰｼﾞｬｰで
    3252         * 許可されていない場合はｴﾗｰを返します｡
    3253         *
    3254         * @og.rev 5.6.6.2 (2013/07/19) 新規作成
    3255         *
    3256         * @param       ip      IPｱﾄﾞﾚｽ
    3257         * @return      ﾎｽﾄ名(取得できない場合は空文字)
    3258         */
    3259        protected String getHostName( final String ip ) {
    3260                String hostname = "";
    3261                try{
    3262                        hostname =  InetAddress.getByName(ip).getHostName();
    3263                }
    3264                catch( final UnknownHostException ex ){
    3265                        final String errMsg = "IPｱﾄﾞﾚｽが解決できません。"
    3266                                + ex.getMessage();
    3267                        throw new HybsSystemException( errMsg,ex );
    3268                }
    3269                catch( final SecurityException ex ){
    3270                        final String errMsg = "この操作はｾｷｭﾘﾃｨ上許可されていません。"
    3271                                + ex.getMessage();
    3272                        throw new HybsSystemException( errMsg,ex );
    3273                }
    3274                return hostname;
    3275        }
    3276
    3277        /**
    3278         * 指定のURLの文字列から、最適なURLを作成します｡
    3279         *
    3280         * 引数の url が、'/' で始まる場合は、ｺﾝﾃｷｽﾄ以下の相対ﾊﾟｽと判断します｡
    3281         * つまり、"/gf" + url で表されることになります｡
    3282         * ただし、経過処置として、先頭が、ｺﾝﾃｷｽﾄを含む文字列の場合は、そのまま返します｡
    3283         *
    3284         * それ以外は、そのまま返します｡
    3285         * ただし、引数が、null やｾﾞﾛ文字列の時は、ｾﾞﾛ文字列を返します｡
    3286         *
    3287         * @og.rev 6.3.2.0 (2015/07/10) 指定のURLの文字列から、最適なURLを作成します｡
    3288         *
    3289         * @param       url     指定のURLの文字列から、最適なURLを作成します｡
    3290         * @return      ｺﾝﾃｷｽﾄに応じた URL を返します｡
    3291         * @og.rtnNotNull
    3292         */
    3293        protected static String makeUrl( final String url ) {
    3294                if( url == null || url.isEmpty() ) { return ""; }
    3295
    3296                if( url.charAt(0) == '/' ) {
    3297                        final String CPATH = '/' + HybsSystem.sys( "CONTEXT_NAME" );            // CPATH = "/gf"
    3298                        if( !url.startsWith( CPATH ) ) {
    3299                                return CPATH + url ;
    3300                        }
    3301                }
    3302
    3303                return url ;
    3304        }
    3305
    3306        /**
    3307         * "org.opengion.hayabusa.message" の、Locale.JAPANESE ﾘｿｰｽから取得するﾒｯｾｰｼﾞを文字列で返します｡
    3308         *
    3309         * id と引数を受け取り、ResourceBundle と、MessageFormat.format で加工した
    3310         * 文字列を返します｡
    3311         * baseName は、F_BS_NM で、Locale に、Locale.JAPANESE を指定したﾒｯｾｰｼﾞを作成します｡
    3312         * hayabusaﾊﾟｯｹｰｼﾞと、pluginﾊﾟｯｹｰｼﾞで主に使われる、ﾒｯｾｰｼﾞの取得方法です｡
    3313         *
    3314         * @og.rev 6.4.3.2 (2016/02/19) 新規追加
    3315         *
    3316         * @param       id              ﾘｿｰｽのｷｰとなるID｡
    3317         * @param       args    ﾘｿｰｽを、MessageFormat.format で加工する場合の引数｡
    3318         * @return      MessageFormat.formatで加工された文字列
    3319         * @see         MsgUtil#H_BS_NM
    3320         */
    3321        protected String getMsg( final String id , final Object... args ) {
    3322                return MsgUtil.getMsg( MsgUtil.H_BS_NM , new Locale( getLanguage() ) , id , args );
    3323        }
    3324
    3325//      /**
    3326//       * ﾀｸﾞﾘﾌﾞで発生したThrowableを session から取り出します｡
    3327//       *
    3328//       * とりだした Throwable は、remove しています｡
    3329//       *
    3330//       * @og.rev 6.8.5.0 (2018/01/09) ﾀｸﾞﾘﾌﾞで発生したｴﾗｰを、session に登録しておきます｡
    3331//       * @og.rev 6.9.2.1 (2018/03/12) ﾀｸﾞﾘﾌﾞで発生したｴﾗｰを、session に登録する処理を、一旦廃止
    3332//       *
    3333//       * @return      元のThrowableｵﾌﾞｼﾞｪｸﾄ
    3334//       */
    3335//      protected Throwable getCommonTagThrowable() {
    3336//              final Throwable th  = (Throwable)getSessionAttribute( "CommonTagThrowable" );
    3337//
    3338//              removeSessionAttribute( "CommonTagThrowable" );
    3339//
    3340//              return th;
    3341//      }
    3342
    3343        /**
    3344         * &#064;があればﾘｸｴｽﾄから、なければ useReq に応じて、値を返します｡
    3345         *
    3346         * &#064;があるかどうか判断して、なければkeyそのもので、getRequestValue した値を返します｡
    3347         * あれば、まず、ｽﾍﾟｰｽが存在しているかどうか判定して、あれば、&#064;を取り除いて、
    3348         * getReservedValue を、なければ、 &#064;を取り除いて、getRequestValue した値を返します｡
    3349         * ｷｰが null の場合は、そのまま、null を返しますが、getRequestValue等した結果が
    3350         * null かｾﾞﾛ文字列の場合は、defvalを返します｡
    3351         *
    3352         * @og.rev 7.2.3.1 (2020/04/17) 新規追加
    3353         *
    3354         * @param       key             &#064;付き／なしのﾘｸｴｽﾄ変数のｷｰ
    3355         * @param       useReq  &#064;が存在しない場合 [true:ﾘｸｴｽﾄから/false:ｷｰを返す]
    3356         * @return      &#064;があればﾘｸｴｽﾄから、なければ useReq に応じて、値を返す
    3357         */
    3358        private String getAtmarkVas( final String key , final boolean useReq ) {
    3359                if( key == null ) { return null; }
    3360
    3361                final String val ;
    3362
    3363                // 先頭が @ の場合は、ﾘｸｴｽﾄ変数のｷｰとして、値を判定
    3364                if( StringUtil.startsChar( key , '@' ) ) {                                                              // １文字 String.startsWith
    3365                        if( key.indexOf( ' ' ) > 0 ) {
    3366                                val = getReservedValue( key.substring( 1 ) );                                   // もう一度変数処理
    3367                        }
    3368                        else {
    3369                                val = getRequestValue( key.substring( 1 ) );
    3370                        }
    3371                }
    3372                else {
    3373                        val = useReq ? getRequestValue( key ) : key ;                                           // @ がない場合は、useReq で、判定する。
    3374                }
    3375
    3376                return val;
    3377        }
    3378
    3379        /**
    3380         * このｵﾌﾞｼﾞｪｸﾄの文字列表現を返します｡
    3381         * 基本的にﾃﾞﾊﾞｯｸﾞ目的に使用します｡
    3382         *
    3383         * @return      このｸﾗｽの文字列表現
    3384         * @og.rtnNotNull
    3385         */
    3386        @Override
    3387        public String toString() {
    3388                return ToString.title( this.getClass().getName() )
    3389                                .println( "Other..."    ,getAttributes().getAttribute() )
    3390                                .fixForm().toString() ;
    3391        }
    3392}