    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.taglib;
    017
    018import org.opengion.hayabusa.common.HybsSystem;
    019import org.opengion.hayabusa.common.HybsSystemException;
    020import org.opengion.hayabusa.resource.GUIInfo;
    021import org.opengion.hayabusa.resource.UserInfo;
    022import org.opengion.hayabusa.resource.CodeData;
    023import org.opengion.hayabusa.resource.FavoriteGUIData;
    024import org.opengion.hayabusa.resource.ResourceManager;
    025import org.opengion.fukurou.util.XHTMLTag;
    026import org.opengion.fukurou.util.FileMap;
    027import org.opengion.fukurou.util.TagBuffer;
    028import org.opengion.fukurou.util.ToString;                                                      // 6.1.1.0 (2015/01/17)
    029import org.opengion.fukurou.util.StringUtil ;
    030import org.opengion.fukurou.util.ArraySet;                                                      // 6.4.3.4 (2016/03/11)
    031
    032import org.opengion.fukurou.system.OgBuilder ;                                          // 6.4.4.1 (2016/03/18)
    033import static org.opengion.fukurou.util.StringUtil.nval ;
    034import static org.opengion.fukurou.system.HybsConst.BUFFER_LARGE;       // 6.1.0.0 (2014/12/26) refactoring
    035import static org.opengion.fukurou.system.HybsConst.BR;                         // 6.1.0.0 (2014/12/26) refactoring
    036
    037import java.util.Set ;
    038import java.util.LinkedHashSet;
    039import java.util.TreeSet;                                                                                       // 6.8.3.1 (2017/12/01)
    040import java.util.Iterator;
    041import java.util.Map;
    042
    043/**
    044 * 画面アクセスメニューを作成します。
    045 *
    046 * 画面リソースの階層番号(レベル)は、
    047 * 　0:グループ分類メニュー(class="GUI_GRP"のtdタグで囲われます)
    048 * 　1:トップ階層(【分類名称】)
    049 * 　2:選択階層(通常の折りたたみメニュー)
    050 * 　3:選択非表示(通常は、隠してあります)
    051 * です。
    052 * お気に入りメニューを登録するキーワードに、HybsSystem.GUI_FAV_MENU_KEY を使用しています。
    053 * これは、エンジン内部で使用しているキーワードです。
    054 *
    055 * ※ 6.9.4.1 (2018/04/09) HYBS_BR の廃止
    056 *    以前から、画面メニューを少し空けるために、HYBS_BR が使われていましたが、廃止しました。
    057 *
    058 * @og.formSample
    059 * ●形式：&lt;og:topMenu /&gt;
    060 * ●body：なし
    061 *
    062 * ●Tag定義：
    063 *   &lt;og:topMenu
    064 *       menuType           【TAG】作成するメニューの種類(NORMAL,GROUP,ONELEVEL,NEXTGUI,MATRIX,MATRIX2,NONE,TILE)を指定します(初期値:NORMAL)
    065 *       expand             【TAG】折り返しメニューを構築するかどうかを指定します(初期値:true)
    066 *       groups             【TAG】表示対象となるグループをCSV形式で指定します
    067 *       classify           【TAG】表示対象となる分類(classify)を指定します
    068 *       href               【TAG】グループメニューの表示対象となるソース名(href)を指定します(初期値:menu.jsp)
    069 *       target             【TAG】グループメニューの表示対象となるフレーム名(target)を指定します(初期値:MENU)
    070 *       imageOnly          【TAG】グループメニューの表示に、画像のみかどうか[true:画像のみ/false:画像＋ラベル]を指定します(初期値:false)
    071 *       sideCount          【TAG】グループメニューの表示対象となるメニューを横並びさせる数を指定します
    072 *       minCellCount       【TAG】表形式メニュー(MATRIX)の一つのセルに含まれる最小行数を指定します(初期値:8)
    073 *       maxCellCount       【TAG】表形式メニュー(MATRIX)の一つのセルに含まれる最大行数を指定します(初期値:8)
    074 *       cache              【TAG】グループメニューのキャッシュを使用するかどうか[true/false]を指定します(初期値:true)
    075 *       match              【TAG】正判定(マッチする場合に、メニューに出す)条件を設定します
    076 *       unmatch            【TAG】逆判定(マッチする場合に、メニューに出さない)条件を設定します
    077 *       useButton          【TAG】画面リンクにボタンを使用するかどうか[true/false]を指定します(初期値:false)
    078 *       buttonRequest      【TAG】マトリクスからの遷移先でボタンメニュー表示するかどうか[true/false]を指定します(初期値:false)
    079 *       inlineStyle        【TAG】標準画面を初期状態で表示するかどうか[true/false]を指定します(初期値:false)
    080 *       useDivOneLevel     【TAG】ONELEVEL,NEXTGUI で、DIVタグ＋design-onelevel 処理をするかどうか[true/false]を指定します(初期値:false)
    081 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
    082 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
    083 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
    084 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
    085 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
    086 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    087 *   &gt;   ... Body ...
    088 *   &lt;/og:topMenu&gt;
    089 *
    090 * ●使用例
    091 *    &lt;og:topMenu /&gt;
    092 *
    093 *    &lt;og:topMenu
    094 *          menuType     = "NORMAL"      NORMAL:通常 / GROUP:グループメニュー / ONELEVEL:１レベル / NEXTGUI:次アクセス先
    095 *                                           / MATRIX:一覧表メニュー / MATRIX2:一覧表メニュー(大分類なし版) / NONE:表示しない / TILE:タイル表示
    096 *          expand       = "true"        true:折り返しメニュー / false:階層メニュー
    097 *          groups       = "AA,BB,CC"    表示対象となるグループをCSV形式で指定します。
    098 *          classify     = "ABC"         表示対象となる分類を指定します。
    099 *          href         = "menu.jsp"    グループメニューの対象ソース名(href)を指定します。
    100 *          target       = "MENU"        グループメニューの対象フレーム名(target)を指定します。
    101 *          imageOnly    = "false"       グループメニューに、 true:画像のみ / false:画像＋ラベル を指定します。
    102 *          sideCount    = "6"           グループメニューの表示対象となるメニューを横並びさせる数を指定します。
    103 *          minCellCount = "8"           表形式メニューの１セルの最小行数を指定します。
    104 *          maxCellCount = "8"           表形式メニューの１セルの最大行数を指定します。
    105 *          cache        = "true"        グループメニューのキャッシュを使用するかどうか指定します。
    106 *          match        = "正規表現"    正判定(マッチする場合に、メニューに出す)条件を設定します。
    107 *          unmatch      = "正規表現"    逆判定(マッチする場合に、メニューに出さない)条件を設定します。
    108 *          useButton    = "false"       ボタン形式のリンクを使用するかを指定します。
    109 *          useDivOneLevel  = "false"    ONELEVEL,NEXTGUI で、DIVタグ＋design-onelevel 処理をするかどうかを指定します。
    110 *    /&gt;
    111 *
    112 * @og.rev 3.5.5.3 (2004/04/09) 新規作成
    113 * @og.group メニュー制御
    114 *
    115 * @version  4.0
    116 * @author   Kohei Naruse
    117 * @since    JDK5.0,
    118 */
    119public class TopMenuTag extends CommonTagSupport {
    120        /** このプログラムのVERSION文字列を設定します。   {@value} */
    121        private static final String VERSION = "7.2.9.4 (2020/11/20)" ;
    122        private static final long serialVersionUID = 729420201120L ;
    123
    124        private static final String FIELD_IN  = "<fieldset style=\"display:inline;\">";
    125        private static final String FIELD_OUT = "</fieldset>" + BR;
    126//      private static final String JSP          = HybsSystem.sys( "JSP" );
    127//      private static final String CNTX         = HybsSystem.sys( "CONTEXT_NAME" );    // 5.5.4.2 (2012/07/13) META-INF/resources 対応
    128        private static final String MENU_IMG = "/jsp/menuImage/" ;                                      // 5.5.4.2 (2012/07/13) META-INF/resources 対応
    129
    130        // 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
    131//      private boolean multiSessionCheck = HybsSystem.sysBool( "USE_MULTI_SESSION_CHECK" );
    132
    133        // 6.7.5.0 (2017/03/10) TILE表示追加
    134        private static final Set<String> MENU_TYPE_SET = new ArraySet<>( "NORMAL","GROUP","ONELEVEL","NEXTGUI","MATRIX","MATRIX2","NONE","TILE" );
    135
    136        private String   menuType       = "NORMAL" ;            // NORMAL,GROUP,ONELEVEL,NEXTGUI,MATRIX,MATRIX2,NONE,TILE
    137        private boolean  expand         = true;                         // true:折り返しメニュー / false:階層メニュー
    138        private String[] groups         ;                                       // 表示対象となるグループをCSV形式で指定します。
    139        private String   selClassify;                                   // 表示対象となる分類を指定します。
    140        private String   href           = "menu.jsp";           // グループメニューの対象ソース名(href)を指定します。
    141        private String   target         = "MENU";                       // グループメニューの対象フレーム名(target)を指定します。
    142        private boolean  imageOnly      ;                                       // グループメニューに、 true:画像のみ / false:画像＋ラベル を指定します
    143        private int      sideCount      = -1;                           // 5.2.3.0 (2010/12/01) 表示対象となるメニューを横並びさせる数を指定します。
    144        private int      minCellCount   = 8;                    // 表形式メニューの１セルの最小行数を指定します。
    145        private int      maxCellCount   = 8;                    // 表形式メニューの１セルの最大行数を指定します。
    146        private boolean  cache          = true;                         // グループメニューのキャッシュを使用するかどうか指定します。
    147        // 3.8.8.7 (2007/05/01) メニューの表示条件指定追加
    148        private String match            ;                                       // 正判定(マッチする場合に、メニューに出す)条件を設定
    149        private String unmatch          ;                                       // 逆判定(マッチする場合に、メニューに出さない)条件を設定
    150        private String imageDir         = MENU_IMG;                     // 6.7.5.0 (2017/03/10) TILE表示追加
    151
    152        private final transient FileMap imgFileMap = new FileMap() ;            // 6.3.9.0 (2015/11/06) helpMapの初期化を、initメソッドに変更する。
    153
    154        private final String JSP         = HybsSystem.sys( "JSP" );                             // 6.9.9.3 (2018/09/25) JavaDoc ｴﾗｰ対応
    155
    156        // MULTI_SESSION_CHECK 時のリンクに付加する情報
    157        private String  mscKey          ;
    158
    159        private boolean  useButton              ;                               // ボタン形式のリンクを使用するか 4.2.1.0 (2008/04/01)
    160        private boolean  buttonRequest  ;                               // マトリクス２からの遷移でボタン形式にするかのリクエスト変数 4.2.1.0 (2008/04/17)
    161        private boolean  excludeButton  ;                               // 4.3.3.0 (2008/10/01) ボタンメニューの場合でも強制的に従来のプルダウンにします。
    162        private boolean  inlineStyle    ;                               // 4.3.3.0 (2008/10/01) trueでLv3の画面にstyle属性でinlineを付加
    163
    164        private boolean  useDivOneLevel ;                               // 5.5.2.3 (2012/05/15) ONELEVEL,NEXTGUI で、DIVタグ＋design-onelevel 処理をするかどうかを指定します。
    165
    166        /**
    167         * デフォルトコンストラクター
    168         *
    169         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    170         */
    171        public TopMenuTag() { super(); }                // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    172
    173        /**
    174         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    175         *
    176         * @og.rev 4.0.0.0 (2007/10/31) 1レベルメニューの見直し
    177         * @og.rev 4.2.1.0 (2008/04/01) マトリクスメニュー2追加
    178         * @og.rev 5.2.3.0 (2010/12/01) NEXTGUI 追加
    179         * @og.rev 5.3.0.0 (2010/11/22) NEXTGUI もマルチセッションチェックをしない。
    180         * @og.rev 5.3.9.0 (2011/09/01) メニューでのヘルプアイコン対応
    181         * @og.rev 5.5.0.4 (2012/03/12) FAQ表示対応
    182         * @og.rev 5.5.2.5 (2012/05/21) FAQ対応 廃止
    183         * @og.rev 5.5.4.2 (2012/07/13) META-INF/resources からの読み取り対応
    184         * @og.rev 6.3.8.3 (2015/10/03) NONE(表示しない) 追加。
    185         * @og.rev 6.3.8.4 (2015/10/09) topMenu 内でのHelp機能を廃止します。
    186         * @og.rev 6.3.8.4 (2015/10/09) FileMap のコンストラクタ変更に伴う対応。
    187         * @og.rev 6.3.9.0 (2015/11/06) helpMapの初期化を、initメソッドに変更する。
    188         * @og.rev 6.7.5.0 (2017/03/10) TILE表示追加(imageDir 属性追加)
    189         * @og.rev 6.9.4.0 (2018/04/02) caseKey 、caseVal 属性対応
    190         * @og.rev 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
    191         * @og.rev 6.9.5.0 (2018/04/23) 6.9.9.3 (2018/09/25) JavaDoc ｴﾗｰ対応
    192         *
    193         * @return      後続処理の指示
    194         */
    195        @Override
    196        public int doEndTag() {
    197                debugPrint();           // 4.0.0 (2005/02/28)
    198                if( useTag() ) {                // 6.9.4.0 (2018/04/02) caseKey 、caseVal 属性対応
    199
    200                        // 6.3.8.3 (2015/10/03) NONE(表示しない) 追加。
    201                        if( "NONE".equals( menuType ) ) { return EVAL_PAGE; }
    202
    203                        // Ver 4.0.0 2007/09/04
    204                        // ONELEVEL, NEXTGUI の場合は、multiSessionCheck を行いません。
    205//                      if( multiSessionCheck && !"ONELEVEL".equals( menuType ) && !"NEXTGUI".equals( menuType ) ) {
    206                        if( !"ONELEVEL".equals( menuType ) && !"NEXTGUI".equals( menuType ) ) {                                                 // 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
    207                                final String cnt = (String)getSessionAttribute( HybsSystem.MULTI_SESSION_CHECK );
    208                                if( cnt == null ) {
    209                                        final String errMsg = "マルチセッションチェックのキーが存在しません。"
    210                                                                + "topMenu タグを実行する前に、必ず jspInit タグを"
    211                                                                + "実行しておいてください。" ;
    212                                        jspPrint( errMsg );
    213                                        return SKIP_PAGE ;              // ページの残りの処理を行わない。
    214                                }
    215                                mscKey = HybsSystem.MULTI_SESSION_CHECK + "=" + cnt ;
    216                        }
    217
    218                        // 6.7.5.0 (2017/03/10) TILE表示追加(imageDir 属性追加)
    219                        final Set<?> set = pageContext.getServletContext().getResourcePaths( imageDir );
    220                        // 6.3.8.4 (2015/10/09) FileMap のコンストラクタ変更に伴う対応。
    221                        // 6.3.9.0 (2015/11/06) helpMapの初期化を、initメソッドに変更する。
    222//                      imgFileMap.init( imageDir , "/" + CNTX + imageDir , set );
    223                        imgFileMap.init( imageDir , "/" + HybsSystem.getContextName() + imageDir , set );               // 6.9.9.3 (2018/09/25) JavaDoc ｴﾗｰ対応
    224
    225                        if( "NORMAL".equals( menuType ) ) {
    226                                jspPrint( "<div class=\"forpos\" id=\"dummy\"></div>" + CR );
    227                                if( ! useButton ){ // 4.2.1.0 (2008/04/26) ボタン時にはお気に入りを出さない
    228                                        jspPrint( makeFavoriteMenu() );
    229                                }
    230                                jspPrint( makeMenu() );
    231                        }
    232                        else if( "GROUP".equals( menuType ) ) {
    233                                jspPrint( makeGroupMenu() );
    234                        }
    235                //      else if( "CLASSIFY".equals( menuType ) ) {
    236                //              jspPrint( makeClassifyMenu() );
    237                //      }
    238                        else if( "ONELEVEL".equals( menuType ) && selClassify != null ) {
    239                                jspPrint( makeOneLevelMenu() );
    240                        }
    241                        // 5.2.3.0 (2010/12/01) NEXTGUI 追加
    242                        else if( "NEXTGUI".equals( menuType ) ) {
    243                                jspPrint( makeNextguiMenu() );
    244                        }
    245                        else if( "MATRIX".equals( menuType ) ) {
    246                                jspPrint( makeMatrixMenu() );
    247                        }
    248                        else if( "MATRIX2".equals( menuType ) ) {       // 4.2.1.0 (2008/04/01) 大分類なし版追加
    249                                jspPrint( makeMatrixMenu2() );
    250                        }
    251                        else if( "TILE".equals( menuType ) ) {          // 6.7.5.0 (2017/03/10) TILE表示追加
    252                                jspPrint( makeTileMenu() );
    253                        }
    254                //      else {
    255                //              jspPrint( "menuType が想定外です。menuType=[" + menuType + "]" );
    256                //      }
    257                }
    258
    259                return EVAL_PAGE ;              // ページの残りを評価する。
    260        }
    261
    262        /**
    263         * タグリブオブジェクトをリリースします。
    264         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    265         *
    266         * @og.rev 5.2.3.0 (2010/12/01) sideCountの初期値を -1(無制限)に変更
    267         * @og.rev 5.3.9.0 (2011/09/01) メニューでのヘルプアイコン対応
    268         * @og.rev 5.5.2.3 (2012/05/15) ONELEVEL,NEXTGUI で、DIVタグ＋design-onelevel 処理をするかどうかを指定します。
    269         * @og.rev 6.3.8.4 (2015/10/09) topMenu 内でのHelp機能を廃止します。
    270         * @og.rev 6.3.9.0 (2015/11/06) helpMapの初期化を、initメソッドに変更する。
    271         * @og.rev 6.7.5.0 (2017/03/10) TILE表示追加(imageDir 属性追加)
    272         * @og.rev 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
    273         */
    274        @Override
    275        protected void release2() {
    276                super.release2();
    277                expand                          = true;
    278                menuType                        = "NORMAL";
    279                groups                          = null;
    280                selClassify                     = null;
    281//              multiSessionCheck       = HybsSystem.sysBool( "USE_MULTI_SESSION_CHECK" );
    282                href                            = "menu.jsp";           // グループメニューの対象ソース名(href)を指定します。
    283                imageOnly                       = false;                        // グループメニューに、 true:画像のみ / false:画像＋ラベル を指定します
    284                target                          = "MENU";                       // グループメニューの対象フレーム名(target)を指定します。
    285                sideCount                       = -1;                           // 5.2.3.0 (2010/12/01) 表示対象となるメニューを横並びさせる数を指定します。
    286                minCellCount            = 8;                            // 表形式メニューの１セルの最小行数を指定します。
    287                maxCellCount            = 8;                            // 表形式メニューの１セルの最大行数を指定します。
    288                mscKey                          = null;                         // MULTI_SESSION_CHECK 時のリンクに付加する情報
    289                imgFileMap.clear();                                             // 6.3.9.0 (2015/11/06) helpMapの初期化を、initメソッドに変更する。
    290                cache                           = true;                         // グループメニューのキャッシュを使用するかどうか指定します。
    291                match                           = null;                         // 正判定(マッチする場合に、メニューに出す)条件を設定
    292                unmatch                         = null;                         // 逆判定(マッチする場合に、メニューに出さない)条件を設定
    293                imageDir                        = MENU_IMG;                     // 6.7.5.0 (2017/03/10) TILE表示追加
    294                useButton                       = false;                        // ボタン形式のリンクを使用するか
    295                buttonRequest           = false;                        // trueでボタンメニューの表示を行う
    296                excludeButton           = false;                        // trueでボタンメニュー時でも強制的に従来のプルダウンにする。
    297                inlineStyle                     = false;                        // trueの場合は標準画面(Lv3)にdisplay:inlineを付加
    298                useDivOneLevel          = false;                        // 5.5.2.3 (2012/05/15) ONELEVEL,NEXTGUI で、DIVタグ＋design-onelevel 処理をするかどうかを指定します。
    299        }
    300
    301        /**
    302         * メニューを表示する為のHTMLを作成します(折り返しJavaScript対応版)。
    303         *
    304         * @og.rev 3.5.6.5 (2004/08/09) GUIInfo の comments 属性を title にセットする。
    305         * @og.rev 3.6.0.9 (2004/12/03) リアルアドレス設定時に、{&#064;XXXX}処理を追加
    306         * @og.rev 3.8.0.0 (2005/06/07) 同一セッションでのマルチ起動対策を行います。
    307         * @og.rev 4.0.0.0 (2005/01/31) GUIInfoの実アドレスのパラメータを考慮する。
    308         * @og.rev 4.0.0.0 (2007/10/31) 分類の廃止に伴い、全面見直し
    309         * @og.rev 4.2.1.0 (2008/04/01) 小分類指定での表示対応(↑の対応での再実装漏れ)
    310         * @og.rev 4.2.1.0 (2008/04/11) 小分類をexpandしない場合にはspanタグで囲う。
    311         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
    312         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止 , gamenId の変数設定
    313         *
    314         * @return  メニュー
    315         * @og.rtnNotNull
    316         */
    317        private String makeMenu() {
    318                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
    319
    320                final UserInfo userInfo = getUser();
    321
    322                // 4.0.0 (2005/01/31)
    323
    324                final GUIInfo[] guiInfos = userInfo.getGUIInfos();
    325//              String gamenId          ;                       // 画面ID
    326                int menuNo = 11;
    327                int kmokuNo = 0;
    328
    329                boolean isInFieldset    = false;                // 大分類の中か？
    330                boolean isInClassify    = false;                // 小分類の中か？
    331                boolean isHiddenMenu    = false;                // 隠しメニューが存在するか？        6.0.2.5 (2014/10/31) refactoring
    332                boolean isClassHidden   = false;                // 分類隠しが存在するか？          6.0.2.5 (2014/10/31) refactoring
    333                int level ;
    334                int preLevel = 0;
    335
    336                for( int i=0; i<guiInfos.length; i++ ) {
    337                        if( guiInfos[i].isRead() ) {            // 4.0.0 (2005/01/31)
    338                                final String gamenId = guiInfos[i].getKey() ;
    339
    340//                              if( match   != null && !gamenId.matches( match  ) ) { continue; }
    341//                              if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
    342                                // 6.9.7.0 (2018/05/14) PMD
    343                                if(             match  != null && !gamenId.matches( match )
    344                                        || unmatch != null && gamenId.matches( unmatch ) ) { continue; }
    345
    346                                // 4.2.1.0 (2008/04/01)
    347                                // 6.9.7.0 (2018/05/14) PMD These nested if statements could be combined
    348//                              if( selClassify != null ) {
    349////                                    if( !selClassify.equals( guiInfos[i].getKey() ) && !selClassify.equals( guiInfos[i].getClassify() ) ) {
    350//                                      if( !selClassify.equals( gamenId ) && !selClassify.equals( guiInfos[i].getClassify() ) ) {
    351                                if( selClassify != null && !selClassify.equals( gamenId ) && !selClassify.equals( guiInfos[i].getClassify() ) ) {
    352                                                continue; // 分類(classify) に含まれない
    353//                                      }
    354                                }
    355
    356                                // 処理すべき画面かのチェック
    357                                final int guiFlg = guiCheck( guiInfos, i );
    358                                if( guiFlg == 0 ) { continue; }
    359
    360                                level = guiInfos[i].getLevel();         // 4.0.0 (2005/01/31)
    361
    362                                // 隠しメニュー展開用
    363                                if( preLevel >= 3 && level < 3 ) {
    364                                        if( isHiddenMenu ) {                    // 6.0.2.5 (2014/10/31) refactoring
    365                                                rtn.append( makeEllipses( menuNo,kmokuNo,3 ) );
    366                                                kmokuNo++;
    367                                        }
    368                                        isHiddenMenu = false;                   // 6.0.2.5 (2014/10/31) refactoring
    369                                }
    370
    371                                // 大分類(フィールドメニュー)
    372                                if( level == 1 ) {
    373                                        if( isInFieldset ) {
    374                                                rtn.append( FIELD_OUT )
    375                                                        .append( "</div>" );
    376                                        }
    377                                        isInFieldset = true;
    378
    379                                        // 隠しメニュー用
    380                                        if( expand ) {
    381                                                rtn.append( "<div class=\"expand1 " );
    382
    383                                                if( guiFlg == 1 ) {
    384                                                        rtn.append( "unpopular ");
    385                                                }
    386
    387                                                rtn.append( "\">" );
    388                                        }
    389                                        rtn.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),level ) );           // 5.5.2.5 (2012/05/21) イメージアイコン対応
    390
    391                                        isInClassify = false;
    392                                }
    393                                // 小分類・直リンク
    394                                else if( level == 2 ) {
    395                                        menuNo++;
    396                                        kmokuNo = 0;
    397                                        if( expand ) {
    398                                                rtn.append( "<div class=\"expand1 " );
    399
    400                                                // 隠しメニュー用
    401                                                if( guiFlg == 1 ) {
    402                                                        rtn.append( "unpopular " );
    403                                                        isClassHidden = true;                   // 6.0.2.5 (2014/10/31) refactoring
    404                                                }
    405
    406                                                // rtn.append( "\" id=\"menu" + menuNo + "\">" );
    407                                                // 4.3.3.0 (2008/10/01) useButton=true時は表示しない
    408                                                rtn.append( "\" id=\"menu" + menuNo + "\" ");
    409                                                if( useButton ){
    410                                                        rtn.append( "style=\"display:none\"");
    411                                                }
    412                                                rtn.append( '>');               // 6.0.2.5 (2014/10/31) char を append する。
    413                                        }
    414                                        else{   // 4.2.1.0 (2008/04/11)expandしない場合にはspan要素で囲ってnon-expandクラスを指定。
    415                                                rtn.append( "<span class=\"non-expand\">" );
    416                                        }
    417
    418                                        rtn.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),level ) );           // 5.5.2.5 (2012/05/21) イメージアイコン対応
    419                                        rtn.append( BR );
    420                                        if( expand ) {
    421                                                rtn.append( "</div>" );
    422                                        }
    423                                        else{   // 4.2.1.0 (2008/04/11)
    424                                                rtn.append( "</span>");
    425                                        }
    426
    427                                        isInClassify = true;
    428                                }
    429                                // 通常メニュー・隠しメニュー
    430                                // 6.9.7.0 (2018/05/14) PMD These nested if statements could be combined
    431//                              else if( level >= 3 ) {
    432//                                      if( isInClassify ) {
    433                                else if( level >= 3 && isInClassify ) {
    434                                                if( expand ) {
    435                                                        rtn.append( "<div class=\"expand2 " );
    436
    437                                                        // 隠しメニュー用
    438                                                        if( level == 4 ) {
    439                                                                rtn.append( "unpopular " );
    440                                                                isHiddenMenu = true;                    // 6.0.2.5 (2014/10/31) refactoring
    441                                                        }
    442
    443                                                        // rtn.append( "\" id=\"menu" + menuNo + "_" + kmokuNo + "\">" );
    444                                                        // 4.3.3.0 (2008/10/01) メニューを初期状態で開けるようにする
    445                                                        // 6.0.2.5 (2014/10/31) char を append する。
    446                                                        rtn.append( "\" id=\"menu" ).append( menuNo ).append( '_' ).append( kmokuNo ).append( "\" " );
    447                                                        if( inlineStyle && level == 3 ) {
    448                                                                rtn.append( " style=\"display:inline\"" );
    449                                                        }
    450                                                        rtn.append( '>' );              // 6.0.2.5 (2014/10/31) char を append する。
    451                                                }
    452                        //                      // 6.9.4.1 (2018/04/09) HYBS_BR 対応
    453                        //                      if( "HYBS_BR".equals( guiInfos[i].getAddress() ) ) {
    454                        //                              rtn.append( BR );
    455                        //                      }
    456                        //                      else {
    457//                      //                      // 画面IDが"HYBS_BR"の時は処理しない
    458//                      //                      if( !"HYBS_BR".equals( guiInfos[i].getKey() ) ) {
    459                                                        rtn.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),level ) );           // 5.5.2.5 (2012/05/21) イメージアイコン対応
    460                        //                      }
    461                                                rtn.append( BR );
    462                                                if( expand ) {
    463                                                        rtn.append( "</div>" );
    464                                                }
    465                                                kmokuNo++;
    466//                                      }
    467                                }
    468
    469                                rtn.append( CR );
    470
    471                                preLevel = level;
    472                        }
    473                }
    474
    475                // 終了処理
    476                if( isHiddenMenu ) {                                                                            // 6.0.2.5 (2014/10/31) refactoring
    477                        rtn.append( makeEllipses( menuNo,kmokuNo,3 ) );
    478                }
    479
    480                if( isInFieldset ) {
    481                        rtn.append( FIELD_OUT );
    482                        rtn.append( "</div>" );
    483                }
    484
    485                if( isClassHidden ) {                                                                           // 6.0.2.5 (2014/10/31) refactoring
    486                        rtn.append( makeEllipses( menuNo,0,2 ) );
    487                }
    488
    489                return rtn.toString();
    490        }
    491
    492        /**
    493         * TILEメニューを表示する為のHTMLを作成します(折り返しJavaScript対応版)。
    494         *
    495         * @og.rev 6.7.5.0 (2017/03/10) TILE表示追加
    496         * @og.rev 6.9.4.0 (2018/04/02) HYBS_BR(ブレイク)の条件を緩める。
    497         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止 , gamenId の変数設定
    498         *
    499         * @return  メニュー
    500         * @og.rtnNotNull
    501         */
    502        private String makeTileMenu() {
    503                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
    504
    505                final UserInfo userInfo = getUser();
    506
    507                // 4.0.0 (2005/01/31)
    508
    509                final GUIInfo[] guiInfos = userInfo.getGUIInfos();
    510//              String gamenId          ;                       // 画面ID
    511                int menuNo = 11;
    512                int kmokuNo = 0;
    513
    514                boolean isInFieldset    = false;                // 大分類の中か？
    515                boolean isInClassify    = false;                // 小分類の中か？
    516                boolean isHiddenMenu    = false;                // 隠しメニューが存在するか？        6.0.2.5 (2014/10/31) refactoring
    517                boolean isClassHidden   = false;                // 分類隠しが存在するか？          6.0.2.5 (2014/10/31) refactoring
    518                int level ;
    519                int preLevel = 0;
    520
    521                String hybsBR = "";                                             // 6.7.5.0 (2017/03/10)
    522                for( int i=0; i<guiInfos.length; i++ ) {
    523                        if( guiInfos[i].isRead() ) {            // 4.0.0 (2005/01/31)
    524                                final String gamenId = guiInfos[i].getKey() ;
    525                                if( match   != null && !gamenId.matches( match  ) ) { continue; }
    526                                if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
    527
    528                                // 4.2.1.0 (2008/04/01)
    529                                // 6.9.7.0 (2018/05/14) PMD These nested if statements could be combined
    530//                              if( selClassify != null ) {
    531//                                      if( !selClassify.equals( gamenId ) && !selClassify.equals( guiInfos[i].getClassify() ) ) {
    532                                if( selClassify != null && !selClassify.equals( gamenId ) && !selClassify.equals( guiInfos[i].getClassify() ) ) {
    533                                                continue; // 分類(classify) に含まれない
    534//                                      }
    535                                }
    536
    537                                // 6.9.4.0 (2018/04/02) HYBS_BR(ブレイク)の条件を緩める。
    538                                if( isInFieldset && isInClassify && "HYBS_BR".equals( guiInfos[i].getAddress() ) ) {            // 6.7.5.0 (2017/03/10)
    539//                              if( "HYBS_BR".equals( gamenId ) ) {                                                                             // 6.9.4.0 (2018/04/02)
    540                                        hybsBR = "</tr><tr>" ;
    541                                }
    542
    543                                // 処理すべき画面かのチェック
    544                                final int guiFlg = guiCheck( guiInfos, i );
    545                                if( guiFlg == 0 ) { continue; }
    546
    547                                level = guiInfos[i].getLevel();         // 4.0.0 (2005/01/31)
    548
    549                                // 隠しメニュー展開用
    550                                if( preLevel >= 3 && level < 3 ) {
    551                                        if( isHiddenMenu ) {                    // 6.0.2.5 (2014/10/31) refactoring
    552                                                rtn.append( makeEllipses( menuNo,kmokuNo,3 ) );
    553                                                kmokuNo++;
    554                                        }
    555                                        isHiddenMenu = false;                   // 6.0.2.5 (2014/10/31) refactoring
    556                                }
    557
    558                                // 大分類(フィールドメニュー)
    559                                if( level == 1 ) {
    560                                        if( isInFieldset ) {
    561                                                rtn.append( "</td></tr></table>" )              // 6.7.5.0 (2017/03/10)
    562                                                        .append( FIELD_OUT )
    563                                                        .append( "</div>" );
    564                                        }
    565                                        isInFieldset = true;
    566
    567                                        // 隠しメニュー用
    568                                        if( expand ) {
    569                                                rtn.append( "<div class=\"expand1 " );
    570
    571                                                if( guiFlg == 1 ) {
    572                                                        rtn.append( "unpopular ");
    573                                                }
    574                                                rtn.append( "\">" );
    575                                        }
    576                                        rtn.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),level ) )            // 5.5.2.5 (2012/05/21) イメージアイコン対応
    577                                                .append( "<table><tr>" );               // 6.7.5.0 (2017/03/10)
    578
    579                                        isInClassify = false;
    580                                }
    581                                // 小分類・直リンク
    582                                else if( level == 2 ) {
    583                                        menuNo++;
    584                                        kmokuNo = 0;
    585                                        if( expand ) {
    586                                                if( isInFieldset ) {            // 6.7.5.0 (2017/03/10)
    587                                                        if( isInClassify ) {
    588                                                                rtn.append( "</td>" ).append( hybsBR ).append( "<td>" );
    589                                                                hybsBR = "";
    590                                                        }
    591                                                        else {
    592                                                                rtn.append( "<td>" );
    593                                                        }
    594                                                }
    595                                                rtn.append( "<div class=\"expand1 " );
    596
    597                                                // 隠しメニュー用
    598                                                if( guiFlg == 1 ) {
    599                                                        rtn.append( "unpopular " );
    600                                                        isClassHidden = true;                   // 6.0.2.5 (2014/10/31) refactoring
    601                                                }
    602
    603                                                // rtn.append( "\" id=\"menu" + menuNo + "\">" );
    604                                                // 4.3.3.0 (2008/10/01) useButton=true時は表示しない
    605                                                rtn.append( "\" id=\"menu" + menuNo + "\" ");
    606                                                if( useButton ){
    607                                                        rtn.append( "style=\"display:none\"");
    608                                                }
    609                                                rtn.append( '>');               // 6.0.2.5 (2014/10/31) char を append する。
    610                                        }
    611                                        else{   // 4.2.1.0 (2008/04/11)expandしない場合にはspan要素で囲ってnon-expandクラスを指定。
    612                                                rtn.append( "<span class=\"non-expand\">" );
    613                                        }
    614
    615                                        rtn.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),-6 ) );                      // 6.7.5.0 (2017/03/10) TILE表示
    616                                        rtn.append( BR );
    617                                        if( expand ) {
    618                                                rtn.append( "</div>" );
    619                                        }
    620                                        else{   // 4.2.1.0 (2008/04/11)
    621                                                rtn.append( "</span>");
    622                                        }
    623
    624                                        isInClassify = true;
    625                                }
    626                                // 通常メニュー・隠しメニュー
    627                                // 6.9.7.0 (2018/05/14) PMD These nested if statements could be combined
    628//                              else if( level >= 3 ) {
    629//                                      if( isInClassify ) {
    630                                else if( level >= 3 && isInClassify ) {
    631                                                if( expand ) {
    632                                                        rtn.append( "<div class=\"expand2 " );
    633
    634                                                        // 隠しメニュー用
    635                                                        if( level == 4 ) {
    636                                                                rtn.append( "unpopular " );
    637                                                                isHiddenMenu = true;                    // 6.0.2.5 (2014/10/31) refactoring
    638                                                        }
    639
    640                                                        // rtn.append( "\" id=\"menu" + menuNo + "_" + kmokuNo + "\">" );
    641                                                        // 4.3.3.0 (2008/10/01) メニューを初期状態で開けるようにする
    642                                                        // 6.0.2.5 (2014/10/31) char を append する。
    643                                                        rtn.append( "\" id=\"menu" ).append( menuNo ).append( '_' ).append( kmokuNo ).append( "\" " );
    644                                                        if( inlineStyle && level == 3 ) {
    645                                                                rtn.append( " style=\"display:inline\"" );
    646                                                        }
    647                                                        rtn.append( '>' );              // 6.0.2.5 (2014/10/31) char を append する。
    648                                                }
    649
    650                        //                      // 6.9.4.1 (2018/04/09) HYBS_BR 対応
    651                        //                      if( "HYBS_BR".equals( guiInfos[i].getAddress() ) ) {                                    // 6.9.4.1 (2018/04/09) HYBS_BR は、アドレスに設定
    652                        //                              rtn.append( BR );
    653                        //                      }
    654                        //                      else {
    655//                      //                      // 画面IDが"HYBS_BR"の時は処理しない
    656//                      //                      if( !"HYBS_BR".equals( gamenId ) ) {
    657                                                        rtn.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),level ) );           // 5.5.2.5 (2012/05/21) イメージアイコン対応
    658                        //                      }
    659                                                rtn.append( BR );
    660                                                if( expand ) {
    661                                                        rtn.append( "</div>" );
    662                                                }
    663                                                kmokuNo++;
    664//                                      }
    665                                }
    666
    667                                rtn.append( CR );
    668                                preLevel = level;
    669                        }
    670                }
    671
    672                // 終了処理
    673                if( isHiddenMenu ) {                                                                            // 6.0.2.5 (2014/10/31) refactoring
    674                        rtn.append( makeEllipses( menuNo,kmokuNo,3 ) );
    675                }
    676
    677                if( isInFieldset ) {
    678                        rtn.append( "</td></tr></table>" )                                              // 6.7.5.0 (2017/03/10)
    679                                .append( FIELD_OUT )
    680                                .append( "</div>" );
    681                }
    682
    683                if( isClassHidden ) {                                                                           // 6.0.2.5 (2014/10/31) refactoring
    684                        rtn.append( makeEllipses( menuNo,0,2 ) );
    685                }
    686
    687                return rtn.toString();
    688        }
    689
    690        /**
    691         * メニューを表示する為のHTMLを作成します(折り返しJavaScript対応版)。
    692         *
    693         * @og.rev 4.0.0.0 (2005/01/31) 個人別のお気に入りメニューを作成します。
    694         * @og.rev 4.0.0.0 (2007/10/31) 分類項目の廃止
    695         * @og.rev 4.1.1.0 (2008/02/05) お気に入り情報はGEA09から取得するように変更
    696         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
    697         * @og.rev 6.4.4.1 (2016/03/18) StringBuilderの代わりに、OgBuilderを使用する。
    698         * @og.rev 6.9.9.1 (2018/08/27) お気に入り編集メニュー(GE0014→GFX000)変更。
    699         *
    700         * @return  個人別のお気に入りメニュー
    701         * @og.rtnNotNull
    702         */
    703        private String makeFavoriteMenu() {
    704
    705                final UserInfo userInfo = getUser();
    706                final Map<String,FavoriteGUIData> favoriteMap = userInfo.getFavoriteMap();
    707
    708                if( favoriteMap.isEmpty() ) { return ""; }
    709
    710                final ResourceManager resource = getResource(); // リソース参照
    711                final String    largeClassify    = resource.getLabelData( "FAVORITE_MENU" ).getShortLabel(); // お気に入り
    712                String  lastClassify     = "";                          // 前方画面の分類
    713                int             menuNo                   = 99999;
    714                int             kmokuNo                  = 0;
    715
    716                // fieldSetタグ、お気に入り編集画面リンクの出力
    717//              final GUIInfo editFavorite = userInfo.getGUIInfo( "GE0014" );
    718                final GUIInfo editFavorite = userInfo.getGUIInfo( "GFX000" );           // 6.9.9.1 (2018/08/27)
    719
    720                final OgBuilder rtn = new OgBuilder()
    721                        .append( "<div class=\"expand1\"> "
    722                                        , makeTagMenuString( null,null,largeClassify,null,1 )
    723                                        , makeTagMenu( editFavorite,resource.getLabelData( "EDIT" ).getShortLabel(),2 )         // 5.5.2.5 (2012/05/21) イメージアイコン対応
    724                                        , BR );
    725
    726                String thisClassify = null;
    727//              String gamenId = null;
    728                FavoriteGUIData favoriteGui = null;
    729                // 4.3.4.4 (2009/01/01) findBugs警告対応
    730                for( final Map.Entry<String, FavoriteGUIData> entry : favoriteMap.entrySet() ) {
    731                        final String gamenId     = entry.getKey();
    732                        favoriteGui = entry.getValue();
    733                        final GUIInfo guiInfo = userInfo.getGUIInfo( gamenId );
    734
    735                        if( match   != null && !gamenId.matches( match  ) ) { continue; }
    736                        if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
    737
    738                        thisClassify = favoriteGui.getClassify();
    739                        if( !lastClassify.equals( thisClassify ) ) {
    740                                menuNo++;
    741                                kmokuNo = 0;
    742                                rtn.appendIf( expand , "<div class=\"expand1\" id=\"menu" , String.valueOf( menuNo ) , "\">" )
    743                                        .append( makeTagMenuString( null,null,thisClassify,thisClassify,2 ) )
    744                                        .append( BR )
    745                                        .appendIfCR( expand , "</div>" );
    746                                lastClassify = thisClassify;
    747                        }
    748
    749                        final String linkLabel = favoriteGui.getName();
    750                        rtn.appendIf( expand
    751                                                        , "<div class=\"expand2\" id=\"menu"
    752                                                        , String.valueOf( menuNo ) , "_" , String.valueOf( kmokuNo ) , "\">" )
    753                                .append( makeTagMenu( guiInfo,linkLabel,3 ) )           // 5.5.2.5 (2012/05/21) イメージアイコン対応
    754                                .append( BR )
    755                                .appendIfCR( expand , "</div>" );
    756                        kmokuNo++;
    757                }
    758                return rtn.append( FIELD_OUT , "</div>" ).toString();
    759        }
    760
    761        /**
    762         * 折りたたみメニューで、非標準メニューの 表示に使う、"←･･･→" を作成します。
    763         *
    764         * @param       menuNo  階層番号
    765         * @param       kmokuNo 階層項目番号
    766         * @param       type    タイプ(1,2限定)
    767         *
    768         * @og.rev 4.0.0.0 (2005/01/31) 新規作成
    769         * @og.rev 6.4.4.1 (2016/03/18) StringBuilderの代わりに、OgBuilderを使用する。
    770         *
    771         * @return  メニュー
    772         * @og.rtnNotNull
    773         */
    774        private String makeEllipses( final int menuNo,final int kmokuNo,final int type ) {
    775                final int tmpType = type-1; // 超暫定対応 4.0.0.0 (2007/10/31)
    776                final String kmkNo = ( tmpType == 1 ) ? "" : "_" + kmokuNo ;
    777
    778                // 4.3.3.0 (2008/10/01) inlineStyleがtrueの場合は←･･･→をinlineで表示する
    779                return new OgBuilder()
    780                                .append( "<div class=\"expand"          , String.valueOf( tmpType ) )
    781                                .append( " ellipses\" id=\"menu"        , String.valueOf( menuNo ) , kmkNo )
    782                                .append( "\" " )
    783                                .appendIf( inlineStyle , "style=\"display:inline\" " )                          // if
    784                                .appendCR( ">" , makeTagMenuString( null,null,"←･･･→",null,type )
    785                                                        , BR , "</div>" )
    786                                .toString();
    787        }
    788
    789        /**
    790         * menuType="GROUP" 時に作成するグループメニュー。
    791         *
    792         * @og.rev 4.0.0.0 (2005/01/31) 新規作成
    793         * @og.rev 4.0.0.0 (2007/10/05) グループのコードリソースが存在しない場合
    794         * @og.rev 4.2.2.0 (2008/05/14) buttonRequestがtrueの場合はTOPへのリンクを表示しない
    795         * @og.rev 4.2.2.0 (2008/05/15) グループ絞込解除(GUI_ALL)の表示文字にラベルリソースを使う。
    796         * @og.rev 5.0.0.3 (2009/09/22) グループが1件の場合に表示されないバグを修正
    797         * @og.rev 5.1.8.0 (2010/07/01) コードリソースのキーが存在しない場合にエラーとなるバグを修正
    798         * @og.rev 5.9.7.1 (2016/04/06) GROPUにgroupsが効くようにする
    799         * @og.rev 6.4.5.0 (2016/04/08) GROPUにgroupsが効くようにする(効率化、ループから出す)
    800         * @og.rev 6.8.3.1 (2017/12/01) GROPUの表示順を、コードリソースの並び順にします。
    801         * @og.rev 5.10.15.2 (2019/09/20) GROUPのマルチバイト文字対応
    802         *
    803         * @return  メニュー
    804         */
    805        private String makeGroupMenu() {
    806
    807                // 画面のグループメニューのキャッシュを取得します。
    808                String groupMenu ;
    809                final String cacheKey  = HybsSystem.GUI_GR_MENU_CACHE_KEY + href + target ;
    810                if( cache ) {
    811                        groupMenu = (String)getSessionAttribute( cacheKey );
    812                        if( groupMenu != null ) { return groupMenu; }   // キャッシュを返します。
    813                }
    814                else {
    815                        removeSessionAttribute( cacheKey );
    816                }
    817
    818                final UserInfo userInfo = getUser();
    819
    820                // 6.8.3.1 (2017/12/01) GROPUの表示順を、コードリソースの並び順にします。
    821                final CodeData groupCode = getResource().getCodeData( "GROUPS" ) ;
    822                final Set<String> groupSet = groupCode == null ? new LinkedHashSet<>()                          // 要素がセットに挿入された順序です(挿入順)。
    823                                                                                                           : new TreeSet<>( (v1,v2) -> groupCode.getAddress( v1 ) - groupCode.getAddress( v2 ) );       // コードリソースの並び順
    824
    825                // そのユーザーで使用できる画面をすべてピックアップします。
    826                // その上で、読取可能なメニューを含むグループを順番に Set にセットしていきます。
    827                final GUIInfo[] guiInfos = userInfo.getGUIInfos();
    828
    829                // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    830                for( final GUIInfo guiInfo : guiInfos ) {
    831                        if( guiInfo.isRead() ) {
    832//              for( int i=0; i<guiInfos.length; i++ ) {
    833//                      if( guiInfos[i].isRead() ) {
    834                                final String gamenId = guiInfo.getKey() ;
    835//                              final String gamenId = guiInfos[i].getKey() ;
    836                                if( match   != null && !gamenId.matches( match  ) ) { continue; }
    837                                if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
    838                                // 6.4.5.0 (2016/04/08) 元のループを、拡張for文に変更しただけ。
    839                                final String[] guiGroups = StringUtil.csv2Array( guiInfo.getGroups() );
    840//                              final String[] guiGroups = StringUtil.csv2Array( guiInfos[i].getGroups() );
    841                                for( final String grp : guiGroups ) { groupSet.add( grp ); }
    842                        }
    843                }
    844
    845                // 6.4.5.0 (2016/04/08) groupsの削除は、後でまとめて行う。
    846                if( groups != null ) {
    847                        for( final String grp : groups ) { groupSet.remove( grp ); }
    848                }
    849
    850                // 5.0.0.3 (2009/09/22)
    851                // 6.1.1.0 (2015/01/17) refactoring 。size()判定をisEmpty() にすると同時に、if...else を反転する。
    852                if( groupSet.isEmpty() ) {
    853                        groupMenu = "";
    854                }
    855                else {
    856                        int sideTmpCnt = 1;
    857                        final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
    858                        rtn.append( "<tr>" );
    859
    860                        final String allMenu = getLabel( "ALL_MENU" ); // 4.2.2.0 (2008/05/15) ALLはラベルリソース使うように変更
    861                        rtn.append( makeTagMenuString( href,target,allMenu,"GUI_ALL",-1 ) );
    862                        if( sideCount > 0 && sideTmpCnt % sideCount == 0 ) { rtn.append("</tr><tr>"); }
    863                        sideTmpCnt++ ;
    864
    865                        final Iterator<String> ite = groupSet.iterator() ;
    866                        if( groupCode != null ) {
    867                                while( ite.hasNext() ) {
    868                                        final String group = ite.next();
    869                                        final int cdAdrs = groupCode.getAddress( group ) ;
    870                                        // 4.0.0.0 (2007/10/05) グループのコードリソースが存在しない場合
    871                                        String groupLabel = "";
    872                                        if( cdAdrs >= 0 ) { groupLabel = groupCode.getLongLabel( cdAdrs ); }
    873
    874                                        // 5.1.8.0 (2010/07/01) コードリソースのキーが存在しない場合にエラーとなるバグを修正
    875                                        if( groupLabel.isEmpty() && group != null && group.length() > 0 ) {
    876                                                groupLabel = group;
    877                                        }
    878
    879//                                      final String src = XHTMLTag.addUrlEncode( href,"group=" + group );
    880                                        final String src = XHTMLTag.addUrlEncode( href,"group=" + StringUtil.urlEncode( group ) ); // 5.10.15.2 (2019/09/20)
    881                                        rtn.append( makeTagMenuString( src,target,groupLabel,group,-1 ) );
    882                                        if( sideCount > 0 && sideTmpCnt % sideCount == 0 ) { rtn.append("</tr><tr>"); }
    883                                        sideTmpCnt++ ;
    884                                }
    885                        }
    886
    887                        if( ! imageOnly && ! buttonRequest ) { // 4.2.2.0 (2008/05/14) ボタンメニュー時はトップメニュー
    888                                rtn.append( makeTagMenuString( JSP + "/index.jsp",target,"Top","GUI_TOP",-1 ) );
    889                        }
    890                        rtn.append( "</tr>" );
    891
    892                        // 画面のグループメニューのキャッシュをセットします。
    893                        groupMenu = rtn.toString() ;
    894                }
    895
    896                if( cache ) {
    897                        setSessionAttribute( cacheKey,groupMenu );
    898                }
    899
    900                return groupMenu;
    901        }
    902
    903        /**
    904         * メニューを表示する為のHTMLを作成します(折り返しJavaScript対応版)。
    905         *
    906         * @og.rev 4.0.0.0 (2005/01/31) GUIInfoの実アドレスのパラメータを考慮する。
    907         * @og.rev 4.0.0.0 (2007/10/31) 一旦廃止
    908         * @og.rev 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    909         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
    910         * @og.rev 5.5.6.0 (2013/01/07) useDivOneLevelの折り返し方法変更
    911         * @og.rev 6.2.6.0 (2015/06/19) QUERYに表示される１行メニュは、説明なしの画面名称のみ表示する。
    912         * @og.rev 5.9.6.1 (2016/03/04) フレーム対応
    913         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止 , gamenId の変数設定
    914         *
    915         * @return  メニュー
    916         * @og.rtnNotNull
    917         */
    918        private String makeOneLevelMenu() {
    919                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
    920
    921                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    922                if( useDivOneLevel ) { rtn.append("<div id=\"design-onelevel\">"); }
    923
    924                final UserInfo userInfo = getUser();
    925
    926                // 4.0.0 (2005/01/31)
    927                final GUIInfo[] guiInfos = userInfo.getGUIInfos();
    928//              String gamenId  ;                       // 画面ID
    929                int sideTmpCnt = 1;
    930
    931                boolean isInClassify = false;
    932
    933                // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    934                for( final GUIInfo guiInfo : guiInfos ) {
    935                        final String gamenId = guiInfo.getKey() ;                               // 6.9.4.1 (2018/04/09)
    936                        final int    level   = guiInfo.getLevel();
    937//              for( int i=0; i<guiInfos.length; i++ ) {
    938//                      final String gamenId = guiInfos[i].getKey() ;                   // 6.9.4.1 (2018/04/09)
    939//                      final int level = guiInfos[i].getLevel();
    940
    941                        if( level == 2 ) {
    942//                              isInClassify = selClassify.equals( guiInfos[i].getKey() );
    943                                // 6.9.8.0 (2018/05/28) FindBugs:コンストラクタで初期化されていないフィールドを null チェックなしで null 値を利用している
    944                                // makeOneLevelMenu() メソッドが呼ばれる条件に、selClassify != null があるのだが。
    945//                              isInClassify = selClassify.equals( gamenId );
    946                                isInClassify = gamenId.equals( selClassify );                   // 6.9.8.0 (2018/05/28) とりあえず比較方法を入れ替えます。
    947                        }
    948
    949                        if( guiInfo.isRead() && level == 3 && isInClassify ) {          // 4.0.0 (2005/01/31)
    950//                      if( guiInfos[i].isRead() && level == 3 && isInClassify ) {              // 4.0.0 (2005/01/31)
    951//                              gamenId = guiInfos[i].getKey() ;
    952                                if( match   != null && !gamenId.matches( match  ) ) { continue; }
    953                                if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
    954
    955                                final String guiLabel = guiInfo.getLabel();                     // 6.2.6.0 (2015/06/19) 画面名称(title無)
    956//                              final String guiLabel = guiInfos[i].getLabel();         // 6.2.6.0 (2015/06/19) 画面名称(title無)
    957
    958                                final String thisGamenId = getGUIInfoAttri( "KEY" );
    959                                if( gamenId.equals( thisGamenId ) ) {
    960                                        // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    961                                        if( useDivOneLevel ) {
    962                                                rtn.append("<span class=\"design-onelevel\">").append( guiLabel ).append( "</span>" );
    963                                        }
    964                                        else {
    965                                                rtn.append( '[' ).append( guiLabel ).append( "] " );            // 6.0.2.5 (2014/10/31) char を append する。
    966                                        }
    967                                }
    968                                else {
    969                                        // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    970                                        if( useDivOneLevel ) {
    971                                                // 5.5.2.5 (2012/05/21) イメージアイコン対応
    972                                                rtn.append("<span class=\"design-onelevel\">").append( makeTagMenu( guiInfo,guiLabel,-5 ) ).append( "</span>" ); // 5.9.6.1
    973//                                              rtn.append("<span class=\"design-onelevel\">").append( makeTagMenu( guiInfos[i],guiLabel,-5 ) ).append( "</span>" ); // 5.9.6.1
    974                                        }
    975                                        else {
    976                                                rtn.append( makeTagMenu( guiInfo,guiLabel,-2 ) );               // 5.5.2.5 (2012/05/21) イメージアイコン対応
    977//                                              rtn.append( makeTagMenu( guiInfos[i],guiLabel,-2 ) );           // 5.5.2.5 (2012/05/21) イメージアイコン対応
    978                                        }
    979                                }
    980
    981                                if( sideCount > 0 ) {
    982                                        // 全件数をサイドカウント数で割った値が最大行数の場合は、終了する。
    983                                        if( sideTmpCnt / sideCount >= maxCellCount ) {
    984                                                //                                              rtn.append("･･･");
    985                                                break;
    986                                        }
    987                                        // 全件数をサイドカウント数で割った余りがゼロの場合は、行ブレイクする。
    988                                        // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    989                                        if( sideTmpCnt % sideCount == 0 ) {
    990                                                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    991                                                // 6.0.2.5 (2014/10/31) refactoring: findBugs対応。分岐もコメントアウトする。
    992                                //              if( useDivOneLevel ) {
    993                                //                      rtn.append( BR ); // 5.6.0.0 (2013/01/07) BRにする(条件分岐は残しておく)
    994                                //                      // rtn.append("<span style=\"clear: both;\" />");
    995                                //              }
    996                                //              else {
    997                                                        rtn.append( BR );
    998                                //              }
    999                                        }
    1000                                        sideTmpCnt++ ;
    1001                                }
    1002                        }
    1003                }
    1004
    1005                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    1006                if( useDivOneLevel ) {
    1007                        rtn.append("<span style=\"clear: both;\" ><!-- --></span></div>");      // 5.9.1.2 (2015/10/23)
    1008                }
    1009
    1010                return rtn.toString();
    1011        }
    1012
    1013        /**
    1014         * 既存のページの次にアクセスされる画面郡のリンクを作成します。
    1015         *
    1016         * これは、現時点の画面に対して、次にアクセスされる画面の候補を
    1017         * ピックアップしておく機能です。
    1018         * 実際には、過去にアクセスされた結果より取得しています。
    1019         * これは、ONELEVEL と置き換えることになる機能です。
    1020         *
    1021         * @og.rev 5.2.3.0 (2010/12/01) NEXTGUI 追加
    1022         * @og.rev 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    1023         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
    1024         * @og.rev 6.2.6.0 (2015/06/19) QUERYに表示される１行メニュは、説明なしの画面名称のみ表示する。
    1025         * @og.rev 6.3.1.0 (2015/06/28) useDivOneLevel がうまく動かなかったので、修正。
    1026         * @og.rev 5.9.6.1 (2016/03/04) フレーム対応
    1027         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"／＞" 止めを、"＞" に変更します)。
    1028         *
    1029         * @return  メニュー
    1030         * @og.rtnNotNull
    1031         */
    1032        private String makeNextguiMenu() {
    1033                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
    1034
    1035                // 今、アクセスしている画面
    1036                final GUIInfo thisGamen = (GUIInfo)getSessionAttribute( HybsSystem.GUIINFO_KEY );
    1037                final String[] nextGuis = thisGamen.getNextGuiArray();
    1038
    1039                final UserInfo userInfo = getUser();
    1040                int sideTmpCnt = 1;
    1041
    1042                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    1043                if( useDivOneLevel ) { rtn.append("<div id=\"design-onelevel\">"); }
    1044
    1045                GUIInfo guiInfo = null;
    1046                // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    1047                for( final String nxtGrp : nextGuis ) {
    1048                        guiInfo = userInfo.getGUIInfo( nxtGrp );
    1049//              for( int i=0; i<nextGuis.length; i++ ) {
    1050//                      guiInfo = userInfo.getGUIInfo( nextGuis[i] );
    1051                        if( guiInfo == null ) { continue; }             // 存在しない、またはアクセス拒否の場合は、無視する。
    1052
    1053                        if( guiInfo.isRead() ) {
    1054                                final String guiLabel = guiInfo.getLabel();             // 6.2.6.0 (2015/06/19) 画面名称(title無)
    1055
    1056                                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    1057                                if( useDivOneLevel ) {
    1058                                        // 5.5.2.5 (2012/05/21) イメージアイコン対応
    1059                                        rtn.append("<span class=\"design-onelevel\">").append( makeTagMenu( guiInfo,guiLabel,-5 ) ).append( "</span>" );
    1060                                }
    1061                                else {
    1062                                        rtn.append( makeTagMenu( guiInfo,guiLabel,-2 ) );               // 5.5.2.5 (2012/05/21) イメージアイコン対応
    1063                                }
    1064
    1065                                if( sideCount > 0 ) {
    1066                                        // 全件数をサイドカウント数で割った値が最大行数の場合は、終了する。
    1067                                        if( sideTmpCnt / sideCount >= maxCellCount ) {
    1068                                                break;
    1069                                        }
    1070                                        // 全件数をサイドカウント数で割った余りがゼロの場合は、行ブレイクする。
    1071                                        // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    1072                                        if( sideTmpCnt % sideCount == 0 ) {
    1073                                                // 6.3.1.0 (2015/06/28) useDivOneLevel がうまく動かなかったので、修正。
    1074                        //                      if( useDivOneLevel ) {
    1075                        //                              rtn.append("<span style=\"clear: both;\" />");
    1076                        //                      }
    1077                        //                      else {
    1078                                                        rtn.append( BR );
    1079                        //                      }
    1080                                        }
    1081                                        sideTmpCnt++ ;
    1082                                }
    1083                        }
    1084                }
    1085
    1086                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
    1087                // 6.3.1.0 (2015/06/28) useDivOneLevel がうまく動かなかったので、修正。
    1088                if( useDivOneLevel ) {
    1089//                      rtn.append("<span style=\"clear: both;\" /></div>");
    1090                        rtn.append("<span style=\"clear: both;\" ></span></div>");                      // 7.0.1.0 (2018/10/15)
    1091                }
    1092
    1093                return rtn.toString();
    1094        }
    1095
    1096        /**
    1097         * メニューを表示する為のHTMLを作成します(マトリクスメニュー)。
    1098         *
    1099         * 分類まとめ、クラス色指定、最小行数設定、最大行数設定の機能があります。
    1100         * 《分類まとめ》 最大行数設定(maxCellCount)に達したセルは、一つ右に新たにセルを作成
    1101         * します。このとき、ヘッダーの CLASSIFY を同じにして、colspan でまとめます。
    1102         * 《クラス色指定》ヘッダー毎に 順次 CLR0,CLR1,････ というクラス属性を付与します。
    1103         * ヘッダーには、MENU_H も出力されています。CLR0 は、大分類ごとに加算されていきますので、
    1104         * 繰り返して同じ色を指定する場合は、CSSファイルでまとめて指定してください。
    1105         * 《最小行数設定》minCellCount 属性を指定することで、１セルに含まれる最小行数を指定できます。
    1106         * これは、セルに入れる &lt;br /&gt; の個数を指定することと同じです。
    1107         * 《最大行数設定》maxCellCount 属性を指定することで、１セルに含まれる最大行数を指定できます。
    1108         * 分類まとめでも説明しましたように、最大値をオーバーすると次のセルから書き始めます。
    1109         *
    1110         * @og.rev 4.0.0.0 (2005/11/30) 新規追加
    1111         * @og.rev 4.0.0.0 (2007/10/05) 分類のコードリソースが存在しない場合
    1112         * @og.rev 5.2.3.0 (2010/12/01) sideCount対応
    1113         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
    1114         * @og.rev 5.5.5.3 (2012/08/17) th,tdにヘッダの画面IDをクラスとして出力
    1115         * @og.rev 6.8.2.3 (2017/11/10) minCellCountの数が、一つ足りない事の修正
    1116         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止 , gamenId の変数設定
    1117         *
    1118         * @return  マトリクスメニュー
    1119         * @og.rtnNotNull
    1120         */
    1121        private String makeMatrixMenu() {
    1122                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
    1123
    1124                final UserInfo userInfo = getUser();
    1125
    1126                // 4.0.0 (2005/01/31)
    1127                final GUIInfo[] guiInfos = userInfo.getGUIInfos();
    1128//              String gamenId          ;                       // 画面ID
    1129                String bkClassifyKey    = null;         // 分類コード(旧)
    1130                String bkClassifyName   = null;         // 分類名称(旧)
    1131                int        cellColorCnt = 0;            // MENU_H に 追加する CLR クラス属性の連番
    1132
    1133                String headGuikey = "";                         //  5.5.5.3 (2012/08/17) ヘッダのgamenId
    1134
    1135                final StringBuilder rtnH = new StringBuilder( BUFFER_LARGE );
    1136                final StringBuilder rtnB = new StringBuilder( BUFFER_LARGE );
    1137
    1138                int level ;
    1139                int preLevel = 0;
    1140
    1141                int lineTmpCnt = 0;                             // セル中の行カウント
    1142                int cellTmpCnt = 0;                             // 1つの分類中のセルカウント
    1143                int cellTmpAllCnt = 0;                  // 5.2.3.0 (2010/12/01) 該当行のセルカウント
    1144
    1145                boolean isInClassify  = false;  // 分類の中か？
    1146                boolean isChangeLevel = false;  // 直リンク用(無理やり通常画面の階層として扱うので)
    1147                boolean isDummyMENU   = false;  // 5.2.3.0 (2010/12/01) sideCountブレーク時の大分類領域の出力可否               7.2.9.4 (2020/11/20) isDummyMENU_S → isDummyMENU
    1148
    1149                for( int i=0; i<guiInfos.length; i++ ) {
    1150                        if( guiInfos[i].isRead() ) {            // 4.0.0 (2005/01/31)
    1151                                final String gamenId = guiInfos[i].getKey() ;
    1152                                if( match   != null && !gamenId.matches( match  ) ) { continue; }
    1153                                if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
    1154
    1155                                // 処理すべき画面かのチェック
    1156                                final int guiFlg = guiCheck( guiInfos, i );
    1157                                if( guiFlg == 0 ) { continue; }
    1158
    1159                                level = guiInfos[i].getLevel();         // 4.0.0 (2005/01/31)
    1160
    1161                                // 大分類が来るまでは処理しない
    1162                                if( level > 1 && rtnH == null ) { continue; }
    1163
    1164                                // 直リンクの場合、無理やり通常画面に変換
    1165                                if( level == 2 && guiInfos[i].getAddress() != null && guiInfos[i].getAddress().length() != 0 ) {
    1166                                        level = 3;
    1167                                        if( !isChangeLevel ) {
    1168                                                isChangeLevel = true;
    1169                                                isInClassify = false;
    1170                                        }
    1171                                }
    1172                                else {
    1173                                        isChangeLevel = false;
    1174                                }
    1175
    1176                                // 分類のブレイク処理
    1177                                if( preLevel >= 3 && level < 3 || !isInClassify ) {                                                             // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
    1178                                        if(  lineTmpCnt != 0 ) {
    1179                                                for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
    1180                                                rtnB.append( "</td>" ).append( CR );
    1181                                        }
    1182
    1183                                        if( bkClassifyKey != null ) {
    1184                                                rtnH.append( "<th colspan=\"" ).append( cellTmpCnt ).append( "\" class=\"MENU_H CLR" )
    1185                                                        .append( cellColorCnt ).append( ' ' ).append( headGuikey ).append( "\">" ); // 5.5.5.3 (2012/08/17)
    1186                                                if( "_SPACE".equals( bkClassifyKey ) ) {
    1187                                                        rtnH.append( '　' );             // 6.0.2.5 (2014/10/31) char を append する。
    1188                                                }
    1189                                                else {
    1190                                                        rtnH.append( makeTagMenuString( null,null,bkClassifyName,bkClassifyKey,-3 ) );
    1191                                                }
    1192                                                rtnH.append( "</th>" );
    1193
    1194                                                // 5.2.3.0 (2010/12/01) sideCount によるセルの改行
    1195                                                cellTmpAllCnt += cellTmpCnt;
    1196                                                if( sideCount > 0 && cellTmpAllCnt >= sideCount ) {
    1197                                                        rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
    1198
    1199                                                        rtnH.setLength(0);              // 6.1.0.0 (2014/12/26) refactoring
    1200                                                        rtnB.setLength(0);              // 6.1.0.0 (2014/12/26) refactoring
    1201                                                        cellTmpAllCnt = 0;
    1202                                                        isDummyMENU   = true;   // 出力予約
    1203                                                }
    1204                                        }
    1205
    1206                                        bkClassifyKey = null;
    1207                                        isInClassify = false;
    1208                                        lineTmpCnt = 0;
    1209                                        cellTmpCnt = 0;
    1210                                }
    1211
    1212                                // 大分類(フィールドメニュー)
    1213                                if( level == 1 ) {
    1214                                        headGuikey = gamenId; // 5.5.5.3 (2012/08/17)
    1215                                        if( preLevel > 0 ) {
    1216                                                cellColorCnt++ ;
    1217                                                rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
    1218                                        }
    1219
    1220                                        rtn.append( "<tr><td rowspan=\"2\" class=\"MENU_S "+ headGuikey +"\">" )        // 5.5.5.3 (2012/08/17)
    1221                                                .append( makeTagMenuString( null,null,guiInfos[i].getName(),gamenId,-3 ) )
    1222                                                .append( "</td>" ).append( CR );
    1223
    1224                                        rtnH.setLength(0);              // 6.1.0.0 (2014/12/26) refactoring
    1225                                        rtnB.setLength(0);              // 6.1.0.0 (2014/12/26) refactoring
    1226                                        cellTmpAllCnt = 0;              // 5.2.3.0 (2010/12/01)
    1227                                        isDummyMENU   = false;  // 5.2.3.0 (2010/12/01) 出力予約解除
    1228                                }
    1229                                // 分類(直リンクの場合は、level=3で処理)
    1230                                else if( level == 2 ) {
    1231                                        isInClassify = true;
    1232//                                      bkClassifyKey = guiInfos[i].getKey();
    1233                                        bkClassifyKey = gamenId;                                                // 6.9.4.1 (2018/04/09)
    1234                                        bkClassifyName = guiInfos[i].getName();
    1235                                }
    1236                                // 通常メニュー・隠しメニュー
    1237                                else if( level >= 3 ) {
    1238
    1239                                        // 元のMENU_Sに戻り、rowspan を書き換える・・・のが邪魔くさいので、td のみ出力しておく。
    1240                                        // 5.2.3.0 (2010/12/01) sideCount によるセルの改行
    1241                                        if( isDummyMENU ) {
    1242                                                rtn.append( "<tr><td rowspan=\"2\" class=\"MENU_S " )
    1243                                                        .append( headGuikey ).append( "\"></td>" )      // 5.5.5.3 (2012/08/17)
    1244                                                        .append( CR );
    1245                                                isDummyMENU = false;            // 出力予約解除
    1246                                        }
    1247
    1248                                        // 画面ID="HYBS_BR"の場合は、セルを変える。
    1249//                                      if( "HYBS_BR".equals( guiInfos[i].getKey() ) ) {
    1250                                        if( "HYBS_BR".equals( guiInfos[i].getAddress() ) ) {                                    // 6.9.4.1 (2018/04/09) HYBS_BR は、アドレスに設定
    1251                                                if( lineTmpCnt != 0 ) {
    1252                                                        for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
    1253                                                        lineTmpCnt = 0;
    1254                                                }
    1255                                        }
    1256                                        // 通常画面
    1257                                        else {
    1258                                                if( lineTmpCnt == 0 ) {
    1259                                                        rtnB.append( "<td class=\"MENU_B " + headGuikey + "\">" ); // 5.5.5.3 (2012/08/17)
    1260                                                        cellTmpCnt++;
    1261                                                }
    1262
    1263                                                rtnB.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),-3 ) );             // 5.5.2.5 (2012/05/21) イメージアイコン対応
    1264                                                lineTmpCnt++;
    1265
    1266                                                if( lineTmpCnt >= maxCellCount ) {
    1267                                                        rtnB.append( "</td>" );
    1268                                                        lineTmpCnt = 0;
    1269                                                }
    1270                                                else {
    1271                                                        rtnB.append( BR );
    1272                                                }
    1273
    1274                                                // 分類の中に入っていない通常画面
    1275                                                if( !isInClassify ) {
    1276                                                        bkClassifyKey = "_SPACE";
    1277                                                        isInClassify = true;
    1278                                                }
    1279                                        }
    1280                                }
    1281
    1282                                preLevel = level;
    1283                        }
    1284                }
    1285
    1286                // 終了処理
    1287                for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
    1288                rtnB.append( "</td>" ).append( CR );
    1289
    1290                if( bkClassifyKey != null ) {
    1291                        rtnH.append( "<th colspan=\"" ).append( cellTmpCnt )
    1292                                .append( "\" class=\"MENU_H CLR" ) .append(  cellColorCnt )
    1293                                .append( ' ' ).append(  headGuikey ).append( "\">" )                    // 5.5.5.3 (2012/08/17)
    1294                                .append( makeTagMenuString( null,null,bkClassifyName,bkClassifyKey,-3 ) )
    1295                                .append( "</th>" );
    1296                }
    1297
    1298                rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
    1299
    1300                return rtn.toString();
    1301        }
    1302
    1303        /**
    1304         * メニューを表示する為のHTMLを作成します(マトリクスメニュー2)。
    1305         *
    1306         * マトリクスメニューをベースとした特別バージョンです。
    1307         * 通常のマトリクスメニューからの変更点は以下の通りです。
    1308         * ①大分類が表示されない
    1309         *   ⇒ 変わりに、1行に表示されているセル数がsideCountで指定した数を超えた場合に
    1310         *      自動的に改行されます。
    1311         * ②画面リンクのターゲット
    1312         *   ⇒ 自分自身のフレームに対してリンク先を表示します。
    1313         *      リンク先は、通常メニュー構成ですが左メニューには該当する小分類の画面しか表示されません。
    1314         * ③小分類でのリンク
    1315         *   ⇒ 小分類をクリックした際に、通常のメニュー構成画面にリンクします。
    1316         *      但し、②と同様に左メニューには該当する小分類の画面しか表示されません。
    1317         *
    1318         * @og.rev 4.2.1.0 (2008/04/01) 新規追加
    1319         * @og.rev 4.2.1.1 (2008/05/02) カテゴリーリンクで一番上の画面のモードが-wとなっている場合に、
    1320         *                               その画面が立ち上がってしまうバグを修正
    1321         * @og.rev 4.2.2.0 (2008/05/14) buttonRequestの付加をmakeTagMenuString()に変更
    1322         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
    1323         * @og.rev 5.5.5.3 (2012/08/17) ヘッダ部のgamenIdをth,tdのクラスに追加
    1324         * @og.rev 6.8.2.3 (2017/11/10) minCellCountの数が、一つ足りない事の修正
    1325         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止 , gamenId の変数設定
    1326         *
    1327         * @return  マトリクスメニュー
    1328         * @og.rtnNotNull
    1329         */
    1330        private String makeMatrixMenu2() {
    1331                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
    1332
    1333                final UserInfo userInfo = getUser();
    1334
    1335                final GUIInfo[] guiInfos = userInfo.getGUIInfos();
    1336//              String gamenId          ;                       // 画面ID
    1337                String bkClassifyKey    = null;         // 分類コード(旧)
    1338                String nextKey                  = null;         // 分類ボタンを押した時に最初の画面が開くようにする
    1339                String bkClassifyName   = null;         // 分類名称(旧)
    1340                final int          cellColorCnt = 0;            // MENU_H に 追加する CLR クラス属性の連番
    1341
    1342                final StringBuilder rtnH = new StringBuilder( BUFFER_LARGE );           // 分類部分の出力用
    1343                final StringBuilder rtnB = new StringBuilder( BUFFER_LARGE );           // 実画面のリンク部分の出力用
    1344
    1345                int level ;
    1346                int preLevel = 0;
    1347
    1348                int lineTmpCnt = 0;                             // セル中の行カウント
    1349                int cellTmpCnt = 0;                             // 1つの分類中のセルカウント
    1350                int cellTmpAllCnt = 0;                  // 該当行のセルカウント
    1351
    1352                boolean isInClassify = false;   // 分類の中か？
    1353                boolean isChangeLevel = false;  // 直リンク用(無理やり通常画面の階層として扱うので)
    1354
    1355                String headGuikey = "" ;                // 5.5.5.3 (2012/08/17)
    1356
    1357                rtn.append( "<tr>" ).append( CR );
    1358
    1359                for( int i=0; i<guiInfos.length; i++ ) {
    1360                        if( guiInfos[i].isRead() ) {            // 4.0.0 (2005/01/31)
    1361                                final String gamenId = guiInfos[i].getKey() ;
    1362                                if( match   != null && !gamenId.matches( match  ) ) { continue; }
    1363                                if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
    1364
    1365                                // 処理すべき画面かのチェック
    1366                                final int guiFlg = guiCheck( guiInfos, i );
    1367                                if( guiFlg == 0 ) { continue; }
    1368
    1369                                level = guiInfos[i].getLevel();         // 4.0.0 (2005/01/31)
    1370
    1371                                // 直リンクの場合、無理やり通常画面に変換
    1372                                if( level == 2 && guiInfos[i].getAddress() != null && guiInfos[i].getAddress().length() != 0 ) {
    1373                                        level = 3;
    1374                                        if( !isChangeLevel ) {
    1375                                                isChangeLevel = true;
    1376                                                isInClassify = false;
    1377                                        }
    1378                                }
    1379                                else {
    1380                                        isChangeLevel = false;
    1381                                }
    1382
    1383                                // 分類のブレイク処理
    1384                                if( preLevel >= 3 && level < 3 || !isInClassify ) {                                                             // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
    1385                                        if(  lineTmpCnt != 0 ) {
    1386                                                for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
    1387                                                //rtnB.append( "</td>" ).append( CR ); // 4.2.1.0 (2008/04/03) リスト
    1388                                                rtnB.append( "</ul></div></td>" ).append( CR );
    1389                                        }
    1390
    1391                                        if( bkClassifyKey != null ) {
    1392                                                // 6.0.2.5 (2014/10/31) char を append する。
    1393                                                rtnH.append( "<th colspan=\"" ).append( cellTmpCnt ).append( "\" class=\"MENU_H CLR" )
    1394                                                        .append( cellColorCnt ).append( ' ' ).append( headGuikey ).append( "\">" );             // 5.5.5.3 (2012/08/17)
    1395                                                if( "_SPACE".equals( bkClassifyKey ) ) {
    1396                                                        rtnH.append( '　' );                                     // 6.0.2.5 (2014/10/31) refactoring
    1397                                                }
    1398                                                else {
    1399                                                        // 6.4.2.1 (2016/02/05) PMD refactoring.
    1400                                                        final String classifyHref = JSP + "/index.jsp?classify=" + bkClassifyKey + "&amp;GAMENID="+nextKey;             // ボタンを押した場合に最初の画面が現れる
    1401                                                        rtnH.append( makeTagMenuString( classifyHref,"_self",bkClassifyName,bkClassifyKey,-3 ) );
    1402                                                }
    1403                                                rtnH.append( "</th>" );
    1404
    1405                                                cellTmpAllCnt += cellTmpCnt;
    1406
    1407                                                if( sideCount > 0 && cellTmpAllCnt >= sideCount ) {
    1408                                                        rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
    1409
    1410                                                        rtnH.setLength(0);                              // 6.1.0.0 (2014/12/26) refactoring
    1411                                                        rtnB.setLength(0);                              // 6.1.0.0 (2014/12/26) refactoring
    1412                                                        cellTmpAllCnt = 0;
    1413                                                }
    1414                                        }
    1415
    1416                                        bkClassifyKey = null;
    1417                                        nextKey           = null;
    1418                                        isInClassify = false;
    1419                                        lineTmpCnt = 0;
    1420                                        cellTmpCnt = 0;
    1421                                }
    1422
    1423                                // 5.5.5.3 (2012/08/17) 大分類(フィールドメニュー)
    1424                                if( level == 1 ) {
    1425                                        headGuikey = gamenId;
    1426                                }
    1427                                // 分類(直リンクの場合は、level=3で処理)
    1428                                else if( level == 2 ) {
    1429                                        isInClassify = true;
    1430                                        if( guiInfos[i].isPulldown() ){ // 4.3.3.0 (2008/10/01) プルダウン化チェック
    1431                                                excludeButton = true;
    1432                                        }
    1433                                        else{
    1434                                                excludeButton = false;
    1435                                        }
    1436//                                      bkClassifyKey = guiInfos[i].getKey();
    1437                                        bkClassifyKey = gamenId;                                        // 6.9.4.1 (2018/04/09)
    1438                                        bkClassifyName = guiInfos[i].getName();
    1439                                        for( int j=i+1; j<guiInfos.length; j++ ) {
    1440                                                if( guiInfos[j] != null && guiInfos[j].isRead() ) {
    1441                                                        nextKey = guiInfos[j].getKey();
    1442                                                        break;
    1443                                                }
    1444                                        }
    1445                                }
    1446                                // 通常メニュー・隠しメニュー
    1447                                else if( level >= 3 ) {
    1448                                        // 画面ID="HYBS_BR"の場合は、セルを変える。
    1449//                                      if( "HYBS_BR".equals( guiInfos[i].getKey() ) ) {
    1450                                        if( "HYBS_BR".equals( guiInfos[i].getAddress() ) ) {                                    // 6.9.4.1 (2018/04/09) HYBS_BR は、アドレスに設定
    1451                                                if( lineTmpCnt != 0 ) {
    1452                                                        for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
    1453                                                        lineTmpCnt = 0;
    1454                                                }
    1455                                        }
    1456                                        // 通常画面
    1457                                        else {
    1458                                                if( lineTmpCnt == 0 ) {
    1459                                                        // rtnB.append( "<td class=\"MENU_B\">" );
    1460                                                        // 4.2.1.0 (2008/04/03) リンクをリスト形式で出す案
    1461                                                        rtnB.append( "<td class=\"MENU_B "+ headGuikey +"\"> <div class=\"gamen-menu-wrap\"><ul class=\"gamen-menu\">" ); // 5.5.5.3 (2012/08/17)
    1462                                                        cellTmpCnt++;
    1463                                                }
    1464
    1465                                                // 5.5.2.5 (2012/05/21) リストは、イメージを設定するので、メソッド側で付与します。
    1466                                                rtnB.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),-4 ) );             // 5.5.2.5 (2012/05/21) イメージアイコン対応
    1467                                                lineTmpCnt++;
    1468
    1469                                                if( lineTmpCnt >= maxCellCount ) {
    1470                                                        // rtnB.append( "</td>" );
    1471                                                        rtnB.append( " </ul> </div></td>" ); // 4.2.1.0 (008/04/03) リスト
    1472                                                        lineTmpCnt = 0;
    1473                                                }
    1474                                //              else {
    1475                                //                      rtnB.append( BR ); // 4.2.1.0 (2008/04/03) リスト。改行不要。
    1476                                //              }
    1477
    1478                                                // 分類の中に入っていない通常画面
    1479                                                if( !isInClassify ) {
    1480                                                        bkClassifyKey = "_SPACE";
    1481                                                        isInClassify = true;
    1482                                                }
    1483                                        }
    1484                                }
    1485                                preLevel = level;
    1486                        }
    1487                }
    1488
    1489                // 終了処理
    1490                // 4.3.3.0 (2008/10/01) 終了処理は0の時行はない
    1491                if( lineTmpCnt != 0){
    1492                        for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }                     // 6.8.2.3 (2017/11/10)
    1493                        rtnB.append( "</td>" ).append( CR );
    1494                }
    1495
    1496                if( bkClassifyKey != null ) {
    1497                        rtnH.append( "<th colspan=\"" + cellTmpCnt + "\" class=\"MENU_H CLR" + cellColorCnt + " " + headGuikey + "\">" ); // 5.5.5.3 (2012/08/17)
    1498
    1499                        // 6.4.2.1 (2016/02/05) PMD refactoring.
    1500                        final String classifyHref = JSP + "/index.jsp?classify=" + bkClassifyKey + "&amp;GAMENID="+nextKey;
    1501                        rtnH.append( makeTagMenuString( classifyHref,"_self",bkClassifyName,bkClassifyKey,-3 ) );
    1502                        rtnH.append( "</th>" );
    1503                }
    1504
    1505                rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
    1506
    1507                return rtn.toString();
    1508        }
    1509
    1510        /**
    1511         * タイプに応じたメニューを表示する為の文字列を作成します。
    1512         * 引数の GUIInfo より、アクセスすべきメニューのhrefと、targetを求めます。
    1513         * type = -3 (マトリクスメニュー) の場合だけ、タグ属性の target を使用します。
    1514         *
    1515         * 　0:フィールドセットメニュー
    1516         * 　1:トップ階層(【分類名称】)
    1517         * 　2:選択階層(通常の折りたたみメニュー)
    1518         * 　3:選択非表示(通常は、隠してあります)
    1519         * 　-1:グループ分類メニュー(class="GUI_GRP"のtdタグで囲われます)
    1520         * 　-2:ラインメニュー([画面名称]　)
    1521         * 　-3:マトリクスメニュー(一覧)
    1522         * 　-4:マトリクスメニュー２(一覧)
    1523         * 　-5:1レベル表示(後続処理は-3と同じ)
    1524         * 　-6:TILE表示時の選択階層(通常の折りたたみメニュー,2:と同じ)
    1525         *
    1526         * @og.rev 4.0.0.0 (2005/01/31) 新規登録(makeTopMenu、makeSecondMenuの置き換え)
    1527         * @og.rev 4.1.0.1 (2008/01/22) アドレスが[..]から始まる画面はマルチセッションチェックを行わない。
    1528         * @og.rev 4.2.1.0 (2008/04/01) マトリクスメニュー2用のタグ作成処理追加
    1529         * @og.rev 4.2.1.0 (2008/04/17) マトリクス２からの遷移先でボタンメニューにする処理
    1530         * @og.rev 4.2.2.0 (2008/05/14) buttonRequestの付加をmakeTagMenuString()に変更
    1531         * @og.rev 4.3.3.7 (2008/11/22) https対応
    1532         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(画面ID単位ではなく、IMAGE_KEYパラメータで指定可能にする。)
    1533         * @og.rev 5.7.8.1 (2014/07/18) realAddress の "/" 対応
    1534         * @og.rev 6.3.8.4 (2015/10/09) KBLINK(リンク区分)を画面のイメージファイルに割り当てます。
    1535         * @og.rev 5.9.6.1 (2016/03/04) -5を追加。-3との違いはresult.jspに飛ばない事
    1536         * @og.rev 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
    1537         *
    1538         * @param       guiInfo GUIInfoリンク
    1539         * @param       bodyIn  BODY部(表示)
    1540         * @param       type    タイプ
    1541         *
    1542         * @return  階層別メニュー文字列
    1543         * @og.rtnNotNull
    1544         */
    1545        private String makeTagMenu( final GUIInfo guiInfo, final String bodyIn, final int type ) {
    1546
    1547                String href              = null;
    1548                String tmpTarget = null;
    1549                final  String gamenId   = guiInfo.getKey();             // 5.5.2.5 (2012/05/21) イメージアイコン対応
    1550                int                       tmpType       = type;                                 // 5.9.6.1
    1551
    1552                if( guiInfo.getAddress() != null && guiInfo.getAddress().length() > 0 ) {
    1553                        final String readAdrs = guiInfo.getRealAddress( "index.jsp" );
    1554                        final String reqParam = getRequestParameter( guiInfo.getParam() );
    1555                        href = XHTMLTag.addUrlEncode( readAdrs,reqParam );
    1556                        tmpTarget = guiInfo.getTarget();
    1557
    1558                        // 4.3.3.7 (2008/11/22) https対応
    1559                        // 5.7.8.1 (2014/07/18) realAddress の "/" 対応
    1560                        final String kblink = guiInfo.getKblink();
    1561                        if( ! readAdrs.startsWith( "http://" ) && ! readAdrs.startsWith( "https://" ) && !"/".equals( kblink ) ) {
    1562                                if( type == -3 ) {
    1563                                        tmpTarget = target;
    1564                                        href = XHTMLTag.addUrlEncode( JSP + "/result.jsp",reqParam );   // 6.2.0.0 (2015/02/27)
    1565                                }
    1566                                else if( type == -4 ) {         // 4.2.1.0 (2008/04/01)
    1567                                        tmpTarget = "_self";
    1568                                        href = XHTMLTag.addUrlEncode( JSP + "/index.jsp",reqParam );    // 6.2.0.0 (2015/02/27)
    1569                                        href = XHTMLTag.addUrlEncode( href,"classify=" + guiInfo.getClassify() );
    1570                                }
    1571                                else if( type == -5 ){          // 5.9.6.1 (2016/03/04)
    1572                                        tmpTarget = target;
    1573                                        tmpType = -3;
    1574                                }
    1575                                href = XHTMLTag.addUrlEncode( href,"GAMENID=" + gamenId );                      // 5.5.2.5 (2012/05/21) せっかくなので、利用する。
    1576
    1577                                // 3.8.0.0 (2005/06/07) 同一セッションでのマルチ起動対策を行います。
    1578                                // 4.1.0.1 (2008/01/22) アドレスが[..]から始まる画面はマルチセッションチェックを行いません。
    1579                                // 4.1.0.1 (2008/04/01) マトリクスメニュー2はマルチセッションチェックを行いません。
    1580//                              if( multiSessionCheck && !guiInfo.getAddress().startsWith( ".." ) && type != -4 ) {
    1581                                if( !guiInfo.getAddress().startsWith( ".." ) && type != -4 ) {          // 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
    1582                                        href = XHTMLTag.addUrlEncode( href,mscKey );
    1583                                }
    1584                        }
    1585                }
    1586                // 5.5.2.5 (2012/05/21) イメージアイコン対応(画面ID単位ではなく、IMAGE_KEYパラメータで指定可能にする。)
    1587                final String imgKey = guiInfo.getImageKey() ;
    1588                return makeTagMenuString( href,tmpTarget,bodyIn,gamenId,imgKey,tmpType ) ; // 5.9.6.1
    1589        }
    1590
    1591        /**
    1592         * タイプに応じたメニューを表示する為の文字列を作成します。
    1593         * 従来からのメソッドの引数のままで、新しい gamenId は、imgKey をそのままセットします。
    1594         *
    1595         * 　0:フィールドセットメニュー
    1596         * 　1:トップ階層(【分類名称】)
    1597         * 　2:選択階層(通常の折りたたみメニュー)
    1598         * 　3:選択非表示(通常は、隠してあります)
    1599         * 　-1:グループ分類メニュー(class="GUI_GRP"のtdタグで囲われます)
    1600         * 　-2:ラインメニュー([画面名称]　)
    1601         * 　-3:マトリクスメニュー(一覧)
    1602         * 　-4:マトリクスメニュー2(一覧)
    1603         * 　-5:1レベル表示(後続処理は-3と同じだが、絶対パスの場合は、画面ﾘｿｰｽのtargetを使用する。)
    1604         * 　-6:TILE表示時の選択階層(通常の折りたたみメニュー,2:と同じ)
    1605         *
    1606         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(画面ID単位ではなく、IMAGE_KEYパラメータで指定可能にする。)
    1607         *
    1608         * @param       href    リンク
    1609         * @param       target  ターゲット
    1610         * @param       bodyIn  BODY部(表示)
    1611         * @param       imgKey  imageファイルの検索キー
    1612         * @param       type    タイプ
    1613         *
    1614         * @return  階層別メニュー文字列
    1615         * @og.rtnNotNull
    1616         */
    1617        private String makeTagMenuString( final String href,final String target, final String bodyIn,
    1618                                                                final String imgKey,final int type ) {
    1619                return makeTagMenuString( href,target,bodyIn,imgKey,imgKey,type );      // gamenId の代わりに、imgKey をセットする。
    1620        }
    1621
    1622        /**
    1623         * タイプに応じたメニューを表示する為の文字列を作成します。
    1624         *
    1625         * タイプは、階層別になっていますが、マイナスは、内部で処理するための記号です。
    1626         *
    1627         * 　0:フィールドセットメニュー
    1628         * 　1:トップ階層(【分類名称】)
    1629         * 　2:選択階層(通常の折りたたみメニュー)
    1630         * 　3:選択非表示(通常は、隠してあります)
    1631         * 　-1:グループ分類メニュー(class="GUI_GRP"のtdタグで囲われます)
    1632         * 　-2:ラインメニュー([画面名称]　)
    1633         * 　-3:マトリクスメニュー(一覧)
    1634         * 　-4:マトリクスメニュー2(一覧)
    1635         * 　-5:1レベル表示(後続処理は-3と同じだが、絶対パスの場合は、画面ﾘｿｰｽのtargetを使用する。)
    1636         * 　-6:TILE表示時の選択階層(通常の折りたたみメニュー,2:と同じ)
    1637         *
    1638         * @og.rev 4.0.0.0 (2005/01/31) 新規登録(makeTopMenu、makeSecondMenuの置き換え)
    1639         * @og.rev 4.0.0.0 (2007/11/28) switch文の中の二重コードを統一します。
    1640         * @og.rev 4.2.1.0 (2008/04/01) ボタン形式のリンク対応、マトリクスメニュー2対応
    1641         * @og.rev 4.2.2.0 (2008/05/14) buttonRequestの付加をここで行うようにする
    1642         * @og.rev 4.3.5.0 (2009/02/01) switch の case で重複項目をまとめます。
    1643         * @og.rev 5.1.4.0 (2010/03/01) onClick,onMouseOver,onMouseOutの処理は、外部のJavaScriptファイルで記述します。
    1644         * @og.rev 5.1.8.0 (2010/07/01) コードリソースのキーが存在しない場合にエラーとなるバグを修正
    1645         * @og.rev 5.3.9.0 (2011/09/01) メニューでのヘルプアイコン対応
    1646         * @og.rev 5.4.4.4 (2012/02/15) ヘルプアイコンはimgKeyがnullでない場合のみとする
    1647         * @og.rev 5.5.0.4 (2012/03/14) FAQ対応
    1648         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(画面ID単位ではなく、IMAGE_KEYパラメータで指定可能にする。)
    1649         * @og.rev 5.5.4.2 (2012/07/13) JSP(/gf/jsp/) ではなく、CNTX(gf)＋MENU_IMG(/jsp/menuImage/) で処理するように変更
    1650         * @og.rev 6.2.2.0 (2015/03/27) BRと\nを相互に変換する処理を追加
    1651         * @og.rev 6.2.2.3 (2015/04/10) htmlフィルターに、BR→改行処理機能を追加。
    1652         * @og.rev 6.3.8.4 (2015/10/09) topMenu 内でのHelp機能を廃止します。
    1653         * @og.rev 6.3.8.4 (2015/10/09) FileMap のコンストラクタ変更に伴う対応。
    1654         * @og.rev 6.7.5.0 (2017/03/10) TILE表示追加
    1655         * @og.rev 6.8.0.1 (2017/06/30) -5:1レベル表示追加(元は、相対パスのみ対応していたが、絶対パスにも対応)
    1656         * @og.rev 6.8.1.6 (2017/09/29) imageOnly="true" で、イメージにリンクが付かないバグ修正。
    1657         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"／＞" 止めを、"＞" に変更します)。
    1658         * @og.rev 7.2.9.4 (2020/11/20) spotbugs:switch 文の2つの case のために同じコードを使用しているメソッド
    1659         *
    1660         * @param       href    リンク
    1661         * @param       target  ターゲット
    1662         * @param       bodyIn  BODY部(表示)
    1663         * @param       gamenId 画面ID/グループIDなど
    1664         * @param       imgKey  imageファイルの検索キー
    1665         * @param       type    タイプ
    1666         *
    1667         * @return  階層別メニュー文字列
    1668         * @og.rtnNotNull
    1669         */
    1670        private String makeTagMenuString( final String href,final String target, final String bodyIn,
    1671                                                                final String gamenId,final String imgKey,final int type ) {
    1672
    1673                final String body ;
    1674                final String img ;                      // 6.7.5.0 (2017/03/10) イメージを、【】の外に出す。
    1675                String listStyle = "<li>";
    1676                // 6.3.8.4 (2015/10/09) FileMap のコンストラクタ変更に伴う対応。
    1677                // 最初に見つけたキーが優先されるので、画面IDのファイルを優先します。
    1678                final String imgFile = imgFileMap.getFilename( gamenId,imgKey );        // 5.5.2.5 (2012/05/21) 属性名変更
    1679                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
    1680                if( imgFile == null ) {
    1681                        img = "";
    1682                        if( imageOnly && bodyIn != null && bodyIn.length() > 0 ) {
    1683                                body = "<span title=\"" + StringUtil.htmlFilter( bodyIn,true ) + "\" >" + bodyIn.charAt(0) + "</span>" ;
    1684                        }
    1685                        else {
    1686                                body = bodyIn ;
    1687                        }
    1688                }
    1689                else {
    1690                        if( imageOnly ) {
    1691                                // 6.8.1.6 (2017/09/29) imageOnly="true" で、イメージにリンクが付かないバグ修正。リンクは、body に付く
    1692                                img = "";
    1693                                body = "<img src=\"" + imgFile + "\" class=\"ICON1\" title=\""
    1694//                                                       + StringUtil.htmlFilter( bodyIn,true ) + "\" />" ;
    1695                                                         + StringUtil.htmlFilter( bodyIn,true ) + "\" >" ;                      // 7.0.1.0 (2018/10/15)
    1696                        }
    1697                        // 5.5.2.5 (2012/05/21) -4(MATRIX Menu2)の場合は、<li style="list-style:url(画像URL);"> で処理する。
    1698                        else if( type == -4 ) {
    1699                                listStyle = "<li style=\"list-style:url(" + imgFile + ");\">" ;
    1700                                body = bodyIn ;
    1701                                img = "";
    1702                        }
    1703                        else {
    1704                                // 6.7.5.0 (2017/03/10) TILE表示のﾚﾍﾞﾙ-6では、イメージ直後に BR を入れる。(暫定処置)
    1705                                if( type == -6 ) {
    1706//                                      img = "<img src=\"" + imgFile + "\" class=\"ICON2\" /><br />" ;         // ICON2 + BR
    1707                                        img = "<img src=\"" + imgFile + "\" class=\"ICON2\" ><br>" ;            // ICON2 + BR   7.0.1.0 (2018/10/15)
    1708                                }
    1709                                else {
    1710//                                      img = "<img src=\"" + imgFile + "\" class=\"ICON1\" />" ;                       // ICON1
    1711                                        img = "<img src=\"" + imgFile + "\" class=\"ICON1\" >" ;                        // ICON1                7.0.1.0 (2018/10/15)
    1712                                }
    1713                                body = bodyIn;
    1714                        }
    1715                }
    1716
    1717                final String in ;
    1718                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
    1719                if( href == null ) {
    1720                        in = body;
    1721                }
    1722                else {
    1723                        if( useButton ) { // 4.2.1.0 (2008/04/01)
    1724                                // 6.1.1.0 (2015/01/17) TagBufferの連結記述
    1725                                in = new TagBuffer( "button" )
    1726                                                .add( "onclick" , "top."+target+".location.href=\'"+ href + "\';" )             // 5.1.4.0 (2010/03/01)
    1727                                                .add( "class"   , "buttonMenu" )                // 4.2.1.0 (2008/04/03) classを追加
    1728                                                .add( "id"              , gamenId )                             // 5.5.2.5 (2012/05/21) idを本当の画面IDで設定
    1729                                                .addBody( body )
    1730                                                .makeTag();
    1731                        }
    1732                        else {
    1733                                // 4.2.2.0 (2008/05/14) ボタン式にする場合はリクエスト変数付加
    1734                                // 4.3.3.0 (2008/10/01) 強制プルダウン化の場合はfalseで渡す(excludeButton の値の反転)
    1735                                final String href2 = buttonRequest
    1736                                                                                        ? XHTMLTag.addUrlEncode( href,"buttonRequest=" + !excludeButton)
    1737                                                                                        : href ;
    1738                                // 6.1.1.0 (2015/01/17) TagBufferの連結記述
    1739                                in = new TagBuffer( "a" )
    1740                                                .add( "class"   , "buttonClassify" , buttonRequest )
    1741                                                .add( "href"    , href2 )
    1742                                                .add( "target"  , target )
    1743                                                .addBody( body )
    1744                                                .makeTag();
    1745                        }
    1746                }
    1747
    1748                // 6.7.5.0 (2017/03/10) イメージを、【】の外に出す。
    1749                String rtn = null;
    1750                switch( type ) {
    1751                        // 6.9.8.0 (2018/05/28) FindBugs:switch 文の2つの case のために同じコードを使用しているメソッド
    1752                        // 偶然同じになったのと、これを対応するとソースがみにくくなるので、このままとします。
    1753                        case 1:  rtn = FIELD_IN + "<legend>" + img + in + "</legend>" ; break;  // 大分類
    1754        //              case 2:  rtn = img + "【" + in + "】"     ; break;                // 小分類・直リンク
    1755                        case 3:                                                                                                 // 通常メニュー
    1756                        case 4:  rtn = "　" + img + in                   ; break;                // 隠れメニュー
    1757                        case -1: rtn = "<td class=\"MENU_G " + gamenId + "\">" + img + in + "</td>" ; break;    // 5.5.2.5 (2012/05/21) グループメニュー
    1758                        case -2: rtn = img + "[" + in + "] "    ; break;                // ラインメニュー
    1759        //              case -3: rtn = img + in                                 ; break;                // マトリクスメニュー
    1760                        case -4: rtn = listStyle + in + "</li>" ; break;                // 4.2.1.0 (2008/04/03) リスト。リストのため■はいらない
    1761                        case -3:                                                                                                // 7.2.9.4 (2020/11/20) マトリクスメニュー
    1762                        case -5: rtn = img + in                                 ; break;                // 6.8.0.1 (2017/06/30) 1レベル表示絶対パス
    1763                        case  2:                                                                                                // 7.2.9.4 (2020/11/20) 小分類・直リンク
    1764                        case -6: rtn = img + "【" + in + "】"     ; break;                // 小分類・直リンク(TILE)
    1765                        default :
    1766                                rtn = "X_" + in ;  break;                                                       // 6.0.2.5 (2014/10/31) break追記
    1767                }
    1768
    1769                return rtn ;
    1770        }
    1771
    1772        /**
    1773         * 【TAG】作成するメニューの種類[NORMAL/GROUP/ONELEVEL/NEXTGUI/MATRIX/MATRIX2]を指定します(初期値:NORMAL)。
    1774         *
    1775         * @og.tag
    1776         * 作成するメニューには、複数の種類があります。
    1777         * <table class="plain">
    1778         *   <caption>メニューの種類</caption>
    1779         *   <tr><th>種類    </th><th>説明  </th></tr>
    1780         *   <tr><td>NORMAL  </td><td>通常の階層メニュー</td></tr>
    1781         *   <tr><td>GROUP   </td><td>GROUPのみを取り出してリンクを作成します。(topMenuに利用)</td></tr>
    1782         *   <tr><td>ONELEVEL</td><td>指定のclassify のメニューのみを取り出してリンクを作成します。(lineMenuに利用)</td></tr>
    1783         *   <tr><td>NEXTGUI </td><td>既存のページの次にアクセスされる画面郡のリンクを作成します。</td></tr>
    1784         *   <tr><td>MATRIX  </td><td>一覧表形式のメニューを作成します。(大分類付きマルチメニュー)</td></tr>
    1785         *   <tr><td>MATRIX2 </td><td>一覧表形式のメニューを作成します。(大分類なしボタンメニュー)</td></tr>
    1786         *   <tr><td>NONE    </td><td>表示しない(ヘッダーメニューを表示しない時などに使用)</td></tr>
    1787         *   <tr><td>TILE    </td><td>イメージを使った全面アイコン画面</td></tr>
    1788         * </table>
    1789         *
    1790         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1791         * @og.rev 5.2.3.0 (2010/12/01) NEXTGUI 追加
    1792         * @og.rev 6.3.4.0 (2015/08/01) Arrays.toString から String.join に置き換え。
    1793         * @og.rev 6.3.8.3 (2015/10/03) NONE(表示しない) 追加(JavaDoc追記のみ)。
    1794         * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    1795         * @og.rev 6.7.5.0 (2017/03/10) TILE表示追加
    1796         *
    1797         * @param       type メニューの種類 [NORMAL/GROUP/ONELEVEL/NEXTGUI/MATRIX/MATRIX2/NONE/TILE]
    1798         */
    1799        public void setMenuType( final String type ) {
    1800                menuType = nval( getRequestParameter( type ),menuType );
    1801                if( ! check( menuType, MENU_TYPE_SET ) ) {
    1802                        final String errMsg = "menuType に、指定できない種類の文字が指定されました。" + CR
    1803                                                        + "menuType=[" + menuType + "] "                                                                + CR
    1804                                                        + "menuType List=" + String.join( ", " , MENU_TYPE_SET ) ;
    1805                        throw new HybsSystemException( errMsg );
    1806                }
    1807        }
    1808
    1809        /**
    1810         * 【TAG】折り返しメニューを構築するかどうかを指定します(初期値:true)。
    1811         *
    1812         * @og.tag
    1813         * trueを設定すると、JavaScriptによる折り返しメニューを構築します。
    1814         * false の場合は、通常のHTMLのみで、階層メニューを構築します。
    1815         * 初期値は、true(折り返しメニュー)です。
    1816         *
    1817         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1818         *
    1819         * @param       flag 折り返しメニュー [true:する/false:しない]
    1820         */
    1821        public void setExpand( final String flag ) {
    1822                expand = nval( getRequestParameter( flag ),expand );
    1823        }
    1824
    1825        /**
    1826         * 【TAG】表示対象となるグループをCSV形式で指定します。
    1827         *
    1828         * @og.tag
    1829         * メニューの表示対象グループをCSV形式で複数指定できます。
    1830         * 指定のグループのメニューだけが、表示対象になります。
    1831         * メニューにも、複数のグループを指定できるため、１グループの指定で、
    1832         * 複数のくくりを表示することも可能です。
    1833         * グループを指定しない場合は、全グループが対象になります。
    1834         * また、メニュー側にグループ指定がない場合は、グループ指定に
    1835         * 関係なく、対象になります。
    1836         * 初期値は、未指定(全メニューが対象)です。
    1837         * 分解方法は、通常のパラメータ取得後に、CSV分解します。
    1838         *
    1839         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1840         *
    1841         * @param       menuGroups 表示対象グループ (CSV形式)
    1842         */
    1843        public void setGroups( final String menuGroups ) {
    1844                groups = StringUtil.csv2Array( getRequestParameter( menuGroups ) );
    1845                if( groups.length == 0 ) { groups = null; }
    1846        }
    1847
    1848        /**
    1849         * 【TAG】表示対象となる分類(classify)を指定します。
    1850         *
    1851         * @og.tag
    1852         * メニューの表示対象となる分類(classify)を指定することで、一まとまりの
    1853         * メニューを作成します。これは、３段階メニューの最終メニューを求める場合に
    1854         * 指定します。
    1855         * 最終メニューは、画面上部に設ける予定のメニューで、上下フレーム分割での
    1856         * 運用時に使用します。
    1857         * 分類の指定がない場合は、すべてが表示対象になります。
    1858         * 初期値は、未指定(全メニューが対象)です。
    1859         *
    1860         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1861         *
    1862         * @param       classify 表示対象分類 (classify)
    1863         */
    1864        public void setClassify( final String classify ) {
    1865                selClassify = nval( getRequestParameter( classify ),selClassify );
    1866        }
    1867
    1868        /**
    1869         * 【TAG】グループメニューの表示対象となるソース名(href)を指定します(初期値:menu.jsp)。
    1870         *
    1871         * @og.tag
    1872         * GROUPメニューの表示対象となるソース名(href)を指定することで、
    1873         * サブメニューを自分自身のフレームに対して割り当てるのか、フレームを分けて
    1874         * 管理するのかを自由に設定できます。
    1875         * 初期値は、menu.jspです。
    1876         *
    1877         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1878         *
    1879         * @param       inHref 表示対象ソース名 (href)
    1880         */
    1881        public void setHref( final String inHref ) {
    1882                href = nval( getRequestParameter( inHref ),href );
    1883        }
    1884
    1885        /**
    1886         * 【TAG】グループメニューの表示対象となるフレーム名(target)を指定します(初期値:MENU)。
    1887         *
    1888         * @og.tag
    1889         * GROUPメニューの表示対象となるフレーム名(target)を指定することで、
    1890         * サブメニューを自分自身のフレームに対して割り当てるのか、フレームを分けて
    1891         * 管理するのかを自由に設定できます。
    1892         * フレーム分割を行うと、変更箇所は、サブメニューのみになる為、動きに無駄が
    1893         * なくなりますが、グループメニューの大きさが固定されてしまいます。
    1894         * 自分自身にすると、グループメニューとサブメニューを一つのフレームに
    1895         * 入れることで、更新時の画面のちらつきは発生しますが、無駄なスペースは
    1896         * 省くことが可能になります。
    1897         * 初期値は、MENU(通常のメニューフレーム)です。
    1898         *
    1899         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1900         *
    1901         * @param       inTarget 表示対象フレーム名 (target)
    1902         */
    1903        public void setTarget( final String inTarget ) {
    1904                target = nval( getRequestParameter( inTarget ),target );
    1905        }
    1906
    1907        /**
    1908         * 【TAG】グループメニューの表示に、画像のみかどうか[true:画像のみ/false:画像＋ラベル]を指定します(初期値:false)。
    1909         *
    1910         * @og.tag
    1911         * GROUPメニューの表示対象として、jsp/menuImage 以下に グループ名と同一の
    1912         * 画像ファイルが存在する場合は、画像を使用します。
    1913         * このフラグを、true に設定すると、画像のみを使用します。
    1914         * false の場合は、画像＋グループ名のラベルを使用します。
    1915         * 画像のみの場合でも、title 属性にグループ名のラベルをセットしますので、
    1916         * マウスカーソルをオーバーすれば、名称がTips表示されます。
    1917         * 画像が存在しない場合に、true(画像のみ)に設定した場合は、ラベルの最初の１文字
    1918         * のみを出力します。
    1919         * 初期値は、false(画像＋ラベル)です。
    1920         *
    1921         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1922         *
    1923         * @param       flag グループメニュー表示 [true:画像のみ/false:画像＋ラベル]
    1924         */
    1925        public void setImageOnly( final String flag ) {
    1926                imageOnly = nval( getRequestParameter( flag ),imageOnly );
    1927        }
    1928
    1929        /**
    1930         * 【TAG】グループメニューの表示対象となるメニューを横並びさせる数を指定します。
    1931         *
    1932         * @og.tag
    1933         * GROUPメニューなどの表示を行う場合に、横方向に何個のメニューを表示させるかを
    1934         * 指定します。例えば、画像のみのリンクと組み合わせれば、より、多くのグループを
    1935         * 横方向に並べることで、小領域に多くの情報を詰めることが可能になります。
    1936         * 0 を設定すると、横方向にのみ並べる(折り返さない)メニューを作ることが
    1937         * 可能になります。
    1938         * 初期値は、無制限です。
    1939         *
    1940         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1941         *
    1942         * @param       count 横並び数
    1943         */
    1944        public void setSideCount( final String count ) {
    1945                sideCount = nval( getRequestParameter( count ),sideCount );
    1946        }
    1947
    1948        /**
    1949         * 【TAG】表形式メニュー(MATRIX)の一つのセルに含まれる最小行数を指定します(初期値:8)。
    1950         *
    1951         * @og.tag
    1952         * 表形式メニュー(MATRIX)では、一つのセルの高さを同一にする為、&lt;br /&gt;タグを挿入します。
    1953         * このタグの挿入する個数を指定します。
    1954         * この個数だけ、メニューの数があろうとなかろうと行を確保します。
    1955         * 指定の値が、実際の行数より少ない場合は、実際の行数分だけ拡張されます。
    1956         * 初期値は、8 です。
    1957         *
    1958         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1959         *
    1960         * @param       count セル内最小行数
    1961         * @see         #setMaxCellCount( String )
    1962         */
    1963        public void setMinCellCount( final String count ) {
    1964                minCellCount = nval( getRequestParameter( count ),minCellCount );
    1965        }
    1966
    1967        /**
    1968         * 【TAG】表形式メニュー(MATRIX)の一つのセルに含まれる最大行数を指定します(初期値:8)。
    1969         *
    1970         * @og.tag
    1971         * 表形式メニュー(MATRIX)では、一つのセルの高さを同一にする為、指定の行数で
    1972         * 新たな セルを作成して、セルを横方向に連結します。
    1973         * 初期値は、8 です。
    1974         *
    1975         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    1976         *
    1977         * @param       count セル内最大行数
    1978         * @see         #setMinCellCount( String )
    1979         */
    1980        public void setMaxCellCount( final String count ) {
    1981                maxCellCount = nval( getRequestParameter( count ),maxCellCount );
    1982        }
    1983
    1984        /**
    1985         * 【TAG】グループメニューのキャッシュを使用するかどうか[true/false]を指定します(初期値:true)。
    1986         *
    1987         * @og.tag
    1988         * GROUPメニューの表示は、一旦作成すると、ほとんど書き換えることがありません。
    1989         * 作成は、使用できる全メニューをスキャンして、その中からグループ属性をピックアップ
    1990         * するという処理を行っている為、明らかに無駄な処理です。
    1991         * そこで、jsp/index.jsp が実行された場合のみキャッシュをクリアして、内部では
    1992         * キャッシュがなければ作成し、あればキャッシュを使うロジックになっています。
    1993         * ここでは、キャッシュを使用するのか、毎回作成しなおすのかを指定します。
    1994         * 対象として、jsp/menuImage 以下に グループ名と同一の
    1995         * 画像ファイルが存在する場合は、画像を使用します。
    1996         * このフラグを、true に設定すると、画像のみを使用します。
    1997         * false の場合は、画像＋グループ名のラベルを使用します。
    1998         * 画像のみの場合でも、title 属性にグループ名のラベルをセットしますので、
    1999         * マウスカーソルをオーバーすれば、名称がTips表示されます。
    2000         * 画像が存在しない場合は、たとえ、true(画像のみ)に設定しても、ラベルを出力します。
    2001         * 初期値は、true(キャッシュする)です。
    2002         *
    2003         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    2004         *
    2005         * @param       flag キャッシュ可否 [true:キャッシュする/false:キャッシュしない]
    2006         */
    2007        public void setCache( final String flag ) {
    2008                cache = nval( getRequestParameter( flag ),cache );
    2009        }
    2010
    2011        /**
    2012         * 【TAG】正判定(マッチする場合に、メニューに出す)条件を設定します。
    2013         *
    2014         * @og.tag
    2015         * メニューを表示する/しないの判定を、画面IDのマッチングで判断します。
    2016         * これは、正規表現で表される引数と、画面IDがマッチする場合に、
    2017         * メニューを表示させます。
    2018         * マッチしない場合は、表示されません。
    2019         * 何も指定しない場合は、ロールの判定みの行われます。
    2020         *
    2021         * @param   mt 正判定条件 (マッチする場合に、メニューに出す)
    2022         */
    2023        public void setMatch( final String mt ) {
    2024                match = nval( getRequestParameter( mt ),match );
    2025        }
    2026
    2027        /**
    2028         * 【TAG】逆判定(マッチする場合に、メニューに出さない)条件を設定します。
    2029         *
    2030         * @og.tag
    2031         * メニューを表示する/しないの判定を、画面IDのマッチングで判断します。
    2032         * これは、正規表現で表される引数と、画面IDがマッチする場合に、
    2033         * メニューを表示させません。
    2034         * マッチしない場合は、表示されます。
    2035         * 何も指定しない場合は、ロールの判定みの行われます。
    2036         *
    2037         * @param   umt 逆判定条件 (マッチする場合に、メニューに出さない)
    2038         */
    2039        public void setUnmatch( final String umt ) {
    2040                unmatch = nval( getRequestParameter( umt ),unmatch );
    2041        }
    2042
    2043        /**
    2044         * 【TAG】メニューに使用する画像ファイルのフォルダを指定します(初期値:{@og.value #MENU_IMG})。
    2045         *
    2046         * @og.tag
    2047         * メニューに使用する画像ファイルのフォルダを指定します。
    2048         * 画面IDのキーと一致する画像ファイルを使用します。
    2049         * 初期値は、{@og.value #MENU_IMG} です。
    2050         * /jspからのフォルダ指定が必要です。
    2051         *
    2052         * @og.rev 6.7.5.0 (2017/03/10) TILE表示追加(imageDir 属性追加)
    2053         *
    2054         * @param   dir メニューに使用する画像ファイルのフォルダ
    2055         */
    2056        public void setImageDir( final String dir ) {
    2057                imageDir = nval( getRequestParameter( dir ),imageDir );
    2058        }
    2059
    2060        /**
    2061         * 【TAG】画面リンクにボタンを使用するかどうか[true/false]を指定します(初期値:false)。
    2062         *
    2063         * @og.tag
    2064         * 画面リンクをボタンリンク形式で表示するかを指定します。
    2065         * falseの場合は、通常のリンクになります。
    2066         * 初期値は、false(通常リンク)です。
    2067         *
    2068         * @og.rev 4.2.1.0 (2008/04/01) 新規登録
    2069         *
    2070         * @param       flag ボタンリンク [true:ボタン形式リンク/false:通常リンク]
    2071         */
    2072        public void setUseButton( final String flag ) {
    2073                useButton = nval( getRequestParameter( flag ),useButton );
    2074        }
    2075
    2076        /**
    2077         * 【TAG】マトリクスからの遷移先でボタンメニュー表示するかどうか[true/false]を指定します(初期値:false)。
    2078         *
    2079         * @og.tag
    2080         * マトリクスメニューからの遷移先でボタンメニューを表示させるために
    2081         * アドレスに付加するリクエスト変数を指定します。
    2082         * trueにするとbuttonRequest=trueのリクエスト変数を付けます。
    2083         * falseの場合はリクエスト変数を付けません。
    2084         * 初期値は、false(プルダウン形式で表示)です。
    2085         *
    2086         * @og.rev 4.2.1.0 (2008/04/17) 新規登録
    2087         *
    2088         * @param       flag メニュー形式 [true:ボタン形式/false:通常形式]
    2089         */
    2090        public void setButtonRequest( final String flag ) {
    2091                buttonRequest = nval( getRequestParameter( flag ),buttonRequest );
    2092        }
    2093
    2094        /**
    2095         * 【TAG】標準画面を初期状態で開いた状態で表示するかどうか[true/false]を指定します(初期値:false)。
    2096         *
    2097         * @og.tag
    2098         * 通常expand=trueの状態では、メニューが折りたたまれています。
    2099         * このinlineStyle属性をtrueにすると標準画面のスタイルにdisplay:inlineを
    2100         * 付加する事で、初期状態でメニューが開いた状態になります。
    2101         * expand=falseとの違いは、隠しメニュー及び分類の折りたたみ機能が利用できる事です。
    2102         * 初期値は、false(折りたたまれた状態)です。
    2103         *
    2104         * @og.rev 4.3.3.0 (2008/10/01) 新規
    2105         *
    2106         * @param       flag メニュースタイル [true:開いた状態/false:閉じた状態]
    2107         */
    2108        public void setInlineStyle( final String flag ) {
    2109                inlineStyle = nval( getRequestParameter( flag ),inlineStyle );
    2110        }
    2111
    2112        /**
    2113         * 【TAG】ONELEVEL,NEXTGUI で、DIVタグ＋design-onelevel 処理をするかどうか[true/false]を指定します(初期値:false)。
    2114         *
    2115         * @og.tag
    2116         * ONELEVEL,NEXTGUI は、QUERY 画面の上部に表示される簡易メニューです。
    2117         * この表記は、[画面リンク] 形式のテキスト表示されていますが、画面名称を固定長にするなどの処理を入れるため、
    2118         * DIVでフォーマットします。
    2119         * 作りは、出力される HTML を確認いただきたいと思います。
    2120         * 全体を、&lt;div id="design-onelevel" &gt; で、囲い、画面名称は、&lt;span clas="design-onelevel" &gt; で、囲います。
    2121         * これを、標準CSSで、固定幅と背景色、リンクの文字色など書き換えて、体裁を整えます。
    2122         * 初期値は、false(従来と同じ)です。
    2123         *
    2124         * @og.rev 5.5.2.3 (2012/05/15) 新規追加
    2125         *
    2126         * @param       flag DIVタグ処理するか [true:DIVタグ処理をする/false:しない]
    2127         */
    2128        public void setUseDivOneLevel( final String flag ) {
    2129                useDivOneLevel = nval( getRequestParameter( flag ),useDivOneLevel );
    2130        }
    2131
    2132        /**
    2133         * 画面オブジェクト一覧より、指定されたインデックスより後に実体となる画面ID
    2134         * (直リンク、通常メニュー、隠しメニュー※改行メニューは除く)が存在するかを判定します。
    2135         * グループスが指定されている場合は、グループで絞り込まれた結果に対して判定を行います。
    2136         *
    2137         * @og.rev 4.0.0.0 (2007/10/30) 新規追加
    2138         * @og.rev 6.9.8.0 (2018/05/28) FindBugs 対応で、groupCheckの判定方法に、groups == null も入れる。
    2139         *
    2140         * @param guiInfos 画面オブジェクト一覧
    2141         * @param idx 検索を開始するインデックス番号
    2142         *
    2143         * @return 0:実体画面が存在せず 1:全て隠しの分類 2:実体画面 or 通常画面を含む分類
    2144         */
    2145        private int guiCheck( final GUIInfo[] guiInfos, final int idx ) {
    2146                int flg = 0;
    2147
    2148                // 実態探し
    2149                if( levelCheck( guiInfos[idx] ) > 0 ) {
    2150                        // グループメニューリンク時の処理
    2151                        // 6.9.8.0 (2018/05/28) FindBugs 対応で、groupCheckの判定方法に、groups == null も入れる。
    2152//                      if( groups == null ) { flg = 2; }
    2153//                      else { flg = groupCheck( guiInfos[idx] ) ? 2 : 0; }
    2154                        flg = groupCheck( guiInfos[idx] ) ? 2 : 0;
    2155                }
    2156                else {
    2157                        for( int j=idx+1; j<guiInfos.length; j++ ) {
    2158                                if( !guiInfos[j].isRead() ) { continue; }
    2159                                if( flg > 1 || guiInfos[j].getLevel() <= guiInfos[idx].getLevel() ) { break; }
    2160
    2161                                // 6.9.8.0 (2018/05/28) FindBugs 対応で、groupCheckの判定方法に、groups == null も入れる。
    2162//                              if( groups == null || groupCheck( guiInfos[j] ) ) {
    2163                                if( groupCheck( guiInfos[j] ) ) {
    2164                                        if( levelCheck( guiInfos[j] ) > 0 ) {
    2165                                                flg = levelCheck( guiInfos[j] );
    2166                                        }
    2167                                }
    2168                        }
    2169                }
    2170
    2171                return flg;
    2172        }
    2173
    2174        /**
    2175         * 指定された画面IDが実体であるか(直リンク、通常メニュー、隠しメニュー※改行メニューは除く)を判定します。
    2176         *
    2177         * @og.rev 4.0.0.0 (2007/10/30) 新規追加
    2178         * @og.rev 4.0.0.0 (2007/11/30) switch に default 追加
    2179         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止
    2180         *
    2181         * @param guiInfo 画面オブジェクト
    2182         *
    2183         * @return 0:分類 1:実体画面(隠し) 2:実体画面(通常) or 直リンク
    2184         */
    2185        private int levelCheck( final GUIInfo guiInfo ) {
    2186                int flg = 0;
    2187
    2188                final String adrs = guiInfo.getAddress();       // 6.9.4.1 (2018/04/09) HYBS_BR は、アドレスに設定
    2189
    2190                switch ( guiInfo.getLevel() ) {
    2191                        case 2:
    2192//                              final String adrs = guiInfo.getAddress();
    2193                                if( adrs != null && adrs.length() > 0 ) {
    2194                                        flg = 2;
    2195                                }
    2196                                break;
    2197                        case 3:
    2198//                              flg = "HYBS_BR".equals( guiInfo.getKey() ) ? flg : 2; break;
    2199                                flg = "HYBS_BR".equals( adrs ) ? flg : 2; break;
    2200                        case 4:
    2201//                              flg = "HYBS_BR".equals( guiInfo.getKey() ) ? flg : 1; break;
    2202                                flg = "HYBS_BR".equals( adrs ) ? flg : 1; break;
    2203                        default :
    2204                                flg = 0; break;
    2205                }
    2206
    2207                return flg;
    2208        }
    2209
    2210        /**
    2211         * 指定された画面IDが設定されたグループスに含まれるかを判定します。
    2212         *
    2213         * groups == null か、または、画面IDが設定されたグループスに含まれる場合、true を返します。
    2214         *
    2215         * @og.rev 4.0.0.0 (2007/10/30) 新規追加
    2216         * @og.rev 6.9.8.0 (2018/05/28) FindBugs 対応で、groupCheckの判定方法に、groups == null も入れる。
    2217         *
    2218         * @param guiInfo 画面オブジェクト
    2219         *
    2220         * @return groupsが nullか、グループスに含まれるかどうか
    2221         */
    2222        private boolean groupCheck( final GUIInfo guiInfo ) {
    2223                // 6.9.8.0 (2018/05/28) FindBugs:コンストラクタで初期化されていないフィールドを null チェックなしで null 値を利用している
    2224                if( groups == null ) { return true; }
    2225                else {
    2226                        boolean flg = false;
    2227
    2228                        // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
    2229                        for( final String grp : groups ) {
    2230                                if( guiInfo.isGroupIn( grp ) ) {
    2231//                      for( int k=0; k<groups.length; k++ ) {
    2232//                              if( guiInfo.isGroupIn( groups[k] ) ) {
    2233                                        flg = true;
    2234                                        break;
    2235                                }
    2236                        }
    2237
    2238                        return flg;
    2239                }
    2240        }
    2241
    2242        /**
    2243         * このオブジェクトの文字列表現を返します。
    2244         * 基本的にデバッグ目的に使用します。
    2245         *
    2246         * @return このクラスの文字列表現
    2247         * @og.rtnNotNull
    2248         */
    2249        @Override
    2250        public String toString() {
    2251                return ToString.title( this.getClass().getName() )
    2252                                .println( "VERSION"                             ,VERSION                        )
    2253                                .println( "menuType"                    ,menuType                       )
    2254                                .println( "expand"                              ,expand                         )
    2255                                .println( "groups"                              ,groups                         )
    2256                                .println( "selClassify"                 ,selClassify            )
    2257                                .println( "href"                                ,href                           )
    2258                                .println( "target"                              ,target                         )
    2259                                .println( "imageOnly"                   ,imageOnly                      )
    2260                                .println( "sideCount"                   ,sideCount                      )
    2261                                .println( "minCellCount"                ,minCellCount           )
    2262                                .println( "maxCellCount"                ,maxCellCount           )
    2263                                .println( "cache"                               ,cache                          )
    2264                                .println( "mscKey"                              ,mscKey                         )
    2265//                              .println( "multiSessionCheck"   ,multiSessionCheck      )       // 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
    2266                                .println( "useButton"                   ,useButton                      )
    2267                                .println( "buttonRequest"               ,buttonRequest          )
    2268                                .println( "MENU_TYPE"                   ,MENU_TYPE_SET          )       // 6.4.3.4 (2016/03/11)
    2269                                .println( "Other..."    ,getAttributes().getAttribute() )
    2270                                .fixForm().toString() ;
    2271        }
    2272}