    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.resource;
    017
    018import java.sql.SQLException;
    019import java.util.List;
    020import java.util.Set;
    021import java.util.ArrayList;
    022import java.util.Arrays;
    023import java.util.Map;
    024import java.util.LinkedHashMap;                                                                         // 6.4.3.1 (2016/02/12) refactoring
    025import java.util.HashMap;
    026//import java.util.concurrent.ConcurrentMap;                                            // 6.4.3.3 (2016/03/04) 7.4.4.0 (2021/06/30) Delete
    027//import java.util.concurrent.ConcurrentHashMap;                                        // 6.4.3.1 (2016/02/12) refactoring 7.4.4.0 (2021/06/30) Delete
    028import java.util.Collections;                                                                           // 6.4.3.1 (2016/02/12) refactoring
    029import java.util.Objects;                                                                                       // 8.4.2.2 (2023/03/17) ﾊｯｼｭｺｰﾄﾞ求め
    030
    031import org.opengion.fukurou.db.DBSimpleTable;
    032import org.opengion.fukurou.db.DBUtil;
    033import org.opengion.fukurou.db.ApplicationInfo;
    034import org.opengion.fukurou.util.Cleanable;
    035import org.opengion.fukurou.util.HybsEntry;
    036import org.opengion.fukurou.system.DateSet;                                                     // 6.4.2.0 (2016/01/29)
    037import org.opengion.fukurou.system.LogWriter;
    038import org.opengion.hayabusa.common.HybsSystem;
    039import org.opengion.hayabusa.common.HybsSystemException;
    040import org.opengion.hayabusa.common.UserSummary;
    041import org.opengion.hayabusa.db.DBEditConfig;
    042import org.opengion.hayabusa.db.DBEditConfigManager;
    043import static org.opengion.fukurou.system.HybsConst.CR ;                        // 6.1.0.0 (2014/12/26)
    044import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;      // 6.1.0.0 (2014/12/26) refactoring
    045
    046/**
    047 * ユーザー情報の取得の為のインターフェースを実装したクラスです。
    048 *
    049 * ログイン時のパスワードのチェックや,国名の識別ID，ポータルページのURLなど
    050 * 個人情報を管理させます。
    051 * 特に,画面アクセス時の権限やメールの送信，各画面にユーザー情報を表示したり,
    052 * エラー時のログファイル，テンポラリディレクトリなども管理します。
    053 *
    054 * {&#064;USER.XXXX} で、XXXX 部に、UserInfo オブジェクトで定義されている
    055 * 属性情報を取り出すことが出来ます。
    056 *
    057 * 以下の値は UserInfo オブジェクトの項目から取得します。
    058 * ・JNAME      ユーザー日本語名称
    059 * ・ID         ユーザーＩＤ
    060 * ・INFO       ユーザー情報(ユーザーID：日本語名称)
    061 * ・LANG       言語
    062 * ・ROLES      ロール
    063 * ・IPADDRESS  IPアドレス
    064 * ・LOGINTIME  ログイン時刻
    065 * ・LASTACCESS 最終アクセス画面ID
    066 *
    067 * 以下の値はあらかじめ、動的に作成されます。
    068 * ・YMD       ８byte の今日のシステム日付
    069 * ・YMDH    １４byte の今日のシステム日時
    070 *
    071 * それ以外は,外部より設定された値です。
    072 * 従来は、USER.IDNO はUSER.ID が５Byte以上の時のみ先頭１文字を除いたユーザーＩＤとして
    073 * オブジェクト項目からの取得でしたが、現在は初期値として設定してあります。
    074 * 外部より再設定可能になっています。
    075 *
    076 * @og.group リソース管理
    077 *
    078 * @version  4.0
    079 * @author   Kazuhiko Hasegawa
    080 * @since    JDK5.0,
    081 */
    082public class UserInfo implements UserSummary , Cleanable {
    083        private static final long serialVersionUID = 568120130913L ;    // 5.6.8.1 (2013/09/13)
    084
    085        // ユーザーリソースのキー指定読み込みのクエリー
    086        // 7.4.4.0 (2021/06/30) Delete
    087        //private static final String QUERY_PARAM = HybsSystem.sys( "USER_PARAMETER_SQL" );
    088
    089        /** 5.6.8.1 (2013/09/13) 最終リクエスト情報のユーザー永続化情報(GE20)へのセーブに使用するキーの接頭語 */
    090        private static final String LAST_REQUEST_DATA_SUFIX = "LAST_REQUEST_" ;
    091
    092        // ｱｸｾｽ統計ﾃｰﾌﾞﾙ(GE15)への接続先を、リソースの接続先より取得します。
    093        private final String DBID = HybsSystem.sys( "RESOURCE_DBID" );
    094
    095        //private static final String YOYAKU = "|JNAME|ID|INFO|LANG|ROLES|IPADDRESS|LOGINTIME|LASTACCESS|YMD|YMDH|" ;
    096        private static final String YOYAKU = "|JNAME|ID|INFO|LANG|ROLES|IPADDRESS|LOGINTIME|LASTACCESS|YMD|YMDH|LASTGAMENNM" ; // 4.4.0.1 (2009/08/08)
    097
    098        private final boolean useAccessTable = HybsSystem.sysBool( "USE_ACCESS_TOKEI_TABLE" );
    099
    100        private final String    userID  ;
    101        private       String    lang    ;       // 5.1.4.0 (2010/03/01) lang を書き換え可能とする。
    102        private final String    jname   ;
    103        private final String    roles   ;
    104        //private final String  droles  ; // 4.4.0.0 (2009/08/02) データロール対応 7.4.4.0 (2021/06/30) Delete
    105        private final String    ipAddress       ;
    106        private final long              loginTime       ;
    107        /** 6.4.3.1 (2016/02/12) val=null を登録しているため、単純に、ConcurrentHashMap に置き換えできない。  */
    108        private final Map<String,String>        attriMap  ;
    109        private final RoleMode  roleMode ;              // ロールズとモードを管理するオブジェクト
    110        //private final DataRole        dataRole ;              // データロールを管理するオブジェクト 7.4.4.0 (2021/06/30) Delete
    111
    112        private final int               hcode           ;                               // 6.4.1.1 (2016/01/16) PMD refactoring. Field hashcode has the same name as a method
    113        /** 6.4.3.1 (2016/02/12) Collections.synchronizedMap で同期処理を行います。  */
    114        private final Map<String,GUIInfo>       guiMap = Collections.synchronizedMap( new LinkedHashMap<>() );                          // 6.4.3.1 (2016/02/12)
    115        private           long          usedTime        ;                               // 4.0.0 (2005/01/31)
    116        /** 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。  */
    117        //private final ConcurrentMap<String,String>    paramMap = new ConcurrentHashMap<>();                                                   // 6.4.3.3 (2016/03/04) 7.4.4.0 (2021/06/30) Delete
    118        private final Object    guiLock         = new Object();
    119        private final String    systemId        ;
    120        /** 6.4.3.1 (2016/02/12) 作成元のMapを、変更不可能なビューを返すようにするため、 ConcurrentHashMap に置き換え不要。  */
    121        private Map<String,FavoriteGUIData> favoriteGuiMap      ;       // 4.1.1.0 (2008/01/22)
    122        private Set<String> forbidAddrSet       ;                               // 5.2.0.0 (2010/09/01)
    123        private final DBEditConfigManager editMgr ;                                                             // 6.0.2.2 (2014/10/03)
    124
    125        /** 6.4.3.1 (2016/02/12) val=null を登録しているため、単純に、ConcurrentHashMap に置き換えできない。  */
    126        private final Map<String,String>        lastRequestMap = new HashMap<>();       // 5.6.8.1 (2013/09/13)
    127
    128        /** コネクションにアプリケーション情報を追記するかどうか指定 */
    129        public static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
    130
    131        // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    132        private final ApplicationInfo appInfo;
    133
    134        // ユーザー永続化情報(GE20)テーブル 読み込み用SQL
    135        // 4.3.4.0 (2008/12/01) ROLE='*'も検索できるようにする
    136        // 5.3.6.0 (2011/06/01) USERID='*'も検索できるようにする
    137        private static final String QUERY_GE20  = "select PARAM_ID,PARAM from GE20"
    138                                                                                        +       " where SYSTEM_ID = ? and USERID in ( ?, '*' )"
    139                                                                                        +       " and ROLES in ( ?, '*' ) and FGJ = '1'"
    140                                                                                        +       " order by USERID,ROLES";
    141
    142        // 4.3.4.0 (2008/12/01) ユーザー永続化情報(GE20)にセーブ時に存在チェックを行うためのSQL
    143        // 4.3.4.4 (2009/01/01) private static を付加
    144        private static final String QUERY_GE20_KEY      = "select KBSET from GE20"
    145                                                                                        +       " where SYSTEM_ID = ? and USERID = ?"
    146                                                                                        +       " and ROLES = ? and PARAM_ID = ? and FGJ = '1'";
    147
    148        // 5.2.3.0 (2010/12/01) アクセス履歴管理
    149        private GUIInfo lastGuiInfo     ;
    150
    151        // saveGUIAccessInfo() メソッドでしか使用しない、定数宣言
    152        private static final int C_SYSTEM_ID            = 0 ;
    153        private static final int C_USERID                       = 1 ;
    154        private static final int C_USERADRS                     = 2 ;
    155        private static final int C_HOSTADRS                     = 3 ;
    156        private static final int C_GUIKEY                       = 4 ;
    157        private static final int C_DYLOGIN                      = 5 ;
    158        private static final int C_DYLOGOUT                     = 6 ;
    159        private static final int C_USED_TIME            = 7 ;
    160        private static final int C_CNT_ACCESS           = 8 ;
    161        private static final int C_CNT_ERROR            = 9 ;
    162        private static final int C_CNT_READ                     = 10 ;
    163        private static final int C_CNT_WRITE            = 11 ;
    164        private static final int C_TM_TOTAL_QUERY       = 12 ;
    165        private static final int C_TM_MAX_QUERY         = 13 ;
    166        private static final int C_MAX_QUERY            = 14 ;
    167        private static final int C_FGJ                          = 15 ;
    168        private static final int C_DYSET                        = 16;
    169        private static final int C_DYUPD                        = 17;
    170        private static final int C_USRSET                       = 18;
    171        private static final int C_USRUPD                       = 19;
    172        private static final int C_PGUPD                        = 20;
    173
    174        // ユーザー永続化情報(GE20)設定でしか使用しない変数の宣言
    175        private static final int C_GE20_SYSTEM_ID       = 0;
    176        private static final int C_GE20_USERID          = 1;
    177        private static final int C_GE20_ROLES           = 2;
    178        private static final int C_GE20_PARAM_ID        = 3;
    179        private static final int C_GE20_PARAM           = 4;
    180        private static final int C_GE20_KBSET           = 5;
    181        private static final int C_GE20_FGJ                     = 6;
    182        private static final int C_GE20_DYSET           = 7;
    183        private static final int C_GE20_DYUPD           = 8;
    184        private static final int C_GE20_USRSET          = 9;
    185        private static final int C_GE20_USRUPD          = 10;
    186        private static final int C_GE20_PGUPD           = 11;
    187
    188        private static final int GE20_KBSET_READONLY    = 1;
    189        private static final int GE20_KBSET_WRITABLE    = 2;
    190
    191        // ロールは全て*で登録する。アプリケーションから動的に登録される値を、
    192        // ロール単位設定しても、ロール変更時に整合性が合わない可能性大なので、
    193        // UserInfoで設定する場合は、全てのロールで有効とする。
    194        private static final String GE20_ROLES = "*";
    195
    196        /**
    197         * コンストラクター
    198         *
    199         * @og.rev 3.0.0.1 (2003/02/14) ユーザー毎のエンコード指定方法を廃止します。
    200         * @og.rev 3.1.3.0 (2003/04/10) ユーザー情報から、エンコード情報を削除する。
    201         * @og.rev 3.4.0.3 (2003/09/10) "root","manager","admin" のロールを、すべて root 権限を与える。
    202         * @og.rev 3.8.5.3 (2006/06/30) USE_USER_IDNO_C_SAPLESS を判定条件に加える。
    203         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    204         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
    205         * @og.rev 4.4.0.0 (2009/08/02) データロール対応
    206         * @og.rev 5.3.6.0 (2011/06/01) ユーザー永続化情報(GE20)の読み込みをUserInfoFactoryから移動
    207         * @og.rev 6.0.2.2 (2014/10/03) DBEditConfigManager をここで作成する。
    208         * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(DataRole.java廃止、GE16廃止)
    209         * @og.rev 8.4.2.2 (2023/03/17) ﾊｯｼｭｺｰﾄﾞ求めに、java.util.Objects#hash を使用します。
    210         *
    211         * @param       userID          ユーザー
    212         * @param       lang            言語
    213         * @param       jname           日本語名称
    214         * @param       roles           ロール
    215         * @param       systemId        システムID
    216         * @param       ipAddress       IPアドレス
    217         * @param   appInfo             アプリ情報オブジェクト
    218         */
    219        public UserInfo( final String userID            ,
    220                                         final String lang                      ,
    221                                         final String jname                     ,
    222                                         final String roles                     ,
    223        //                               final String droles            , // 4.4.0.0 (2009/08/02) 7.4.4.0 (2021/06/30) Delete
    224                                         final String systemId          ,
    225                                         final String ipAddress         ,
    226                                         final ApplicationInfo appInfo  ) {
    227                this.userID             = userID        ;
    228                this.lang               = lang          ;
    229                this.jname              = jname         ;
    230                this.roles              = roles         ;
    231        //      this.droles             = droles        ; // 4.4.0.0 (2009/08/02) 7.4.4.0 (2021/06/30) Delete
    232                this.systemId   = systemId      ;
    233                this.roleMode   = RoleMode.newInstance( roles );        // 4.3.0.0 (2008/07/04) ロールモード
    234        //      this.dataRole   = DataRole.newInstance( droles, systemId, appInfo ); // 4.4.0.0 (2009/08/02) 7.4.4.0 (2021/06/30) Delete
    235                this.ipAddress  = ipAddress     ;
    236                this.appInfo    = appInfo       ;
    237                loginTime               = System.currentTimeMillis();
    238                usedTime                = loginTime;
    239                attriMap                = new HashMap<>();
    240
    241                // 3.5.6.0 (2004/06/18) hashCode を計算しておきます。
    242                // 8.4.2.2 (2023/03/17) ﾊｯｼｭｺｰﾄﾞ求めに、java.util.Objects#hash を使用します。
    243//              hcode = (int)(loginTime^(loginTime>>>32)) ;
    244                hcode = Objects.hash( userID, Long.valueOf( loginTime ) );
    245
    246                // 3.8.1.2 (2005/12/19) USER.IDNO をAttributeにセットする。
    247                // 3.8.5.3 (2006/06/30) USE_USER_IDNO_C_SAPLESS を判定条件に加える。
    248                final boolean IDNO_C_SAPLESS = HybsSystem.sysBool( "USE_USER_IDNO_C_SAPLESS" );         // 6.4.2.1 (2016/02/05) PMD refactoring. Useless parentheses.
    249                final String idno = userID.length() > 5 && IDNO_C_SAPLESS ? userID.substring(1) : userID ;
    250                attriMap.put( "IDNO",idno ) ;                           // コンストラクタ内なので、同期処理は入れていません。
    251
    252                // ユーザーパラメータなどの初期設定を行います。
    253                // 7.4.4.0 (2021/06/30) Delete
    254        //      initLoad() ;
    255
    256                // 5.3.6.0 (2011/06/01) ユーザー永続化情報(GE20)からDBに保存されたUserInfo情報を読み出します。
    257                dbLoad();
    258
    259                // 5.3.6.0 (2011/06/01) Edit情報の一覧を作成します。
    260                editMgr = new DBEditConfigManager( attriMap );                  // 6.0.2.2 (2014/10/03) 作成方法変更
    261        }
    262
    263        /**
    264         * ユーザーパラメータを取得します。
    265         * ユーザーパラメーターは、通常、GE16 テーブルより取得します。
    266        // * 取得するSQL文は、SystemData の USER_PARAMETER_SQL に記述しておきます。
    267         * ユーザーパラメータに、値が存在しない場合は、システムリソースより
    268         * 取得します。
    269         *
    270         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    271         * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(GE16廃止)
    272         *
    273         * @param       key     パラメータキー
    274         *
    275         * @return      パラメータ値(ユーザーパラメータになければ、システムリソースより取得
    276         */
    277        public String getParameter( final String key ) {
    278                String val = null;
    279                if( key != null ) {
    280                        // 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    281        //                      val = paramMap.get( key );                                                                              // 7.4.4.0 (2021/06/30) Delete
    282                        if( val == null ) { val = HybsSystem.sys( key ); }
    283                }
    284                return val;
    285        }
    286
    287        /**
    288         * ユーザーログイン時刻を取得します。
    289         *
    290         * @return      ログイン時刻
    291         */
    292        @Override       // UserSummary
    293        public long getLoginTime() {
    294                return loginTime;
    295        }
    296
    297        /**
    298         * ユーザーのログインIPアドレスを取得します。
    299         *
    300         * @return      IPアドレス
    301         *
    302         */
    303        @Override       // UserSummary
    304        public String getIPAddress() {
    305                return ipAddress;
    306        }
    307
    308        /**
    309         * ユーザーを取得します。
    310         *
    311         * @return      ユーザー
    312         *
    313         */
    314        @Override       // UserSummary
    315        public String getUserID() {
    316                return userID;
    317        }
    318
    319        /**
    320         * ユーザー情報ロケール(言語)を取得します。
    321         *
    322         * @return      ロケール(言語)
    323         */
    324        @Override       // UserSummary
    325        public String getLang() {
    326                return lang ;
    327        }
    328
    329        /**
    330         * ユーザー情報ロケール(言語)をセットします。
    331         *
    332         * @og.rev 5.1.4.0 (2010/03/01) lang を書き換え可能とする。
    333         *
    334         * @param newLang       ロケール(言語)
    335         */
    336        public void setLang( final String newLang ) {
    337                lang = newLang ;
    338        }
    339
    340        /**
    341         * ユーザー情報 名称(日本語)を取得します。
    342         *
    343         * @return      名称(日本語)
    344         */
    345        @Override       // UserSummary
    346        public String getJname() {
    347                return jname ;
    348        }
    349
    350        /**
    351         * ユーザー情報 ロール(役割)を取得します。
    352         *
    353         * @return      ロール(役割)
    354         */
    355        @Override       // UserSummary
    356        public String getRoles() {
    357                return roles ;
    358        }
    359
    360        /**
    361         * ロールモード情報を取得します。
    362         *
    363         * @og.rev 4.3.0.0 (2008/07/04) 新規追加
    364         *
    365         * @return      ロールモード情報
    366         */
    367        public RoleMode getRoleMode() {
    368                return roleMode ;
    369        }
    370
    371        /**
    372         * オブジェクトの識別子として，ユーザー情報を返します。
    373         *
    374         * @return  ユーザー情報
    375         * @og.rtnNotNull
    376         */
    377        @Override       // UserSummary
    378        public String getInfo() {
    379                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
    380                        .append( userID ).append( " ： " )
    381                        .append( jname  ).append( CR );
    382                return rtn.toString();
    383        }
    384
    385//      /**
    386//       * DBEditConfigManagerオブジェクトを返します。
    387//       *
    388//       * ここでは、内部オブジェクトそのものを返します。
    389//       *
    390//       * @og.rev 6.4.5.0 (2016/04/08) 新規追加。UserInfo オブジェクトから、出来るだけEditConfig関係の処理を除外します。
    391//       * @og.rev 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します。
    392//       *
    393//       * @return  DBEditConfigManagerオブジェクト
    394//       */
    395//      public DBEditConfigManager getEditConfigManager() {
    396//              return editMgr;
    397//      }
    398
    399        /**
    400         * UserInfoの属性文字列を登録します。
    401         *
    402         * 予約文字(JNAME,ID,INFO,LANG,ROLES,IPADDRESS,LOGINTIME,LASTACCESS,YMD,YMDH,LASTGAMENNM)を
    403         * 登録しようとした場合は、エラーにします。
    404         *
    405         * ※ 属性文字列キーが不正の場合、HybsSystemException が、throw されます。
    406         *
    407         * @param       key     キー
    408         * @param       value   値
    409         * @param       save    ユーザー永続化情報(GE20)に情報を保存するか
    410         */
    411        public void setAttribute( final String key,final String value, final boolean save ) {
    412                setAttribute( key, value, save, false );
    413        }
    414
    415        /**
    416         * UserInfoの属性文字列を登録します。
    417         *
    418         * 予約文字(JNAME,ID,INFO,LANG,ROLES,IPADDRESS,LOGINTIME,LASTACCESS,YMD,YMDH,LASTGAMENNM)を
    419         * 登録しようとした場合は、エラーにします。
    420         *
    421         * ※ 属性文字列キーが不正の場合、HybsSystemException が、throw されます。
    422         *
    423         * @og.rev 3.5.6.0 (2004/06/18) synchronized をattriMap に行います。
    424         * @og.rev 4.3.4.0 (2008/12/01) ユーザー永続化情報(GE20)へ登録するかのフラグを追加
    425         * @og.rev 5.3.6.0 (2011/06/01) ユーザー永続化情報(GE20)へ登録時に全ユーザー公開するかのフラグを追加
    426         * @og.rev 5.6.8.1 (2013/09/13) 値が null、またはゼロ文字列の場合、処理しません。
    427         * @og.rev 5.7.2.2 (2014/01/24) 値が null、またはゼロ文字列の場合でも処理します。(5.6.8.1 以前に戻します)
    428         *
    429         * @param       key     キー
    430         * @param       value   値
    431         * @param       save    ユーザー永続化情報(GE20)に情報を保存するか
    432         * @param       common  ユーザー永続化情報(GE20)に保存した情報を全ユーザー公開するか
    433         */
    434        private void setAttribute( final String key,final String value, final boolean save, final boolean common ) {
    435                if( key != null && YOYAKU.indexOf( "|" + key + "|" ) < 0 ) {
    436                        // 5.6.8.1 (2013/09/13) 値が null、またはゼロ文字列の場合、処理しません。
    437                        // 5.7.2.2 (2014/01/24) 値が null、またはゼロ文字列の場合でも処理します。(5.6.8.1 以前に戻します)
    438                        synchronized( attriMap ) {
    439                                attriMap.put( key,value ) ;
    440                        }
    441
    442                        // 4.3.4.0 (2008/12/01) 追加
    443                        if( save ) {
    444                                savePermanently( key ,value, common );
    445                        }
    446                }
    447                else {
    448                        final String errMsg = "属性文字列キーが不正です。 key=[" + key + "]"
    449                                                + CR
    450                                                + "null または予約語(" + YOYAKU + ") は指定できません。";
    451                        throw new HybsSystemException( errMsg );
    452                }
    453        }
    454
    455        /**
    456         * UserInfoの属性文字列を取得します。
    457         *
    458         * 以下の値は UserInfo オブジェクトの項目から取得します。
    459         * <pre>
    460         * ・JNAME      ユーザー日本語名称
    461         * ・ID         ユーザーＩＤ
    462         * ・IDNO       (初期値)USER.ID が５Byte以上の時のみ先頭１文字を除いたユーザーＩＤ
    463         * ・INFO       ユーザー情報(ユーザーID：日本語名称)
    464         * ・LANG       言語
    465         * ・ROLES      ロール
    466         * ・IPADDRESS  IPアドレス
    467         * ・LOGINTIME  ログイン時刻
    468         * ・LASTACCESS 最終アクセス画面ID
    469         * ・LASTGAMENNM 最終アクセス画面名
    470         *
    471         * 以下の値はあらかじめ、動的に作成されます。
    472         * ・YMD       ８byte の今日のシステム日付
    473         * ・YMDH    １４byte の今日のシステム日時
    474         * </pre>
    475         *
    476         * それ以外は,外部より設定された値です。
    477         *
    478         * @og.rev 2.1.0.2 (2002/11/07) USER.IDNO の返す値をUSER.ID が５Byte以上の時のみ、
    479         * 先頭1文字を除いた値を返す様に変更。それ以外は、USER.IDを返す。
    480         *
    481         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応  ENCODE 追加
    482         * @og.rev 3.1.3.0 (2003/04/10) ユーザー情報から、エンコード情報を削除する。
    483         * @og.rev 3.5.4.2 (2003/12/15) ENAME,MAILTO、MAILUSERID、MAILPASSWD、GROUP、PROJECTを削除する。
    484         * @og.rev 3.5.6.0 (2004/06/18) synchronized をattriMap に行います。
    485         * @og.rev 3.6.0.0 (2004/09/17) PASSWD を削除する。
    486         * @og.rev 3.8.1.2 (2005/12/19) USER.IDNO を削除する。(外部設定可能にするため)
    487         * @og.rev 3.8.7.0 (2006/12/15) ApplicationInfoオブジェクトから最終アクセス画面を取得
    488         * @og.rev 4.4.0.0 (2009/08/02) データロール属性対応
    489         * @og.rev 4.4.0.1 (2009/08/08) LASTGAMENNM追加
    490         * @og.rev 6.4.1.1 (2016/01/16) PMD refactoring. Position literals first in String comparisons for EqualsIgnoreCase.
    491         * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。
    492         * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(DataRole.java廃止)
    493         *
    494         * @param       key     キー
    495         *
    496         * @return      UserInfoの属性文字列
    497         */
    498        @Override       // UserSummary
    499        public String getAttribute( final String key ) {
    500                final String rtn ;
    501
    502                if( key == null ) { rtn = null; }
    503                else {
    504                        if(      "JNAME"                .equalsIgnoreCase( key ) ) { rtn = jname; }
    505                        else if( "ID"                   .equalsIgnoreCase( key ) ) { rtn = userID; }
    506                        else if( "INFO"                 .equalsIgnoreCase( key ) ) { rtn = getInfo(); }
    507                        else if( "LANG"                 .equalsIgnoreCase( key ) ) { rtn = lang; }
    508                        else if( "ROLE"                 .equalsIgnoreCase( key ) ) { rtn = roles; }
    509                        else if( "ROLES"                .equalsIgnoreCase( key ) ) { rtn = roles; }
    510        //              else if( "DROLES"               .equalsIgnoreCase( key ) ) { rtn = droles; } // 4.4.0.0 (2009/08/02) 7.4.4.0 (2021/06/30) Delete
    511                        else if( "IPADDRESS"    .equalsIgnoreCase( key ) ) { rtn = ipAddress; }
    512                        else if( "LOGINTIME"    .equalsIgnoreCase( key ) ) { rtn = HybsSystem.getDate( loginTime ); }
    513                        else if( "YMD"                  .equalsIgnoreCase( key ) ) { rtn = DateSet.getDate( "yyyyMMdd" ); }                                     // 6.4.2.0 (2016/01/29)
    514                        else if( "YMDH"                 .equalsIgnoreCase( key ) ) { rtn = DateSet.getDate( "yyyyMMddHHmmss" ); }                       // 6.4.2.0 (2016/01/29)
    515                        else if( "LASTACCESS"   .equalsIgnoreCase( key ) ) { rtn = getGamenId(); }
    516                        else if( "LASTGAMENNM"  .equalsIgnoreCase( key ) ) { rtn = getGamenName(); }
    517                        else {
    518                                synchronized( attriMap ) {
    519                                        rtn = attriMap.get( key ) ;
    520                                }
    521                        }
    522                }
    523
    524                return rtn ;
    525        }
    526
    527        /**
    528         * ApplicationInfo から、画面ID を取得します。
    529         * ApplicationInfoが null の場合は、null を返します。
    530         *
    531         * @og.rev 6.4.1.1 (2016/01/16) 新規追加
    532         *
    533         * @return      画面ID(ApplicationInfo#getGamenId())
    534         */
    535        private String getGamenId() {
    536                return appInfo == null ? null : appInfo.getGamenId();
    537        }
    538
    539        /**
    540         * GUIInfo から、画面名 を取得します。
    541         * GUIInfo がない場合、または、GUIInfo の取り出しも元の、画面ID がない、
    542         * さらに、画面ID の取出し元の ApplicationInfoが null の場合は、null を返します。
    543         *
    544         * @og.rev 6.4.1.1 (2016/01/16) 新規追加
    545         *
    546         * @return      画面名(GUIInfo#getName())
    547         */
    548        private String getGamenName() {
    549                final GUIInfo guiInfo = getGUIInfo( getGamenId() );             // 引数 null 対応済み
    550                return guiInfo == null ? null : guiInfo.getName();
    551        }
    552
    553        /**
    554         * UserInfoの属性文字列の内部情報を返します。
    555         * この内部情報の中には、UserInfo 自身の管理情報も含めます。
    556         * 独自管理キーは、JNAME,ID,IDNO,INFO,LANG,ROLES,IPADDRESS,LOGINTIME,LASTACCESS,LASTGAMENNM です。
    557         *
    558         * それ以外は,外部より設定された値です。
    559         *
    560         * @og.rev 4.0.0.0 (2004/12/31) 新規作成
    561         * @og.rev 4.4.0.1 (2009/08/08) LASTGAMENNM追加
    562         *
    563         * @return 属性文字列のHybsEntryオブジェクト配列
    564         * @og.rtnNotNull
    565         */
    566        public HybsEntry[] getEntrys() {
    567                final List<HybsEntry> list = new ArrayList<>();
    568
    569                list.add( new HybsEntry( "JNAME"                , getAttribute( "JNAME"         ) ,"ユーザー日本語名称" ) );
    570                list.add( new HybsEntry( "ID"                   , getAttribute( "ID"            ) ,"ユーザーＩＤ" ) );
    571                list.add( new HybsEntry( "IDNO"                 , getAttribute( "IDNO"          ) ,"USER.ID が５Byte以上の時のみ先頭１文字を除いたユーザーＩＤ" ) );
    572                list.add( new HybsEntry( "INFO"                 , getAttribute( "INFO"          ) ,"ユーザー情報(ユーザーID：日本語名称)" ) );
    573                list.add( new HybsEntry( "LANG"                 , getAttribute( "LANG"          ) ,"言語" ) );
    574                list.add( new HybsEntry( "ROLES"                , getAttribute( "ROLES"         ) ,"ロールズ" ) );
    575                list.add( new HybsEntry( "IPADDRESS"    , getAttribute( "IPADDRESS" ) ,"IPアドレス" ) );
    576                list.add( new HybsEntry( "LOGINTIME"    , getAttribute( "LOGINTIME" ) ,"ログイン時刻" ) );
    577                list.add( new HybsEntry( "LASTACCESS"   , getAttribute( "LASTACCESS" ) ,"最終アクセス画面ID" ) );
    578                list.add( new HybsEntry( "LASTGAMENNM"  , getAttribute( "LASTGAMENNM") ,"最終アクセス画面名" ) ); // 4.4.0.1 (2009/08/08)
    579                list.add( new HybsEntry( "YMD"                  , getAttribute( "YMD"           ) ,"　８byte の今日のシステム日付" ) );
    580                list.add( new HybsEntry( "YMDH"                 , getAttribute( "YMDH"          ) ,"１４byte の今日のシステム日時" ) );
    581
    582                synchronized( attriMap ) {
    583                        final String[] keys = attriMap.keySet().toArray( new String[attriMap.size()] );
    584                        Arrays.sort( keys );
    585                        for( int i=0; i<keys.length; i++ ) {
    586                                list.add( new HybsEntry( keys[i],getAttribute( keys[i] ) ) );
    587                        }
    588                }
    589                return list.toArray( new HybsEntry[list.size()] );
    590        }
    591
    592        /**
    593         * UserInfoの属性文字列を削除します。
    594         *
    595         * @param       key     キー
    596         * @param       save    ユーザー永続化情報(GE20)から情報を削除するか
    597         */
    598        public void removeAttribute( final String key, final boolean save ) {
    599                removeAttribute( key, save, false );
    600        }
    601
    602        /**
    603         * UserInfoの属性文字列を削除します。
    604         *
    605         * @og.rev 3.5.6.0 (2004/06/18) synchronized をattriMap に行います。
    606         * @og.rev 5.3.6.0 (2011/06/01) ユーザー永続化情報(GE20)から削除するかのフラグを追加
    607         *
    608         * @param       key     キー
    609         * @param       save    ユーザー永続化情報(GE20)から情報を削除するか
    610         * @param       common  ユーザー永続化情報(GE20)から情報削除時、全ユーザー公開情報を削除するか
    611         */
    612        private void removeAttribute( final String key, final boolean save, final boolean common ) {
    613                synchronized( attriMap ) {
    614                        attriMap.remove( key ) ;
    615                }
    616
    617                if( save ) {
    618                        deletePermanently( key, common );
    619                }
    620        }
    621
    622        /**
    623         * ユーザー個別の画面オブジェクトのマップをセットします。
    624         *
    625         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    626         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    627         * @og.rev 4.1.1.0 (2008/01/29) 画面の格上げとお気に入りマップ作成はクラスUserAccessTableに依頼
    628         * @og.rev 5.2.0.0 (2010/09/01) アクセス禁止アドレスによる不正アクセス防止機能追加
    629         * @og.rev 6.4.3.1 (2016/02/12) Collections.synchronizedMap で同期処理を行います
    630         *
    631         * @param       newGuiMap                       画面オブジェクトのマップ
    632         * @param       newForbidAddrSet        アクセス禁止アドレスセット
    633         */
    634        public void setGUIMap( final Map<String,GUIInfo> newGuiMap, final Set<String> newForbidAddrSet ) {
    635                if( newGuiMap != null ) {
    636                        synchronized( guiLock ) {
    637                                guiMap.clear();                                                 // 6.4.3.1 (2016/02/12)
    638                                guiMap.putAll( newGuiMap );                             // 6.4.3.1 (2016/02/12)
    639                                forbidAddrSet  = newForbidAddrSet;
    640                                favoriteGuiMap = UserAccessTable.makeAccessDB( guiMap,systemId,userID,lang );
    641                        }
    642                }
    643        }
    644
    645        /**
    646         * ユーザー個別の画面オブジェクトを取得します。
    647         * アクセスできない画面IDが指定されたときは、null が返ります。
    648         *
    649         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    650         * @og.rev 5.2.0.0 (2010/09/01) guiMap の null 判定を追加
    651         * @og.rev 6.4.1.1 (2016/01/16) 引数の gamenId が、null の場合は、null を返すように変更。
    652         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    653         *
    654         * @param       gamenId 画面ID
    655         *
    656         * @return      画面オブジェクト
    657         */
    658        public GUIInfo getGUIInfo( final String gamenId ) {
    659                return gamenId == null ? null : guiMap.get( gamenId );
    660        }
    661
    662        /**
    663         * ユーザー個別の画面オブジェクトのマップを取得します。
    664         *
    665         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    666         * @og.rev 5.2.0.0 (2010/09/01) guiMap の null 判定を追加
    667         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    668         *
    669         * @return      画面オブジェクトの配列
    670         */
    671        public GUIInfo[] getGUIInfos() {
    672                return guiMap.values().toArray( new GUIInfo[guiMap.size()] ) ;
    673        }
    674
    675        /**
    676         * アクセスが許可されているアドレスかどうかをチェックします。
    677         *
    678         * チェックの方法は、ブラックリスト方式です。
    679         * 画面リソースに登録された一覧の内、そのユーザーが許可されていないアドレスに
    680         * 対してのみfalseが返ります。
    681         * 画面リソースに登録されていないアドレスや、アドレスにURLの区切り文字(/)が
    682         * 含まれている場合はチェックされません。(trueが返ります)
    683         *
    684         * @og.rev 5.2.0.0 (2010/09/01) 新規追加
    685         *
    686         * @param addr チェック対象のアドレス
    687         *
    688         * @return アクセスが許可されているアドレスかどうか
    689         */
    690        public boolean isValidAddr( final String addr ) {
    691                synchronized( guiLock ) {
    692                        return forbidAddrSet == null || !forbidAddrSet.contains( addr ) ;
    693                }
    694        }
    695
    696        /**
    697         * ユーザー個別のお気に入り画面オブジェクトのマップを取得します。
    698         *
    699         * @og.rev 4.1.1.0 (2008/01/31) 新規追加
    700         * @og.rev 6.4.3.1 (2016/02/12) Collections.unmodifiableMap( Map&lt;? extends K,? extends V&gt; ) で作成された変更不可のMapを返します。
    701         *
    702         * @return      お気に入り画面オブジェクトのマップ
    703         */
    704        public Map<String,FavoriteGUIData> getFavoriteMap() {
    705                return favoriteGuiMap;
    706        }
    707
    708        /**
    709         * 画面オブジェクトのマップがセット済みかどうかを取得します。
    710         *
    711         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    712         * @og.rev 6.4.3.1 (2016/02/12) isInfoSet 廃止。
    713         *
    714         * @return 画面オブジェクトのマップがセット済みかどうか(true:セット済み / false:未セット)
    715         */
    716        public boolean isGUIInfoSet() {
    717                return !guiMap.isEmpty();                       // 6.4.3.1 (2016/02/12)
    718        }
    719
    720        /**
    721         * 指定のユーザーロールに対する最終的なアクセス条件を取得します。
    722         * アクセス条件は、複数あるユーザーロールの中で、最大のアクセス条件を算出します。
    723         * 例えば、AAA(-r)|BBB(-w)|CCC(mr) の３つのロール/モードが設定されている場合、
    724         * ユーザーが、AAA だけの場合は、-r ですが、AAA|BBB を持っている場合は、-w になります。
    725         * さらに、BBB|CCC と持っている場合は、(-w:書き込み許可)と(mr:メニューから読取許可)の
    726         * 権限により、mw:メニューからの書き込み許可が与えられます。
    727         * モード指定がある場合は、AND演算になります。
    728         * 例えば、AAA(-r)|BBB(-w)|CCC(mr) と BBB|CCC(-r) の場合、(-r)+(-w)+(mr)*(-r)=-w に
    729         * なります。ロールは、OR ですが、モードは、同一ロールでのAND になります。
    730         * 実際には、メニュー表示の可否は、ポップアップ系によく用いられますので、上記のような
    731         * 許可が実際にあるかどうかは不明ですが、すべてのモードのOR条件での結合になります。
    732         *
    733         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
    734         *
    735         * @param       other   ロールモード
    736         *
    737         * @return アクセスビット
    738         */
    739        public byte getAccessBitMode( final RoleMode other ) {
    740                return roleMode.getAccessBitMode( other );
    741        }
    742
    743        /**
    744         * このユーザーの権限で、指定のロールが許可されているかどうかを判定します。
    745         *
    746         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
    747         * @og.rev 4.3.0.1 (2008/08/11) ロールチェック時の引数間違い、是正
    748         * @og.rev 6.3.6.1 (2015/08/28) '_' を、null と同等に扱います(すべて許可と同じ)
    749         *
    750         * @param       role    チェックを行うロール
    751         *
    752         * @return      アクセスできる(true)/出来ない(false)
    753         */
    754        public boolean isAccess( final String role ) {
    755                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    756                return role == null || role.isEmpty() || role.charAt(0) == '_'
    757                                || roleMode.getAccessBitMode( RoleMode.newInstance( role ) ) > 0 ;              // 4.3.0.1 (2008/08/11)
    758        }
    759
    760        /**
    761         * 初期化(クリア)します(org.opengion.fukurou.util.Cleanable の実装)。
    762         * 画面オブジェクトのマップをクリアし、セット済みフラグを未セットに設定します。
    763         * システムリソースの USE_ACCESS_TOKEI_TABLE が true の場合は、
    764         * 画面アクセス状況を、ｱｸｾｽ統計ﾃｰﾌﾞﾙ(GE15)に書き込みます。
    765        // * ユーザー単位のパラメータは、システムリソースの USER_PARAMETER_SQL で
    766        // * 定義された値を検索して、取り込みます。
    767         *
    768         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    769         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    770         * @og.rev 5.6.8.1 (2013/09/13) lastRequestMap を ユーザー永続化情報(GE20) に書き込みます。
    771         * @og.rev 6.4.3.1 (2016/02/12) isInfoSet 廃止。
    772         * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(GE16廃止)
    773         */
    774        public void clear() {
    775                if( useAccessTable && isGUIInfoSet() ) { saveGUIAccessInfo(); }         // 6.4.3.1 (2016/02/12) isInfoSet 廃止
    776        //      initLoad() ;                                                                                                                    // 7.4.4.0 (2021/06/30) Delete
    777
    778                saveLastRequestValues();        // 5.6.8.1 (2013/09/13) lastRequestMap を ユーザー永続化情報(GE20) に書き込みます。
    779        }
    780
    781        // /**
    782        // * ユーザーパラメータを取得します。
    783        // * 画面オブジェクトのマップをクリアし、セット済みフラグを未セットに設定します。
    784        // * ユーザー単位のパラメータは、システムリソースの USER_PARAMETER_SQL で
    785        // * 定義された値を検索して、取り込みます。
    786        // *
    787        // * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    788        // * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    789        // * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(GE16廃止)
    790        // */
    791        // private void initLoad() {
    792        //      // ユーザーパラメータの取得
    793        //      if( QUERY_PARAM != null && QUERY_PARAM.length() > 0 ) {
    794        //              final String[] args = new String[] { systemId,userID };
    795        //              // 画面ID,操作,プログラムID
    796        //              if( appInfo != null ) {
    797        //                      // 画面ID,操作,プログラムID
    798        //                      appInfo.setModuleInfo( "UserInfo",null,"initLoad" );
    799        //              }
    800        //              final String[][] vals = DBUtil.dbExecute( QUERY_PARAM,args,appInfo,DBID );
    801
    802        //              // 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    803        //                      paramMap.clear();
    804        //                      for( int i=0; i<vals.length; i++ ) {
    805        //                              final String key = vals[i][0];
    806        //                              final String val = vals[i][1];
    807        //                              // 6.4.3.1 (2016/02/12) ConcurrentMap 系は、key,val ともに not null 制限です。
    808        //                              if( key != null && val != null && !val.isEmpty() ) {            // 元の条件 val.isEmpty() も加味しておきます。
    809        //                                      paramMap.put( key,val );
    810        //                              }
    811        //                      }
    812        //      }
    813        // }
    814
    815        /**
    816         * ユーザー永続化情報(GE20)からDBに保存されたUserInfoのパラメーターを取得します。
    817         *
    818         * ここでは、キーの先頭が、LAST_REQUEST_DATA_SUFIX(="LAST_REQUEST_")文字列が、
    819         * 付いている物だけ lastRequestMap マップに設定します。(分けて管理します)
    820         *
    821         * @og.rev 5.3.6.0 (2011/06/01) 新規追加
    822         * @og.rev 5.6.8.1 (2013/09/13) setAttribute メソッドではなく、直接 Mapに登録します。
    823         * @og.rev 5.7.2.2 (2014/01/24) 値が null、またはゼロ文字列の場合でも処理します。(5.6.8.1 以前に戻します)
    824         *
    825         * ※ コンストラクタのみで呼ばれるため、synchronized は入れていません。
    826         * @see         #LAST_REQUEST_DATA_SUFIX
    827         */
    828        private void dbLoad() {
    829                // ユーザー永続化情報(GE20)テーブル読み込み
    830                final String[] argsGe20 = new String[] { systemId,userID,roles };
    831                final String[][] valsGe20 = DBUtil.dbExecute( QUERY_GE20,argsGe20,appInfo,DBID );
    832
    833                for( int i=0; i<valsGe20.length; i++ ) {
    834                        // 4.3.4.0 (2008/12/01) ユーザー永続化情報(GE20)から読み込んでいるので、当然保存しない
    835                        final String key = valsGe20[i][0];
    836                        final String val = valsGe20[i][1];
    837                        if( key != null && key.length() > 0 ) {
    838                                if( key.startsWith( LAST_REQUEST_DATA_SUFIX ) ) {
    839                                        // val が null かどうかは問わない
    840                                        lastRequestMap.put( key.substring( LAST_REQUEST_DATA_SUFIX.length() ) , val );
    841                                }
    842                                else {
    843                                        // 5.7.2.2 (2014/01/24) 値が null、またはゼロ文字列の場合でも処理します。(5.6.8.1 以前に戻します)
    844                                        attriMap.put( key,val ) ;
    845                                }
    846                        }
    847                }
    848        }
    849
    850        /**
    851         * 画面ID、編集名より編集設定オブジェクトを返します。
    852         * また、ここで指定された編集名がこの画面での選択済み編集として登録されます。
    853         *
    854         * @og.rev 5.3.6.0 (2011/06/01) 新規追加
    855         * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。
    856         *
    857         * @param guikey 画面ID
    858         * @param editName 編集名
    859         *
    860         * @return 編集設定オブジェクト
    861         */
    862        public DBEditConfig getEditConfig( final String guikey, final String editName ) {
    863                if( editName != null ) {
    864                        final String selEditName = getAttribute( "EDIT_SELECTED_" + guikey );
    865                        if( !editName.equals( selEditName ) ) {
    866                                setAttribute( "EDIT_SELECTED_" + guikey, editName, true );
    867                        }
    868                }
    869        //      else {
    870        //              setSelectedEdit( guikey, null );
    871        //      }
    872                return editMgr.getEditConfig( guikey, editName );
    873        }
    874
    875        /**
    876         * 編集設定オブジェクトの配列を返します。
    877         *
    878         * DBEditConfigManagerを直接返していましたが、それを廃止します。
    879         *
    880         * @og.rev 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します。
    881         *
    882         * @param guikey 画面ID
    883         * @return  編集設定オブジェクトの配列
    884         */
    885        public DBEditConfig[] getEditConfigs( final String guikey ) {
    886                return editMgr.getEditConfigs( guikey );
    887        }
    888
    889        /**
    890         * 指定の画面ID、編集名で編集設定オブジェクトを追加します。
    891         * 既に登録されている場合は、既存の編集情報を更新します。
    892         *
    893         * ※ 廃止予定ですが、対応が間に合わないため、暫定的に残しています。
    894         *
    895         * @og.rev 5.3.6.0 (2011/06/01) 新規追加
    896         * @og.rev 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更
    897         * @og.rev 6.0.2.2 (2014/10/03) getEditKeys(String,String) を、DBEditConfig ⇒ DBEditConfigManager 変更
    898         * @og.rev 6.3.9.1 (2015/11/27) getEditKeys(String,String) は、DBEditConfigManager ⇒ DBEditConfig へ移動。
    899         * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。廃止
    900         *
    901         * @param guikey 画面ID
    902         * @param editName 編集名
    903         * @param config 編集設定オブジェクト
    904         */
    905        public void addEditConfig( final String guikey, final String editName, final DBEditConfig config ) {
    906                if( config != null ) {
    907                        editMgr.addEditConfig( guikey, editName, config );
    908
    909                        final boolean isCommon = config.isCommon();
    910                        config.forEach( guikey
    911                                                , (key,val) -> {
    912                                                                if( val != null && val.length() > 0 ) {
    913                                                                        setAttribute( key, val, true, isCommon );
    914                                                                }
    915                                                                else {
    916                                                                        removeAttribute( key, true, isCommon );
    917                                                                }
    918                                                        } );
    919                }
    920        }
    921
    922        /**
    923         * 指定の画面ID、編集名の編集設定を削除します。
    924         *
    925         * ※ 廃止予定ですが、対応が間に合わないため、暫定的に残しています。
    926         *
    927         * @og.rev 5.3.6.0 (2011/06/01) 新規追加
    928         * @og.rev 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更
    929         * @og.rev 6.0.2.2 (2014/10/03) getEditKeys( String, String ) を、DBEditConfig ⇒ DBEditConfigManager 変更
    930         * @og.rev 6.3.9.1 (2015/11/27) getEditKeys(String,String) は、DBEditConfigManager ⇒ DBEditConfig へ移動。
    931         * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。廃止
    932         *
    933         * @param guikey 画面ID
    934         * @param editName 編集名
    935         */
    936        public void deleteEditConfig( final String guikey, final String editName ) {
    937                final DBEditConfig config = editMgr.deleteEditConfig( guikey, editName );
    938                if( config != null ) {
    939                        final boolean isCommon = config.isCommon();
    940        //              final String[] editKeys = DBEditConfig.getEditKeys( guikey, editName );                 // 6.3.9.1 (2015/11/27) メソッド移動
    941        //              // 編集設定が存在しない場合エラー。
    942        //              if( !isExistValue( editKeys[0], ( isCommon ? "*" : userID ), "*" ) ) {
    943        //                      final String errMsg = "編集設定が存在しません。";
    944        //                      throw new HybsSystemException( errMsg );        // 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更
    945        //              }
    946
    947                        config.forEach( guikey , (key,val) -> removeAttribute( key, true, isCommon ) );
    948
    949        //              for( int i=0; i<editKeys.length; i++ ) {
    950        //                      removeAttribute( editKeys[i], true, isCommon );
    951        //              }
    952                        removeAttribute( "EDIT_SELECTED_"      + guikey, true, isCommon );              // 6.0.2.2 (2014/10/03) 初期値用のキーも削除
    953                        removeAttribute( "EDIT_NAME_SELECTED_" + guikey, true, isCommon );              // 6.0.2.2 (2014/10/03) 昔のキーは強制削除
    954                }
    955
    956        //      if( editName != null ) {
    957        //              String selEditName = getSelectedEdit( guikey );
    958        //              if( !editName.equals( selEditName ) ) {
    959        //                      setSelectedEdit( guikey, null );
    960        //              }
    961        //      }
    962        }
    963
    964        /**
    965         * 指定の画面IDに対して選択済みの編集名を返します。
    966         *
    967         * @og.rev 5.3.6.0 (2011/06/01) 新規追加
    968         * @og.rev 6.0.2.2 (2014/10/03) EDIT_NAME_SELECTED_ を、EDIT_SELECTED_ に変更
    969         * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。廃止
    970         *
    971         * @param guikey 画面ID
    972         *
    973         * @return 選択済み編集名
    974         */
    975        public String getSelectedEdit( final String guikey ) {
    976                return getAttribute( "EDIT_SELECTED_" + guikey );
    977        }
    978
    979        /**
    980         * 最後に使用されたリクエスト変数の値を、Mapを読み取って登録します。
    981         *
    982         * 読み取り対象は、先に lastRequestMap に登録済みのキーだけです。
    983         * そのため、{&#064;LAST.XXXX} で値を要求されたときに、キーが
    984         * 登録されていない場合は、キーだけ(値 nullで)登録しておきます。
    985         *
    986         * @og.rev 5.6.8.1 (2013/09/13) 新規追加
    987         *
    988         * @param reqMap リクエスト変数のMap
    989         */
    990        public void setLastRequestMap( final Map<String,String[]> reqMap ) {
    991                if( reqMap != null ) {
    992                        synchronized( lastRequestMap ) {
    993                                for( final String key : lastRequestMap.keySet() ) {
    994                                        if( key != null ) {                                                                     // 6.4.3.3 (2016/03/04)
    995                                                final String[] vals = reqMap.get( key );
    996                                                if( vals != null ) {
    997                                                        String val = null;
    998                                                        for( int i=0; i<vals.length; i++ ) {
    999                                                                val = vals[i];
    1000                                                                if( ! "0".equals( val ) ) { break; }    // チェックボックス対応
    1001                                                        }
    1002                                                        lastRequestMap.put( key, val );                         // val は、null もあり得る。
    1003                                                }
    1004                                        }
    1005                                }
    1006                        }
    1007                }
    1008        }
    1009
    1010        /**
    1011         * 最後に使用されたリクエスト変数の値を、設定します。
    1012         *
    1013         * この処理は、{&#064;LAST.XXXX} は、リクエスト値があれば、それが優先的に
    1014         * 使われます。
    1015         *
    1016         * @og.rev 5.6.8.1 (2013/09/13) 新規追加
    1017         *
    1018         * @param  key リクエストキー
    1019         * @param  val 設定値
    1020         */
    1021        public void setLastRequestValue( final String key,final String val ) {
    1022                if( key != null && key.length() > 0) {
    1023                        synchronized( lastRequestMap ) {
    1024                                lastRequestMap.put( key, val );
    1025                        }
    1026                }
    1027        }
    1028
    1029        /**
    1030         * 最後に使用されたリクエスト変数の値を、取得します。
    1031         *
    1032         * 画面で簡素に使用できるように、少し特殊な処理を行います。
    1033         * query 画面で {&#064;LAST.XXXX} を呼ぶと、lastRequestMap にキーがなければ、
    1034         * キーだけ先に追加します。あれば、値を取得するだけです。
    1035         * そして、result画面で command="NEW" の場合のみ、リクエスト情報のMapから、
    1036         * lastRequestMap に持っているキーで(NULLでない場合は)上書きセットします。
    1037         * キャッシュ量を減らすことと、処理の対象キーを減らす意味を持っています。
    1038         *
    1039         * @og.rev 5.6.8.1 (2013/09/13) 新規追加
    1040         *
    1041         * @param  key リクエストキー
    1042         * @return 設定値
    1043         */
    1044        public String getLastRequestValue( final String key ) {
    1045                String rtn = null;
    1046                if( key != null && key.length() > 0) {
    1047                        synchronized( lastRequestMap ) {
    1048                                if( lastRequestMap.containsKey( key ) ) {       // キーを持っているかどうかを判定
    1049                                        rtn = lastRequestMap.get( key );
    1050                                }
    1051                                else {
    1052                                        lastRequestMap.put( key, null );                // キーだけ登録しておく。
    1053                                }
    1054                        }
    1055                }
    1056                return rtn ;
    1057        }
    1058
    1059        /**
    1060         * lastRequestMap を ユーザー永続化情報(GE20) に書き込みます。
    1061         *
    1062         * clear() 処理が実行された場合に、まとめて ユーザー永続化情報(GE20) に書き込みます。
    1063         * タイミング的には、saveGUIAccessInfo() メソッドと同じですが、saveGUIAccessInfo() は、
    1064         * 書き込む条件( useAccessTable && isInfoSet ) があります。
    1065         * セーブする時には、他の属性と区別するため、接頭語 LAST_REQUEST_DATA_SUFIX(="LAST_REQUEST_") を
    1066         * キーに付けて渡します。
    1067         *
    1068         * 読み取りは、dbLoad() で、attriMap と同じタイミングで、コンストラクタで、行います。
    1069         *
    1070         * @og.rev 5.6.8.1 (2013/09/13) 新規追加
    1071         * @og.rev 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.entrySet() を使う様に変更。
    1072         * @og.rev 6.4.3.4 (2016/03/11) forループを、forEach メソッドに置き換えます。
    1073         *
    1074         * @see         #clear()
    1075         * @see         #dbLoad()
    1076         */
    1077        private void saveLastRequestValues() {
    1078                int cnt = 0;
    1079                synchronized( lastRequestMap ) {
    1080                        // 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.entrySet() を使う様に変更。
    1081                        // 6.4.3.4 (2016/03/11) forループを、forEach メソッドに置き換えます。
    1082                        lastRequestMap.forEach( (key,val) -> savePermanently( LAST_REQUEST_DATA_SUFIX + key , val , false ) );
    1083
    1084                        cnt = lastRequestMap.size();
    1085                }
    1086                System.out.println( "  [" + userID + "] 最終ﾘｸｴｽﾄ情報({@LAST.XXXX})を、(GE20)に、[" + cnt + "]件、登録しました。" );
    1087        }
    1088
    1089        /**
    1090         * アクセスログ取得の為,ApplicationInfoオブジェクトを返します。
    1091         *
    1092         * @og.rev 3.8.7.0 (2006/12/15) 新規追加
    1093         *
    1094         * @param       gamenId 実行中の画面ID
    1095         * @param       prgId   実行中のプログラムID
    1096         *
    1097         * @return      ApplicationInfoオブジェクト
    1098         */
    1099        public ApplicationInfo getApplicationInfo( final String gamenId,final String prgId ) {
    1100                if( appInfo != null ) {
    1101                        // 画面ID,操作,プログラムID
    1102                        appInfo.setModuleInfo( gamenId,null,prgId );
    1103                }
    1104                return appInfo;
    1105        }
    1106
    1107        /**
    1108         * 自然比較メソッド
    1109         * インタフェース Comparable の 実装です。
    1110         * ユーザーの順序は、ユーザーID そのものの順序であらわされます。
    1111         * 同一ユーザーの場合は，ログインタイムの順番になります。
    1112         *
    1113         * @og.rev 5.1.8.0 (2010/07/01) UserSummary の Comparable を型設定
    1114         *
    1115         * @param       object  比較対象のObject
    1116         *
    1117         * @return      このオブジェクトが指定されたオブジェクトより小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数
    1118         */
    1119        @Override       // Comparable
    1120        public int compareTo( final UserSummary object ) {
    1121                int test1 = userID.compareTo( object.getUserID() );
    1122                if( test1 == 0 ) {
    1123                        test1 = (int)( loginTime - object.getLoginTime() ) ;
    1124                }
    1125                return test1;
    1126        }
    1127
    1128        /**
    1129         * このオブジェクトと他のオブジェクトが等しいかどうかを示します。
    1130         * インタフェース Comparable の 実装に関連して、再定義しています。
    1131         * ユーザーは、ユーザーIDが等しく、かつ ログイン時刻が同一の場合に、
    1132         * 等しいと判断されます。
    1133         *
    1134         * @param   object 比較対象の参照オブジェクト
    1135         *
    1136         * @return      引数に指定されたオブジェクトとこのオブジェクトが等しい場合は true、そうでない場合は false
    1137         */
    1138        @Override       // Object
    1139        public boolean equals( final Object object ) {
    1140                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    1141                return object instanceof UserInfo
    1142                                        && userID.equals( ((UserInfo)object).getUserID()  )
    1143                                        && loginTime == ( ((UserInfo)object).getLoginTime() );
    1144        }
    1145
    1146        /**
    1147         * オブジェクトのハッシュコード値を返します。
    1148         * このメソッドは、java.util.Hashtable によって提供されるような
    1149         * ハッシュテーブルで使用するために用意されています。
    1150         * equals( Object ) メソッドをオーバーライトした場合は、hashCode() メソッドも
    1151         * 必ず 記述する必要があります。
    1152         * ここでは、ログイン時刻(long 値)の上位 32 ビットと下位 32 ビットの排他的論理和
    1153         * を求めています。
    1154         * (int)(this.longValue()^(this.longValue()&gt;&gt;&gt;32))
    1155         *
    1156         * ※ hashCode の 同一オブジェクトには同一ハッシュコードという規則と
    1157         *    発生頻度,ランダム性を考慮すれば、ログイン時刻そのもの(long)の
    1158         *    ハッシュコードでも運用上は全く問題ないと考えられます。
    1159         *
    1160         * @og.rev 3.5.6.0 (2004/06/18) 新規追加
    1161         *
    1162         * @return  このオブジェクトのハッシュコード値
    1163         *
    1164         */
    1165        @Override       // Object
    1166        public int hashCode() { return hcode ; }
    1167
    1168        /**
    1169         * オブジェクトの識別子として，詳細なユーザー情報を返します。
    1170         *
    1171         * @return  詳細なユーザー情報
    1172         * @og.rtnNotNull
    1173         */
    1174        @Override       // Object
    1175        public String toString() {
    1176                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
    1177                        .append( "userID   :" ).append( userID   ).append( CR )
    1178                        .append( "lang     :" ).append( lang     ).append( CR )
    1179                        .append( "jname    :" ).append( jname    ).append( CR )
    1180                        .append( "roles    :" ).append( roles    ).append( CR )
    1181                        .append( "IPAddress:" ).append( ipAddress ).append( CR )
    1182                        .append( "loginTime:" ).append( loginTime ).append( CR );
    1183                return rtn.toString();
    1184        }
    1185
    1186        /**
    1187         * ユーザー個別の画面オブジェクトの明細情報をｱｸｾｽ統計ﾃｰﾌﾞﾙ(GE15)に登録します。
    1188         *
    1189         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    1190         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    1191         * @og.rev 4.0.0.0 (2007/10/05) SQLServer 互換性の為、SUBSTRB を廃止します。
    1192         * @og.rev 4.1.1.0 (2008/01/30) ユーザーアクセス画面管理テーブルに画面の最終アクセス時間を更新
    1193         * @og.rev 5.0.2.0 (2009/11/01) 作成・更新日付がセットされていないバグを修正
    1194         * @og.rev 5.2.3.0 (2010/12/01) 画面アクセスの履歴(順番)を管理する機能を追加
    1195         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
    1196         * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。
    1197         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
    1198         */
    1199        private void saveGUIAccessInfo() {
    1200        //      if( !useAccessTable || !isInfoSet ) { return ; }
    1201
    1202                final GUIInfo[] infos = getGUIInfos() ;
    1203                guiMap.clear();                                                 // 6.4.3.1 (2016/02/12) getGUIInfos() してから、クリアします。
    1204
    1205                final long crntTime = System.currentTimeMillis();
    1206
    1207                final String[] names = new String[] { "SYSTEM_ID","USERID","USERADRS","HOSTADRS","GUIKEY","DYLOGIN","DYLOGOUT",
    1208                                                                                "USED_TIME","CNT_ACCESS","CNT_ERROR","CNT_READ","CNT_WRITE",
    1209                                                                                "TM_TOTAL_QUERY","TM_MAX_QUERY","MAX_QUERY","FGJ","DYSET","DYUPD","USRSET","USRUPD","PGUPD" };
    1210                String[] values = new String[names.length];
    1211
    1212                values[C_SYSTEM_ID              ] = HybsSystem.sys( "SYSTEM_ID" );
    1213                values[C_USERID                 ] = userID;
    1214                values[C_USERADRS               ] = ipAddress;
    1215                values[C_HOSTADRS               ] = HybsSystem.sys( "HOST_ADRS" );
    1216                values[C_GUIKEY                 ] = "";
    1217                values[C_DYLOGIN                ] = DateSet.getDate( loginTime,"yyyyMMddHHmmss" );                              // 6.4.2.0 (2016/01/29)
    1218                values[C_DYLOGOUT               ] = DateSet.getDate( "yyyyMMddHHmmss" );                                                // 6.4.2.0 (2016/01/29)
    1219                values[C_USED_TIME              ] = String.valueOf( Math.round( (crntTime-usedTime) / 1000.0d ) );      // 秒に変換
    1220                values[C_CNT_ACCESS             ] = "0";
    1221                values[C_CNT_ERROR              ] = "0";
    1222                values[C_CNT_READ               ] = "0";
    1223                values[C_CNT_WRITE              ] = "0";
    1224                values[C_TM_TOTAL_QUERY ] = "0";
    1225                values[C_TM_MAX_QUERY   ] = "0";
    1226                values[C_MAX_QUERY              ] = "";
    1227                values[C_FGJ                    ] = "1";
    1228                values[C_DYSET                  ] = DateSet.getDate( "yyyyMMddHHmmss" );                                                // 6.4.2.0 (2016/01/29)
    1229                values[C_DYUPD                  ] = DateSet.getDate( "yyyyMMddHHmmss" );                                                // 6.4.2.0 (2016/01/29)
    1230                values[C_USRSET                 ] = "userInfo";
    1231                values[C_USRUPD                 ] = "userInfo";
    1232                values[C_PGUPD                  ] = "userInfo";
    1233
    1234                usedTime = crntTime ;
    1235
    1236                final DBSimpleTable dbTable = new DBSimpleTable( names );
    1237                // 画面ID,操作,プログラムID
    1238                getApplicationInfo( "UserInfo","saveGUI" );
    1239                dbTable.setApplicationInfo( appInfo );  // 3.8.7.0 (2006/12/15)
    1240                dbTable.setConnectionID( DBID );                // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応
    1241                dbTable.setTable( "GE15" );
    1242                // 4.0.0.0 (2007/10/05) SQLServer 互換性の為、CLOB化します。
    1243        //      dbTable.addConstrain( names[C_MAX_QUERY],"SUBSTRB(?,1,4000)" );
    1244
    1245                boolean okFlag = false;
    1246                try {
    1247                        dbTable.startInsert();
    1248
    1249                        // UserInfo に関する情報の登録
    1250                        dbTable.execute( values );
    1251
    1252                        // GUIInfo に関する情報の登録
    1253                        if( infos != null ) {
    1254                                values[C_USED_TIME] = "0";      // USED_TIME をクリアしておきます。
    1255                                final String logoutTime = DateSet.getDate( "yyyyMMddHHmmss" );                                  // 6.4.2.0 (2016/01/29)
    1256                                for( int i=0; i<infos.length; i++ ) {
    1257                                        final GUIAccessCount access = infos[i].getGUIAccessCount();
    1258                                        final int cnt = access.getAccessCount();
    1259                                        if( cnt > 0 ) {
    1260                                                values[C_GUIKEY                 ] = access.getKey();
    1261                                                values[C_CNT_ACCESS             ] = String.valueOf( cnt );
    1262                                                values[C_CNT_ERROR              ] = String.valueOf( access.getErrorCount() );
    1263                                                values[C_CNT_READ               ] = String.valueOf( access.getReadCount() );
    1264                                                values[C_CNT_WRITE              ] = String.valueOf( access.getWriteCount() );
    1265                                                values[C_TM_TOTAL_QUERY ] = String.valueOf( access.getQueryTime() );
    1266                                                values[C_TM_MAX_QUERY   ] = String.valueOf( access.getMaxQueryTime() );
    1267                                                values[C_MAX_QUERY              ] = access.getMaxQuery();
    1268        //                                      dbTable.addValues( values );
    1269                                                dbTable.execute( values );
    1270                                                // 4.1.1.0(2008/01/28)画面アクセス時間の更新
    1271                                                // 5.2.3.0 (2010/12/01) 画面アクセスの履歴(順番)を管理する機能を追加
    1272                                                final String keys = infos[i].getNextGuiKeys();
    1273                                                UserAccessTable.updateLastAccessTime( systemId,userID,access.getKey(),logoutTime,keys );
    1274                                        }
    1275                                }
    1276                        }
    1277                        okFlag = true;
    1278                }
    1279                catch( final SQLException ex) {
    1280                        LogWriter.log( "  [" + userID + "] ｱｸｾｽ統計ﾃｰﾌﾞﾙ(GE15)登録時にエラーが発生しました" );
    1281                        LogWriter.log( ex.getMessage() );
    1282                }
    1283                finally {
    1284                        final int cnt = dbTable.close( okFlag );
    1285                        System.out.println( "  [" + userID + "] ｱｸｾｽ統計ﾃｰﾌﾞﾙ(GE15)に、[" + cnt + "]件、追加しました。" );
    1286                }
    1287        }
    1288
    1289        /**
    1290         * userInfoにセットされた値/キーをDBに登録します。
    1291         * 既にキーが存在している場合は、既存データを更新し、なければ追加します。
    1292         *
    1293         * @og.rev 5.3.6.0 (2011/06/01) 全ユーザー情報として保存できるように対応
    1294         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
    1295         * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。
    1296         * @og.rev 6.4.5.0 (2016/04/08) DBEditConfigManager で使えるように、private → public にします(ちょっと不安)。
    1297         *
    1298         * @param key キー
    1299         * @param value 値
    1300         * @param isCommon ユーザーID='*'(全ユーザー公開)として登録するかどうか
    1301         */
    1302        public void savePermanently( final String key, final String value, final boolean isCommon ) {
    1303
    1304                // 追加変更時に共通でセットされる値を設定
    1305                final String[] names = new String[] { "SYSTEM_ID","USERID","ROLES","PARAM_ID","PARAM","KBSET"
    1306                                                                                ,"FGJ","DYSET","DYUPD","USRSET","USRUPD","PGUPD" };
    1307                String[] values = new String[names.length];
    1308                values[C_GE20_SYSTEM_ID ] = HybsSystem.sys( "SYSTEM_ID" );
    1309                values[C_GE20_USERID    ] = ( isCommon ? "*" : userID );
    1310                values[C_GE20_ROLES             ] = GE20_ROLES;
    1311                values[C_GE20_PARAM_ID  ] = key;
    1312                values[C_GE20_PARAM             ] = value;
    1313                values[C_GE20_KBSET             ] = String.valueOf( GE20_KBSET_WRITABLE );
    1314                values[C_GE20_FGJ               ] = "1";
    1315                values[C_GE20_DYSET             ] = DateSet.getDate( "yyyyMMddHHmmss" );                                // 6.4.2.0 (2016/01/29)
    1316                values[C_GE20_DYUPD             ] = DateSet.getDate( "yyyyMMddHHmmss" );                                // 6.4.2.0 (2016/01/29)
    1317                values[C_GE20_USRSET    ] = userID;
    1318                values[C_GE20_USRUPD    ] = userID;
    1319                values[C_GE20_PGUPD     ] = "UserInfo";
    1320
    1321                // 画面ID,操作,プログラムID
    1322                getApplicationInfo( "UserInfo","registValueToDB" );
    1323
    1324                final DBSimpleTable dbTable = new DBSimpleTable( names );
    1325                dbTable.setApplicationInfo( appInfo );  // 3.8.7.0 (2006/12/15)
    1326                dbTable.setConnectionID( DBID );                // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応
    1327                dbTable.setTable( "GE20" );
    1328
    1329                boolean okFlag = false;
    1330                try {
    1331                        if( isExistValue( key, ( isCommon ? "*" : userID ), GE20_ROLES ) ) {
    1332                                final String where = "SYSTEM_ID = [SYSTEM_ID] and USERID = [USERID] and ROLES = [ROLES] and PARAM_ID = [PARAM_ID] and FGJ='1'";
    1333                                dbTable.setWhere( where );
    1334                                dbTable.startUpdate();
    1335                        }
    1336                        else {
    1337                                dbTable.startInsert();
    1338                        }
    1339                        dbTable.execute( values );
    1340                        okFlag = true;
    1341                }
    1342                catch( final SQLException ex ) {
    1343                        throw new HybsSystemException( "ユーザー永続化情報(GE20)設定時にエラーが発生しました", ex );
    1344                }
    1345                finally {
    1346                        dbTable.close( okFlag );
    1347                }
    1348        }
    1349
    1350        /**
    1351         * userInfoから削除された値/キーをDBからも削除します。
    1352         *
    1353         * @og.rev 5.3.6.0 (2011/06/01) 新規追加
    1354         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
    1355         *
    1356         * @param key キー
    1357         * @param isCommon ユーザーID='*'(全ユーザー公開)から削除するかどうか
    1358         */
    1359        private void deletePermanently( final String key, final boolean isCommon ) {
    1360
    1361                // 追加変更時に共通でセットされる値を設定
    1362                final String[] names = new String[] { "SYSTEM_ID","USERID","ROLES","PARAM_ID" };
    1363                String[] values = new String[names.length];
    1364                values[C_GE20_SYSTEM_ID ] = HybsSystem.sys( "SYSTEM_ID" );
    1365                values[C_GE20_USERID    ] = ( isCommon ? "*" : userID );
    1366                values[C_GE20_ROLES             ] = GE20_ROLES;
    1367                values[C_GE20_PARAM_ID  ] = key;
    1368
    1369                // 画面ID,操作,プログラムID
    1370                getApplicationInfo( "UserInfo","deleteValueFromDB" );
    1371
    1372                final DBSimpleTable dbTable = new DBSimpleTable( names );
    1373                dbTable.setApplicationInfo( appInfo );
    1374                dbTable.setConnectionID( DBID );                // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応
    1375                dbTable.setTable( "GE20" );
    1376
    1377                boolean okFlag = false;
    1378                try {
    1379                        final String where = "SYSTEM_ID = [SYSTEM_ID] and USERID = [USERID] and ROLES = [ROLES] and PARAM_ID = [PARAM_ID] and FGJ='1'";
    1380                        dbTable.setWhere( where );
    1381                        dbTable.startDelete();
    1382                        dbTable.execute( values );
    1383                        okFlag = true;
    1384                }
    1385                catch( final SQLException ex ) {
    1386                        throw new HybsSystemException( "ユーザー永続化情報(GE20)削除時にエラーが発生しました", ex );
    1387                }
    1388                finally {
    1389                        dbTable.close( okFlag );
    1390                }
    1391        }
    1392
    1393        /**
    1394         * ユーザー永続化情報(GE20)に該当のキーが存在するかをチェックします。
    1395         *
    1396         * @og.rev 5.3.6.0 (2011/06/01) 全ユーザー情報として保存できるように対応
    1397         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
    1398         *
    1399         * @param key キー
    1400         * @param userid ユーザーID
    1401         * @param roles ロール
    1402         *
    1403         * @return true:存在している/false:存在していない
    1404         */
    1405        private boolean isExistValue( final String key, final String userid, final String roles ) {
    1406                final String[] args = { HybsSystem.sys( "SYSTEM_ID" ), userid, roles, key };
    1407
    1408                // 画面ID,操作,プログラムID
    1409                getApplicationInfo( "UserInfo","isExistValue" );
    1410
    1411                final String[][] rtn = DBUtil.dbExecute( QUERY_GE20_KEY, args, appInfo, DBID ); // 5.5.5.1 (2012/08/07)
    1412                if( rtn == null || rtn.length == 0 ) {
    1413                        return false;
    1414                }
    1415                else if( rtn[0].length > 0 ) {
    1416                        if( String.valueOf( GE20_KBSET_READONLY ).equals( rtn[0][0] ) ) {
    1417                                throw new HybsSystemException( "読み取り専用情報のため、書き込みできません" );
    1418                        }
    1419                        else {
    1420                                return true;
    1421                        }
    1422                }
    1423                else {
    1424                        throw new HybsSystemException( "ユーザー永続化情報(GE20)検索時にエラーが発生しました。" );
    1425                }
    1426        }
    1427
    1428        // /**
    1429        // * 指定されたカラムキーに対応するデータの条件式を返します。
    1430        // *
    1431        // * @og.rev 4.4.0.0 (2009/08/02) 新規追加
    1432        // * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(DataRole.java廃止)
    1433        // *
    1434        // * @param clm カラム名
    1435        // *
    1436        // * @return データの条件式
    1437        // */
    1438        // 7.4.4.0 (2021/06/30) Delete
    1439        // public String getDataCondition( final String clm ) {
    1440        //      return dataRole.getCondition( clm );
    1441        // }
    1442
    1443        /**
    1444         * このユーザーでアクセスされた画面オブジェクトを設定します。
    1445         *
    1446         * これは、画面アクセスの履歴(順番)を管理する機能に使います。
    1447         *
    1448         * @og.rev 5.2.3.0 (2010/12/01) 新規追加
    1449         *
    1450         * @param guiInfo 画面オブジェクト
    1451         */
    1452        public void setAccessGui( final GUIInfo guiInfo ) {
    1453                if( lastGuiInfo != null && guiInfo != null ) {
    1454                        lastGuiInfo.setNextGuiKey( guiInfo.getKey() );
    1455                }
    1456                lastGuiInfo = guiInfo ;         // 最後にアクセスした GUIInfo を設定
    1457        }
    1458}