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.fukurou.util.XHTMLTag;
022import org.opengion.fukurou.util.TagBuffer;
023import org.opengion.fukurou.util.StringUtil;
024
025import static org.opengion.fukurou.util.StringUtil.nval;
026import org.opengion.fukurou.util.EnumType;
027
028import java.util.Locale;
029
030/**
031 * 戻るボタン/戻るリンクを表示するHTML拡張タグです(通常はcustom/query_info.jspに組込み)。
032 *
033 * custom/query_info.jsp に組み込むことで、全てのquery.jspに組込む事ができます。
034 * 戻るボタン/リンクを表示するかどうかの条件判定は、
035 *   条件1:自分自身へ戻る機能はサポートできません。
036 *   条件2:BACK_GAMENID が存在するか、または、gamenId で指示された場合のみ表示。
037 *   条件3:command="NEW" で、キャッシュに設定しておく必要がある。
038 *
039 * @og.formSample
040 * ●形式:<og:backGamen keys="・・・" vals="・・・" > ・・Body・・ </og:backGamen>
041 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します)
042 *
043 * ●Tag定義:
044 *   <og:backGamen
045 *       type               【TAG】ボタンのタイプ[link/button/relLink/relButton/historyBack]を指定します(初期値:link)
046 *       command            【TAG】(通常は使いません)戻る時に指定する command を設定できます(初期値:RENEW)
047 *       gamenId            【TAG】(通常は使いません)戻り先の画面をセットします(初期値:BACK_GAMENID)
048 *       keys               【TAG】リンク先に渡すキーをCSV形式で複数指定します
049 *       vals               【TAG】keys属性に対応する値をCSV形式で複数指定します
050 *       lbl                【TAG】ラベルリソースのラベルIDを指定します
051 *       href               【HTML】リンク先のURLを指定します
052 *       target             【HTML】リンク先の表示ターゲットを指定します(初期値:CONTENTS)
053 *       id                 【HTML】要素に対して固有の名前(id)をつける場合に設定します
054 *       lang               【HTML】要素の内容と他の属性値の言語(lang,xml:lang)を指定します
055 *       dir                【HTML】文字表記の方向(dir)を指定します
056 *       title              【HTML】要素に対する補足的情報(title)を設定します
057 *       style              【HTML】この要素に対して適用させるスタイルシート(style)を設定します
058 *       tabindex           【HTML】タブの移動順(tabindex)を指定します(0 ~ 32767)
059 *       accesskey          【HTML】アクセスキー(alt+キーで直接指定)を割り当てます(初期値:R)
060 *       clazz              【HTML】要素に対して class 属性を設定します
061 *       language           【TAG】タグ内部で使用する言語コード[ja/en/zh/…]を指定します
062 *       onClick            【HTML】JavaScriptのイベント onClick を設定します(例:onClick="renew('query.jsp','QUERY');")
063 *       onBlur             【HTML】JavaScriptのイベント onBlur を設定します(例:onBlur="this.value=value.toUpperCase();")
064 *       onFocus            【HTML】JavaScriptのイベント onFocus を設定します
065 *       ondblClick         【HTML】JavaScriptのイベント ondblClick を設定します
066 *       onMouseDown        【HTML】JavaScriptのイベント onMouseDown を設定します
067 *       onMouseUp          【HTML】JavaScriptのイベント onMouseUp を設定します
068 *       onMouseMove        【HTML】JavaScriptのイベント onMouseMove を設定します
069 *       onMouseOut         【HTML】JavaScriptのイベント onMouseOut を設定します
070 *       onMouseOver        【HTML】JavaScriptのイベント onMouseOver を設定します
071 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
072 *   >   ... Body ...
073 *   </og:backGamen>
074 *
075 * ●使用例
076 *   <og:backGamen keys="displayMsg,clear" vals="MSG0065,true" >
077 *       <og:img src="{@SYS.JSP}/image/back.gif" alt="{@BACK_GAMENID}" />
078 *       <og:message lbl="MSG0049" />
079 *   </og:backGamen>
080 *
081 * 7.3.1.0 (2021/02/02)
082 *  リンクタグで、useBackLink 属性を使用することで、戻るリンクをある程度制御できます。
083 *  何も指定しない場合(null)は、従来通りです。
084 * true:相手先に(条件が成立すれば)戻るリンクを表示。条件が成立しない場合は、自身へのリンクが表示。
085 * false:必ず表示しない
086 * 未指定(null):従来通り…自分自身では戻るリンクを表示せず、別画面の場合のみ表示します。
087 *
088 * @og.rev 3.1.8.0 (2003/05/16) 新規作成
089 * @og.group 画面制御
090 *
091 * @version     4.0
092 * @author      Kazuhiko Hasegawa
093 * @since       JDK5.0,
094 */
095public class BackGamenTag extends HTMLTagSupport {
096        /** このプログラムのVERSION文字列を設定します。 {@value} */
097        private static final String VERSION = "8.5.2.0 (2023/07/14)" ;
098        private static final long serialVersionUID = 852020230714L ;
099
100        // 4.0.0 (2005/05/31) JDK5.0 enum 対応
101        /**
102         * type 属性として指定できる選択肢を定義します。
103         */
104        private static final EnumType<String> CHECK_TYPE =
105                                new EnumType<>( "ボタンのタイプ","link" )
106                                        .append( "link"                 ,"戻るリンクを作成します。"                                 )
107                                        .append( "relLink"              ,"戻るリンク(相対パス)を作成します。"           )
108                                        .append( "button"               ,"戻るボタンを作成します。"                                 )
109                                        .append( "relButton"    ,"戻るボタン(相対パス)を作成します。"           )
110                                        .append( "historyBack"  ,"通常のヒストリバックボタンを作成します。" ) ;
111
112//      // 6.9.4.1 (2018/04/09) FILEFILTER使用時(紙芝居作成時)に、true になります。8.5.2.0 (2023/07/14) Delete
113//      private static final boolean USE_FILEFILTER = "true".equalsIgnoreCase( HybsSystem.sys( "USE_FILEFILTER" ) );    // null時は、false
114
115        /** ボタンのタイプ */
116        private String          type            = CHECK_TYPE.getDefault() ;
117        /** コマンド */
118        private String          command         = "RENEW" ;
119        /** 戻り先の画面ID */
120        private String          gamenId         ;
121        /** リンク先の表示ターゲット */
122        private String          target          = "CONTENTS";
123        /** ボタンに使用するショートカットキー文字 */
124        private String          accesskey       = "R";
125        /** リンク先に渡すキー */
126        private String[]        keys            ;
127        /** リンク先に渡すキーに対する値 */
128        private String[]        vals            ;
129        /** BODY 部分に記述した値 */
130        private String          body            ;
131        /** 戻るアドレス */
132        private String          backAddress     ;                                               // 4.0.1.0 (2007/12/18)
133
134        /**
135         * デフォルトコンストラクター
136         *
137         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
138         */
139        public BackGamenTag() { super(); }              // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
140
141        /**
142         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
143         *
144         * @return      後続処理の指示( EVAL_BODY_BUFFERED )
145         */
146        @Override
147        public int doStartTag() {
148                return EVAL_BODY_BUFFERED ;     // Body を評価する。( extends BodyTagSupport 時)
149        }
150
151        /**
152         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
153         *
154         * @return      後続処理の指示(SKIP_BODY)
155         */
156        @Override
157        public int doAfterBody() {
158                body = getBodyString();
159
160                return SKIP_BODY ;
161        }
162
163        /**
164         * タグリブオブジェクトをリリースします。
165         *
166         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
167         */
168        @Override
169        protected void release2() {
170                super.release2();
171                type            = CHECK_TYPE.getDefault();
172                command         = "RENEW";
173                gamenId         = null;
174                target          = "CONTENTS";
175                accesskey       = "R";
176                keys            = null;
177                vals            = null;
178                body            = null;
179                backAddress     = null;
180        }
181
182        /**
183         * 戻るボタン/戻るリンクを作成します。
184         *
185         * @og.rev 3.1.8.0 (2003/05/16) BACK_GAMENID のキャッシュの取り出し先を変更する。
186         * @og.rev 3.5.4.0 (2003/11/25) 履歴(history)オブジェクトのback() メソッドを利用した戻る機能を追加します。
187         * @og.rev 4.0.1.0 (2007/12/17) BackAddress対応
188         * @og.rev 5.0.2.0 (2009/11/01) 相対パスでの戻るリンク対応
189         *
190         * @return      戻るボタン/戻るリンク
191         */
192        @Override
193        protected String makeTag() {
194                String rtn = "" ;
195
196                if( gamenId == null ) {
197                        gamenId = getBackGamenId();
198                }
199                if( backAddress == null) {                                                      // 4.0.1.0 (2007/12/17)
200                        backAddress = getBackAddress();
201                }
202
203                // 4.0.0 (2005/05/31)
204                if( "historyBack".equalsIgnoreCase( type ) ) {
205                        final String hb = getRequest().getParameter( "historyBack" );
206                        if( "1".equals( hb ) ) {
207                                rtn = makeHistoryBackTag();
208                        }
209                }
210                else {
211                        if( checkCondition( gamenId ) ) {
212                                set( "target" ,nval( get( "target" ), target ) );
213
214                                // 5.0.2.0 (2009/11/01) 相対パスでの戻る対応
215                                if( "link".equalsIgnoreCase( type ) || "relLink".equalsIgnoreCase( type ) ) {
216                                        rtn = makeLinkTag();
217                                }
218                                else if( "button".equalsIgnoreCase( type ) || "relButton".equalsIgnoreCase( type ) ) {
219                                        rtn = makeButtonTag();                                  // 3.8.1.2 (2005/12/19)
220                                }
221                                else {
222                                        final String errMsg = "指定の type は、下記の範囲で指定してください。"
223                                                                        + "type=" + type + " : "
224                                                                        + CHECK_TYPE.toString();
225                                        throw new HybsSystemException( errMsg );
226                                }
227                        }
228                }
229
230                return rtn ;
231        }
232
233        /**
234         * 戻るリンクを作成します。
235         *
236         * @og.rev 3.5.5.0 (2004/03/12) 戻るアドレスを、GUIInfoより取得するように変更。
237         * @og.rev 4.0.0.0 (2005/01/31) GUIInfoの実アドレスのパラメータを考慮する。
238         * @og.rev 3.7.0.3 (2005/03/01) 戻る行番号を、BACK_ROW_KEYより取得し、SEL_ROW で渡す。
239         * @og.rev 4.0.1.0 (2007/12/17) 戻るアドレスをbackAddressを使うように変更
240         * @og.rev 4.0.2.1 (2007/12/27) リクエスト部からGAMENIDを外していたが、二段階戻る場合に不具合が出たため元に戻す
241         * @og.rev 5.0.2.0 (2009/11/01) 相対パスでの戻るリンク対応
242         * @og.rev 6.9.4.1 (2018/04/09) FILEFILTER使用時(紙芝居作成時)は、相対リンクを出力するようにします。
243         * @og.rev 8.5.2.0 (2023/07/14) 一部の機能廃止による修正(問合・トラブル 0200010980)
244         *
245         * @return      戻るリンク
246         * @og.rtnNotNull
247         */
248        private String makeLinkTag() {
249                set( "body",getMsglbl( gamenId ) );
250                String href = get( "href" );
251                if( href == null) {
252                        // 3.5.5.0 (2004/03/12)
253                        // 5.0.2.0 (2009/11/01) 相対パスでの戻る対応
254//                      if( backAddress == null || "relLink".equalsIgnoreCase( type ) ) {       // 4.0.1.0 (2007/12/17) if文追加
255//                      if( backAddress == null || "relLink".equalsIgnoreCase( type ) || USE_FILEFILTER ) {     // 6.9.4.1 (2018/04/09) FILEFILTER使用時は、相対リンクを出力
256                        if( backAddress == null || "relLink".equalsIgnoreCase( type ) ) {       // 8.5.2.0 (2023/07/14) Modify
257                                final GUIInfo guiInfo = getGUIInfo( gamenId );                                  // 4.0.0 (2005/01/31)
258                                if( guiInfo == null ) { return ""; }                                                    // 見つからない場合は、アクセス不可
259                                final String address = guiInfo.getRealAddress( "index.jsp" );
260                                href = getRequestParameter( address );
261                        }
262                        else { // 4.0.1.0 (2007/12/17)
263                                href = backAddress;
264                        }
265                }
266
267                // 3.7.0.3 (2005/03/01) 戻る行番号を、BACK_ROW_KEYより取得し、SEL_ROW で渡す。
268                final String rowkey = HybsSystem.BACK_ROW_KEY + getGUIInfoAttri( "KEY" );
269                final String rowVal = (String)getSessionAttribute( rowkey );
270
271                final String[] keys2 = new String[] { "command","GAMENID","SEL_ROW" };
272                final String[] vals2 = new String[] {  command , gamenId , rowVal   };
273                final String urlEnc2 = XHTMLTag.urlEncode( keys2,vals2 );
274                href = XHTMLTag.addUrlEncode( href,urlEnc2 );
275
276                final String urlEnc = XHTMLTag.urlEncode( keys,vals );
277                href = XHTMLTag.addUrlEncode( href,urlEnc );
278
279                set( "href",href );
280
281                return XHTMLTag.link( getAttributes() ) ;
282        }
283
284        /**
285         * 戻るボタンのフォームを作成します。
286         *
287         * @og.rev 3.5.5.0 (2004/03/12) 戻るアドレスを、GUIInfoより取得するように変更。
288         * @og.rev 3.5.5.5 (2004/04/23) hidden の出力に、XHTMLTag.hidden を使用します。
289         * @og.rev 3.8.1.2 (2005/12/19) メソッド名変更、inputタグ⇒buttonタグ変更
290         * @og.rev 4.0.1.0 (2007/12/17) BACK_ADDRESS対応
291         * @og.rev 5.0.2.0 (2009/11/01) 相対パスでの戻るリンク対応
292         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
293         * @og.rev 6.9.4.1 (2018/04/09) FILEFILTER使用時(紙芝居作成時)は、相対リンクを出力するようにします。
294         * @og.rev 8.5.2.0 (2023/07/14) 一部の機能廃止による修正(問合・トラブル 0200010980)
295         *
296         * @return      戻るボタンのフォーム
297         * @og.rtnNotNull
298         */
299        private String makeButtonTag() {
300
301                final String href = get( "href" );
302                if( href == null ) {
303                        // 3.5.5.0 (2004/03/12)
304                        // 5.0.2.0 (2009/11/01) 相対パスでの戻る対応
305//                      if( backAddress == null || "relButton".equalsIgnoreCase( type ) ) {     // 4.0.1.0 (2007/12/18) if文化
306//                      if( backAddress == null || "relButton".equalsIgnoreCase( type ) || USE_FILEFILTER ) {   // 6.9.4.1 (2018/04/09) FILEFILTER使用時は、相対リンクを出力
307                        if( backAddress == null || "relButton".equalsIgnoreCase( type ) ) {     // 8.5.2.0 (2023/07/14) Modify
308                                final GUIInfo guiInfo = getGUIInfo( gamenId );
309                                final String address = guiInfo.getRealAddress();
310                                set( "action", address + "index.jsp" );
311                        }
312                        else {
313                                set( "action", backAddress );                           // 4.0.1.0 (2007/12/18)
314                        }
315                }
316                else {
317                        set( "action",href ) ;
318                }
319
320                // 6.1.1.0 (2015/01/17) TagBufferの連結記述
321                final String tag = new TagBuffer( "button" )
322                                                        .add( "type"            ,"submit" )
323                                                        .add( "accesskey"       ,get( "accesskey" ) )
324                                                        .addBody( getMsglbl( gamenId ) )
325                                                        .makeTag();
326
327                final StringBuilder body = new StringBuilder( BUFFER_MIDDLE )
328                        .append( tag )                                                                                                          // 6.1.1.0 (2015/01/17)
329                        .append( CR )
330                        // command を hidden で作成します。
331                        .append( XHTMLTag.hidden( "command",command ) )                                         // hidden(name,value);
332                        .append( CR )
333                        // GAMENID を hidden で作成します。
334                        .append( XHTMLTag.hidden( "GAMENID",gamenId ) )                                         // hidden(name,value);
335                        .append( CR );
336
337                // keys,vals を hidden で作成します。
338                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
339                if( keys != null && vals != null ) {
340                        if( keys.length != vals.length ) {
341                                final String errMsg = "キーとバリューの個数が異なります。"
342                                                        + CR
343                                                        + " keys.length=[" + keys.length + "]  vals.length=[" + vals.length + "]"
344                                                        + " keys=" + StringUtil.array2csv( keys ) + CR
345                                                        + " vals=" + StringUtil.array2csv( vals ) ;                     // 5.1.8.0 (2010/07/01) errMsg 修正
346                                throw new HybsSystemException( errMsg );
347                        }
348
349                        for( int i=0; i<keys.length; i++ ) {
350                                body.append( XHTMLTag.hidden( keys[i],vals[i] ) )                               // hidden(name,value);
351                                        .append( CR );
352                        }
353                }
354
355                // 3.7.0.3 (2005/03/01) 戻る行番号を、BACK_ROW_KEYより取得し、SEL_ROW で渡す。
356                final String rowkey = HybsSystem.BACK_ROW_KEY + getGUIInfo( "GUI.KEY" );
357                final String rowVal = (String)getSessionAttribute( rowkey );
358                // 3.7.0.5 (2005/04/11) null の時は、返さないように変更
359                if( rowVal != null ) {
360                        body.append( XHTMLTag.hidden( "SEL_ROW",rowVal ) )                                      // hidden(name,value);
361                                .append( CR );
362                }
363
364                set( "body",body.toString() );
365
366                return XHTMLTag.form( getAttributes() ) ;
367        }
368
369        /**
370         * 戻るリンク(historyBack)を作成します。
371         *
372         * @og.rev 3.5.4.0 (2003/11/25) 履歴(history)オブジェクトのback() メソッドを利用した戻る機能を追加します。
373         *
374         * @return      戻るリンク
375         * @og.rtnNotNull
376         */
377        private String makeHistoryBackTag() {
378                final StringBuilder link = new StringBuilder( BUFFER_MIDDLE )
379                        .append( "<a onClick=\"history.back()\">" )
380                        .append( getMsglbl( gamenId ) )
381                        .append( "</a>" );
382
383                return link.toString() ;
384        }
385
386        /**
387         * BACK_GAMENID の値を取り出します。
388         *
389         * 値は、キャッシュではなく、session より HybsSystem.BACK_GAMENID_KEY をキーに
390         * 取り出します。
391         *
392         * @og.rev 3.1.8.0 (2003/05/16) BACK_GAMENID のキャッシュの取り出し先を変更する。
393         *
394         * @return      BACK_GAMENID の値
395         */
396        private String getBackGamenId() {
397                final String key = HybsSystem.BACK_GAMENID_KEY + getGUIInfoAttri( "KEY" );      // 4.0.0 (2005/01/31)
398                return (String)getSessionAttribute( key );
399        }
400
401        /**
402         * BACK_ADDRESS の値を取り出します。
403         *
404         * 値は、キャッシュではなく、session より HybsSystem.BACK_ADDRESS_KEY をキーに
405         * 取り出します。
406         *
407         * @og.rev 4.0.1.0 (2007/12/17) メソッド追加
408         *
409         * @return      BACK_GAMENID の値
410         */
411        private String getBackAddress() {
412                final String key = HybsSystem.BACK_ADDRESS_KEY + getGUIInfoAttri( "KEY" );      // 4.0.0 (2005/01/31)
413
414                return (String)getSessionAttribute( key );
415        }
416
417        /**
418         * 【TAG】ボタンのタイプ[link/button/relLink/relButton/historyBack]を指定します(初期値:link)。
419         *
420         * @og.tag
421         * button と設定すると、戻るボタンに、link と設定すると、戻るリンクになります。
422         * historyBack は、IE等の戻る操作と同じで、JavaScriptのヒストリーバックを行います。
423         * また、relButton、relLinkとすると、それぞれ相対パス(画面IDから飛び先のアドレスを元に生成)
424         * で戻り先のアドレスが生成されます。
425         * 初期値は、戻るリンク(link)です。
426         * ※ 6.9.4.1 (2018/04/09) FILEFILTER使用時(紙芝居作成時)は、相対リンクを出力します。
427         *
428         * <table class="plain">
429         *   <caption>ボタンのタイプ説明</caption>
430         *   <tr><th>タイプ               </th><th>説明                             </th></tr>
431         *   <tr><td>link               </td><td>戻るリンク                  </td></tr>
432         *   <tr><td>button             </td><td>戻るボタン                 </td></tr>
433         *   <tr><td>relLink    </td><td>戻るリンク(相対パス)   </td></tr>
434         *   <tr><td>relButton  </td><td>戻るボタン(相対パス)  </td></tr>
435         *   <tr><td>historyBack</td><td>通常のヒストリバックボタン        </td></tr>
436         * </table>
437         *
438         * @og.rev 5.0.2.0 (2009/11/01) 相対パスでの戻るリンク対応
439         *
440         * @param       tp      ボタンのタイプ [link/button/relLink/relButton/historyBack]
441         */
442        public void setType( final String tp ) {
443                type = CHECK_TYPE.nval( tp );
444        }
445
446        /**
447         * 【TAG】(通常は使いません)戻る時に指定する command を設定できます(初期値:RENEW)。
448         *
449         * @og.tag
450         * 通常は、RENEW で戻ります。
451         * (初期値は、RENEW なので設定不要です。)
452         *
453         * @param       cmd     コマンド
454         */
455        public void setCommand( final String cmd ) {
456                command = nval( getRequestParameter( cmd ),command );
457                if( command != null ) { command = command.toUpperCase(Locale.JAPAN); }
458        }
459
460        /**
461         * 【TAG】(通常は使いません)戻り先の画面をセットします(初期値:BACK_GAMENID)。
462         *
463         * @og.tag
464         * 通常は、自動的に、BACK_GAMENID の値がセットされますが、
465         * 先祖に戻る(画面A⇒画面B⇒画面C のときに、画面Aに戻る)場合や、
466         * 別の画面に、進む場合に、直接指定します。
467         * (初期値は、来た画面:BACK_GAMENID ですので、設定不要です。)
468         * 値は、キャッシュではなく、session より HybsSystem.BACK_GAMENID_KEY をキーに
469         * 取り出します。
470         * これは、command="NEW" で、BACK_GAMENID リクエストが存在し、BACK_GAMENID と
471         * 自分自身の画面IDが異なる場合のみ、RequestCacheTag#backGamenIdSet メソッドで
472         * session に登録されます。
473         *
474         * @param       id      戻り先の画面ID
475         */
476        public void setGamenId( final String id ) {
477                gamenId = nval( getRequestParameter( id ),gamenId );
478        }
479
480        /**
481         * 【TAG】リンク先に渡すキーをCSV形式で複数指定します。
482         *
483         * @og.tag
484         * 戻る時に、検索時のキャッシュに指定した引数以外に指定したり、別の値に置き換えたり
485         * する場合のキーを設定できます。CSV形式で複数指定できます。
486         * vals 属性には、キーに対応する値を、設定してください。
487         * 例:<b>keys="displayMsg,clear"</b> vals="MSG0065,true"
488         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
489         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
490         *
491         * @og.rev 3.5.6.2 (2004/07/05) CommonTagSupport#getCSVParameter を使用
492         *
493         * @param       key     リンク先に渡すキー (例:keys="displayMsg,clear")
494         * @see         #setVals( String )
495         */
496        public void setKeys( final String key ) {
497                keys = getCSVParameter( key );
498        }
499
500        /**
501         * 【TAG】keys属性に対応する値をCSV形式で複数指定します。
502         *
503         * @og.tag
504         * キーに設定した値を、CSV形式で複数して出来ます。
505         * 指定順序は、キーと同じにしておいて下さい。
506         * 例:keys="displayMsg,clear" <b>vals="MSG0065,true"</b>
507         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
508         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
509         *
510         * @og.rev 3.5.6.2 (2004/07/05) CommonTagSupport#getCSVParameter を使用
511         *
512         * @param       val     keys属性に対応する値 (例:vals="MSG0065,true")
513         * @see         #setKeys( String )
514         */
515        public void setVals( final String val ) {
516                vals = getCSVParameter( val );
517        }
518
519        /**
520         * 【HTML】リンク先の表示ターゲットを指定します(初期値:CONTENTS)。
521         *
522         * @og.tag
523         * リンク先の文書を表示させるフレーム、またはウィンドウの名前を指定します。
524         *
525         * @param       tgt     リンク先の表示ターゲット
526         */
527        public void setTarget( final String tgt ) {
528                set( "target",getRequestParameter( tgt ) );
529        }
530
531        /**
532         * 【HTML】リンク先のURLを指定します。
533         *
534         * @og.tag リンク先のURLを指定します。
535         *
536         * @param       href    リンク先のURL
537         */
538        public void setHref( final String href ) {
539                set( "href",getRequestParameter( href ) );
540        }
541
542        /**
543         * メッセージラベル(msglbl)をセットします。
544         *
545         * メッセージラベルは、meg属性か、lbl属性で登録された値を、
546         * それぞれのリソースに応じて各言語に変換した結果を格納しています。
547         * meg属性 と lbl属性は、同時登録できません。
548         *
549         * @og.rev 5.7.1.2 (2013/12/20) msg ⇒ msglbl 変更
550         *
551         * @param       gamenId 画面ID
552         *
553         * @return      メッセージラベル
554         * @og.rtnNotNull
555         */
556        private String getMsglbl( final String gamenId ) {
557                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
558                final String msglbl = getMsglbl();                                      // 5.7.1.2 (2013/12/20) msg ⇒ msglbl 変更
559
560                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
561                if( msglbl == null ) {
562                        if( body == null || body.isEmpty() ) {
563                                final GUIInfo guiInfo = getGUIInfo( gamenId );          // 4.0.0 (2005/01/31)
564                                if( guiInfo != null ) {
565                                        rtn.append( guiInfo.getLongName() );
566                                }
567                        }
568                        else {
569                                rtn.append( body );
570                        }
571                }
572                else {
573                        rtn.append( msglbl );
574                        set( "accesskey",nval( get( "accesskey" ),accesskey ) );
575                        rtn.append( '(' ).append( get( "accesskey" ) ).append( ')' ) ;          // 6.0.2.5 (2014/10/31) char を append する。
576                }
577
578                return rtn.toString() ;
579        }
580
581        /**
582         * 画面に戻るボタン/リンクを表示するかどうかを条件判定します。
583         * 引数の gamenId は、BACK_GAMENID の事で、このタグの属性定義で設定されて
584         * いない場合は、session より、BACK_GAMENID を取り出します。つまり、取り出す為には、
585         * command="NEW" で、キャッシュに設定しておく必要があります。
586         *
587         * 随時、条件を追加していきます。
588         *
589         * 条件1:自分自身へ戻る機能はサポートできません。
590         * 条件2:command="NEW" で、キャッシュに設定しておく必要がある。
591         *
592         * @og.rev 3.5.5.0 (2004/03/12) デバッグ情報を出力するように機能追加
593         * @og.rev 7.3.1.0 (2021/02/02) useBackLink 属性の値を使用する。
594         *
595         * @param       gmnId   画面ID(BACK_GAMENID)
596         *
597         * @return      判定結果
598         */
599        private boolean checkCondition( final String gmnId ) {
600                // 7.3.1.0 (2021/02/02)
601                final String useBkLink = getRequest().getParameter( "useBackLink" );
602                if( "false".equalsIgnoreCase( useBkLink ) ) { return false; }                   // false の場合は無条件でリンクを出さない。
603
604                final String thisGamen = getGUIInfoAttri( "KEY" );      // 4.0.0 (2005/01/31)
605                final boolean rtn = gmnId != null
606                                                && gmnId.length() > 0
607                                                && ! gmnId.equals( thisGamen ) ;
608
609                // 7.3.1.0 (2021/02/02)
610                if( !rtn && "true".equalsIgnoreCase( useBkLink ) ) {
611                        gamenId = thisGamen;                                                    // true の場合は、gamenIdがnullだとリンクが出ない。
612                        return true;
613                }
614
615                // 3.5.5.0 (2004/03/12)
616                if( isDebug() ) {
617                        final String cmd =pageContext.getRequest().getParameter( "command" );
618
619                        // 6.0.2.5 (2014/10/31) char を append する。
620                        final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
621                                .append( getDocumentLink() )            // 4.0.0 (2005/02/28)
622                                .append( "<pre>" )
623                                .append( "command  =[" ).append( cmd       ).append( ']' ).append( CR )
624                                .append( "type     =[" ).append( type      ).append( ']' ).append( CR )
625                                .append( "gamenId  =[" ).append( gmnId     ).append( ']' ).append( CR )
626                                .append( "thisGamen=[" ).append( thisGamen ).append( ']' ).append( CR )
627                                .append( "useBkLink=[" ).append( useBkLink ).append( ']' ).append( CR ) // 7.3.1.0 (2021/02/02)
628                                .append( "checkCondition=[" ).append( rtn  ).append( ']' )
629                                .append( "</pre>" );
630                        jspPrint( buf.toString() );
631                }
632
633                return rtn ;
634        }
635}