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 org.opengion.hayabusa.common.HybsSystem;
019import org.opengion.hayabusa.common.HybsSystemException;
020import org.opengion.fukurou.util.StringUtil;
021import org.opengion.fukurou.util.HybsEntry;
022
023import java.util.List;
024import java.util.ArrayList;
025import java.util.Set;
026import java.util.LinkedHashSet;
027
028/**
029 * 画面情報の取得の為のインターフェースです。
030 *
031 * {@GUI.XXXX} で、XXXX 部に、GUIInfo オブジェクトで定義されている
032 * 属性情報を取り出すことが出来ます。
033 *
034 * ・KEY           画面ID
035 * ・ADDRESS       実行アドレス
036 * ・REALADDRESS   実行実アドレス
037 * ・SEQUENCE      表示順
038 * ・GROUPS        メニュグループ
039 * ・CLASSIFY      メニュ分類
040 * ・LEVEL         メニュ階層番号
041 * ・LABEL         画面名称
042 * ・NAME          画面名称(=SNAME)
043 * ・SNAME         画面名称(short)
044 * ・LNAME         画面名称(long)
045 * ・ROLES         ロールズ
046 * ・MODE          アクセスモード列(mr,mw,-r,-w の羅列)
047 * ・TARGET        ターゲット
048 * ・PARAM         設定値(パラメータ)
049 * ・KBLINK        リンク区分
050 * ・DESCRIPTION   概要説明
051 * ・IMAGEKEY      イメージキー
052 * ・DYUPD         更新日時
053 * ・ISREAD        読取り許可[true/false]
054 * ・ISWRITE       書込み許可[true/false]
055 *
056 * @og.group リソース管理
057 *
058 * @version  4.0
059 * @author   Kazuhiko Hasegawa
060 * @since    JDK5.0,
061 */
062public final class GUIInfo implements Comparable<GUIInfo> {     // 4.3.3.6 (2008/11/15) Generics警告対応
063
064        private static final String YOYAKU = "|KEY|ADDRESS|REALADDRESS|SEQUENCE"
065                                                                                + "|GROUPS|CLASSIFY|LEVEL|LABEL|NAME"
066                                                                                + "|SNAME|LNAME|ROLES|MODE|TARGET"
067                                                                                + "|PARAM|KBLINK|DESCRIPTION|DYUPD|IMAGEKEY|" ;         // 5.5.2.5 (2012/05/21) イメージアイコン
068
069        private final GUIData   guiData ;
070        private final LabelData labelData ;
071        private final String[]  groupKeys ;
072
073        private final boolean   menuFlag  ;             // メニューへの表示可否属性
074        private final boolean   writeFlag ;             // 書き込み許可属性
075        private final byte              bitMode ;               // ビットモード(UserInfo 加味済み)
076        private final boolean   pulldownFlag;   // 4.3.3.0 (2008/10/01) 強制プルダウン化属性
077
078        private final GUIAccessCount accessCount ;              // この画面へのアクセス統計を管理します。
079
080        private int   level = 0;
081
082        private final Set<String> nextGui = new LinkedHashSet<String>();        // 5.2.3.0 (2010/12/01) アクセス履歴管理
083
084        /**
085         * コンストラクター
086         *
087         * 引数の bitMode は、UserInfo と加味済み
088         *
089         * @og.rev 4.3.0.0 (2008/07/04) ファイル入出力制御追加
090         * @og.rev 4.3.3.0 (2008/10/01) 強制プルダウンモード追加
091         *
092         * @param       guiData         画面データオブジェクトID
093         * @param       labelData       ラベルデータオブジェクト
094         * @param       bitMode ビットモード配列 "--:000","-r:001","-w:010","mr:101","mw:110" に対応した数字(0,1,2,5,6)
095         */
096        public GUIInfo( final GUIData   guiData ,
097                                        final LabelData labelData ,
098                                        final byte              bitMode ) {
099                this.guiData    = guiData;
100                this.labelData  = labelData;
101                groupKeys               = StringUtil.csv2Array( guiData.getGroups() );
102
103                menuFlag        = RoleMode.isMenu( bitMode );
104                writeFlag       = RoleMode.isWrite( bitMode );
105                pulldownFlag = RoleMode.isPulldown( bitMode ); // 4.3.3.0 (2008/10/01)
106                accessCount = new GUIAccessCount( guiData.getGuiKey() ) ;
107                this.bitMode = bitMode ;
108
109                level = guiData.getGuiLevel();
110        }
111
112        /**
113         * 画面情報 画面ID を取得します。
114         *
115         * @return      画面ID
116         */
117        public String getKey() {
118                return guiData.getGuiKey();
119        }
120
121        /**
122         * 実行アドレス情報を取得します。
123         *
124         * @return      実行アドレス
125         */
126        public String getAddress() {
127                return guiData.getAddress();
128        }
129
130        /**
131         * トップからの実行アドレス情報を取得します。
132         * コンテキスト名とリンク区分属性を利用して、サーバートップからのアドレスを
133         * 返します。ただし、GUIリソースに、http://~ または、.~ から始まるアドレスは
134         * そのまま、なにも変換せずに返します。
135         * 実アドレスには、param属性の情報を付加します。param属性は、接続文字を用いずに
136         * そのまま連結されますので、/index.jsp?AAA=XX&amp;BBB=YY という感じで "/" から
137         * はじめます。
138         *
139         * http://AAAA  ⇒  http://AAAA
140         * ../../AAAA/  ⇒  ../../AAAA/
141         * AAAA         ⇒  /CONTEXT_NAME/KBLINK/AAAA/    param なし
142         * AAAA         ⇒  /CONTEXT_NAME/KBLINK/AAAA/index.jsp?AAA=XX&amp;BBB=YY  param あり
143         *
144         * @og.rev 3.5.5.0 (2004/03/12) 新規追加
145         * @og.rev 4.0.0.0 (2005/01/31) param属性追加
146         *
147         * @return      実行実アドレス
148         */
149        public String getRealAddress() {
150                return guiData.getRealAddress();
151        }
152
153        /**
154         * トップからの実行アドレス情報を取得します。
155         * コンテキスト名とリンク区分属性を利用して、サーバートップからのアドレスを
156         * 返します。ただし、GUIリソースに、http://~ または、.~ から始まるアドレスは
157         * そのまま、なにも変換せずに返します。
158         * 実アドレスには、param属性の情報を付加します。param属性は、接続文字を用いずに
159         * そのまま連結されますので、/index.jsp?AAA=XX&amp;BBB=YY という感じで "/" から
160         * はじめます。
161         * また、アドレスの最後がスラッシュ(/)で終了している場合は、page属性を追加します。
162         *
163         * http://AAAA  ⇒  http://AAAA
164         * ../../AAAA/  ⇒  ../../AAAA/
165         * AAAA         ⇒  /CONTEXT_NAME/KBLINK/AAAA/    param なし
166         * AAAA         ⇒  /CONTEXT_NAME/KBLINK/AAAA/index.jsp?AAA=XX&amp;BBB=YY  param あり
167         *
168         * @og.rev 4.0.0.0 (2005/01/31) 新規追加(param属性追加)
169         *
170         * @param    page          実行ページ(index.jsp など)
171         *
172         * @return      実行実アドレス
173         */
174        public String getRealAddress( final String page ) {
175                return guiData.getRealAddress( page );
176        }
177
178        /**
179         * 画面の表示順を取得します。
180         *
181         * @return      画面の表示順
182         */
183        public int getSequence() {
184                return guiData.getSeqno();
185        }
186
187        /**
188         * 画面の階層番号(レベル)を取得します。
189         * 画面階層は、
190         *  0:予約階層(将来的にタブブラウザ対応時に使用
191         *  1:トップ階層(通常のメニューの分類として表示されます。)
192         *  2:選択階層(通常の折りたたみメニューの画面選択時に使用されます。)
193         *  3以下:下位階層(通常の選択メニューとして、1段下げて表示されます。)
194         * です。
195         * なお、これらの意味は、実際にメニューを作成/表示するクラスに依存します。
196         *
197         * @return      画面の表示順
198         */
199        public int getLevel() {
200                return level;
201        }
202
203        /**
204         * 画面の階層番号(レベル)をアップします。
205         *
206         * これは、レベルが3の場合(階層時の隠しメニュー)をレベル2に
207         * することで、常に見えているメニューに格上げします。
208         * 具体的には、設定値が隠しメニューの場合に、アクセスするとレベル2へ格上げ
209         * することで、個人単位で、過去の履歴に応じたメニュー配置が可能になります。
210         */
211        public void setLevelUp() {
212                if( level == 4 ) { level = 3; } // 4.0.0.0 (2007/10/30)
213        }
214
215        /**
216         * 画面情報 メニュグループのオリジナルキー を取得します。
217         * メニュグループは、カンマ区切りで複数登録できます。
218         *
219         * @return      メニュ分類のキー
220         */
221        public String getGroups() {
222                return guiData.getGroups();
223        }
224
225        /**
226         * 指定の文字列がグループに含まれているかどうかを判定します。
227         * メニュグループは、カンマ区切りで複数登録できますので、そのうちの
228         * どれかに含まれていれば、true を返します。
229         * このメニューそのものに、グループが指定されていない場合は、
230         * デフォルトグループという扱いで、true を返します。
231         * 引数が、null または、ゼロ文字列の場合も、同様に、true を返します。
232         *
233         * @param       group   判定するグループ
234         *
235         * @return      グループに含まれているかどうか
236         */
237        public boolean isGroupIn( final String group ) {
238                if( groupKeys.length == 0 || group == null || group.length() == 0 ) {
239                        return true;
240                }
241
242                for( int i=0; i<groupKeys.length; i++ ) {
243                        if( group.equals( groupKeys[i] ) ) {
244                                return true;
245                        }
246                }
247                return false;
248        }
249
250        /**
251         * 画面情報 メニュ分類のオリジナルキー を取得します。
252         *
253         * @return      メニュ分類のキー
254         */
255        public String getClassify() {
256                return guiData.getClassify();
257        }
258
259        /**
260         * 画面情報 画面名称 を取得します。
261         * これは、加工前のラベルリソースに登録されている値です。
262         *
263         * @return      画面名称
264         */
265        public String getLabel() {
266                return labelData.getLabel();
267        }
268
269        /**
270         * 画面情報 画面名称(short) を取得します。
271         * この名称は、チップ表示付きの文字列を返します。
272         *
273         * @return      画面名称(short)
274         */
275        public String getName() {
276                return labelData.getShortLabel();
277        }
278
279        /**
280         * 画面情報 画面名称(long) を取得します。
281         * この名称は、チップ表示付きの文字列を返します。
282         *
283         * @return      画面名称(long)
284         */
285        public String getLongName() {
286                return labelData.getLongLabel();
287        }
288
289        /**
290         * 画面情報 ロール を取得します。
291         * ロールは、AAA|BBB|CCC と『|』の区切り文字で複数登録できます。
292         * ユーザーのロール(こちらも、XXX|YYY|AAAと複数登録可能)とマッチする
293         * ロールがあれば、その画面のアクセス許可があります。
294         * 読み書きと、メニュー表示は、アクセスモードで指定します。
295         *
296         * @return      ロール
297         */
298        public String getRoles() {
299                return guiData.getRoles();
300        }
301
302        /**
303         * アクセスモードを取得します。
304         *
305         * r,w,_ を各ロール毎に設定します。
306         * mr:メニューよりアクセスできる読取専用画面です。登録ボタンは表示されません。
307         * mw:メニューよりアクセスできる登録編集画面です。表示もします。
308         * -r:メニューに現れませんが、アクセスすることは可能です。読取専用。
309         * -w:メニューに現れませんが、アクセスすることは可能です。読み書き出来ます。
310         *
311         * この2文字ずつのセットが、各ロールに対応付けられたアクセス制御になります。
312         * ロールが、AAA|BBB|CCC|DDD で、モードが mw|mr|-r|-w であれば、
313         * AAA は、mw , BBB は、mr ,CCC は、-r ,DDD は -w と設定されたことになります。
314         * 特別に、2文字のみ登録された場合は、全ロールが同一モードに設定
315         * されたとみなします。
316         *
317         * @return      ロール毎のアクセスモード列(mr,mw,-r,-w の羅列)
318         */
319        public String getMode() {
320                return guiData.getMode();
321        }
322
323        /**
324         * 画面を表示する時のターゲット属性を取得します。
325         *
326         * @return      ターゲット
327         */
328        public String getTarget() {
329                return guiData.getTarget();
330        }
331
332        /**
333         * 画面を表示する時のパラメータ属性を取得します。
334         *
335         * @return      パラメータ
336         */
337        public String getParam() {
338                return guiData.getParam();
339        }
340
341        /**
342         * リンク区分属性を取得します。
343         *
344         * @og.rev 3.4.0.0 (2003/09/01) リンク区分(KBLINK)属性を追加。
345         *
346         * @return      リンク区分
347         */
348        public String getKblink() {
349                return guiData.getKblink();
350        }
351
352        /**
353         * 概要説明属性を取得します。
354         * 概要説明が設定されていない場合は、longName を返します。
355         *
356         * @og.rev 3.5.6.5 (2004/08/09) 概要説明(DESCRIPTION)属性を追加。
357         *
358         * @return      概要説明
359         */
360        public String getDescription() {
361                return labelData.getDescription() ;
362        }
363
364        /**
365         * 更新日時を取得します。
366         *
367         * @og.rev 5.3.3.0 (2011/03/01) 新規作成
368         *
369         * @return      更新日時
370         */
371        public String getDyupd() {
372                return guiData.getDyupd();
373        }
374
375        /**
376         * イメージアイコンのキーを返します。
377         *
378         * 画面にアイコンを追加する場合、jsp/menuImage フォルダに、画面ID と同じ名称の
379         * 画像ファイルを置く必要があります。
380         * 本来は、画面リソース(GEA11)に、カラムを追加して対応すべきですが、互換性の関係より、
381         * PARAM 属性で、所定のキーを登録することで使えるようにします。
382         * この、PARAMは、画面アドレスの引数(たとえば、command=NEW など)を使うためのパラメータですが、
383         * アイコン割り当て(IMAGE_KEY=XXXX)を使用することで、XXXX をキーとして使います。
384         * IMAGE_KEY=XXXX が指定されない場合は、画面IDが、imageKey として返されます。
385         *
386         * @og.rev 5.5.2.5 (2012/05/21) 新規追加
387         *
388         * @return      イメージアイコンのキー
389         */
390        public String getImageKey() {
391                return guiData.getImageKey();
392        }
393
394        /**
395         * ロールモード情報を取得します。
396         *
397         * @og.rev 4.3.0.0 (2008/07/04) 新規追加
398         *
399         * @return      ロールモード
400         */
401        public RoleMode getRoleMode() {
402                return guiData.getRoleMode() ;
403        }
404
405        /**
406         * リードアクセス(読取り許可)の 可否を チェックします。
407         * アクセスチェックは、画面のロールをユーザーの
408         * それと比較して条件が含まれているかどうかを確認します。
409         * 条件が null (または0ストリング)の場合は, true となります。
410         * 条件の判断は、AND 条件です。
411         * さらに、その他の条件部分を判断して、OR 条件で先の結果と突き合わせます。
412         * ユーザーのロールが、 "root" の場合は,rw 属性のみのチェックで判断します。
413         *
414         * @og.rev 3.5.4.0 (2003/11/25) 引数にロールズを渡します。
415         *
416         * @return  アクセスOK:true  アクセス拒否:false
417         */
418        public boolean isRead() {
419                return menuFlag;
420        }
421
422        /**
423         * ライトアクセス(書込み許可)の 可否を チェックします。
424         * アクセスチェックは、画面のロールをユーザーの
425         * それと比較して条件が含まれているかどうかを確認します。
426         * 条件が null (または0ストリング)の場合は, true となります。
427         * 条件の判断は、AND 条件です。
428         * さらに、その他の条件部分を判断して、OR 条件で先の結果と突き合わせます。
429         * ユーザーのロールが、 "root" の場合は,rw 属性のみのチェックで判断します。
430         *
431         * @og.rev 3.5.4.0 (2003/11/25) 引数にロールズを渡します。
432         *
433         * @return  アクセスOK:true  アクセス拒否:false
434         */
435        public boolean isWrite() {
436                return writeFlag;
437        }
438
439        /**
440         * ボタンメニューにプルダウンを指定するのかをチェックします。
441         *
442         * @og.rev 4.3.3.0 (2008/10/01) 新規作成
443         *
444         * @return プルダウン化の場合true
445         */
446        public boolean isPulldown() {
447                return pulldownFlag;
448        }
449
450        /**
451         * 指定のユーザーロールに対するビット条件を取得します。
452         * この bitMode は、すでにユーザー単位に作成された値です。
453         *
454         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
455         *
456         * @return アクセスビット
457         */
458        public byte getBitMode() {
459                return bitMode;
460        }
461        
462        /**
463         * FAQがGE80に関連画面IDとして存在しているかどうか
464         * 
465         * @og.rev 5.6.4.3 (2013/05/25) 追加
466         *
467         * @return      FAQの存在
468         */
469        public boolean isFaq() {
470                return guiData.isFaq();
471        }
472
473        /**
474         * GUIInfoの属性文字列を取得します。
475         *
476         * ・KEY           画面ID
477         * ・ADDRESS       実行アドレス
478         * ・REALADDRESS   実行実アドレス
479         * ・SEQUENCE      表示順
480         * ・GROUPS        メニュグループ
481         * ・CLASSIFY      メニュ分類
482         * ・LEVEL         メニュ階層番号
483         * ・LABEL         画面名称
484         * ・NAME          画面名称(=SNAME)
485         * ・SNAME         画面名称(short)
486         * ・LNAME         画面名称(long)
487         * ・ROLES         ロール
488         * ・MODE          アクセスモード列(mr,mw,-r,-w の羅列)
489         * ・TARGET        ターゲット
490         * ・PARAM         設定値(パラメータ)
491         * ・KBLINK        リンク区分
492         * ・DESCRIPTION   概要説明
493         * ・IMAGEKEY      イメージキー
494         * ・DYUPD         更新日時
495         * ・ISREAD        読取り許可[true/false]
496         * ・ISWRITE       書込み許可[true/false]
497         *
498         * @og.rev 3.4.0.0 (2003/09/01) リンク区分(KBLINK)属性を追加。
499         * @og.rev 3.5.5.0 (2004/03/12) 実行実アドレス(REALADDRESS)属性を追加。
500         * @og.rev 3.5.6.5 (2004/08/09) 概要説明(DESCRIPTION)属性を追加。
501         * @og.rev 4.0.0.0   (2005/11/30) ISREAD,ISWRITE 属性を追加。
502         * @og.rev 5.3.3.0 (2011/03/01) 更新日時を追加
503         * @og.rev 5.5.2.5 (2012/05/21) IMAGEKEY 追加
504         * @og.rev 5.6.4.3 (2013/05/25) FAQ追加
505         *
506         * @param       key     キー
507         *
508         * @return      属性文字列の値
509         */
510        public String getAttribute( final String key ) {
511                if( key == null ) { return null; }
512                final String rtn ;
513
514                if(      key.equalsIgnoreCase( "KEY"         ) ) { rtn = getKey(); }
515                else if( key.equalsIgnoreCase( "GUICLM"      ) ) { rtn = labelData.getKey(); }
516                else if( key.equalsIgnoreCase( "ADDRESS"     ) ) { rtn = getAddress(); }
517                else if( key.equalsIgnoreCase( "REALADDRESS" ) ) { rtn = getRealAddress(); }
518                else if( key.equalsIgnoreCase( "SEQUENCE"    ) ) { rtn = String.valueOf( getSequence() ); }
519                else if( key.equalsIgnoreCase( "GROUPS"      ) ) { rtn = getGroups(); }
520                else if( key.equalsIgnoreCase( "CLASSIFY"    ) ) { rtn = getClassify(); }
521                else if( key.equalsIgnoreCase( "LEVEL"       ) ) { rtn = String.valueOf( getLevel() ); }
522                else if( key.equalsIgnoreCase( "LABEL"       ) ) { rtn = getLabel(); }
523                else if( key.equalsIgnoreCase( "NAME"        ) ) { rtn = getName(); }
524                else if( key.equalsIgnoreCase( "SNAME"       ) ) { rtn = getName(); }
525                else if( key.equalsIgnoreCase( "LNAME"       ) ) { rtn = getLongName(); }
526                else if( key.equalsIgnoreCase( "ROLE"        ) ) { rtn = getRoles(); }
527                else if( key.equalsIgnoreCase( "ROLES"       ) ) { rtn = getRoles(); }
528                else if( key.equalsIgnoreCase( "MODE"        ) ) { rtn = getMode(); }
529                else if( key.equalsIgnoreCase( "TARGET"      ) ) { rtn = getTarget(); }
530                else if( key.equalsIgnoreCase( "PARAM"       ) ) { rtn = getParam(); }
531                else if( key.equalsIgnoreCase( "KBLINK"      ) ) { rtn = getKblink(); }
532                else if( key.equalsIgnoreCase( "DESCRIPTION" ) ) { rtn = getDescription(); }    // 3.5.6.5 (2004/08/09)
533                else if( key.equalsIgnoreCase( "IMAGEKEY"    ) ) { rtn = getImageKey(); }               // 3.5.6.5 (2004/08/09)
534                else if( key.equalsIgnoreCase( "DYUPD"       ) ) { rtn = getDyupd(); }                  // 5.5.2.5 (2012/05/21)
535                else if( key.equalsIgnoreCase( "ISREAD"      ) ) { rtn = String.valueOf( isRead() ); }  // 4.0.0 (2005/11/30)
536                else if( key.equalsIgnoreCase( "ISWRITE"     ) ) { rtn = String.valueOf( isWrite() ); } // 4.0.0 (2005/11/30)
537                else if( key.equalsIgnoreCase( "FAQ"         ) ) { rtn = String.valueOf(isFaq()); } // 5.6.4.3 (2013/05/24)
538                else {
539                        String errMsg = "属性文字列キーが不正です。 key=[" + key + "]"
540                                                + HybsSystem.CR
541                                                + "予約語(" + YOYAKU + ") 以外は指定できません。" ;
542                        throw new HybsSystemException( errMsg );
543                }
544                return rtn ;
545        }
546
547        /**
548         * GUIInfoの属性文字列の内部情報を返します。
549         * この内部情報の中には、getAttribute( String ) で取得できる管理情報です。
550         *
551         * @og.rev 4.0.0.0 (2004/12/31) 新規作成
552         * @og.rev 5.3.3.0 (2011/03/01) 更新日時を追加
553         * @og.rev 5.5.2.5 (2012/05/21) IMAGEKEY 追加
554         *
555         * @return      属性文字列のHybsEntryオブジェクト配列
556         */
557        public HybsEntry[] getEntrys() {
558                List<HybsEntry> list = new ArrayList<HybsEntry>();
559
560                list.add( new HybsEntry( "GUI.KEY"         , getAttribute( "KEY"         ) , "画面ID" ) );
561                list.add( new HybsEntry( "GUI.GUICLM"      , getAttribute( "GUICLM"      ) , "画面カラムID" ) );
562                list.add( new HybsEntry( "GUI.ADDRESS"     , getAttribute( "ADDRESS"     ) , "実行アドレス" ) );
563                list.add( new HybsEntry( "GUI.REALADDRESS" , getAttribute( "REALADDRESS" ) , "実行実アドレス" ) );
564                list.add( new HybsEntry( "GUI.SEQUENCE"    , getAttribute( "SEQUENCE"    ) , "表示順" ) );
565                list.add( new HybsEntry( "GUI.GROUPS"      , getAttribute( "GROUPS"      ) , "メニュグループ" ) );
566                list.add( new HybsEntry( "GUI.CLASSIFY"    , getAttribute( "CLASSIFY"    ) , "メニュ分類" ) );
567                list.add( new HybsEntry( "GUI.LEVEL"       , getAttribute( "LEVEL"       ) , "メニュ階層番号" ) );
568                list.add( new HybsEntry( "GUI.LABEL"       , getAttribute( "LABEL"       ) , "画面名称" ) );
569                list.add( new HybsEntry( "GUI.NAME"        , getAttribute( "NAME"        ) , "画面名称(=SNAME)" ) );
570                list.add( new HybsEntry( "GUI.SNAME"       , getAttribute( "SNAME"       ) , "画面名称(short)" ) );
571                list.add( new HybsEntry( "GUI.LNAME"       , getAttribute( "LNAME"       ) , "画面名称(long)" ) );
572                list.add( new HybsEntry( "GUI.ROLES"       , getAttribute( "ROLES"       ) , "ロール" ) );
573                list.add( new HybsEntry( "GUI.MODE"        , getAttribute( "MODE"        ) , "アクセスモード列(mr,mw,-r,-w の羅列)" ) );
574                list.add( new HybsEntry( "GUI.TARGET"      , getAttribute( "TARGET"      ) , "ターゲット" ) );
575                list.add( new HybsEntry( "GUI.PARAM"       , getAttribute( "PARAM"       ) , "パラメータ" ) );
576                list.add( new HybsEntry( "GUI.KBLINK"      , getAttribute( "KBLINK"      ) , "リンク区分" ) );
577                list.add( new HybsEntry( "GUI.DESCRIPTION" , getAttribute( "DESCRIPTION" ) , "概要説明" ) );
578                list.add( new HybsEntry( "GUI.IMAGEKEY"    , getAttribute( "IMAGEKEY"    ) , "イメージキー" ) );      // 5.5.2.5 (2012/05/21)
579                list.add( new HybsEntry( "GUI.DYUPD"       , getAttribute( "DYUPD"       ) , "更新日時" ) );                // 5.3.3.0 (2011/03/01)
580                list.add( new HybsEntry( "GUI.ISREAD"      , getAttribute( "ISREAD"      ) , "読取り許可[true/false]" ) );
581                list.add( new HybsEntry( "GUI.ISWRITE"     , getAttribute( "ISWRITE"     ) , "書込み許可[true/false]" ) );
582
583                return list.toArray( new HybsEntry[list.size()] );
584        }
585
586        /**
587         * データベース検索した数と、掛かった時間(ms)を、セットします。
588         * これは、セキュリティ上の監視フラグで、不必要に、大量の
589         * データが検索された場合や、不正なデータアクセスがあるかどうかを
590         * 監視するための統計情報を取得します。
591         * 画面オブジェクトは、各ユーザー毎に作成されているため、個々の
592         * ユーザー毎/画面毎のアクセス状況を見ることが可能になります。
593         *
594         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
595         *
596         * @param  cnt データベース検索した数
597         * @param  time データベース検索した数
598         * @param  query そのときのSQL文
599         */
600        public void addReadCount( final int cnt,final long time,final String query ) {
601                accessCount.addReadCount( cnt,time,query );
602        }
603
604        /**
605         * データベース登録した数と、掛かった時間(ms)を、セットします。
606         * これは、セキュリティ上の監視フラグで、不必要に、大量の
607         * データが登録された場合や、不正なデータアクセスがあるかどうかを
608         * 監視するための統計情報を取得します。
609         * 画面オブジェクトは、各ユーザー毎に作成されているため、個々の
610         * ユーザー毎/画面毎のアクセス状況を見ることが可能になります。
611         *
612         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
613         *
614         * @param  cnt データベース登録した数
615         * @param  time データベース検索した数
616         * @param  query そのときのSQL文
617         */
618        public void addWriteCount( final int cnt,final long time,final String query ) {
619                accessCount.addWriteCount( cnt,time,query );
620        }
621
622        /**
623         * この画面へのアクセス回数を、+1します。
624         * アクセス回数は、このメソッドの呼び出し回数のことです。
625         * 現状では、result.jsp 画面でセットすることで、アクセス数を
626         * 数えることにします。
627         *
628         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
629         *
630         */
631        public void addAccessCount() {
632                if( level == 4 ) { level = 3; } // 4.0.0.0 (2007/10/30)
633                accessCount.addAccessCount();
634        }
635
636        /**
637         * エラー発生時の件数を+1します。
638         * これは、エラー発生時に呼び出すことで、エラー件数をチェックすることが
639         * 可能になります。
640         * 一般にエラーには、予期するエラー(必須入力登録漏れ等)と、予期しないエラー
641         * がありますが、ここでは、Java の Exceptionが発生する予期しないエラーの
642         * 件数をカウントします。
643         *
644         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
645         *
646         */
647        public void addErrorCount() {
648                accessCount.addErrorCount();
649        }
650
651        /**
652         * この画面のアクセス統計オブジェクトを取得します。
653         *
654         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
655         *
656         * @return      アクセス統計オブジェクト
657         */
658        public GUIAccessCount getGUIAccessCount() {
659                return accessCount;
660        }
661
662        /**
663         * この画面の次にアクセスされた画面IDをセットします。
664         *
665         * これは、画面アクセスの履歴(順番)を管理する機能を提供します。
666         * 自分自身の次にアクセスされる画面IDの集合を管理することで
667         * QUERY画面上部のショートカットリンクに、次に使用する画面の
668         * リンクを用意することが可能になります。
669         *
670         * @og.rev 5.2.3.0 (2010/12/01) アクセス履歴管理
671         *
672         * @param       guiKey  この画面の次にアクセスされた画面ID
673         */
674        public void setNextGuiKey( final String guiKey ) {
675                // 自分自身の場合は、セットしない。
676                if( guiKey != null && !guiKey.equals( getKey() ) ) {
677                        synchronized( nextGui ) {
678                                // 再挿入を避けているのは、処理時間を考慮しているだけ。意味があるかは不明。
679                                if( !nextGui.contains( guiKey ) ) {
680                                        nextGui.add( guiKey ) ;
681                                }
682                        }
683                }
684        }
685
686        /**
687         * この画面の次にアクセスされた画面IDのCSV文字列を取得します。
688         *
689         * これは、画面アクセスの履歴(順番)をカンマ区切り文字列で取り出します。
690         * アクセス履歴を外部記憶媒体に出力する場合に使用します。
691         *
692         * @og.rev 5.2.3.0 (2010/12/01) アクセス履歴管理
693         *
694         * @return      この画面の次にアクセスされた画面IDのCSV文字列
695         */
696        public String getNextGuiKeys() {
697                StringBuilder buf = new StringBuilder();
698                synchronized( nextGui ) {
699                        for( String key : nextGui ) {
700                                buf.append( key ).append( "," );
701                        }
702                }
703                return buf.toString();
704        }
705
706        /**
707         * この画面の次にアクセスされた画面IDの文字列配列で取得します。
708         *
709         * これは、画面アクセスの履歴(順番)を文字列配列で取り出します。
710         *
711         * @og.rev 5.2.3.0 (2010/12/01) アクセス履歴管理
712         *
713         * @return      この画面の次にアクセスされた画面IDの文字列配列
714         */
715        public String[] getNextGuiArray() {
716                final String[] rtnAry ;
717                synchronized( nextGui ) {
718                        rtnAry = nextGui.toArray( new String[nextGui.size()] );
719                }
720
721                return rtnAry ;
722        }
723        
724        /**
725         * 自然比較メソッド
726         * インタフェース Comparable の 実装に関連して、再定義しています。
727         * 登録されたシーケンス(画面の表示順)で比較します。
728         * equals メソッドでは、キーの同一性のみに着目して判定しています。
729         * この比較では、(運用上同一キーは発生しませんが)たとえ同一キーが存在した
730         * としても、その比較値が同じになることを保証していません。
731         *
732         * @param   other 比較対象のObject
733         *
734         * @return  このオブジェクトが指定されたオブジェクトより小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数
735         * @throws  ClassCastException 引数が GUIInfo ではない場合
736         * @throws  IllegalArgumentException 引数が null の場合
737         */
738        public int compareTo( final GUIInfo other ) {           // 4.3.3.6 (2008/11/15) Generics警告対応
739                if( other == null ) {
740                        String errMsg = "引数が、null です。" ;
741                        throw new IllegalArgumentException( errMsg );
742                }
743                return getSequence() - other.getSequence();             // 4.3.3.6 (2008/11/15) Generics警告対応
744        }
745
746        /**
747         * このオブジェクトと他のオブジェクトが等しいかどうかを示します。
748         * 画面は、画面IDが等しければ、言語や表示順に関係なく同一とみなされます。
749         * GUIInfo は、ユーザー個別に扱われ、そのグループには、key は唯一で、かつ
750         * 同一言語内で扱われるオブジェクトの為、同一とみなします。
751         *
752         * @param   object 比較対象の参照オブジェクト
753         *
754         * @return      引数に指定されたオブジェクトとこのオブジェクトが等しい場合は true、そうでない場合は false
755         */
756        @Override
757        public boolean equals( final Object object ) {
758                if( object instanceof GUIInfo ) {
759                        return getKey().equals( ((GUIInfo)object).getKey() );
760                }
761                return false ;
762        }
763
764        /**
765         * オブジェクトのハッシュコード値を返します。
766         * このメソッドは、java.util.Hashtable によって提供されるような
767         * ハッシュテーブルで使用するために用意されています。
768         * equals( Object ) メソッドをオーバーライトした場合は、hashCode() メソッドも
769         * 必ず 記述する必要があります。
770         * この実装では、getKey().hashCode() と同値を返します。
771         *
772         * @return  このオブジェクトのハッシュコード値
773         */
774        @Override
775        public int hashCode() {
776                return getKey().hashCode() ;
777        }
778
779        /**
780         * オブジェクトの識別子として,詳細な画面情報を返します。
781         *
782         * @og.rev 3.4.0.0 (2003/09/01) リンク区分(KBLINK)属性を追加。
783         * @og.rev 3.5.5.0 (2004/03/12) 実行アドレス(ADDRESS)属性を追加。
784         * @og.rev 5.3.3.0 (2011/03/01) 更新日時を追加
785         * @og.rev 5.5.2.5 (2012/05/21) IMAGEKEY 追加
786         *
787         * @return  詳細な画面情報
788         */
789        @Override
790        public String toString() {
791                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
792                rtn.append( "key        :").append( getKey()           ).append( HybsSystem.CR );       // 画面ID
793                rtn.append( "lvlclm     :").append( labelData.getKey() ).append( HybsSystem.CR );       // 画面カラムID
794                rtn.append( "address    :").append( getAddress()       ).append( HybsSystem.CR );       // 実行アドレス
795                rtn.append( "sequence   :").append( getSequence()      ).append( HybsSystem.CR );       // 表示順
796                rtn.append( "groups     :").append( getGroups()        ).append( HybsSystem.CR );       // メニュグループ
797                rtn.append( "classify   :").append( getClassify()      ).append( HybsSystem.CR );       // メニュ分類
798                rtn.append( "level      :").append( getLevel()         ).append( HybsSystem.CR );       // 階層レベル
799                rtn.append( "name       :").append( getName()          ).append( HybsSystem.CR );       // 画面名称
800                rtn.append( "longName   :").append( getLongName()      ).append( HybsSystem.CR );       // 画面名称(long)
801                rtn.append( "roles      :").append( getRoles()         ).append( HybsSystem.CR );       // ロール
802                rtn.append( "mode       :").append( getMode()          ).append( HybsSystem.CR );       // アクセスモード  "rwrwrw"
803                rtn.append( "target     :").append( getTarget()        ).append( HybsSystem.CR );       // ターゲット
804                rtn.append( "kblink     :").append( getKblink()        ).append( HybsSystem.CR );       // リンク区分
805                rtn.append( "description:").append( getDescription()   ).append( HybsSystem.CR );       // 概要説明
806                rtn.append( "imageKey   :").append( getImageKey()      ).append( HybsSystem.CR );       // イメージキー 5.5.2.5 (2012/05/21)
807                rtn.append( "dyupd      :").append( getDyupd()         ).append( HybsSystem.CR );       // 更新日時
808                return rtn.toString();
809        }
810}