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