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