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