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.HybsSystemException;
019import org.opengion.fukurou.util.ToString;                                              // 6.1.1.0 (2015/01/17)
020
021import static org.opengion.fukurou.util.StringUtil.nval;
022
023/**
024 * タブ形式のリンクを表示する場合に、タブそのものを表示するタグです。
025 *
026 * tabLinkタグを親タグとし、listType="TAG"を指定した場合に、このタグを使用して
027 * タブを個別に定義します。
028 *
029 * タグの使用方法については、tabLinkタグのドキュメントを参照して下さい。
030 *
031 * 各属性は、{@XXXX} 変数が使用できます。
032 * これは、ServletRequest から、XXXXをキーに値を取り出し、この変数に割り当てます。
033 * つまり、このXXXXをキーにリクエストすれば、この変数に値をセットすることができます。
034 *
035 * @og.formSample
036 * ●形式:<og:tabLink href="…" > <og:tabList name="TAB1" … /> … </og:tabLink >
037 * ●body:なし
038 *
039 * ●Tag定義:
040 *   <og:tabList
041 *       name             ○【TAG】要素に対して固有の名前をつけます(必須)。
042 *       lbl                【TAG】ラベルリソースのラベルIDを指定します
043 *       href               【TAG】リンク先のJSPを指定します(初期値:result.jsp)
044 *       term               【TAG】処理する条件を指定します(初期値:null)
045 *       termList           【TAG】処理する条件を含むような文字列を指定します
046 *       delTerm            【TAG】処理しないタブを選択する条件を指定します(初期値:null)
047 *       delTermList        【TAG】処理しない条件を含むような文字列を指定します
048 *       unselClass         【TAG】非選択タブのクラスを指定します(初期値:unselTab)
049 *       keys               【TAG】リンク先のJSPに引数として渡すキーをCSV形式で指定します
050 *       vals               【TAG】リンク先のJSPに引数として渡す値をCSV形式で指定します
051 *       roles              【TAG】ロールをセットします
052 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 7.4.1.0 (2021/04/23)
053 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 7.4.1.0 (2021/04/23)
054 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない) 7.4.1.0 (2021/04/23)
055 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない) 7.4.1.0 (2021/04/23)
056 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない) 7.4.1.0 (2021/04/23)
057 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
058 *   />
059 *
060 * ●使用例
061 *   tabListタグからタブリストを生成する場合
062 *      <og:tabLink
063 *          listType        = "DB"                      タブの一覧をどこから取得するか
064 *          href            = "result.jsp"              リンク先のJSP
065 *          target          = "RESULT"                  リンクターゲット
066 *          openTab         = "[true/false]"            タブ表示後にタブを自動で開く
067 *          openTabName     = "{@PN}               自動で開くタブの名前
068 *          constKeys       = "KEY1"                    次画面に固定で渡すキー一覧
069 *          constVals       = "{@VAL1}"            次画面に固定で渡す値一覧
070 *          listCount       = "10"                      1行辺りに表示するタブの数
071 *          selClass        = "selTab"                  選択タブのクラス
072 *          unselClass      = "unselTab"                非選択タブのクラス
073 *          width           = "100px"                   タブリンクの幅
074 *          height          = "50px"                    タブリンクの高さ
075 *       >
076 *          <og:tabList name="TAB1" href="result1.jsp" keys="PN,CDK" vals="ABC,V" />
077 *          <og:tabList name="TAB2" href="result2.jsp" keys="PN,CDK" vals="BCD,W" />
078 *          <og:tabList name="TAB3" href="result3.jsp" keys="PN,CDK" vals="CDE,X" />
079 *      </og:tabLink>
080 *
081 * @og.group 画面表示
082 *
083 * @version 4.3.5.0 (2008/02/01)
084 * @author Nakamura
085 * @since JDK1.4,
086 */
087public class TabListTag extends CommonTagSupport {
088        /** このプログラムのVERSION文字列を設定します。   {@value} */
089        private static final String VERSION = "7.4.1.0 (2021/04/23)" ;
090        private static final long serialVersionUID = 741020210423L ;
091
092        private String  name            ;
093        private String  href            ;
094        private String  unselClass      ;
095
096        private String[] keys           ;
097        private String[] vals           ;
098
099        private String  term            ;
100        private String  termList        ;
101        private String  delTerm         ;
102        private String  delTermList     ;
103        private boolean visible         ;
104
105        /**
106         * デフォルトコンストラクター
107         *
108         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
109         */
110        public TabListTag() { super(); }                // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
111
112        /**
113         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
114         *
115         * @og.rev 6.3.9.0 (2015/11/06) TabLinkTagの取得タイミングを、#doEndTag() に移す。
116         * @og.rev 7.4.1.0 (2021/04/23) caseKey,caseVal,caseNN,caseNull,caseIf 属性を追加
117         *
118         * @return      後続処理の指示
119         */
120        @Override
121        public int doEndTag() {
122                debugPrint();
123
124                // 7.4.1.0 (2021/04/23) caseKey,caseVal,caseNN,caseNull,caseIf 属性を追加
125                if( !useTag() ) { return EVAL_PAGE ; }
126
127                visible = getUser().isAccess( get( "roles" ) );
128
129                // delTermが優先
130                if( visible ) {
131                        visible = delTermList == null || delTerm == null || delTermList.indexOf( delTerm ) < 0 ;
132                }
133
134                // delTermで表示対象となった場合に、termを処理
135                if( visible ) {
136                        visible = termList == null || term == null || termList.indexOf( term ) >= 0 ;
137                }
138
139                // 6.3.9.0 (2015/11/06) TabLinkTagの取得タイミングを、#doEndTag() に移す。
140                final TabLinkTag tabLink = (TabLinkTag)findAncestorWithClass( this,TabLinkTag.class );
141                if( tabLink == null ) {
142                        final String errMsg = "tabLink タグの BODY部で使用してください。";
143                        throw new HybsSystemException( errMsg );
144                }
145
146                tabLink.addTag( href, name, getMsglbl(), unselClass, visible, keys, vals );
147
148                return EVAL_PAGE ;
149        }
150
151        /**
152         * タグリブオブジェクトをリリースします。
153         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
154         *
155         * @og.rev 6.3.9.0 (2015/11/06) TabLinkTagの取得タイミングを、#doEndTag() に移す。
156         */
157        @Override
158        protected void release2() {
159                super.release2();
160                name                    = null;
161                href                    = null;
162                term                    = null;
163                termList                = null;
164                delTerm                 = null;
165                delTermList             = null;
166                unselClass              = null;
167                keys                    = null;
168                vals                    = null;
169                visible                 = false;
170        }
171
172        /**
173         * 【TAG】要素に対して固有の名前をつけます。
174         *
175         * @og.tag
176         * 要素に対して固有の名前をつけます。
177         * ここで設定された名称は、自動でタブを表示するためのopenTabName属性判定にも使用されます。
178         *
179         * @param   nm タブ名
180         */
181        public void setName( final String nm ) {
182                name = nval( getRequestParameter( nm ), name );
183        }
184
185        /**
186         * 【TAG】リンク先のJSPを指定します(初期値:result.jsp)。
187         *
188         * @og.tag
189         * リンク先のJSPを指定します。
190         * ここで指定しない場合は、tagLinkタグの値が適用されます。
191         *
192         * @param       hr リンク先のJSP
193         */
194        public void setHref( final String hr ) {
195                href = nval( getRequestParameter( hr ), href );
196        }
197
198        /**
199         * 【TAG】処理する条件を指定します(初期値:null)。
200         *
201         * @og.tag
202         * termListで与えられた文字列に、term文字列(大文字/小文字の区別あり)が
203         * 含まれていれば、OPEN選択タブとして処理します。
204         * OPEN選択タブでないタブは、初期値OPENにならないだけで、タブそのものは表示されます。
205         * OPEN選択とDELETE選択が競合した場合は、DELETE選択が優先されます。
206         * 初期値は、 null です。
207         *
208         * @param       str 処理する条件文字列
209         */
210        public void setTerm( final String str ) {
211                term = nval( getRequestParameter( str ),term );
212        }
213
214        /**
215         * 【TAG】処理する条件を含むような文字列を指定します。
216         *
217         * @og.tag
218         * termListで与えられた文字列に、term文字列(大文字/小文字の区別あり)が
219         * 含まれていれば、OPEN選択タブとして処理します。
220         * 例えば、"A","B","C" という文字列が、term で指定された
221         * 場合に処理するようにしたい場合は、"A|B|C" をセットします。
222         * 初期値は、 null です。
223         * 判定は、文字列を含むかどうかなので、1文字のみの場合は、"|"区切りにする
224         * 必要はありません。
225         * OPEN選択とDELETE選択が競合した場合は、DELETE選択が優先されます。
226         *
227         * @param       list 処理する条件 (indexOf による含む/含まない判定)
228         */
229        public void setTermList( final String list ) {
230                termList = nval( getRequestParameter( list ),termList );
231        }
232
233        /**
234         * 【TAG】処理しないタブを選択する条件を指定します(初期値:null)。
235         *
236         * @og.tag
237         * delTermListで与えられた文字列に、delTerm文字列(大文字/小文字の区別あり)が
238         * 含まれていれば、DELETE選択タブとして処理します。
239         * DELETE選択タブは、タブそのものが表示されません。
240         * ただし、タブのselectIndex は、DELETEされたタブも含めて、カウントされますので、
241         * JSPでの設定時の順番がインデックス番号になります。
242         * OPEN選択とDELETE選択が競合した場合は、DELETE選択が優先されます。
243         * 初期値は、 null です。
244         *
245         * @param       str 非表示タブ
246         */
247        public void setDelTerm( final String str ) {
248                delTerm = nval( getRequestParameter( str ),delTerm );
249        }
250
251        /**
252         * 【TAG】処理しない条件を含むような文字列を指定します。
253         *
254         * @og.tag
255         * delTermListで与えられた文字列に、delTerm文字列(大文字/小文字の区別あり)が
256         * 含まれていれば、DELETE選択タブとして処理します。
257         * 例えば、"A","B","C" という文字列が、delTerm で指定された
258         * 場合に処理しないようにしたい場合は、"A|B|C" をセットします。
259         * 初期値は、 null です。
260         * 判定は、文字列を含むかどうかなので、1文字のみの場合は、"|"区切りにする
261         * 必要はありません。
262         * OPEN選択とDELETE選択が競合した場合は、DELETE選択が優先されます。
263         *
264         * @param       list 非表示タブ条件 (indexOf による含む/含まない判定)
265         */
266        public void setDelTermList( final String list ) {
267                delTermList = nval( getRequestParameter( list ),delTermList );
268        }
269
270        /**
271         * 【TAG】非選択タブのクラスを指定します(初期値:unselTab)。
272         *
273         * @og.tag
274         * タブが選択されていない状態にある場合の、タブ部分のクラス名を指定します。
275         * このクラス名を変更する場合は、そのクラスをcustom/custom.css等で再定義して下さい。
276         * tabListタグで指定された値は、tabLinkタグで指定されたものより優先されます。
277         * 初期値は、unselTabです。
278         *
279         * @param       cls 選択タブのクラス名
280         */
281        public void setUnselClass( final String cls ) {
282                unselClass = nval( getRequestParameter( cls ), unselClass );
283        }
284
285        /**
286         * 【TAG】リンク先のJSPに引数として渡すキーをCSV形式で指定します。
287         *
288         * @og.tag
289         * リンク先のJSPに引数として渡すキーをCSV形式で指定します。
290         *
291         * @param       key キー(CSV形式)
292         */
293        public void setKeys( final String key ) {
294                keys = getCSVParameter( key );
295        }
296
297        /**
298         * 【TAG】リンク先のJSPに引数として渡す値をCSV形式で指定します。
299         *
300         * @og.tag
301         * リンク先のJSPに引数として渡す値をCSV形式で指定します。
302         *
303         * @param       val 値(CSV形式)
304         */
305        public void setVals( final String val ) {
306                vals = getCSVParameter( val );
307        }
308
309        /**
310         * 【TAG】ロールをセットします。
311         *
312         * @og.tag
313         * ここで指定したカラムロールを元に、ユーザー毎のアクセス許可がチェックされます。
314         * アクセス許可されないと、表示されません。
315         * このロールを指定しない場合は、カラムリソースのロールが使用されます。
316         *
317         * @param       roles パラメータ
318         */
319        public void setRoles( final String roles ) {
320                set( "roles",getRequestParameter( roles ) );
321        }
322
323        /**
324         * このオブジェクトの文字列表現を返します。
325         * 基本的にデバッグ目的に使用します。
326         *
327         * @return このクラスの文字列表現
328         * @og.rtnNotNull
329         */
330        @Override
331        public String toString() {
332                return ToString.title( this.getClass().getName() )
333                                .println( "VERSION"             ,VERSION        )
334                                .println( "name"                ,name           )
335                                .println( "href"                ,href           )
336                                .println( "term"                ,term           )
337                                .println( "termList"    ,termList       )
338                                .println( "delTerm"             ,delTerm        )
339                                .println( "delTermList" ,delTermList)
340                                .println( "Other..."    ,getAttributes().getAttribute() )
341                                .fixForm().toString() ;
342        }
343}