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