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 * ●形式:<og:topMenu />
060 * ●body:なし
061 *
062 * ●Tag定義:
063 *   <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 *   >   ... Body ...
088 *   </og:topMenu>
089 *
090 * ●使用例
091 *    <og:topMenu />
092 *
093 *    <og:topMenu
094 *          menuType     = "NORMAL"      NORMAL:通常 / GROUP:グループメニュー / ONELEVEL:1レベル / 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"           表形式メニューの1セルの最小行数を指定します。
104 *          maxCellCount = "8"           表形式メニューの1セルの最大行数を指定します。
105 *          cache        = "true"        グループメニューのキャッシュを使用するかどうか指定します。
106 *          match        = "正規表現"    正判定(マッチする場合に、メニューに出す)条件を設定します。
107 *          unmatch      = "正規表現"    逆判定(マッチする場合に、メニューに出さない)条件を設定します。
108 *          useButton    = "false"       ボタン形式のリンクを使用するかを指定します。
109 *          useDivOneLevel  = "false"    ONELEVEL,NEXTGUI で、DIVタグ+design-onelevel 処理をするかどうかを指定します。
110 *    />
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.0.1.0 (2018/10/15)" ;
122        private static final long serialVersionUID = 701020181015L ;
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;                    // 表形式メニューの1セルの最小行数を指定します。
145        private int      maxCellCount   = 8;                    // 表形式メニューの1セルの最大行数を指定します。
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  ;                               // マトリクス2からの遷移でボタン形式にするかのリクエスト変数 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;                            // 表形式メニューの1セルの最小行数を指定します。
287                maxCellCount            = 8;                            // 表形式メニューの1セルの最大行数を指定します。
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                for( int i=0; i<guiInfos.length; i++ ) {
830                        if( guiInfos[i].isRead() ) {
831                                final String gamenId = guiInfos[i].getKey() ;
832                                if( match   != null && !gamenId.matches( match  ) ) { continue; }
833                                if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
834                                // 6.4.5.0 (2016/04/08) 元のループを、拡張for文に変更しただけ。
835                                final String[] guiGroups = StringUtil.csv2Array( guiInfos[i].getGroups() );
836                                for( final String grp : guiGroups ) { groupSet.add( grp ); }
837                        }
838                }
839
840                // 6.4.5.0 (2016/04/08) groupsの削除は、後でまとめて行う。
841                if( groups != null ) {
842                        for( final String grp : groups ) { groupSet.remove( grp ); }
843                }
844
845                // 5.0.0.3 (2009/09/22)
846                // 6.1.1.0 (2015/01/17) refactoring 。size()判定をisEmpty() にすると同時に、if...else を反転する。
847                if( groupSet.isEmpty() ) {
848                        groupMenu = "";
849                }
850                else {
851                        int sideTmpCnt = 1;
852                        final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
853                        rtn.append( "<tr>" );
854
855                        final String allMenu = getLabel( "ALL_MENU" ); // 4.2.2.0 (2008/05/15) ALLはラベルリソース使うように変更
856                        rtn.append( makeTagMenuString( href,target,allMenu,"GUI_ALL",-1 ) );
857                        if( sideCount > 0 && sideTmpCnt % sideCount == 0 ) { rtn.append("</tr><tr>"); }
858                        sideTmpCnt++ ;
859
860                        final Iterator<String> ite = groupSet.iterator() ;
861                        if( groupCode != null ) {
862                                while( ite.hasNext() ) {
863                                        final String group = ite.next();
864                                        final int cdAdrs = groupCode.getAddress( group ) ;
865                                        // 4.0.0.0 (2007/10/05) グループのコードリソースが存在しない場合
866                                        String groupLabel = "";
867                                        if( cdAdrs >= 0 ) { groupLabel = groupCode.getLongLabel( cdAdrs ); }
868
869                                        // 5.1.8.0 (2010/07/01) コードリソースのキーが存在しない場合にエラーとなるバグを修正
870                                        if( groupLabel.isEmpty() && group != null && group.length() > 0 ) {
871                                                groupLabel = group;
872                                        }
873
874//                                      final String src = XHTMLTag.addUrlEncode( href,"group=" + group );
875                                        final String src = XHTMLTag.addUrlEncode( href,"group=" + StringUtil.urlEncode( group ) ); // 5.10.15.2 (2019/09/20)
876                                        rtn.append( makeTagMenuString( src,target,groupLabel,group,-1 ) );
877                                        if( sideCount > 0 && sideTmpCnt % sideCount == 0 ) { rtn.append("</tr><tr>"); }
878                                        sideTmpCnt++ ;
879                                }
880                        }
881
882                        if( ! imageOnly && ! buttonRequest ) { // 4.2.2.0 (2008/05/14) ボタンメニュー時はトップメニュー
883                                rtn.append( makeTagMenuString( JSP + "/index.jsp",target,"Top","GUI_TOP",-1 ) );
884                        }
885                        rtn.append( "</tr>" );
886
887                        // 画面のグループメニューのキャッシュをセットします。
888                        groupMenu = rtn.toString() ;
889                }
890
891                if( cache ) {
892                        setSessionAttribute( cacheKey,groupMenu );
893                }
894
895                return groupMenu;
896        }
897
898        /**
899         * メニューを表示する為のHTMLを作成します(折り返しJavaScript対応版)。
900         *
901         * @og.rev 4.0.0.0 (2005/01/31) GUIInfoの実アドレスのパラメータを考慮する。
902         * @og.rev 4.0.0.0 (2007/10/31) 一旦廃止
903         * @og.rev 5.5.2.3 (2012/05/15) useDivOneLevel 対応
904         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
905         * @og.rev 5.5.6.0 (2013/01/07) useDivOneLevelの折り返し方法変更
906         * @og.rev 6.2.6.0 (2015/06/19) QUERYに表示される1行メニュは、説明なしの画面名称のみ表示する。
907         * @og.rev 5.9.6.1 (2016/03/04) フレーム対応
908         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止 , gamenId の変数設定
909         *
910         * @return  メニュー
911         * @og.rtnNotNull
912         */
913        private String makeOneLevelMenu() {
914                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
915
916                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
917                if( useDivOneLevel ) { rtn.append("<div id=\"design-onelevel\">"); }
918
919                final UserInfo userInfo = getUser();
920
921                // 4.0.0 (2005/01/31)
922                final GUIInfo[] guiInfos = userInfo.getGUIInfos();
923//              String gamenId  ;                       // 画面ID
924                int sideTmpCnt = 1;
925
926                boolean isInClassify = false;
927
928                for( int i=0; i<guiInfos.length; i++ ) {
929                        final String gamenId = guiInfos[i].getKey() ;                           // 6.9.4.1 (2018/04/09)
930                        final int level = guiInfos[i].getLevel();
931
932                        if( level == 2 ) {
933//                              isInClassify = selClassify.equals( guiInfos[i].getKey() );
934                                // 6.9.8.0 (2018/05/28) FindBugs:コンストラクタで初期化されていないフィールドを null チェックなしで null 値を利用している
935                                // makeOneLevelMenu() メソッドが呼ばれる条件に、selClassify != null があるのだが。
936//                              isInClassify = selClassify.equals( gamenId );
937                                isInClassify = gamenId.equals( selClassify );                   // 6.9.8.0 (2018/05/28) とりあえず比較方法を入れ替えます。
938                        }
939
940                        if( guiInfos[i].isRead() && level == 3 && isInClassify ) {              // 4.0.0 (2005/01/31)
941//                              gamenId = guiInfos[i].getKey() ;
942                                if( match   != null && !gamenId.matches( match  ) ) { continue; }
943                                if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
944
945                                final String guiLabel = guiInfos[i].getLabel();         // 6.2.6.0 (2015/06/19) 画面名称(title無)
946
947                                final String thisGamenId = getGUIInfoAttri( "KEY" );
948                                if( gamenId.equals( thisGamenId ) ) {
949                                        // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
950                                        if( useDivOneLevel ) {
951                                                rtn.append("<span class=\"design-onelevel\">").append( guiLabel ).append( "</span>" );
952                                        }
953                                        else {
954                                                rtn.append( '[' ).append( guiLabel ).append( "] " );            // 6.0.2.5 (2014/10/31) char を append する。
955                                        }
956                                }
957                                else {
958                                        // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
959                                        if( useDivOneLevel ) {
960                                                // 5.5.2.5 (2012/05/21) イメージアイコン対応
961                                                rtn.append("<span class=\"design-onelevel\">").append( makeTagMenu( guiInfos[i],guiLabel,-5 ) ).append( "</span>" ); // 5.9.6.1 
962                                        }
963                                        else {
964                                                rtn.append( makeTagMenu( guiInfos[i],guiLabel,-2 ) );           // 5.5.2.5 (2012/05/21) イメージアイコン対応
965                                        }
966                                }
967
968                                if( sideCount > 0 ) {
969                                        // 全件数をサイドカウント数で割った値が最大行数の場合は、終了する。
970                                        if( sideTmpCnt / sideCount >= maxCellCount ) {
971                                                //                                              rtn.append("・・・");
972                                                break;
973                                        }
974                                        // 全件数をサイドカウント数で割った余りがゼロの場合は、行ブレイクする。
975                                        // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
976                                        if( sideTmpCnt % sideCount == 0 ) {
977                                                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
978                                                // 6.0.2.5 (2014/10/31) refactoring: findBugs対応。分岐もコメントアウトする。
979                                //              if( useDivOneLevel ) {
980                                //                      rtn.append( BR ); // 5.6.0.0 (2013/01/07) BRにする(条件分岐は残しておく)
981                                //                      // rtn.append("<span style=\"clear: both;\" />");
982                                //              }
983                                //              else {
984                                                        rtn.append( BR );
985                                //              }
986                                        }
987                                        sideTmpCnt++ ;
988                                }
989                        }
990                }
991
992                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
993                if( useDivOneLevel ) {
994                        rtn.append("<span style=\"clear: both;\" ><!-- --></span></div>");      // 5.9.1.2 (2015/10/23)
995                }
996
997                return rtn.toString();
998        }
999
1000        /**
1001         * 既存のページの次にアクセスされる画面郡のリンクを作成します。
1002         *
1003         * これは、現時点の画面に対して、次にアクセスされる画面の候補を
1004         * ピックアップしておく機能です。
1005         * 実際には、過去にアクセスされた結果より取得しています。
1006         * これは、ONELEVEL と置き換えることになる機能です。
1007         *
1008         * @og.rev 5.2.3.0 (2010/12/01) NEXTGUI 追加
1009         * @og.rev 5.5.2.3 (2012/05/15) useDivOneLevel 対応
1010         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
1011         * @og.rev 6.2.6.0 (2015/06/19) QUERYに表示される1行メニュは、説明なしの画面名称のみ表示する。
1012         * @og.rev 6.3.1.0 (2015/06/28) useDivOneLevel がうまく動かなかったので、修正。
1013         * @og.rev 5.9.6.1 (2016/03/04) フレーム対応
1014         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。
1015         *
1016         * @return  メニュー
1017         * @og.rtnNotNull
1018         */
1019        private String makeNextguiMenu() {
1020                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
1021
1022                // 今、アクセスしている画面
1023                final GUIInfo thisGamen = (GUIInfo)getSessionAttribute( HybsSystem.GUIINFO_KEY );
1024                final String[] nextGuis = thisGamen.getNextGuiArray();
1025
1026                final UserInfo userInfo = getUser();
1027                int sideTmpCnt = 1;
1028
1029                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
1030                if( useDivOneLevel ) { rtn.append("<div id=\"design-onelevel\">"); }
1031
1032                GUIInfo guiInfo = null;
1033                for( int i=0; i<nextGuis.length; i++ ) {
1034                        guiInfo = userInfo.getGUIInfo( nextGuis[i] );
1035                        if( guiInfo == null ) { continue; }             // 存在しない、またはアクセス拒否の場合は、無視する。
1036
1037                        if( guiInfo.isRead() ) {
1038                                final String guiLabel = guiInfo.getLabel();             // 6.2.6.0 (2015/06/19) 画面名称(title無)
1039
1040                                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
1041                                if( useDivOneLevel ) {
1042                                        // 5.5.2.5 (2012/05/21) イメージアイコン対応
1043                                        rtn.append("<span class=\"design-onelevel\">").append( makeTagMenu( guiInfo,guiLabel,-5 ) ).append( "</span>" );
1044                                }
1045                                else {
1046                                        rtn.append( makeTagMenu( guiInfo,guiLabel,-2 ) );               // 5.5.2.5 (2012/05/21) イメージアイコン対応
1047                                }
1048
1049                                if( sideCount > 0 ) {
1050                                        // 全件数をサイドカウント数で割った値が最大行数の場合は、終了する。
1051                                        if( sideTmpCnt / sideCount >= maxCellCount ) {
1052                                                break;
1053                                        }
1054                                        // 全件数をサイドカウント数で割った余りがゼロの場合は、行ブレイクする。
1055                                        // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
1056                                        if( sideTmpCnt % sideCount == 0 ) {
1057                                                // 6.3.1.0 (2015/06/28) useDivOneLevel がうまく動かなかったので、修正。
1058                        //                      if( useDivOneLevel ) {
1059                        //                              rtn.append("<span style=\"clear: both;\" />");
1060                        //                      }
1061                        //                      else {
1062                                                        rtn.append( BR );
1063                        //                      }
1064                                        }
1065                                        sideTmpCnt++ ;
1066                                }
1067                        }
1068                }
1069
1070                // 5.5.2.3 (2012/05/15) useDivOneLevel 対応
1071                // 6.3.1.0 (2015/06/28) useDivOneLevel がうまく動かなかったので、修正。
1072                if( useDivOneLevel ) {
1073//                      rtn.append("<span style=\"clear: both;\" /></div>");
1074                        rtn.append("<span style=\"clear: both;\" ></span></div>");                      // 7.0.1.0 (2018/10/15)
1075                }
1076
1077                return rtn.toString();
1078        }
1079
1080        /**
1081         * メニューを表示する為のHTMLを作成します(マトリクスメニュー)。
1082         *
1083         * 分類まとめ、クラス色指定、最小行数設定、最大行数設定の機能があります。
1084         * 《分類まとめ》 最大行数設定(maxCellCount)に達したセルは、一つ右に新たにセルを作成
1085         * します。このとき、ヘッダーの CLASSIFY を同じにして、colspan でまとめます。
1086         * 《クラス色指定》ヘッダー毎に 順次 CLR0,CLR1,・・・・ というクラス属性を付与します。
1087         * ヘッダーには、MENU_H も出力されています。CLR0 は、大分類ごとに加算されていきますので、
1088         * 繰り返して同じ色を指定する場合は、CSSファイルでまとめて指定してください。
1089         * 《最小行数設定》minCellCount 属性を指定することで、1セルに含まれる最小行数を指定できます。
1090         * これは、セルに入れる &lt;br /&gt; の個数を指定することと同じです。
1091         * 《最大行数設定》maxCellCount 属性を指定することで、1セルに含まれる最大行数を指定できます。
1092         * 分類まとめでも説明しましたように、最大値をオーバーすると次のセルから書き始めます。
1093         *
1094         * @og.rev 4.0.0.0 (2005/11/30) 新規追加
1095         * @og.rev 4.0.0.0 (2007/10/05) 分類のコードリソースが存在しない場合
1096         * @og.rev 5.2.3.0 (2010/12/01) sideCount対応
1097         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
1098         * @og.rev 5.5.5.3 (2012/08/17) th,tdにヘッダの画面IDをクラスとして出力
1099         * @og.rev 6.8.2.3 (2017/11/10) minCellCountの数が、一つ足りない事の修正
1100         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止 , gamenId の変数設定
1101         *
1102         * @return  マトリクスメニュー
1103         * @og.rtnNotNull
1104         */
1105        private String makeMatrixMenu() {
1106                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
1107
1108                final UserInfo userInfo = getUser();
1109
1110                // 4.0.0 (2005/01/31)
1111                final GUIInfo[] guiInfos = userInfo.getGUIInfos();
1112//              String gamenId          ;                       // 画面ID
1113                String bkClassifyKey    = null;         // 分類コード(旧)
1114                String bkClassifyName   = null;         // 分類名称(旧)
1115                int        cellColorCnt = 0;            // MENU_H に 追加する CLR クラス属性の連番
1116
1117                String headGuikey = "";                         //  5.5.5.3 (2012/08/17) ヘッダのgamenId
1118
1119                final StringBuilder rtnH = new StringBuilder( BUFFER_LARGE );
1120                final StringBuilder rtnB = new StringBuilder( BUFFER_LARGE );
1121
1122                int level ;
1123                int preLevel = 0;
1124
1125                int lineTmpCnt = 0;                             // セル中の行カウント
1126                int cellTmpCnt = 0;                             // 1つの分類中のセルカウント
1127                int cellTmpAllCnt = 0;                  // 5.2.3.0 (2010/12/01) 該当行のセルカウント
1128
1129                boolean isInClassify  = false;  // 分類の中か?
1130                boolean isChangeLevel = false;  // 直リンク用(無理やり通常画面の階層として扱うので)
1131                boolean isDummyMENU_S = false;  // 5.2.3.0 (2010/12/01) sideCountブレーク時の大分類領域の出力可否
1132
1133                for( int i=0; i<guiInfos.length; i++ ) {
1134                        if( guiInfos[i].isRead() ) {            // 4.0.0 (2005/01/31)
1135                                final String gamenId = guiInfos[i].getKey() ;
1136                                if( match   != null && !gamenId.matches( match  ) ) { continue; }
1137                                if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
1138
1139                                // 処理すべき画面かのチェック
1140                                final int guiFlg = guiCheck( guiInfos, i );
1141                                if( guiFlg == 0 ) { continue; }
1142
1143                                level = guiInfos[i].getLevel();         // 4.0.0 (2005/01/31)
1144
1145                                // 大分類が来るまでは処理しない
1146                                if( level > 1 && rtnH == null ) { continue; }
1147
1148                                // 直リンクの場合、無理やり通常画面に変換
1149                                if( level == 2 && guiInfos[i].getAddress() != null && guiInfos[i].getAddress().length() != 0 ) {
1150                                        level = 3;
1151                                        if( !isChangeLevel ) {
1152                                                isChangeLevel = true;
1153                                                isInClassify = false;
1154                                        }
1155                                }
1156                                else {
1157                                        isChangeLevel = false;
1158                                }
1159
1160                                // 分類のブレイク処理
1161                                if( preLevel >= 3 && level < 3 || !isInClassify ) {                                                             // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
1162                                        if(  lineTmpCnt != 0 ) {
1163                                                for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
1164                                                rtnB.append( "</td>" ).append( CR );
1165                                        }
1166
1167                                        if( bkClassifyKey != null ) {
1168                                                rtnH.append( "<th colspan=\"" ).append( cellTmpCnt ).append( "\" class=\"MENU_H CLR" )
1169                                                        .append( cellColorCnt ).append( ' ' ).append( headGuikey ).append( "\">" ); // 5.5.5.3 (2012/08/17)
1170                                                if( "_SPACE".equals( bkClassifyKey ) ) {
1171                                                        rtnH.append( ' ' );             // 6.0.2.5 (2014/10/31) char を append する。
1172                                                }
1173                                                else {
1174                                                        rtnH.append( makeTagMenuString( null,null,bkClassifyName,bkClassifyKey,-3 ) );
1175                                                }
1176                                                rtnH.append( "</th>" );
1177
1178                                                // 5.2.3.0 (2010/12/01) sideCount によるセルの改行
1179                                                cellTmpAllCnt += cellTmpCnt;
1180                                                if( sideCount > 0 && cellTmpAllCnt >= sideCount ) {
1181                                                        rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
1182
1183                                                        rtnH.setLength(0);              // 6.1.0.0 (2014/12/26) refactoring
1184                                                        rtnB.setLength(0);              // 6.1.0.0 (2014/12/26) refactoring
1185                                                        cellTmpAllCnt = 0;
1186                                                        isDummyMENU_S = true;   // 出力予約
1187                                                }
1188                                        }
1189
1190                                        bkClassifyKey = null;
1191                                        isInClassify = false;
1192                                        lineTmpCnt = 0;
1193                                        cellTmpCnt = 0;
1194                                }
1195
1196                                // 大分類(フィールドメニュー)
1197                                if( level == 1 ) {
1198                                        headGuikey = gamenId; // 5.5.5.3 (2012/08/17)
1199                                        if( preLevel > 0 ) {
1200                                                cellColorCnt++ ;
1201                                                rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
1202                                        }
1203
1204                                        rtn.append( "<tr><td rowspan=\"2\" class=\"MENU_S "+ headGuikey +"\">" )        // 5.5.5.3 (2012/08/17)
1205                                                .append( makeTagMenuString( null,null,guiInfos[i].getName(),gamenId,-3 ) )
1206                                                .append( "</td>" ).append( CR );
1207
1208                                        rtnH.setLength(0);              // 6.1.0.0 (2014/12/26) refactoring
1209                                        rtnB.setLength(0);              // 6.1.0.0 (2014/12/26) refactoring
1210                                        cellTmpAllCnt = 0;              // 5.2.3.0 (2010/12/01)
1211                                        isDummyMENU_S = false;  // 5.2.3.0 (2010/12/01) 出力予約解除
1212                                }
1213                                // 分類(直リンクの場合は、level=3で処理)
1214                                else if( level == 2 ) {
1215                                        isInClassify = true;
1216//                                      bkClassifyKey = guiInfos[i].getKey();
1217                                        bkClassifyKey = gamenId;                                                // 6.9.4.1 (2018/04/09)
1218                                        bkClassifyName = guiInfos[i].getName();
1219                                }
1220                                // 通常メニュー・隠しメニュー
1221                                else if( level >= 3 ) {
1222
1223                                        // 元のMENU_Sに戻り、rowspan を書き換える・・・のが邪魔くさいので、td のみ出力しておく。
1224                                        // 5.2.3.0 (2010/12/01) sideCount によるセルの改行
1225                                        if( isDummyMENU_S ) {
1226                                                rtn.append( "<tr><td rowspan=\"2\" class=\"MENU_S " )
1227                                                        .append( headGuikey ).append( "\"></td>" )      // 5.5.5.3 (2012/08/17)
1228                                                        .append( CR );
1229                                                isDummyMENU_S = false;          // 出力予約解除
1230                                        }
1231
1232                                        // 画面ID="HYBS_BR"の場合は、セルを変える。
1233//                                      if( "HYBS_BR".equals( guiInfos[i].getKey() ) ) {
1234                                        if( "HYBS_BR".equals( guiInfos[i].getAddress() ) ) {                                    // 6.9.4.1 (2018/04/09) HYBS_BR は、アドレスに設定
1235                                                if( lineTmpCnt != 0 ) {
1236                                                        for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
1237                                                        lineTmpCnt = 0;
1238                                                }
1239                                        }
1240                                        // 通常画面
1241                                        else {
1242                                                if( lineTmpCnt == 0 ) {
1243                                                        rtnB.append( "<td class=\"MENU_B " + headGuikey + "\">" ); // 5.5.5.3 (2012/08/17)
1244                                                        cellTmpCnt++;
1245                                                }
1246
1247                                                rtnB.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),-3 ) );             // 5.5.2.5 (2012/05/21) イメージアイコン対応
1248                                                lineTmpCnt++;
1249
1250                                                if( lineTmpCnt >= maxCellCount ) {
1251                                                        rtnB.append( "</td>" );
1252                                                        lineTmpCnt = 0;
1253                                                }
1254                                                else {
1255                                                        rtnB.append( BR );
1256                                                }
1257
1258                                                // 分類の中に入っていない通常画面
1259                                                if( !isInClassify ) {
1260                                                        bkClassifyKey = "_SPACE";
1261                                                        isInClassify = true;
1262                                                }
1263                                        }
1264                                }
1265
1266                                preLevel = level;
1267                        }
1268                }
1269
1270                // 終了処理
1271                for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
1272                rtnB.append( "</td>" ).append( CR );
1273
1274                if( bkClassifyKey != null ) {
1275                        rtnH.append( "<th colspan=\"" ).append( cellTmpCnt )
1276                                .append( "\" class=\"MENU_H CLR" ) .append(  cellColorCnt )
1277                                .append( ' ' ).append(  headGuikey ).append( "\">" )                    // 5.5.5.3 (2012/08/17)
1278                                .append( makeTagMenuString( null,null,bkClassifyName,bkClassifyKey,-3 ) )
1279                                .append( "</th>" );
1280                }
1281
1282                rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
1283
1284                return rtn.toString();
1285        }
1286
1287        /**
1288         * メニューを表示する為のHTMLを作成します(マトリクスメニュー2)。
1289         *
1290         * マトリクスメニューをベースとした特別バージョンです。
1291         * 通常のマトリクスメニューからの変更点は以下の通りです。
1292         * ①大分類が表示されない
1293         *   ⇒ 変わりに、1行に表示されているセル数がsideCountで指定した数を超えた場合に
1294         *      自動的に改行されます。
1295         * ②画面リンクのターゲット
1296         *   ⇒ 自分自身のフレームに対してリンク先を表示します。
1297         *      リンク先は、通常メニュー構成ですが左メニューには該当する小分類の画面しか表示されません。
1298         * ③小分類でのリンク
1299         *   ⇒ 小分類をクリックした際に、通常のメニュー構成画面にリンクします。
1300         *      但し、②と同様に左メニューには該当する小分類の画面しか表示されません。
1301         *
1302         * @og.rev 4.2.1.0 (2008/04/01) 新規追加
1303         * @og.rev 4.2.1.1 (2008/05/02) カテゴリーリンクで一番上の画面のモードが-wとなっている場合に、
1304         *                               その画面が立ち上がってしまうバグを修正
1305         * @og.rev 4.2.2.0 (2008/05/14) buttonRequestの付加をmakeTagMenuString()に変更
1306         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(makeTagMenuのパラメータ変更)
1307         * @og.rev 5.5.5.3 (2012/08/17) ヘッダ部のgamenIdをth,tdのクラスに追加
1308         * @og.rev 6.8.2.3 (2017/11/10) minCellCountの数が、一つ足りない事の修正
1309         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止 , gamenId の変数設定
1310         *
1311         * @return  マトリクスメニュー
1312         * @og.rtnNotNull
1313         */
1314        private String makeMatrixMenu2() {
1315                final StringBuilder rtn = new StringBuilder( BUFFER_LARGE );
1316
1317                final UserInfo userInfo = getUser();
1318
1319                final GUIInfo[] guiInfos = userInfo.getGUIInfos();
1320//              String gamenId          ;                       // 画面ID
1321                String bkClassifyKey    = null;         // 分類コード(旧)
1322                String nextKey                  = null;         // 分類ボタンを押した時に最初の画面が開くようにする
1323                String bkClassifyName   = null;         // 分類名称(旧)
1324                final int          cellColorCnt = 0;            // MENU_H に 追加する CLR クラス属性の連番
1325
1326                final StringBuilder rtnH = new StringBuilder( BUFFER_LARGE );           // 分類部分の出力用
1327                final StringBuilder rtnB = new StringBuilder( BUFFER_LARGE );           // 実画面のリンク部分の出力用
1328
1329                int level ;
1330                int preLevel = 0;
1331
1332                int lineTmpCnt = 0;                             // セル中の行カウント
1333                int cellTmpCnt = 0;                             // 1つの分類中のセルカウント
1334                int cellTmpAllCnt = 0;                  // 該当行のセルカウント
1335
1336                boolean isInClassify = false;   // 分類の中か?
1337                boolean isChangeLevel = false;  // 直リンク用(無理やり通常画面の階層として扱うので)
1338
1339                String headGuikey = "" ;                // 5.5.5.3 (2012/08/17)
1340
1341                rtn.append( "<tr>" ).append( CR );
1342
1343                for( int i=0; i<guiInfos.length; i++ ) {
1344                        if( guiInfos[i].isRead() ) {            // 4.0.0 (2005/01/31)
1345                                final String gamenId = guiInfos[i].getKey() ;
1346                                if( match   != null && !gamenId.matches( match  ) ) { continue; }
1347                                if( unmatch != null && gamenId.matches( unmatch ) ) { continue; }
1348
1349                                // 処理すべき画面かのチェック
1350                                final int guiFlg = guiCheck( guiInfos, i );
1351                                if( guiFlg == 0 ) { continue; }
1352
1353                                level = guiInfos[i].getLevel();         // 4.0.0 (2005/01/31)
1354
1355                                // 直リンクの場合、無理やり通常画面に変換
1356                                if( level == 2 && guiInfos[i].getAddress() != null && guiInfos[i].getAddress().length() != 0 ) {
1357                                        level = 3;
1358                                        if( !isChangeLevel ) {
1359                                                isChangeLevel = true;
1360                                                isInClassify = false;
1361                                        }
1362                                }
1363                                else {
1364                                        isChangeLevel = false;
1365                                }
1366
1367                                // 分類のブレイク処理
1368                                if( preLevel >= 3 && level < 3 || !isInClassify ) {                                                             // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
1369                                        if(  lineTmpCnt != 0 ) {
1370                                                for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
1371                                                //rtnB.append( "</td>" ).append( CR ); // 4.2.1.0 (2008/04/03) リスト
1372                                                rtnB.append( "</ul></div></td>" ).append( CR );
1373                                        }
1374
1375                                        if( bkClassifyKey != null ) {
1376                                                // 6.0.2.5 (2014/10/31) char を append する。
1377                                                rtnH.append( "<th colspan=\"" ).append( cellTmpCnt ).append( "\" class=\"MENU_H CLR" )
1378                                                        .append( cellColorCnt ).append( ' ' ).append( headGuikey ).append( "\">" );             // 5.5.5.3 (2012/08/17)
1379                                                if( "_SPACE".equals( bkClassifyKey ) ) {
1380                                                        rtnH.append( ' ' );                                     // 6.0.2.5 (2014/10/31) refactoring
1381                                                }
1382                                                else {
1383                                                        // 6.4.2.1 (2016/02/05) PMD refactoring.
1384                                                        final String classifyHref = JSP + "/index.jsp?classify=" + bkClassifyKey + "&amp;GAMENID="+nextKey;             // ボタンを押した場合に最初の画面が現れる
1385                                                        rtnH.append( makeTagMenuString( classifyHref,"_self",bkClassifyName,bkClassifyKey,-3 ) );
1386                                                }
1387                                                rtnH.append( "</th>" );
1388
1389                                                cellTmpAllCnt += cellTmpCnt;
1390
1391                                                if( sideCount > 0 && cellTmpAllCnt >= sideCount ) {
1392                                                        rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
1393
1394                                                        rtnH.setLength(0);                              // 6.1.0.0 (2014/12/26) refactoring
1395                                                        rtnB.setLength(0);                              // 6.1.0.0 (2014/12/26) refactoring
1396                                                        cellTmpAllCnt = 0;
1397                                                }
1398                                        }
1399
1400                                        bkClassifyKey = null;
1401                                        nextKey           = null;
1402                                        isInClassify = false;
1403                                        lineTmpCnt = 0;
1404                                        cellTmpCnt = 0;
1405                                }
1406
1407                                // 5.5.5.3 (2012/08/17) 大分類(フィールドメニュー) 
1408                                if( level == 1 ) {
1409                                        headGuikey = gamenId; 
1410                                }
1411                                // 分類(直リンクの場合は、level=3で処理)
1412                                else if( level == 2 ) {
1413                                        isInClassify = true;
1414                                        if( guiInfos[i].isPulldown() ){ // 4.3.3.0 (2008/10/01) プルダウン化チェック
1415                                                excludeButton = true;
1416                                        }
1417                                        else{
1418                                                excludeButton = false;
1419                                        }
1420//                                      bkClassifyKey = guiInfos[i].getKey();
1421                                        bkClassifyKey = gamenId;                                        // 6.9.4.1 (2018/04/09)
1422                                        bkClassifyName = guiInfos[i].getName();
1423                                        for( int j=i+1; j<guiInfos.length; j++ ) {
1424                                                if( guiInfos[j] != null && guiInfos[j].isRead() ) {
1425                                                        nextKey = guiInfos[j].getKey();
1426                                                        break;
1427                                                }
1428                                        }
1429                                }
1430                                // 通常メニュー・隠しメニュー
1431                                else if( level >= 3 ) {
1432                                        // 画面ID="HYBS_BR"の場合は、セルを変える。
1433//                                      if( "HYBS_BR".equals( guiInfos[i].getKey() ) ) {
1434                                        if( "HYBS_BR".equals( guiInfos[i].getAddress() ) ) {                                    // 6.9.4.1 (2018/04/09) HYBS_BR は、アドレスに設定
1435                                                if( lineTmpCnt != 0 ) {
1436                                                        for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }             // 6.8.2.3 (2017/11/10)
1437                                                        lineTmpCnt = 0;
1438                                                }
1439                                        }
1440                                        // 通常画面
1441                                        else {
1442                                                if( lineTmpCnt == 0 ) {
1443                                                        // rtnB.append( "<td class=\"MENU_B\">" );
1444                                                        // 4.2.1.0 (2008/04/03) リンクをリスト形式で出す案
1445                                                        rtnB.append( "<td class=\"MENU_B "+ headGuikey +"\"> <div class=\"gamen-menu-wrap\"><ul class=\"gamen-menu\">" ); // 5.5.5.3 (2012/08/17)
1446                                                        cellTmpCnt++;
1447                                                }
1448
1449                                                // 5.5.2.5 (2012/05/21) リストは、イメージを設定するので、メソッド側で付与します。
1450                                                rtnB.append( makeTagMenu( guiInfos[i],guiInfos[i].getName(),-4 ) );             // 5.5.2.5 (2012/05/21) イメージアイコン対応
1451                                                lineTmpCnt++;
1452
1453                                                if( lineTmpCnt >= maxCellCount ) {
1454                                                        // rtnB.append( "</td>" );
1455                                                        rtnB.append( " </ul> </div></td>" ); // 4.2.1.0 (008/04/03) リスト
1456                                                        lineTmpCnt = 0;
1457                                                }
1458                                //              else {
1459                                //                      rtnB.append( BR ); // 4.2.1.0 (2008/04/03) リスト。改行不要。
1460                                //              }
1461
1462                                                // 分類の中に入っていない通常画面
1463                                                if( !isInClassify ) {
1464                                                        bkClassifyKey = "_SPACE";
1465                                                        isInClassify = true;
1466                                                }
1467                                        }
1468                                }
1469                                preLevel = level;
1470                        }
1471                }
1472
1473                // 終了処理
1474                // 4.3.3.0 (2008/10/01) 終了処理は0の時行はない
1475                if( lineTmpCnt != 0){
1476                        for( int j=lineTmpCnt; j<minCellCount; j++ ) { rtnB.append( BR ); }                     // 6.8.2.3 (2017/11/10)
1477                        rtnB.append( "</td>" ).append( CR );
1478                }
1479
1480                if( bkClassifyKey != null ) {
1481                        rtnH.append( "<th colspan=\"" + cellTmpCnt + "\" class=\"MENU_H CLR" + cellColorCnt + " " + headGuikey + "\">" ); // 5.5.5.3 (2012/08/17)
1482
1483                        // 6.4.2.1 (2016/02/05) PMD refactoring.
1484                        final String classifyHref = JSP + "/index.jsp?classify=" + bkClassifyKey + "&amp;GAMENID="+nextKey;
1485                        rtnH.append( makeTagMenuString( classifyHref,"_self",bkClassifyName,bkClassifyKey,-3 ) );
1486                        rtnH.append( "</th>" );
1487                }
1488
1489                rtn.append( rtnH ).append( "</tr><tr>" ).append( rtnB ).append( "</tr>" );
1490
1491                return rtn.toString();
1492        }
1493
1494        /**
1495         * タイプに応じたメニューを表示する為の文字列を作成します。
1496         * 引数の GUIInfo より、アクセスすべきメニューのhrefと、targetを求めます。
1497         * type = -3 (マトリクスメニュー) の場合だけ、タグ属性の target を使用します。
1498         *
1499         *  0:フィールドセットメニュー
1500         *  1:トップ階層(【分類名称】)
1501         *  2:選択階層(通常の折りたたみメニュー)
1502         *  3:選択非表示(通常は、隠してあります)
1503         *  -1:グループ分類メニュー(class="GUI_GRP"のtdタグで囲われます)
1504         *  -2:ラインメニュー([画面名称] )
1505         *  -3:マトリクスメニュー(一覧)
1506         *  -4:マトリクスメニュー2(一覧)
1507         *  -5:1レベル表示(後続処理は-3と同じ)
1508         *  -6:TILE表示時の選択階層(通常の折りたたみメニュー,2:と同じ)
1509         *
1510         * @og.rev 4.0.0.0 (2005/01/31) 新規登録(makeTopMenu、makeSecondMenuの置き換え)
1511         * @og.rev 4.1.0.1 (2008/01/22) アドレスが[..]から始まる画面はマルチセッションチェックを行わない。
1512         * @og.rev 4.2.1.0 (2008/04/01) マトリクスメニュー2用のタグ作成処理追加
1513         * @og.rev 4.2.1.0 (2008/04/17) マトリクス2からの遷移先でボタンメニューにする処理
1514         * @og.rev 4.2.2.0 (2008/05/14) buttonRequestの付加をmakeTagMenuString()に変更
1515         * @og.rev 4.3.3.7 (2008/11/22) https対応
1516         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(画面ID単位ではなく、IMAGE_KEYパラメータで指定可能にする。)
1517         * @og.rev 5.7.8.1 (2014/07/18) realAddress の "/" 対応
1518         * @og.rev 6.3.8.4 (2015/10/09) KBLINK(リンク区分)を画面のイメージファイルに割り当てます。
1519         * @og.rev 5.9.6.1 (2016/03/04) -5を追加。-3との違いはresult.jspに飛ばない事
1520         * @og.rev 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
1521         *
1522         * @param       guiInfo GUIInfoリンク
1523         * @param       bodyIn  BODY部(表示)
1524         * @param       type    タイプ
1525         *
1526         * @return  階層別メニュー文字列
1527         * @og.rtnNotNull
1528         */
1529        private String makeTagMenu( final GUIInfo guiInfo, final String bodyIn, final int type ) {
1530
1531                String href              = null;
1532                String tmpTarget = null;
1533                final  String gamenId   = guiInfo.getKey();             // 5.5.2.5 (2012/05/21) イメージアイコン対応
1534                int                       tmpType       = type;                                 // 5.9.6.1
1535
1536                if( guiInfo.getAddress() != null && guiInfo.getAddress().length() > 0 ) {
1537                        final String readAdrs = guiInfo.getRealAddress( "index.jsp" );
1538                        final String reqParam = getRequestParameter( guiInfo.getParam() );
1539                        href = XHTMLTag.addUrlEncode( readAdrs,reqParam );
1540                        tmpTarget = guiInfo.getTarget();
1541
1542                        // 4.3.3.7 (2008/11/22) https対応
1543                        // 5.7.8.1 (2014/07/18) realAddress の "/" 対応
1544                        final String kblink = guiInfo.getKblink();
1545                        if( ! readAdrs.startsWith( "http://" ) && ! readAdrs.startsWith( "https://" ) && !"/".equals( kblink ) ) {
1546                                if( type == -3 ) {
1547                                        tmpTarget = target;
1548                                        href = XHTMLTag.addUrlEncode( JSP + "/result.jsp",reqParam );   // 6.2.0.0 (2015/02/27)
1549                                }
1550                                else if( type == -4 ) {         // 4.2.1.0 (2008/04/01)
1551                                        tmpTarget = "_self";
1552                                        href = XHTMLTag.addUrlEncode( JSP + "/index.jsp",reqParam );    // 6.2.0.0 (2015/02/27)
1553                                        href = XHTMLTag.addUrlEncode( href,"classify=" + guiInfo.getClassify() );
1554                                }
1555                                else if( type == -5 ){          // 5.9.6.1 (2016/03/04)
1556                                        tmpTarget = target;
1557                                        tmpType = -3;
1558                                }
1559                                href = XHTMLTag.addUrlEncode( href,"GAMENID=" + gamenId );                      // 5.5.2.5 (2012/05/21) せっかくなので、利用する。
1560
1561                                // 3.8.0.0 (2005/06/07) 同一セッションでのマルチ起動対策を行います。
1562                                // 4.1.0.1 (2008/01/22) アドレスが[..]から始まる画面はマルチセッションチェックを行いません。
1563                                // 4.1.0.1 (2008/04/01) マトリクスメニュー2はマルチセッションチェックを行いません。
1564//                              if( multiSessionCheck && !guiInfo.getAddress().startsWith( ".." ) && type != -4 ) {
1565                                if( !guiInfo.getAddress().startsWith( ".." ) && type != -4 ) {          // 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
1566                                        href = XHTMLTag.addUrlEncode( href,mscKey );
1567                                }
1568                        }
1569                }
1570                // 5.5.2.5 (2012/05/21) イメージアイコン対応(画面ID単位ではなく、IMAGE_KEYパラメータで指定可能にする。)
1571                final String imgKey = guiInfo.getImageKey() ;
1572                return makeTagMenuString( href,tmpTarget,bodyIn,gamenId,imgKey,tmpType ) ; // 5.9.6.1
1573        }
1574
1575        /**
1576         * タイプに応じたメニューを表示する為の文字列を作成します。
1577         * 従来からのメソッドの引数のままで、新しい gamenId は、imgKey をそのままセットします。
1578         *
1579         *  0:フィールドセットメニュー
1580         *  1:トップ階層(【分類名称】)
1581         *  2:選択階層(通常の折りたたみメニュー)
1582         *  3:選択非表示(通常は、隠してあります)
1583         *  -1:グループ分類メニュー(class="GUI_GRP"のtdタグで囲われます)
1584         *  -2:ラインメニュー([画面名称] )
1585         *  -3:マトリクスメニュー(一覧)
1586         *  -4:マトリクスメニュー2(一覧)
1587         *  -5:1レベル表示(後続処理は-3と同じだが、絶対パスの場合は、画面リソースのtargetを使用する。)
1588         *  -6:TILE表示時の選択階層(通常の折りたたみメニュー,2:と同じ)
1589         *
1590         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(画面ID単位ではなく、IMAGE_KEYパラメータで指定可能にする。)
1591         *
1592         * @param       href    リンク
1593         * @param       target  ターゲット
1594         * @param       bodyIn  BODY部(表示)
1595         * @param       imgKey  imageファイルの検索キー
1596         * @param       type    タイプ
1597         *
1598         * @return  階層別メニュー文字列
1599         * @og.rtnNotNull
1600         */
1601        private String makeTagMenuString( final String href,final String target, final String bodyIn,
1602                                                                final String imgKey,final int type ) {
1603                return makeTagMenuString( href,target,bodyIn,imgKey,imgKey,type );      // gamenId の代わりに、imgKey をセットする。
1604        }
1605
1606        /**
1607         * タイプに応じたメニューを表示する為の文字列を作成します。
1608         *
1609         * タイプは、階層別になっていますが、マイナスは、内部で処理するための記号です。
1610         *
1611         *  0:フィールドセットメニュー
1612         *  1:トップ階層(【分類名称】)
1613         *  2:選択階層(通常の折りたたみメニュー)
1614         *  3:選択非表示(通常は、隠してあります)
1615         *  -1:グループ分類メニュー(class="GUI_GRP"のtdタグで囲われます)
1616         *  -2:ラインメニュー([画面名称] )
1617         *  -3:マトリクスメニュー(一覧)
1618         *  -4:マトリクスメニュー2(一覧)
1619         *  -5:1レベル表示(後続処理は-3と同じだが、絶対パスの場合は、画面リソースのtargetを使用する。)
1620         *  -6:TILE表示時の選択階層(通常の折りたたみメニュー,2:と同じ)
1621         *
1622         * @og.rev 4.0.0.0 (2005/01/31) 新規登録(makeTopMenu、makeSecondMenuの置き換え)
1623         * @og.rev 4.0.0.0 (2007/11/28) switch文の中の二重コードを統一します。
1624         * @og.rev 4.2.1.0 (2008/04/01) ボタン形式のリンク対応、マトリクスメニュー2対応
1625         * @og.rev 4.2.2.0 (2008/05/14) buttonRequestの付加をここで行うようにする
1626         * @og.rev 4.3.5.0 (2009/02/01) switch の case で重複項目をまとめます。
1627         * @og.rev 5.1.4.0 (2010/03/01) onClick,onMouseOver,onMouseOutの処理は、外部のJavaScriptファイルで記述します。
1628         * @og.rev 5.1.8.0 (2010/07/01) コードリソースのキーが存在しない場合にエラーとなるバグを修正
1629         * @og.rev 5.3.9.0 (2011/09/01) メニューでのヘルプアイコン対応
1630         * @og.rev 5.4.4.4 (2012/02/15) ヘルプアイコンはimgKeyがnullでない場合のみとする
1631         * @og.rev 5.5.0.4 (2012/03/14) FAQ対応
1632         * @og.rev 5.5.2.5 (2012/05/21) イメージアイコン対応(画面ID単位ではなく、IMAGE_KEYパラメータで指定可能にする。)
1633         * @og.rev 5.5.4.2 (2012/07/13) JSP(/gf/jsp/) ではなく、CNTX(gf)+MENU_IMG(/jsp/menuImage/) で処理するように変更
1634         * @og.rev 6.2.2.0 (2015/03/27) BRと\nを相互に変換する処理を追加
1635         * @og.rev 6.2.2.3 (2015/04/10) htmlフィルターに、BR→改行処理機能を追加。
1636         * @og.rev 6.3.8.4 (2015/10/09) topMenu 内でのHelp機能を廃止します。
1637         * @og.rev 6.3.8.4 (2015/10/09) FileMap のコンストラクタ変更に伴う対応。
1638         * @og.rev 6.7.5.0 (2017/03/10) TILE表示追加
1639         * @og.rev 6.8.0.1 (2017/06/30) -5:1レベル表示追加(元は、相対パスのみ対応していたが、絶対パスにも対応)
1640         * @og.rev 6.8.1.6 (2017/09/29) imageOnly="true" で、イメージにリンクが付かないバグ修正。
1641         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。
1642         *
1643         * @param       href    リンク
1644         * @param       target  ターゲット
1645         * @param       bodyIn  BODY部(表示)
1646         * @param       gamenId 画面ID/グループIDなど
1647         * @param       imgKey  imageファイルの検索キー
1648         * @param       type    タイプ
1649         *
1650         * @return  階層別メニュー文字列
1651         * @og.rtnNotNull
1652         */
1653        private String makeTagMenuString( final String href,final String target, final String bodyIn,
1654                                                                final String gamenId,final String imgKey,final int type ) {
1655
1656                final String body ;
1657                final String img ;                      // 6.7.5.0 (2017/03/10) イメージを、【】の外に出す。
1658                String listStyle = "<li>";
1659                // 6.3.8.4 (2015/10/09) FileMap のコンストラクタ変更に伴う対応。
1660                // 最初に見つけたキーが優先されるので、画面IDのファイルを優先します。
1661                final String imgFile = imgFileMap.getFilename( gamenId,imgKey );        // 5.5.2.5 (2012/05/21) 属性名変更
1662                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
1663                if( imgFile == null ) {
1664                        img = "";
1665                        if( imageOnly && bodyIn != null && bodyIn.length() > 0 ) {
1666                                body = "<span title=\"" + StringUtil.htmlFilter( bodyIn,true ) + "\" >" + bodyIn.charAt(0) + "</span>" ;
1667                        }
1668                        else {
1669                                body = bodyIn ;
1670                        }
1671                }
1672                else {
1673                        if( imageOnly ) {
1674                                // 6.8.1.6 (2017/09/29) imageOnly="true" で、イメージにリンクが付かないバグ修正。リンクは、body に付く
1675                                img = "";
1676                                body = "<img src=\"" + imgFile + "\" class=\"ICON1\" title=\""
1677//                                                       + StringUtil.htmlFilter( bodyIn,true ) + "\" />" ;
1678                                                         + StringUtil.htmlFilter( bodyIn,true ) + "\" >" ;                      // 7.0.1.0 (2018/10/15)
1679                        }
1680                        // 5.5.2.5 (2012/05/21) -4(MATRIX Menu2)の場合は、<li style="list-style:url(画像URL);"> で処理する。
1681                        else if( type == -4 ) {
1682                                listStyle = "<li style=\"list-style:url(" + imgFile + ");\">" ;
1683                                body = bodyIn ;
1684                                img = "";
1685                        }
1686                        else {
1687                                // 6.7.5.0 (2017/03/10) TILE表示のレベル-6では、イメージ直後に BR を入れる。(暫定処置)
1688                                if( type == -6 ) {
1689//                                      img = "<img src=\"" + imgFile + "\" class=\"ICON2\" /><br />" ;         // ICON2 + BR
1690                                        img = "<img src=\"" + imgFile + "\" class=\"ICON2\" ><br>" ;            // ICON2 + BR   7.0.1.0 (2018/10/15)
1691                                }
1692                                else {
1693//                                      img = "<img src=\"" + imgFile + "\" class=\"ICON1\" />" ;                       // ICON1
1694                                        img = "<img src=\"" + imgFile + "\" class=\"ICON1\" >" ;                        // ICON1                7.0.1.0 (2018/10/15)
1695                                }
1696                                body = bodyIn;
1697                        }
1698                }
1699
1700                final String in ;
1701                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
1702                if( href == null ) {
1703                        in = body;
1704                }
1705                else {
1706                        if( useButton ) { // 4.2.1.0 (2008/04/01)
1707                                // 6.1.1.0 (2015/01/17) TagBufferの連結記述
1708                                in = new TagBuffer( "button" )
1709                                                .add( "onclick" , "top."+target+".location.href=\'"+ href + "\';" )             // 5.1.4.0 (2010/03/01)
1710                                                .add( "class"   , "buttonMenu" )                // 4.2.1.0 (2008/04/03) classを追加
1711                                                .add( "id"              , gamenId )                             // 5.5.2.5 (2012/05/21) idを本当の画面IDで設定
1712                                                .addBody( body )
1713                                                .makeTag();
1714                        }
1715                        else {
1716                                // 4.2.2.0 (2008/05/14) ボタン式にする場合はリクエスト変数付加
1717                                // 4.3.3.0 (2008/10/01) 強制プルダウン化の場合はfalseで渡す(excludeButton の値の反転)
1718                                final String href2 = buttonRequest 
1719                                                                                        ? XHTMLTag.addUrlEncode( href,"buttonRequest=" + !excludeButton)
1720                                                                                        : href ;
1721                                // 6.1.1.0 (2015/01/17) TagBufferの連結記述
1722                                in = new TagBuffer( "a" )
1723                                                .add( "class"   , "buttonClassify" , buttonRequest )
1724                                                .add( "href"    , href2 )
1725                                                .add( "target"  , target )
1726                                                .addBody( body )
1727                                                .makeTag();
1728                        }
1729                }
1730
1731                // 6.7.5.0 (2017/03/10) イメージを、【】の外に出す。
1732                String rtn = null;
1733                switch( type ) {
1734                        // 6.9.8.0 (2018/05/28) FindBugs:switch 文の2つの case のために同じコードを使用しているメソッド
1735                        // 偶然同じになったのと、これを対応するとソースがみにくくなるので、このままとします。
1736                        case 1:  rtn = FIELD_IN + "<legend>" + img + in + "</legend>" ; break;  // 大分類
1737                        case 2:  rtn = img + "【" + in + "】"     ; break;                // 小分類・直リンク
1738                        case 3:                                                                                                 // 通常メニュー
1739                        case 4:  rtn = " " + img + in                   ; break;                // 隠れメニュー
1740                        case -1: rtn = "<td class=\"MENU_G " + gamenId + "\">" + img + in + "</td>" ; break;    // 5.5.2.5 (2012/05/21) グループメニュー
1741                        case -2: rtn = img + "[" + in + "] "    ; break;                // ラインメニュー
1742                        case -3: rtn = img + in                                 ; break;                // マトリクスメニュー
1743                        case -4: rtn = listStyle + in + "</li>" ; break;                // 4.2.1.0 (2008/04/03) リスト。リストのため■はいらない
1744                        case -5: rtn = img + in                                 ; break;                // 6.8.0.1 (2017/06/30) 1レベル表示絶対パス
1745                        case -6: rtn = img + "【" + in + "】"     ; break;                // 小分類・直リンク(TILE)
1746                        default :
1747                                rtn = "X_" + in ;  break;                                                       // 6.0.2.5 (2014/10/31) break追記
1748                }
1749
1750                return rtn ;
1751        }
1752
1753        /**
1754         * 【TAG】作成するメニューの種類[NORMAL/GROUP/ONELEVEL/NEXTGUI/MATRIX/MATRIX2]を指定します(初期値:NORMAL)。
1755         *
1756         * @og.tag
1757         * 作成するメニューには、複数の種類があります。
1758         * <table class="plain">
1759         *   <caption>メニューの種類</caption>
1760         *   <tr><th>種類    </th><th>説明  </th></tr>
1761         *   <tr><td>NORMAL  </td><td>通常の階層メニュー</td></tr>
1762         *   <tr><td>GROUP   </td><td>GROUPのみを取り出してリンクを作成します。(topMenuに利用)</td></tr>
1763         *   <tr><td>ONELEVEL</td><td>指定のclassify のメニューのみを取り出してリンクを作成します。(lineMenuに利用)</td></tr>
1764         *   <tr><td>NEXTGUI </td><td>既存のページの次にアクセスされる画面郡のリンクを作成します。</td></tr>
1765         *   <tr><td>MATRIX  </td><td>一覧表形式のメニューを作成します。(大分類付きマルチメニュー)</td></tr>
1766         *   <tr><td>MATRIX2 </td><td>一覧表形式のメニューを作成します。(大分類なしボタンメニュー)</td></tr>
1767         *   <tr><td>NONE    </td><td>表示しない(ヘッダーメニューを表示しない時などに使用)</td></tr>
1768         *   <tr><td>TILE    </td><td>イメージを使った全面アイコン画面</td></tr>
1769         * </table>
1770         *
1771         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1772         * @og.rev 5.2.3.0 (2010/12/01) NEXTGUI 追加
1773         * @og.rev 6.3.4.0 (2015/08/01) Arrays.toString から String.join に置き換え。
1774         * @og.rev 6.3.8.3 (2015/10/03) NONE(表示しない) 追加(JavaDoc追記のみ)。
1775         * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
1776         * @og.rev 6.7.5.0 (2017/03/10) TILE表示追加
1777         *
1778         * @param       type メニューの種類 [NORMAL/GROUP/ONELEVEL/NEXTGUI/MATRIX/MATRIX2/NONE/TILE]
1779         */
1780        public void setMenuType( final String type ) {
1781                menuType = nval( getRequestParameter( type ),menuType );
1782                if( ! check( menuType, MENU_TYPE_SET ) ) {
1783                        final String errMsg = "menuType に、指定できない種類の文字が指定されました。" + CR
1784                                                        + "menuType=[" + menuType + "] "                                                                + CR
1785                                                        + "menuType List=" + String.join( ", " , MENU_TYPE_SET ) ;
1786                        throw new HybsSystemException( errMsg );
1787                }
1788        }
1789
1790        /**
1791         * 【TAG】折り返しメニューを構築するかどうかを指定します(初期値:true)。
1792         *
1793         * @og.tag
1794         * trueを設定すると、JavaScriptによる折り返しメニューを構築します。
1795         * false の場合は、通常のHTMLのみで、階層メニューを構築します。
1796         * 初期値は、true(折り返しメニュー)です。
1797         *
1798         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1799         *
1800         * @param       flag 折り返しメニュー [true:する/false:しない]
1801         */
1802        public void setExpand( final String flag ) {
1803                expand = nval( getRequestParameter( flag ),expand );
1804        }
1805
1806        /**
1807         * 【TAG】表示対象となるグループをCSV形式で指定します。
1808         *
1809         * @og.tag
1810         * メニューの表示対象グループをCSV形式で複数指定できます。
1811         * 指定のグループのメニューだけが、表示対象になります。
1812         * メニューにも、複数のグループを指定できるため、1グループの指定で、
1813         * 複数のくくりを表示することも可能です。
1814         * グループを指定しない場合は、全グループが対象になります。
1815         * また、メニュー側にグループ指定がない場合は、グループ指定に
1816         * 関係なく、対象になります。
1817         * 初期値は、未指定(全メニューが対象)です。
1818         * 分解方法は、通常のパラメータ取得後に、CSV分解します。
1819         *
1820         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1821         *
1822         * @param       menuGroups 表示対象グループ (CSV形式)
1823         */
1824        public void setGroups( final String menuGroups ) {
1825                groups = StringUtil.csv2Array( getRequestParameter( menuGroups ) );
1826                if( groups.length == 0 ) { groups = null; }
1827        }
1828
1829        /**
1830         * 【TAG】表示対象となる分類(classify)を指定します。
1831         *
1832         * @og.tag
1833         * メニューの表示対象となる分類(classify)を指定することで、一まとまりの
1834         * メニューを作成します。これは、3段階メニューの最終メニューを求める場合に
1835         * 指定します。
1836         * 最終メニューは、画面上部に設ける予定のメニューで、上下フレーム分割での
1837         * 運用時に使用します。
1838         * 分類の指定がない場合は、すべてが表示対象になります。
1839         * 初期値は、未指定(全メニューが対象)です。
1840         *
1841         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1842         *
1843         * @param       classify 表示対象分類 (classify)
1844         */
1845        public void setClassify( final String classify ) {
1846                selClassify = nval( getRequestParameter( classify ),selClassify );
1847        }
1848
1849        /**
1850         * 【TAG】グループメニューの表示対象となるソース名(href)を指定します(初期値:menu.jsp)。
1851         *
1852         * @og.tag
1853         * GROUPメニューの表示対象となるソース名(href)を指定することで、
1854         * サブメニューを自分自身のフレームに対して割り当てるのか、フレームを分けて
1855         * 管理するのかを自由に設定できます。
1856         * 初期値は、menu.jspです。
1857         *
1858         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1859         *
1860         * @param       inHref 表示対象ソース名 (href)
1861         */
1862        public void setHref( final String inHref ) {
1863                href = nval( getRequestParameter( inHref ),href );
1864        }
1865
1866        /**
1867         * 【TAG】グループメニューの表示対象となるフレーム名(target)を指定します(初期値:MENU)。
1868         *
1869         * @og.tag
1870         * GROUPメニューの表示対象となるフレーム名(target)を指定することで、
1871         * サブメニューを自分自身のフレームに対して割り当てるのか、フレームを分けて
1872         * 管理するのかを自由に設定できます。
1873         * フレーム分割を行うと、変更箇所は、サブメニューのみになる為、動きに無駄が
1874         * なくなりますが、グループメニューの大きさが固定されてしまいます。
1875         * 自分自身にすると、グループメニューとサブメニューを一つのフレームに
1876         * 入れることで、更新時の画面のちらつきは発生しますが、無駄なスペースは
1877         * 省くことが可能になります。
1878         * 初期値は、MENU(通常のメニューフレーム)です。
1879         *
1880         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1881         *
1882         * @param       inTarget 表示対象フレーム名 (target)
1883         */
1884        public void setTarget( final String inTarget ) {
1885                target = nval( getRequestParameter( inTarget ),target );
1886        }
1887
1888        /**
1889         * 【TAG】グループメニューの表示に、画像のみかどうか[true:画像のみ/false:画像+ラベル]を指定します(初期値:false)。
1890         *
1891         * @og.tag
1892         * GROUPメニューの表示対象として、jsp/menuImage 以下に グループ名と同一の
1893         * 画像ファイルが存在する場合は、画像を使用します。
1894         * このフラグを、true に設定すると、画像のみを使用します。
1895         * false の場合は、画像+グループ名のラベルを使用します。
1896         * 画像のみの場合でも、title 属性にグループ名のラベルをセットしますので、
1897         * マウスカーソルをオーバーすれば、名称がTips表示されます。
1898         * 画像が存在しない場合に、true(画像のみ)に設定した場合は、ラベルの最初の1文字
1899         * のみを出力します。
1900         * 初期値は、false(画像+ラベル)です。
1901         *
1902         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1903         *
1904         * @param       flag グループメニュー表示 [true:画像のみ/false:画像+ラベル]
1905         */
1906        public void setImageOnly( final String flag ) {
1907                imageOnly = nval( getRequestParameter( flag ),imageOnly );
1908        }
1909
1910        /**
1911         * 【TAG】グループメニューの表示対象となるメニューを横並びさせる数を指定します。
1912         *
1913         * @og.tag
1914         * GROUPメニューなどの表示を行う場合に、横方向に何個のメニューを表示させるかを
1915         * 指定します。例えば、画像のみのリンクと組み合わせれば、より、多くのグループを
1916         * 横方向に並べることで、小領域に多くの情報を詰めることが可能になります。
1917         * 0 を設定すると、横方向にのみ並べる(折り返さない)メニューを作ることが
1918         * 可能になります。
1919         * 初期値は、無制限です。
1920         *
1921         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1922         *
1923         * @param       count 横並び数
1924         */
1925        public void setSideCount( final String count ) {
1926                sideCount = nval( getRequestParameter( count ),sideCount );
1927        }
1928
1929        /**
1930         * 【TAG】表形式メニュー(MATRIX)の一つのセルに含まれる最小行数を指定します(初期値:8)。
1931         *
1932         * @og.tag
1933         * 表形式メニュー(MATRIX)では、一つのセルの高さを同一にする為、&lt;br /&gt;タグを挿入します。
1934         * このタグの挿入する個数を指定します。
1935         * この個数だけ、メニューの数があろうとなかろうと行を確保します。
1936         * 指定の値が、実際の行数より少ない場合は、実際の行数分だけ拡張されます。
1937         * 初期値は、8 です。
1938         *
1939         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1940         *
1941         * @param       count セル内最小行数
1942         * @see         #setMaxCellCount( String )
1943         */
1944        public void setMinCellCount( final String count ) {
1945                minCellCount = nval( getRequestParameter( count ),minCellCount );
1946        }
1947
1948        /**
1949         * 【TAG】表形式メニュー(MATRIX)の一つのセルに含まれる最大行数を指定します(初期値:8)。
1950         *
1951         * @og.tag
1952         * 表形式メニュー(MATRIX)では、一つのセルの高さを同一にする為、指定の行数で
1953         * 新たな セルを作成して、セルを横方向に連結します。
1954         * 初期値は、8 です。
1955         *
1956         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1957         *
1958         * @param       count セル内最大行数
1959         * @see         #setMinCellCount( String )
1960         */
1961        public void setMaxCellCount( final String count ) {
1962                maxCellCount = nval( getRequestParameter( count ),maxCellCount );
1963        }
1964
1965        /**
1966         * 【TAG】グループメニューのキャッシュを使用するかどうか[true/false]を指定します(初期値:true)。
1967         *
1968         * @og.tag
1969         * GROUPメニューの表示は、一旦作成すると、ほとんど書き換えることがありません。
1970         * 作成は、使用できる全メニューをスキャンして、その中からグループ属性をピックアップ
1971         * するという処理を行っている為、明らかに無駄な処理です。
1972         * そこで、jsp/index.jsp が実行された場合のみキャッシュをクリアして、内部では
1973         * キャッシュがなければ作成し、あればキャッシュを使うロジックになっています。
1974         * ここでは、キャッシュを使用するのか、毎回作成しなおすのかを指定します。
1975         * 対象として、jsp/menuImage 以下に グループ名と同一の
1976         * 画像ファイルが存在する場合は、画像を使用します。
1977         * このフラグを、true に設定すると、画像のみを使用します。
1978         * false の場合は、画像+グループ名のラベルを使用します。
1979         * 画像のみの場合でも、title 属性にグループ名のラベルをセットしますので、
1980         * マウスカーソルをオーバーすれば、名称がTips表示されます。
1981         * 画像が存在しない場合は、たとえ、true(画像のみ)に設定しても、ラベルを出力します。
1982         * 初期値は、true(キャッシュする)です。
1983         *
1984         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
1985         *
1986         * @param       flag キャッシュ可否 [true:キャッシュする/false:キャッシュしない]
1987         */
1988        public void setCache( final String flag ) {
1989                cache = nval( getRequestParameter( flag ),cache );
1990        }
1991
1992        /**
1993         * 【TAG】正判定(マッチする場合に、メニューに出す)条件を設定します。
1994         *
1995         * @og.tag
1996         * メニューを表示する/しないの判定を、画面IDのマッチングで判断します。
1997         * これは、正規表現で表される引数と、画面IDがマッチする場合に、
1998         * メニューを表示させます。
1999         * マッチしない場合は、表示されません。
2000         * 何も指定しない場合は、ロールの判定みの行われます。
2001         *
2002         * @param   mt 正判定条件 (マッチする場合に、メニューに出す)
2003         */
2004        public void setMatch( final String mt ) {
2005                match = nval( getRequestParameter( mt ),match );
2006        }
2007
2008        /**
2009         * 【TAG】逆判定(マッチする場合に、メニューに出さない)条件を設定します。
2010         *
2011         * @og.tag
2012         * メニューを表示する/しないの判定を、画面IDのマッチングで判断します。
2013         * これは、正規表現で表される引数と、画面IDがマッチする場合に、
2014         * メニューを表示させません。
2015         * マッチしない場合は、表示されます。
2016         * 何も指定しない場合は、ロールの判定みの行われます。
2017         *
2018         * @param   umt 逆判定条件 (マッチする場合に、メニューに出さない)
2019         */
2020        public void setUnmatch( final String umt ) {
2021                unmatch = nval( getRequestParameter( umt ),unmatch );
2022        }
2023
2024        /**
2025         * 【TAG】メニューに使用する画像ファイルのフォルダを指定します(初期値:{@og.value #MENU_IMG})。
2026         *
2027         * @og.tag
2028         * メニューに使用する画像ファイルのフォルダを指定します。
2029         * 画面IDのキーと一致する画像ファイルを使用します。
2030         * 初期値は、{@og.value #MENU_IMG} です。
2031         * /jspからのフォルダ指定が必要です。
2032         *
2033         * @og.rev 6.7.5.0 (2017/03/10) TILE表示追加(imageDir 属性追加)
2034         *
2035         * @param   dir メニューに使用する画像ファイルのフォルダ
2036         */
2037        public void setImageDir( final String dir ) {
2038                imageDir = nval( getRequestParameter( dir ),imageDir );
2039        }
2040
2041        /**
2042         * 【TAG】画面リンクにボタンを使用するかどうか[true/false]を指定します(初期値:false)。
2043         *
2044         * @og.tag
2045         * 画面リンクをボタンリンク形式で表示するかを指定します。
2046         * falseの場合は、通常のリンクになります。
2047         * 初期値は、false(通常リンク)です。
2048         *
2049         * @og.rev 4.2.1.0 (2008/04/01) 新規登録
2050         *
2051         * @param       flag ボタンリンク [true:ボタン形式リンク/false:通常リンク]
2052         */
2053        public void setUseButton( final String flag ) {
2054                useButton = nval( getRequestParameter( flag ),useButton );
2055        }
2056
2057        /**
2058         * 【TAG】マトリクスからの遷移先でボタンメニュー表示するかどうか[true/false]を指定します(初期値:false)。
2059         *
2060         * @og.tag
2061         * マトリクスメニューからの遷移先でボタンメニューを表示させるために
2062         * アドレスに付加するリクエスト変数を指定します。
2063         * trueにするとbuttonRequest=trueのリクエスト変数を付けます。
2064         * falseの場合はリクエスト変数を付けません。
2065         * 初期値は、false(プルダウン形式で表示)です。
2066         *
2067         * @og.rev 4.2.1.0 (2008/04/17) 新規登録
2068         *
2069         * @param       flag メニュー形式 [true:ボタン形式/false:通常形式]
2070         */
2071        public void setButtonRequest( final String flag ) {
2072                buttonRequest = nval( getRequestParameter( flag ),buttonRequest );
2073        }
2074
2075        /**
2076         * 【TAG】標準画面を初期状態で開いた状態で表示するかどうか[true/false]を指定します(初期値:false)。
2077         *
2078         * @og.tag
2079         * 通常expand=trueの状態では、メニューが折りたたまれています。
2080         * このinlineStyle属性をtrueにすると標準画面のスタイルにdisplay:inlineを
2081         * 付加する事で、初期状態でメニューが開いた状態になります。
2082         * expand=falseとの違いは、隠しメニュー及び分類の折りたたみ機能が利用できる事です。
2083         * 初期値は、false(折りたたまれた状態)です。
2084         *
2085         * @og.rev 4.3.3.0 (2008/10/01) 新規
2086         *
2087         * @param       flag メニュースタイル [true:開いた状態/false:閉じた状態]
2088         */
2089        public void setInlineStyle( final String flag ) {
2090                inlineStyle = nval( getRequestParameter( flag ),inlineStyle );
2091        }
2092
2093        /**
2094         * 【TAG】ONELEVEL,NEXTGUI で、DIVタグ+design-onelevel 処理をするかどうか[true/false]を指定します(初期値:false)。
2095         *
2096         * @og.tag
2097         * ONELEVEL,NEXTGUI は、QUERY 画面の上部に表示される簡易メニューです。
2098         * この表記は、[画面リンク] 形式のテキスト表示されていますが、画面名称を固定長にするなどの処理を入れるため、
2099         * DIVでフォーマットします。
2100         * 作りは、出力される HTML を確認いただきたいと思います。
2101         * 全体を、&lt;div id="design-onelevel" &gt; で、囲い、画面名称は、&lt;span clas="design-onelevel" &gt; で、囲います。
2102         * これを、標準CSSで、固定幅と背景色、リンクの文字色など書き換えて、体裁を整えます。
2103         * 初期値は、false(従来と同じ)です。
2104         *
2105         * @og.rev 5.5.2.3 (2012/05/15) 新規追加
2106         *
2107         * @param       flag DIVタグ処理するか [true:DIVタグ処理をする/false:しない]
2108         */
2109        public void setUseDivOneLevel( final String flag ) {
2110                useDivOneLevel = nval( getRequestParameter( flag ),useDivOneLevel );
2111        }
2112
2113        /**
2114         * 画面オブジェクト一覧より、指定されたインデックスより後に実体となる画面ID
2115         * (直リンク、通常メニュー、隠しメニュー※改行メニューは除く)が存在するかを判定します。
2116         * グループスが指定されている場合は、グループで絞り込まれた結果に対して判定を行います。
2117         *
2118         * @og.rev 4.0.0.0 (2007/10/30) 新規追加
2119         * @og.rev 6.9.8.0 (2018/05/28) FindBugs 対応で、groupCheckの判定方法に、groups == null も入れる。
2120         *
2121         * @param guiInfos 画面オブジェクト一覧
2122         * @param idx 検索を開始するインデックス番号
2123         *
2124         * @return 0:実体画面が存在せず 1:全て隠しの分類 2:実体画面 or 通常画面を含む分類
2125         */
2126        private int guiCheck( final GUIInfo[] guiInfos, final int idx ) {
2127                int flg = 0;
2128
2129                // 実態探し
2130                if( levelCheck( guiInfos[idx] ) > 0 ) {
2131                        // グループメニューリンク時の処理
2132                        // 6.9.8.0 (2018/05/28) FindBugs 対応で、groupCheckの判定方法に、groups == null も入れる。
2133//                      if( groups == null ) { flg = 2; }
2134//                      else { flg = groupCheck( guiInfos[idx] ) ? 2 : 0; }
2135                        flg = groupCheck( guiInfos[idx] ) ? 2 : 0;
2136                }
2137                else {
2138                        for( int j=idx+1; j<guiInfos.length; j++ ) {
2139                                if( !guiInfos[j].isRead() ) { continue; }
2140                                if( flg > 1 || guiInfos[j].getLevel() <= guiInfos[idx].getLevel() ) { break; }
2141
2142                                // 6.9.8.0 (2018/05/28) FindBugs 対応で、groupCheckの判定方法に、groups == null も入れる。
2143//                              if( groups == null || groupCheck( guiInfos[j] ) ) {
2144                                if( groupCheck( guiInfos[j] ) ) {
2145                                        if( levelCheck( guiInfos[j] ) > 0 ) {
2146                                                flg = levelCheck( guiInfos[j] );
2147                                        }
2148                                }
2149                        }
2150                }
2151
2152                return flg;
2153        }
2154
2155        /**
2156         * 指定された画面IDが実体であるか(直リンク、通常メニュー、隠しメニュー※改行メニューは除く)を判定します。
2157         *
2158         * @og.rev 4.0.0.0 (2007/10/30) 新規追加
2159         * @og.rev 4.0.0.0 (2007/11/30) switch に default 追加
2160         * @og.rev 6.9.4.1 (2018/04/09) HYBS_BR の廃止
2161         *
2162         * @param guiInfo 画面オブジェクト
2163         *
2164         * @return 0:分類 1:実体画面(隠し) 2:実体画面(通常) or 直リンク
2165         */
2166        private int levelCheck( final GUIInfo guiInfo ) {
2167                int flg = 0;
2168
2169                final String adrs = guiInfo.getAddress();       // 6.9.4.1 (2018/04/09) HYBS_BR は、アドレスに設定
2170
2171                switch ( guiInfo.getLevel() ) {
2172                        case 2:
2173//                              final String adrs = guiInfo.getAddress();
2174                                if( adrs != null && adrs.length() > 0 ) {
2175                                        flg = 2;
2176                                }
2177                                break;
2178                        case 3:
2179//                              flg = "HYBS_BR".equals( guiInfo.getKey() ) ? flg : 2; break;
2180                                flg = "HYBS_BR".equals( adrs ) ? flg : 2; break;
2181                        case 4:
2182//                              flg = "HYBS_BR".equals( guiInfo.getKey() ) ? flg : 1; break;
2183                                flg = "HYBS_BR".equals( adrs ) ? flg : 1; break;
2184                        default :
2185                                flg = 0; break;
2186                }
2187
2188                return flg;
2189        }
2190
2191        /**
2192         * 指定された画面IDが設定されたグループスに含まれるかを判定します。
2193         *
2194         * groups == null か、または、画面IDが設定されたグループスに含まれる場合、true を返します。
2195         *
2196         * @og.rev 4.0.0.0 (2007/10/30) 新規追加
2197         * @og.rev 6.9.8.0 (2018/05/28) FindBugs 対応で、groupCheckの判定方法に、groups == null も入れる。
2198         *
2199         * @param guiInfo 画面オブジェクト
2200         *
2201         * @return groupsが nullか、グループスに含まれるかどうか
2202         */
2203        private boolean groupCheck( final GUIInfo guiInfo ) {
2204                // 6.9.8.0 (2018/05/28) FindBugs:コンストラクタで初期化されていないフィールドを null チェックなしで null 値を利用している
2205                if( groups == null ) { return true; }
2206                else {
2207                        boolean flg = false;
2208
2209                        for( int k=0; k<groups.length; k++ ) {
2210                                if( guiInfo.isGroupIn( groups[k] ) ) {
2211                                        flg = true;
2212                                        break;
2213                                }
2214                        }
2215
2216                        return flg;
2217                }
2218        }
2219
2220        /**
2221         * このオブジェクトの文字列表現を返します。
2222         * 基本的にデバッグ目的に使用します。
2223         *
2224         * @return このクラスの文字列表現
2225         * @og.rtnNotNull
2226         */
2227        @Override
2228        public String toString() {
2229                return ToString.title( this.getClass().getName() )
2230                                .println( "VERSION"                             ,VERSION                        )
2231                                .println( "menuType"                    ,menuType                       )
2232                                .println( "expand"                              ,expand                         )
2233                                .println( "groups"                              ,groups                         )
2234                                .println( "selClassify"                 ,selClassify            )
2235                                .println( "href"                                ,href                           )
2236                                .println( "target"                              ,target                         )
2237                                .println( "imageOnly"                   ,imageOnly                      )
2238                                .println( "sideCount"                   ,sideCount                      )
2239                                .println( "minCellCount"                ,minCellCount           )
2240                                .println( "maxCellCount"                ,maxCellCount           )
2241                                .println( "cache"                               ,cache                          )
2242                                .println( "mscKey"                              ,mscKey                         )
2243//                              .println( "multiSessionCheck"   ,multiSessionCheck      )       // 6.9.5.0 (2018/04/23) multiSessionCheck 廃止(true固定)
2244                                .println( "useButton"                   ,useButton                      )
2245                                .println( "buttonRequest"               ,buttonRequest          )
2246                                .println( "MENU_TYPE"                   ,MENU_TYPE_SET          )       // 6.4.3.4 (2016/03/11)
2247                                .println( "Other..."    ,getAttributes().getAttribute() )
2248                                .fixForm().toString() ;
2249        }
2250}