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