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.StringUtil;
020import org.opengion.fukurou.util.Attributes;
021
022import static org.opengion.fukurou.util.StringUtil.nval ;
023
024/**
025 * 検索結果のカラム表示に対して様々な属性を付加(マーキング)するタグです(参照:viewMarker)。
026 *
027 * このタグは、カラム毎にマーキングするタグです。親タグとして、viewMarker を
028 * 使用する必要があります。
029 * このタグでは、BODY部に指定した値を、レンデラーとして使用します。通常の文字は、
030 * そのままで、{@XXXX}で指定した変数は、リクエスト値を設定します。
031 * [XXXX]で指定した値は、検索結果のDBTableModelの値を行毎に割り当てます。
032 * マーカー指定の有無(マーカーするかしないか)は、onMark属性と、markList属性で
033 * 指定します。markList属性に指定の値に、onMark属性に設定した値が存在する場合、
034 * マーカーされます。 このmarkList属性には、"1" と "true"が初期設定
035 * されているため、onMark属性に"1" または "true"を指定すれば、全行マークされます。
036 * また、どちらの属性も、{@XXXX} や、[XXXX]変数が使用できます。[XXXX]変数では、
037 * 行毎に、onMark属性や、markList属性を設定できる為、(通常はどちらか固定)
038 * 行毎の マーカー指定の有無を指定できます。
039 * [XXXX]変数でカラム名の先頭に$を付加した場合(例:[$XXXX])は、元の値がURLエンコード
040 * されて返されます。
041 * ※ <b>現段階では、viewMarker がカラム名をキーにcolumnMarkerオブジェクトを
042 * 管理している為、行毎にマークの有無は指定できますが、マークを切り替える
043 * 使い方が出来ません。</b>
044 *
045 * @og.formSample
046 * ●形式:&lt;og:columnMarker column="・・・" ・・・ &gt; ・・・ &lt;/og:columnMarker &gt;
047 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
048 *
049 * ●Tag定義:
050 *   &lt;og:columnMarker
051 *       column             【TAG】マーク処理を行うカラム名を指定します
052 *       columns            【TAG】マーク処理を行うカラム名をカンマ区切り(CSV形式)で複数指定します
053 *       onMark             【TAG】マークを処理する(true or 1)/処理しない(false or 0)の設定を指定します(初期値:true)
054 *       markList           【TAG】処理するマークを含むような文字列を、"|"区切りの文字列で指定します(初期値:"true|TRUE|1")
055 *       instrVals          【TAG】スペースで区切られた複数の値について、マークします
056 *       useFormatDeco      【TAG】[$XXXX],[#XXXX]機能を有効にします(初期値:false)
057 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
058 *   &gt;   ... Body ...
059 *   &lt;/og:columnMarker&gt;
060 *
061 * ●使用例
062 *     商品CD2(CDSYHN02)は赤字で表示する。
063 *     商品CD3(CDSYHN03)は-----と表示する。
064 *     &lt;og:viewMarker command="{&#064;command}"&gt;
065 *         &lt;og:columnMarker column="CDSYHN02" onMark="true" &gt;
066 *             &lt;font color='red'&gt;[VCDSYHN02]&lt;/font&gt;
067 *         &lt;/og:columnMarker&gt;
068 *         &lt;og:columnMarker column="CDSYHN03" onMark="[XXXX]" markList="[YYYY]" &gt;
069 *             &lt;CENTER&gt;&lt;-----&lt;/CENTER&gt;
070 *         &lt;/og:columnMarker&gt;
071 *     &lt;/og:viewMarker&gt;
072 *
073 * @og.group 画面表示
074 *
075 * @version  4.0
076 * @author       Kazuhiko Hasegawa
077 * @since    JDK5.0,
078 */
079public class ColumnMarkerTag extends CommonTagSupport {
080        //* このプログラムのVERSION文字列を設定します。   {@value} */
081        private static final String VERSION = "5.6.3.0 (2013/04/01)" ;
082
083        private static final long serialVersionUID = 563020130401L ;
084
085        private String          column          = null;
086        private String[]        columns         = null;
087        private String          onMark          = "true";                       // true または 1
088        // 3.5.2.0 (2003/10/20)
089        private String          markList        = "true|TRUE|1";        // true または 1
090        private String          instrVals       = null;                         // 3.8.8.1 (2007/01/06)
091
092        private String          useFormatDeco = "false";                // 5.6.3.0 (2013/04/01) [$XXXX],[#XXXX]機能を有効にするかどうか
093
094        /**
095         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
096         *
097         * @return      後続処理の指示( EVAL_BODY_BUFFERED )
098         */
099        @Override
100        public int doStartTag() {
101                return EVAL_BODY_BUFFERED ;     // Body を評価する。( extends BodyTagSupport 時)
102        }
103
104        /**
105         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
106         *
107         * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
108         * @og.rev 3.5.2.0 (2003/10/20) markList属性を追加
109         * @og.rev 3.8.8.1 (2007/01/06) instrVals属性を追加
110         * @og.rev 4.0.0.0 (2005/08/31) 同一カラムの複数登録を許可します。
111         * @og.rev 5.6.3.0 (2013/04/01) useFormatDeco属性を追加([$XXXX],[#XXXX]機能を有効にするかどうか)
112         *
113         * @return      後続処理の指示(SKIP_BODY)
114         */
115        @Override
116        public int doAfterBody() {
117                ViewMarkerTag viewMarker = (ViewMarkerTag)findAncestorWithClass( this,ViewMarkerTag.class );
118                if( viewMarker != null ) {
119                        String marker = getBodyString();
120
121                        set( "body"             ,marker );
122                        set( "onMark"   ,onMark );
123                        set( "markList" ,markList );
124                        set( "instrVals",instrVals );                   // 3.8.8.1 (2007/01/06)
125                        set( "useFormatDeco",useFormatDeco );   // 5.6.3.0 (2013/04/01) [$XXXX],[#XXXX]機能を有効にするかどうか
126                        boolean flag = false;
127                        if( column != null && column.length() > 0 ) {
128                                // 4.0.0 (2005/08/31) 同一カラムの複数登録を許可します。
129                                set( "column",column );
130                                viewMarker.addAttribute( getAttributes() );
131                                flag = true;
132                        }
133
134                        if( columns != null && columns.length > 0 ) {
135                                flag = true;
136                                for( int i=0; i<columns.length; i++ ) {
137                                        String newMarker = StringUtil.replace( marker,"[$1]","[" + columns[i] + "]" );
138                                        set( "body"  ,newMarker );
139                                        // 4.0.0 (2005/08/31) 同一カラムの複数登録を許可します。
140                                        set( "column",columns[i] );
141                                        viewMarker.addAttribute( new Attributes( getAttributes() ) );
142                                }
143                        }
144
145                        if( ! flag ) {
146                                String errMsg = "colum か、columns は、どちらか必ず必要です。";
147                                throw new HybsSystemException( errMsg );
148                        }
149                }
150                return SKIP_BODY ;
151        }
152
153        /**
154         * タグリブオブジェクトをリリースします。
155         *
156         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
157         *
158         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
159         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
160         * @og.rev 3.5.2.0 (2003/10/20) markList属性を追加
161         * @og.rev 3.8.8.1 (2007/01/06) instrVals属性を追加
162         * @og.rev 5.6.3.0 (2013/04/01) useFormatDeco属性を追加
163         *
164         */
165        @Override
166        protected void release2() {
167                super.release2();
168                column          = null;
169                columns         = null;
170                onMark          = "true";                       // true または 1
171                markList        = "true|TRUE|1";
172                instrVals       = null;                         // 3.8.8.1 (2007/01/06)
173                useFormatDeco = "false";                // 5.6.3.0 (2013/04/01) [$XXXX],[#XXXX]機能を有効にするかどうか
174        }
175
176        /**
177         * 【TAG】マーク処理を行うカラム名を指定します。
178         *
179         * @og.tag
180         * このカラム名のTableModelに対して、マークを処理します。
181         *
182         * @param       clm カラム名
183         */
184        public void setColumn( final String clm ) {
185                column = getRequestParameter( clm );
186        }
187
188        /**
189         * 【TAG】マーク処理を行うカラム名をカンマ区切り(CSV形式)で複数指定します。
190         *
191         * @og.tag
192         * この複数のカラム名のTableModelに対して、 マークを処理します。
193         * カラム名は、カンマ区切りで複数指定することができます。その場合は、
194         * 指定のカラムに対して、すべて同一の処理を行います。
195         * 分解方法は、通常のパラメータ取得後に、CSV分解します。
196         *
197         * @og.rev 3.5.6.2 (2004/07/05) 先に配列に分解してからリクエスト変数の値を取得
198         * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。
199         *
200         * @param       clms マーク処理を行うカラム名(CSV形式)
201         */
202        public void setColumns( final String clms ) {
203                columns = StringUtil.csv2Array( getRequestParameter( clms ) );
204                if( columns.length == 0 ) { columns = null; }
205        }
206
207        /**
208         * 【TAG】マークを処理する(true or 1)/処理しない(false or 0)の設定を指定します(初期値:true)。
209         *
210         * @og.tag
211         * マークを処理する場合は、"true"(または "1")
212         * 処理しない場合は, "true以外"(または "0")をセットします。
213         * 初期値は、 "true"(マークを処理する)です。
214         * さらに、[カラム名] で、動的にカラムの値で、マークをする、しないを
215         * 選ぶ事が可能になります。値は、"true"(または "1") で、マークします。
216         * 追記 3.5.2.0 (2003/10/20):markList属性に、処理対象文字列郡を指定できます。
217         * これにより、マークを処理するかどうかの判断が、true,1 以外にも使用できるようになりました。
218         *
219         * @og.rev 3.5.0.0 (2003/09/17) onMark に、[カラム名] の値をセットできるように修正。
220         *
221         * @param       flag マークの処理 [true,1:処理する/それ以外:処理しない]
222         */
223        public void setOnMark( final String flag ) {
224                onMark = nval( getRequestParameter( flag ),onMark );
225        }
226
227        /**
228         * 【TAG】処理するマークを含むような文字列を、"|"区切りの文字列で指定します(初期値:"true|TRUE|1")。
229         *
230         * @og.tag
231         * markListで与えられた文字列に、onMark文字列(大文字/小文字の区別あり)が
232         * 含まれていれば、処理します。
233         * 例えば、"A","B","C" という文字列が、onMark で指定された
234         * 場合に処理するようにしたい場合は、"A|B|C" をセットします。
235         * markList には、[カラム名]指定が可能です。
236         * 初期値は、 "true|TRUE|1"です。
237         *
238         * @og.rev 3.5.2.0 (2003/10/20) 新規追加
239         *
240         * @param       list 処理するマーク(indexOf による含む/含まない判定)
241         */
242        public void setMarkList( final String list ) {
243                markList = nval( getRequestParameter( list ),markList );
244        }
245
246        /**
247         * 【TAG】スペースで区切られた複数の値について、マークします。
248         *
249         * @og.tag
250         * 最終的に作成された表示結果に対して、引数の文字列を含む箇所に、
251         * <span class="instr0">引数文字列</span> 文字列と置き換えます。
252         * 0 の部分は、引数文字列の現れた順番を指定します。
253         * これにより、部分検索された箇所のみにマークすることが可能です。
254         * 部分文字列は、スペースで区切り、それぞれ独立した形でマーク
255         * されますので、検索エンジン等で検索したキャッシュ表示のような
256         * 効果を持たすことが可能になります。
257         *
258         * @param       val スペースで区切られた複数の値
259         * @see         SqlAndTag#setInstrVals( String )
260         */
261        public void setInstrVals( final String val ) {
262                instrVals = nval( getRequestParameter( val ),instrVals );
263        }
264
265        /**
266         * 【TAG】[$XXXX],[#XXXX]機能を有効にするかどうか指定します(初期値:"false")。
267         *
268         * @og.tag
269         * カラムのフォーマット処理で、[$XXXX],[#XXXX]などの就職記号を付けると、
270         * データでない値を出力できます。
271         * [$XXXX] は、レンデラー処理された文字列を、[#XXXX]は、ラベルリソースを出力します。
272         * この、columnMarker のデフォルトでは、[$XXXX]は、URLエンコード処理された結果が
273         * 返されます。他の処理(viewタグのボディ部等)とは異なる処理ですが、互換性のため、
274         * [$XXXX]のレンデラー処理は、行われません。
275         * この、属性で、"true" を設定すれば、他のフォーマット処理と同じ処理が実行されます。
276         * 初期値は、互換性を考慮し、"false" になっています。
277         *
278         * @og.rev 5.6.3.0 (2013/04/01) 新規追加
279         *
280         * @param       val [$XXXX],[#XXXX]機能を有効にするかどうか(true:有効/false:無効)
281         */
282        public void setUseFormatDeco( final String val ) {
283                useFormatDeco = nval( getRequestParameter( val ),useFormatDeco );
284        }
285
286        /**
287         * このオブジェクトの文字列表現を返します。
288         * 基本的にデバッグ目的に使用します。
289         *
290         * @return このクラスの文字列表現
291         */
292        @Override
293        public String toString() {
294                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
295                                .println( "VERSION"             ,VERSION        )
296                                .println( "column"              ,column         )
297                                .println( "columns"             ,columns        )
298                                .println( "onMark"              ,onMark         )
299                                .println( "markList"    ,markList       )
300                                .println( "Other..."    ,getAttributes().getAttribute() )
301                                .fixForm().toString() ;
302        }
303}