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.hayabusa.html.TabData;
020import static org.opengion.fukurou.util.StringUtil.nval ;
021
022/**
023 * タブペインで、項目を分割して表示するタグのタブそのものを作成します。
024 *
025 * ※ データの大きさによってtabLink、tabList と使い分けてください。
026 *
027 * 一つの大きなHTMLを、タブを使用することで複数の塊に分割表示できます。
028 * 分割された各タブは、一つのHTMLのため、タブ間の移動による情報の消失はありません。
029 * また、一つのHTMLのため、タブにまたがって入力した値は、すべて 一括送信することも
030 * 可能です。(Formタグで、全てのタブをまとめて記述していれば)
031 * 個々のタブの指定は、この tab タグを使用します。
032 * それらを、タブテーブル の BODY 部に記述します。タブは、記述された順番に、
033 * 設定されます。
034 * タブテーブル の BODY 部に記述するタブは、必ず一つ以上必要です。
035 *
036 * @og.formSample
037 * ●形式:<og:tabTable  ...  >
038 *             <og:tab name="paGE1" lbl="page 1" >
039 *                    <jsp:directive.include file="paGE1.jsp" />
040 *             </og:tab>
041 *             <og:tab name="page2" lbl="page 2" >
042 *                    <jsp:directive.include file="page2.jsp" />
043 *             </og:tab>
044 *         </og:tabTable >
045 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します)
046 *
047 * ●Tag定義:
048 *   <og:tab
049 *       lbl                【TAG】ラベルリソースのラベルIDを指定します
050 *       name                要素に対して固有の名前(id)をつける場合に設定します
051 *       term               【廃止】処理する条件を指定します(初期値:null)
052 *       termList           【廃止】処理する条件を含むような文字列を指定します
053 *       delTerm            【廃止】処理しないタブを選択する条件を指定します(初期値:null)
054 *       delTermList        【廃止】処理しない条件を含むような文字列を指定します
055 *       style              【TAG】タブに与える 初期 style 属性を指定します
056 *       keys               【廃止】タブが選択状態(OPEN選択タブ時)に使用するキーをCSV形式で複数指定します
057 *       vals               【廃止】タブが選択状態(OPEN選択タブ時)に使用する値をCSV形式で複数指定します
058 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
059 *   >   ... Body ...
060 *   </og:tab>
061 *
062 * ●使用例
063 *  <og:tabTable>
064 *    <og:tab lbl="page 1">
065 *      <table summary="layout" >
066 *        <tr>
067 *          <og:column name="SYSTEM_ID" must="true" />
068 *          <og:column name="COLUMN_NAME" />
069 *          <og:column name="RENDERER"    />
070 *        </tr>
071 *      </table>
072 *    </og:tab>
073 *    <og:tab lbl="page 2">
074 *      <table summary="layout" >
075 *        <tr>
076 *          <og:column name="DBTYPE"      />
077 *          <og:column name="NAME_JA"     />
078 *          <og:column name="EDITOR"      />
079 *        </tr>
080 *      </table>
081 *    </og:tab>
082 *  </og:tabTable>
083 *
084 * @og.rev 3.5.6.5 (2004/08/09) 新規作成
085 * @og.rev 5.9.1.3 (2015/10/30) jQuery方式に変更して復活(このタグはコメントの修正のみ)
086 * @og.group 画面部品
087 *
088 * @version  4.0
089 * @author       Kazuhiko Hasegawa
090 * @since    JDK5.0,
091 */
092public class TabTag extends CommonTagSupport {
093        //* このプログラムのVERSION文字列を設定します。   {@value} */
094        private static final String VERSION = "4.0.0.0 (2005/08/31)" ;
095
096        private static final long serialVersionUID = 400020050831L ;
097
098        private String text = null;
099        private String name = null;
100        private String body = null;
101        private String style = null;    // 3.8.6.1 (2006/10/24)
102
103        private String[] keys           = null;         // 3.8.6.2 (2006/11/01)
104        private String[] vals           = null;         // 3.8.6.2 (2006/11/01)
105        private Object[] backVals       = null;         // 3.8.6.2 (2006/11/01)
106
107        // 3.8.6.1 (2006/10/20)
108        private String  term            = null;
109        private String  termList        = null;
110        private String  delTerm         = null;
111        private String  delTermList     = null;
112        private boolean isOpen          = false;                // term    が termList    に含まれている場合 true
113        private boolean isDelete        = false;                // delTerm が delTermList に含まれている場合 true
114        private TabTableTag tabTable = null;
115
116        /**
117         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
118         *
119         * @og.rev 3.8.6.2 (2006/11/01) keys,vals属性の処理を追加
120         *
121         * @return      後続処理の指示
122         */
123        @Override
124        public int doStartTag() {
125                tabTable = (TabTableTag)findAncestorWithClass( this,TabTableTag.class );
126                // isSelected の判断は、OPEN/DELETE 関係なく、タブの数だけ実行する必要がある。
127                if( tabTable != null ) {
128                        isOpen = tabTable.isSelected();
129                }
130                else {
131                        String errMsg = "tabTable タグの BODY部で使用してください。";
132                        throw new HybsSystemException( errMsg );
133                }
134
135                // del条件リストに存在する場合は、DELETE選択タブとして認識される。
136                isDelete = ( delTermList != null && delTerm != null && delTermList.indexOf( delTerm ) >= 0 ) ;
137                if( isDelete ) { return(SKIP_BODY); }                   // Body を評価しない
138
139                // isSelected の判断 が優先される。
140                if( !isOpen ) {
141                        // 条件リストに存在する場合は、OPEN選択タブとして認識される。
142                        isOpen = ( termList != null && term != null && termList.indexOf( term ) >= 0 ) ;
143                }
144
145                // keys変数の元の値の退避とvals 値の設定。
146                if( isOpen && keys != null && keys.length > 0 ) {
147                        int size = keys.length;
148                        backVals = new Object[size];
149                        for( int i=0; i<size; i++ ) {
150                                String key = keys[i];
151                                if( key != null && key.length() > 0 ) {
152                                        backVals[i] = getRequestAttribute( key );
153                                        setRequestAttribute( key,vals[i] );
154                                }
155                        }
156                }
157
158                return( EVAL_BODY_BUFFERED );   // Body を評価する。( extends BodyTagSupport 時)
159        }
160
161        /**
162         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
163         *
164         * @return      後続処理の指示(SKIP_BODY)
165         */
166        @Override
167        public int doAfterBody() {
168                body = getBodyString();
169                return(SKIP_BODY);
170        }
171
172        /**
173         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
174         *
175         * @og.rev 3.8.6.1 (2006/10/20) term、termList、action属性を追加
176         * @og.rev 3.8.6.2 (2006/11/01) keys,vals属性の処理を追加
177         *
178         * @return      後続処理の指示
179         */
180        @Override
181        public int doEndTag() {
182                debugPrint();           // 4.0.0 (2005/02/28)
183                if( !isDelete ) {
184                        // keys変数の元の値の戻し。
185                        if( isOpen && keys != null && keys.length > 0 ) {
186                                int size = keys.length;
187                                for( int i=0; i<size; i++ ) {
188                                        String key = keys[i];
189                                        if( key != null && key.length() > 0 ) {
190                                                if( backVals[i] != null ) {
191                                                        setRequestAttribute( key,backVals[i] );
192                                                }
193                                                else {
194                                                        removeRequestAttribute( key );
195                                                }
196                                        }
197                                }
198                        }
199
200                        text = getMsglbl();
201
202                        TabData tab = new TabData( text,name,body,isOpen,style );
203                        tabTable.addTabData( tab );
204                }
205                return(EVAL_PAGE);
206        }
207
208        /**
209         * タグリブオブジェクトをリリースします。
210         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
211         *
212         * @og.rev 3.8.6.1 (2006/10/20) term、termList、action属性を追加
213         * @og.rev 3.8.6.2 (2006/11/01) keys, vals, isOpen, delTerm, delTermList 属性を追加
214         */
215        @Override
216        protected void release2() {
217                super.release2();
218                text            = null;
219                name            = null;
220                body            = null;
221                term            = null;
222                termList        = null;
223                delTerm         = null;
224                delTermList     = null;
225                style           = null;
226                keys            = null;         // 3.8.6.2 (2006/11/01)
227                vals            = null;         // 3.8.6.2 (2006/11/01)
228                isOpen          = false;        // 3.8.6.2 (2006/11/01)
229                isDelete        = false;        // 3.8.6.2 (2006/11/01)
230                tabTable        = null;
231        }
232
233        /**
234         * 【廃止】要素に対して固有の名前(id)をつける場合に設定します。
235         *
236         * @og.tag 名前セット
237         * 
238         * @og.rev 5.9.1.3 (2015/10/30) 復活
239         *
240         * @param   name 名前
241         */
242        public void setName( final String name ) {
243                this.name = getRequestParameter( name );
244        }
245
246        /**
247         * 【廃止】処理する条件を指定します(初期値:null)。
248         *
249         * @og.tag
250         * termListで与えられた文字列に、term文字列(大文字/小文字の区別あり)が
251         * 含まれていれば、OPEN選択タブとして処理します。
252         * OPEN選択タブでないタブは、初期値OPENにならないだけで、タブそのものは表示されます。
253         * OPEN選択とDELETE選択が競合した場合は、DELETE選択が優先されます。
254         * 初期値は、 null です。
255         *
256         * @og.rev 3.8.6.1 (2006/10/20) 新規追加
257         *
258         * @param       flag 処理する条件
259         * @deprecated クラスが廃止されました。
260         */
261        @Deprecated public void setTerm( final String flag ) {
262                term = nval( getRequestParameter( flag ),term );
263        }
264
265        /**
266         * 【廃止】処理する条件を含むような文字列を指定します。
267         *
268         * @og.tag
269         * termListで与えられた文字列に、term文字列(大文字/小文字の区別あり)が
270         * 含まれていれば、OPEN選択タブとして処理します。
271         * 例えば、"A","B","C" という文字列が、term で指定された
272         * 場合に処理するようにしたい場合は、"A|B|C" をセットします。
273         * 初期値は、 null です。
274         * 判定は、文字列を含むかどうかなので、1文字のみの場合は、"|"区切りにする
275         * 必要はありません。
276         * OPEN選択とDELETE選択が競合した場合は、DELETE選択が優先されます。
277         *
278         * @og.rev 3.8.6.1 (2006/10/20) 新規追加
279         *
280         * @param       list 処理する条件(indexOf による含む/含まない判定)
281         * @deprecated クラスが廃止されました。
282         */
283        @Deprecated public void setTermList( final String list ) {
284                termList = nval( getRequestParameter( list ),termList );
285        }
286
287        /**
288         * 【廃止】処理しないタブを選択する条件を指定します(初期値:null)。
289         *
290         * @og.tag
291         * delTermListで与えられた文字列に、delTerm文字列(大文字/小文字の区別あり)が
292         * 含まれていれば、DELETE選択タブとして処理します。
293         * DELETE選択タブは、タブそのものが表示されません。
294         * ただし、タブのselectIndex は、DELETEされたタブも含めて、カウントされますので、
295         * JSPでの設定時の順番がインデックス番号になります。
296         * OPEN選択とDELETE選択が競合した場合は、DELETE選択が優先されます。
297         * 初期値は、 null です。
298         *
299         * @og.rev 3.8.6.2 (2006/11/01) 新規追加
300         *
301         * @param       flag DELETE選択タブ条件
302         * @deprecated クラスが廃止されました。
303         */
304        @Deprecated public void setDelTerm( final String flag ) {
305                delTerm = nval( getRequestParameter( flag ),delTerm );
306        }
307
308        /**
309         * 【廃止】処理しない条件を含むような文字列を指定します。
310         *
311         * @og.tag
312         * delTermListで与えられた文字列に、delTerm文字列(大文字/小文字の区別あり)が
313         * 含まれていれば、DELETE選択タブとして処理します。
314         * 例えば、"A","B","C" という文字列が、delTerm で指定された
315         * 場合に処理しないようにしたい場合は、"A|B|C" をセットします。
316         * 初期値は、 null です。
317         * 判定は、文字列を含むかどうかなので、1文字のみの場合は、"|"区切りにする
318         * 必要はありません。
319         * OPEN選択とDELETE選択が競合した場合は、DELETE選択が優先されます。
320         *
321         * @og.rev 3.8.6.2 (2006/11/01) 新規追加
322         *
323         * @param       list DELETE選択タブ条件文字列(indexOf による含む/含まない判定)
324         */
325        @Deprecated public void setDelTermList( final String list ) {
326                delTermList = nval( getRequestParameter( list ),delTermList );
327        }
328
329        /**
330         * 【廃止】タブに与える 初期 style 属性を指定します。
331         *
332         * @og.tag
333         * ts:tab 本体では、初期選択時のスタイルシートを、defaultStyle と
334         * selectedStyle で与える必要があります。これは、id 属性を設定して、
335         * 外部でスタイルシートを定義する形式で指定できません。
336         * ここで指定した style 属性 は、tabTableTag で与える style 属性 より優先度は
337         * 高くなります。
338         * ここでの style は、タブの OPEN選択には関係ありません。
339         *
340         * @og.rev 3.8.6.1 (2006/10/24) 新規追加
341         *
342         * @param       st タブに与える 初期 style 属性
343         * @deprecated クラスが廃止されました。
344         */
345        @Deprecated public void setStyle( final String st ) {
346                style = nval( getRequestParameter( st ),style );
347        }
348
349        /**
350         * 【廃止】タブが選択状態(OPEN選択タブ時)に使用するキーをCSV形式で複数指定します。
351         *
352         * @og.tag
353         * タブのBODY内部でのみ有効なscope="request"変数を定義できます。
354         * 条件は、term、termList によるOPEN選択タブ時にのみ指定のタブの
355         * BODY部内のみに有効になります。
356         * タブの前に設定されている scope="request"変数 は退避され、BODY部が
357         * 終了した時点で、元の変数に値が戻されます。
358         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
359         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
360         *
361         * @og.rev 3.8.6.2 (2006/11/01) 新規追加
362         *
363         * @param       key キー(CSV形式)
364         * @deprecated クラスが廃止されました。
365         */
366        @Deprecated public void setKeys( final String key ) {
367                keys = getCSVParameter( key );
368        }
369
370        /**
371         * 【廃止】タブが選択状態(OPEN選択タブ時)に使用する値をCSV形式で複数指定します。
372         *
373         * @og.tag
374         * タブのBODY内部でのみ有効なscope="request"変数を定義できます。
375         * 条件は、term、termList によるOPEN選択タブ時にのみ指定のタブの
376         * BODY部内のみに有効になります。
377         * タブの前に設定されている scope="request"変数 は退避され、BODY部が
378         * 終了した時点で、元の変数に値が戻されます。
379         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
380         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
381         *
382         * @param       val 値(CSV形式)
383         * @deprecated クラスが廃止されました。
384         */
385        @Deprecated public void setVals( final String val ) {
386                vals = getCSVParameter( val );
387        }
388
389        /**
390         * このオブジェクトの文字列表現を返します。
391         * 基本的にデバッグ目的に使用します。
392         *
393         * @return このクラスの文字列表現
394         */
395        @Override
396        public String toString() {
397                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
398                                .println( "VERSION"             ,VERSION        )
399                                .println( "text"                ,text           )
400                                .println( "name"                ,name           )
401                                .println( "body"                ,body           )
402                                .println( "term"                ,term           )
403                                .println( "termList"    ,termList       )
404                                .println( "Other..."    ,getAttributes().getAttribute() )
405                                .fixForm().toString() ;
406        }
407}