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 static org.opengion.fukurou.util.StringUtil.*; 019 020import java.util.regex.Matcher; 021import java.util.regex.Pattern; 022 023import org.opengion.fukurou.util.StringUtil; 024import org.opengion.hayabusa.common.HybsSystem; 025import org.opengion.hayabusa.common.HybsSystemException; 026 027/** 028 * Where句を作成するための条件を指定します。 029 * 030 * このタグのvalue 値に、{@XXXX} 変数が含まれている場合、そのリクエスト値が 031 * ない場合は、このタグそのものがなにも出力しません。(つまり条件から消えます。) 032 * startKeyは、value を連結する場合の頭に置かれる文字列で、where句の最初には表示されず、 033 * それ以降について、表示されます。(つまり、where VALUE1 and VALUE2 and VALUE3 … です。) 034 * startKey の初期値は、"and" です。 035 * multi は、{@XXXX} 変数に、値が複数含まれている場合の処理を規定します。 036 * 複数の値とは、同一nameでチェックボックス指定や、メニューでの複数指定した場合、 037 * リクエストが配列で送られます。multi="true" とすると、'xx1','xx2','xx3', ・・・ という 038 * 形式に変換されます。 039 * 具体的には、"where PN in ( {@PN} )" という文字列に対して、 040 * "where PN in ( 'xx1','xx2','xx3' )" を作成することができます。 041 * multi の初期値は、"false" です。 042 * SystemData の USE_SQL_INJECTION_CHECK が true か、quotCheck 属性が true の場合は、 043 * SQLインジェクション対策用のクォーティションチェックを行います。リクエスト引数に 044 * クォーティション(')が含まれると、エラーになります。 045 * 同様にUSE_XSS_CHECKがtrueか、xssCheck属性がtrueの場合は、 046 * クロスサイトススクリプティング(XSS)対策のためless/greater than signのチェックを行います。 047 * 048 * 各属性は、{@XXXX} 変数が使用できます。 049 * これは、ServletRequest から、XXXX をキーに値を取り出し,この変数に割り当てます。 050 * つまり、このXXXXをキーにリクエストすれば、この変数に値をセットすることができます。 051 * 052 * @og.formSample 053 * ●形式:<og:and startKey="[and|or|…]" value="…" multi="[false|true]" /> 054 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します) 055 * 056 * ●Tag定義: 057 * <og:and 058 * startKey 【TAG】SQL条件句の最初の演算子を指定します(初期値:and) 059 * value 【TAG】条件の値を セットします 060 * multi 【TAG】複数の引数に対して処理するかどうか[true/false]を設定します(初期値:false) 061 * separator 【TAG】multi アクション時の文字列を分割する項目区切り文字をセットします 062 * quotCheck 【TAG】リクエスト情報の クォーティション(') 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_SQL_INJECTION_CHECK[=true]) 063 * instrVals 【TAG】スペースで区切られた複数の値すべてを含む条件を作成します 064 * instrType 【TAG】instrValsで複数の値を条件にする際の方法を指定します(初期値:and) 065 * xssCheck 【TAG】リクエスト情報の HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_XSS_CHECK[=true]) 066 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 067 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 068 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true) 069 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true) 070 * placeHolder 【TAG】value の?に設定する値を指定します。(queryType="JDBCPrepared"専用) 071 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 072 * > ... Body ... 073 * </og:and> 074 * 075 * ●使用例 076 * <og:query command="NEW"> 077 * select PN,YOBI,NMEN,HINM from XX01 078 * <og:where> 079 * <og:and value="PN = '{@PN}'" /> 080 * <og:and value="YOBI like '{@YOBI}%'" /> 081 * </og:where> 082 * order by PN 083 * </og:query> 084 * 085 * ・検索条件が入力された時(PN=AAA , YOBI=BBB) 086 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 where PN = 'AAA' and YOBI like 'BBB%' order by PN 087 * 088 * ・検索条件が片方入力されなかった時(PNがNULLのとき, YOBI=BBB) 089 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 where YOBI like 'BBB%' order by PN 090 * 091 * ・検索条件が入力されなかった時(PNがNULL, YOBIがNULL) WHERE句がなくなる。 092 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 order by PN 093 * 094 * 注意:WhereTagを使わない場合に、検索条件が入力されなかった場合は、下記のようになります。 095 * select PN,YOBI,NMEN,HINM from XX01 where PN = '' and YOBI like '%' order by PN 096 * 097 * -------------------------------------------------------------------------------------------------------------- 098 * 099 * <og:query command="NEW"> 100 * select PN,YOBI,NMEN,HINM from XX01 where PN="11111" 101 * <og:where startKey="and"> 102 * <og:and value="YOBI in ({@YOBI})" multi="true" /> 103 * <og:and value="HINM like '{@HINM}%'" /> 104 * </og:where> 105 * order by PN 106 * </og:query> 107 * 108 * ・YOBI を複数選択し、in で検索する時(YOBI=AA,BB,CC を選択) 109 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 where PN = '11111' 110 * and YOBI in ( 'AA','BB','CC' ) and HINM like 'BBB%' order by PN 111 * 112 * -------------------------------------------------------------------------------------------------------------- 113 * placeHolderを利用する場合の利用例。 114 * queryタグのsqlTypeはJDBCPrepared専用です。 115 * 116 * <og:query command="NEW" sqlType="JDBCPrepared"> 117 * SELECT * FROM XX01 118 * <og:where> 119 * <og:and value="K01 = ?" placeHolder="{@VAL1}" /> 120 * <og:and value="K02 LIKE ?" placeHolder="{@VAL2}%" /> 121 * <og:and value="K03 IN (?)" multi="true" placeHolder="{@VAL3}" /> 122 * <og:and value="K04 = ? || ?" placeHolder="{@VAL4},{@VAL5}" /> 123 * <og:and value="K05 IN (?,?)" multi="true" placeHolder="{@VAL6},{@VAL7}" /> 124 * </og:where> 125 * </og:query> 126 * 127 * ※SELECT句に?を利用する場合は、下記のように、queryタグのnames属性を利用してください。 128 * 129 * <og:query command="NEW" sqlType="JDBCPrepared" names="VAL1"> 130 * SELECT ?, A.* FROM XX01 A 131 * <og:and value="A.K01 = ?" placeHolder="{@VAL2}" /> 132 * </og:query> 133 * 134 * @og.group 画面部品 135 * 136 * @version 4.0 137 * @author Kazuhiko Hasegawa 138 * @since JDK5.0, 139 */ 140public class SqlAndTag extends CommonTagSupport { 141 //* このプログラムのVERSION文字列を設定します。 {@value} */ 142 private static final String VERSION = "5.5.1.1 (2012/04/06)" ; 143 144 private static final long serialVersionUID = 551120120406L ; 145 146 private String startKey = "and"; 147 private String value = ""; 148 private String instrVals = null; // 3.8.8.1 (2007/01/06) 149 private String instrType = "and"; // 5.4.1.0 (2011/11/01) 150 private boolean multi = false; 151 private boolean quotCheck = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" ); // 4.0.0 (2005/08/31) 152 private boolean xssCheck = HybsSystem.sysBool( "USE_XSS_CHECK" ); // 5.0.0.2 (2009/09/15) 153 154 private boolean allNull = false; // 5.0.0.2 (2009/09/15) 155 156// private String matchKey = null; // 5.1.9.0 (2010/08/01) ⇒ 5.2.2.0 (2010/11/01) 廃止(caseKey,caseVal属性を使用してください。) 157 158// private String matchVal = null; // 5.1.9.0 (2010/08/01) ⇒ 5.2.2.0 (2010/11/01) 廃止(caseKey,caseVal属性を使用してください。) 159 160 private String separator = null; // 5.2.2.0 (2010/11/01) 項目区切り文字 161 162 // 5.10.2.1 (2018/08/18) 163 private String placeHolder = null; 164 private final String regex2 = "\\?"; // multipleの?追加 165 private final String afRegex2 = "?,?"; 166 private Pattern pattern_multi = Pattern.compile(regex2); 167 private final String regex3 = "\\{@.+?\\}"; // 文字列から、{@XXX}を抽出(multipleの複数指定用) 168 private Pattern pattern_trg = Pattern.compile(regex3); 169 170 /** 171 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 172 * 173 * @og.rev 4.0.0.0 (2006/12/05) BODY 部の値を value に使用する機能追加 174 * @og.rev 4.0.0.0 (2005/08/31) useQuotCheck() によるSQLインジェクション対策 175 * @og.rev 5.0.0.2 (2009/09/15) XSS対策 176 * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 177 * 178 * @return 後続処理の指示 179 */ 180 @Override 181 public int doStartTag() { 182 // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 183 if( useTag() ) { 184 useQuotCheck( quotCheck ); 185 // 5.0.0.2 (2009/09/15) XSS対策 186 useXssCheck( xssCheck ); 187 188 value = getRequestParameter( value ); 189 190 if( value == null || value.isEmpty() ) { 191 return( EVAL_BODY_BUFFERED ); // Body を評価する。( extends BodyTagSupport 時) 192 } 193 194 // if( value != null && value.length() > 0 ) { 195 // return( SKIP_BODY ); // Body を評価しない 196 // } 197 // else { 198 // return( EVAL_BODY_BUFFERED ); // Body を評価する。( extends BodyTagSupport 時) 199 // } 200 } 201 return( SKIP_BODY ); // Body を評価しない 202 } 203 204 /** 205 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。 206 * 207 * @og.rev 4.0.0.0 (2006/12/05) BODY 部の値を value に使用する機能追加 208 * 209 * @return 後続処理の指示(SKIP_BODY) 210 */ 211 @Override 212 public int doAfterBody() { 213 value = getBodyString(); 214 return(SKIP_BODY); 215 } 216 217 /** 218 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 219 * 220 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 221 * @og.rev 3.8.8.1 (2007/01/06) makeInstrVals を加味する。 222 * @og.rev 5.0.0.2 (2009/09/15) multi時のallNull対応 223 * @og.rev 5.1.9.0 (2010/08/01) matchKey 、matchVal 対応 ⇒ 5.2.2.0 (2010/11/01) 廃止 224 * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 225 * 226 * @return 後続処理の指示 227 */ 228 @Override 229 public int doEndTag() { 230 debugPrint(); // 4.0.0 (2005/02/28) 231 // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 232 if( useTag() ) { 233 SqlWhereTag where = (SqlWhereTag)findAncestorWithClass( this,SqlWhereTag.class ); 234 if( where == null ) { 235// String errMsg = "<b>このタグは、where タグの内部におく必要があります。</b>"; 236 String errMsg = "<b>" + getTagName() + "タグは、where タグの内部におく必要があります。</b>"; 237 throw new HybsSystemException( errMsg ); 238 } 239 240 // 5.1.9.0 (2010/08/01) matchKey 、matchVal 対応 ⇒ 5.2.2.0 (2010/11/01) 廃止 241 // boolean flag = (matchKey == null) || (matchVal == null) || matchKey.matches( matchVal ) ; 242 243 // 5.10.2.1 (2018/08/18) 244 // プレースホルダーが設定されている場合は、プレースホルーダの括弧整合性チェック 245 if( placeHolder!=null && placeHolder.length() > 0 ) { 246 getRequestParameter( placeHolder ); 247 } 248 249 // if( ! isNull() ) { 250 // if( ! isNull() && ! allNull ) { // 5.0.0.2 (2009/09/15) 251 // if( ! isNull() && ! allNull && flag ) { // 5.1.9.0 (2010/08/01) 252 if( ! isNull() && ! allNull ) { // 5.2.2.0 (2010/11/01) 253// value = makeInstrVals( instrVals,value ); // 3.8.8.1 (2007/01/06) 254 value = makeInstrVals( instrVals,instrType,value ); // 5.4.1.0 (2011/11/01) 255 256 if( value != null ) { 257 // 5.10.2.1 (2018/08/18) 258 // プレースホルダー指定の場合の処理 259 if( placeHolder!=null && placeHolder.length() > 0 ) { 260 QueryTag query = null; 261 query = (QueryTag)findAncestorWithClass( this, QueryTag.class); 262 if(multi) { 263 // multiの場合は、?の数を増やして、設定する値も増やす 264 // placeHolder属性から、対象文字列を取得。 265 // 複数指定の場合を、考慮して、繰り返し処理を行う。 266 Matcher matcher_trg = pattern_trg.matcher(placeHolder); 267 while(matcher_trg.find()) { 268 String trgPlaceHolder = matcher_trg.group(); 269 String[] list = getRequestParameterValues(trgPlaceHolder); 270 // 2つ以上の値につき、,?を追加 271 for(int i=1; i<list.length; i++) { 272 Matcher matcher = pattern_multi.matcher(value); 273 value = matcher.replaceFirst(afRegex2); 274 } 275 276 for(int i=0; i<list.length; i++) { 277 query.addListPlaceValue(list[i]); 278 } 279 } 280 }else { 281 query.addListPlaceValue(placeHolder); 282 } 283 } 284 285 // whereタグへの通常設定処理 286 set( "keyWord", startKey ); 287 set( "value" , value ); 288 where.setAttributes( getAttributes() ); 289 } 290 } 291 } 292 293 return(EVAL_PAGE); 294 } 295 296 297 /** 298 * タグリブオブジェクトをリリースします。 299 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 300 * 301 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加 302 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 303 * @og.rev 3.8.8.1 (2007/01/06) instrVals 属性追加 304 * @og.rev 4.0.0.0 (2005/08/31) quotCheck 属性の追加 305 * @og.rev 5.0.0.2 (2009/09/15) XSS対応 306 * @og.rev 5.0.0.2 (2009/09/15) multi時のallNull対応 307 * @og.rev 5.1.9.0 (2010/08/01) matchKey、matchVal 属性の追加 308 * @og.rev 5.2.2.0 (2010/11/01) separator , isMatch 属性の追加 309 * @og.rev 5.2.2.0 (2010/11/01) matchKey、matchVal 属性廃止(caseKey,caseVal属性を使用してください。) 310 * @og.rev 5.4.1.0 (2011/11/01) instrType属性追加 311 * @og.rev 5.10.2.1 (2018/08/18) placeHolder属性追加 312 */ 313 @Override 314 protected void release2() { 315 super.release2(); 316 startKey = "and"; 317 value = ""; 318 instrVals = null; // 3.8.8.1 (2007/01/06) 319 instrType = "and"; // 5.4.1.0 (2011/11/01) 320 multi = false; 321 quotCheck = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" ); // 4.0.0 (2005/08/31) 322 xssCheck = HybsSystem.sysBool( "USE_XSS_CHECK" ); // 5.0.0.2 (2009/09/15) 323 allNull = false; // 5.0.0.2 (2009/09/15) 324// matchKey = null; // 5.1.9.0 (2010/08/01) 新規追加 325// matchVal = null; // 5.1.9.0 (2010/08/01) 新規追加 326 separator = null; // 5.2.2.0 (2010/11/01) 項目区切り文字 327 placeHolder = null; // 5.10.2.1 (2018/08/18) プレースホルダー判定用 328 } 329 330 /** 331 * リクエスト情報の文字列を取得します。 332 * 333 * これは、通常のgetRequestParameter 処理の中で呼ばれる getRequestValue を 334 * オーバーライトしています。 335 * 336 * @og.rev 5.0.0.2 (2009/09/15) valuesの全NULL/空文字をisNull扱いにする 337 * @og.rev 5.3.8.0 (2011/08/01) Attribute等からも値が取得できるようにする。の対応時の特殊処理 338 * 339 * @param key キー 340 * 341 * @return リクエスト情報の文字列 342 */ 343 @Override 344 protected String getRequestValue( final String key ) { 345 String rtn = ""; 346 347 if( multi ) { 348 // 5.3.8.0 (2011/08/01) getRequestValues の中で、getRequestValue を呼び出すためこのままでは 349 // 再帰呼び出しが永遠に続くので、2回目以降は、再帰しないように、強制的に multi の値を書き換えます。 350 multi = false; // 5.3.8.0 (2011/08/01) 再帰しないように、強制的に値を書き換え 351 String[] array = getRequestValues( key ); 352 allNull = true; // 5.0.0.2 (2009/09/15) arrayの内容が全てnull/空文字か 353 if( ! isNull() ) { 354 // 5.0.0.2 (2009/09/15) 全てnull/空文字の場合はnullと扱い 355 for( int i = 0; i < array.length; i++ ) { 356 if( array[i] != null && array[i].length() > 0 ) { 357 allNull = false; 358 break; 359 } 360 } 361 if( ! allNull ){ 362 rtn = makeCSVvalue( array ); 363 } 364 } 365 multi = true; // 5.3.8.0 (2011/08/01) 強制的に書き換えた値を元に戻す。 366 } 367 else { 368 rtn = super.getRequestValue( key ); 369 } 370 return rtn ; 371 } 372 373 /** 374 * 複数の値を 'xx1','xx2','xx3', ・・・ という形式に変換します。 375 * 376 * この処理は、in などで使用するためのリクエストを配列で受け取って処理 377 * する場合の文字列を加工します。 378 * 379 * @og.rev 5.2.2.0 (2010/11/01) separator 対応 380 * 381 * @param array 元の配列文字列 382 * 383 * @return 連結後の文字列 384 */ 385 private String makeCSVvalue( final String[] array ) { 386 if( array == null || array.length == 0 ) { 387 String errMsg = "array 引数に、null や、サイズゼロの配列は使用できません。"; 388 throw new HybsSystemException( errMsg ); 389 } 390 391 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 392 393 if( separator != null ) { 394 for(int i=0; i < array.length; i++) { 395 String[] ary = array[i].split( separator ); 396 for( int j=0; j<ary.length; j++ ) { 397 buf.append( "'" ); 398 buf.append( ary[j] ); 399 buf.append( "'," ); 400 } 401 } 402 buf.deleteCharAt( buf.length()-1 ); // 最後の ピリオドを削除する。 403 } 404 else { 405 for(int i=0; i < array.length; i++) { 406 buf.append( "'" ); 407 buf.append( array[i] ); 408 buf.append( "'," ); 409 } 410 buf.deleteCharAt( buf.length()-1 ); // 最後の ピリオドを削除する。 411 } 412// buf.append( "'" ); 413// buf.append( array[0] ); 414// buf.append( "'" ); 415// for(int i=1; i < array.length; i++) { 416// buf.append( ",'" ); 417// buf.append( array[i] ); 418// buf.append( "'" ); 419// } 420 return buf.toString(); 421 } 422 423 /** 424 * スペースで区切られた複数の値を and 接続で連結します。 425 * 426 * value="CLM" instrVals="ABC DEF GHI" と指定すると、 427 * value="CLM LIKE '%ABC%' AND CLM LIKE '%DEF%' AND CLM LIKE '%GHI%' " 428 * という文字列を作成します。 429 * 個別にLIKE検索項目を AND 連結する為、現れる場所に依存しません。 430 * 逆に、現れる順序を指定する場合は、ABC%DEF の様に指定可能です。 431 * ただし、columnMarker の instrVals で、複数文字のマーカーを行う場合、 432 * ABC%DEF という文字列は、オリジナルでないので、マークアップされません。 433 * 434 * @og.rev 5.4.1.0 (2011/11/01) instrType属性対応 435 * @og.rev 5.5.1.1 (2012/04/06) notin対応 436 * 437 * @param instrVals 繰返し処理を行う 値 438 * @param instrType 連結方法 439 * @param value 繰返し処理を行う value 440 * 441 * @return 連結後の文字列 442 * @see #setInstrVals( String ) 443 * @see ColumnMarkerTag#setInstrVals( String ) 444 */ 445 private String makeInstrVals( final String instrVals, final String instrType , final String value ) { 446 if( instrVals == null || instrVals.length() == 0 ) { return value; } 447 448 String reqVals = nval( getRequestParameter( instrVals ),null ); 449 if( reqVals == null || reqVals.length() == 0 ) { return null; } 450 451 final String[] vals ; 452 if( multi ) { 453 // multi のときは、makeCSVvalue で加工された値になっている。 454 vals = StringUtil.csv2Array( reqVals,',' ); 455 // 前後の ' はずし 456 for( int i=0; i<vals.length; i++ ) { 457 vals[i] = vals[i].substring( 1,vals[i].length()-1 ); 458 } 459 } 460 else { 461 vals = StringUtil.csv2Array( reqVals,' ' ); 462 } 463 464 if( vals == null || vals.length == 0 ) { return null; } 465 466 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL ); 467 468// buf.append( value ); 469// buf.append( " LIKE '%" ); 470// buf.append( vals[0] ); 471// buf.append( "%'" ); 472 473 buf.append( " (" ); 474 // 条件:and ⇒ 各値をandのlike条件で結合(%あり) 475 if( instrType.startsWith( "a" ) ) { 476 for(int i=0; i < vals.length; i++) { 477 if( i > 0 ) { buf.append( " and " ); } 478 buf.append( value ); 479 buf.append( " LIKE '%" ).append( vals[i] ).append( "%'" ); 480 } 481 } 482 // 条件:or ⇒ 各値をorのlike条件で結合(%あり) 483 else if( instrType.startsWith( "o" ) ) { 484 for(int i=0; i < vals.length; i++) { 485 if( i > 0 ) { buf.append( " or " ); } 486 buf.append( value ); 487 buf.append( " LIKE '%" ).append( vals[i] ).append( "%'" ); 488 } 489 } 490 // 条件:in ⇒ 各値をorのlike条件で結合(%なし) 491 else if( instrType.startsWith( "i" ) ) { 492 for(int i=0; i < vals.length; i++) { 493 if( i > 0 ) { buf.append( " or " ); } 494 buf.append( value ); 495 buf.append( " LIKE '" ).append( vals[i] ).append( "'" ); 496 } 497 } 498 // 条件:notin ⇒ 各値をandのnot like条件で結合(%なし) 5.5.1.1(2012/04/05) 499 else if( instrType.startsWith( "n" ) ) { 500 for(int i=0; i < vals.length; i++) { 501 if( i > 0 ) { buf.append( " and " ); } 502 buf.append( value ); 503 buf.append( " NOT LIKE '" ).append( vals[i] ).append( "'" ); 504 } 505 } 506 else { 507 String errMsg = "instrTypeには、'and','or','in','notin'のいずれかを指定して下さい。instrType=[" + instrType + "]"; 508 throw new HybsSystemException( errMsg ); 509 } 510 buf.append( ") " ); 511 512 return buf.toString(); 513 } 514 515 /** 516 * 【TAG】SQL条件句の最初の演算子を指定します(初期値:and)。 517 * 518 * @og.tag 519 * value を連結する場合の頭に置かれる文字列で、where句の最初には表示されず、 520 * それ以降について、表示されます。 521 * (つまり、where VALUE1 and VALUE2 and VALUE3 … です。) 522 * startKey の初期値は、"and" です。 523 * 524 * @param skey 条件句の最初の演算子 525 */ 526 public void setStartKey( final String skey ) { 527 if( skey != null && skey.length() > 0 ) { startKey = skey; } 528 } 529 530 /** 531 * 【TAG】条件の値を セットします。 532 * 533 * @og.tag 534 * 条件値に、{@XXXX} 変数が含まれている場合、そのリクエスト値がない場合は、 535 * このタグそのものがなにも出力しません。(つまり条件から消えます。) 536 * BODY 部に記述することが可能です。その場合は、条件属性になにも設定できません。 537 * 538 * @param val 条件値 539 */ 540 public void setValue( final String val ) { 541 value = val; 542 } 543 544 /** 545 * 【TAG】スペースで区切られた複数の値すべてを含む条件を作成します。 546 * 547 * @og.tag 548 * 通常、value="CLM LIKE 'ABC%'" という文字列を指定しますが、 549 * value="CLM" instrVals="ABC DEF GHI" と指定すると、 550 * value="CLM LIKE '%ABC%' AND CLM LIKE '%DEF%' AND CLM LIKE '%GHI%' " 551 * という文字列を作成します。 552 * これは、instrVals に指定した引数に対して、スペース区切りで分割し、 553 * 前方の value に複数のAND検索を同時に実現できるように指定します 554 * 個別にLIKE検索項目を AND 連結する為、現れる場所に依存しません。 555 * 逆に、現れる順序を指定する場合は、ABC%DEF の様に指定可能です。 556 * ただし、columnMarker の instrVals で、複数文字のマーカーを行う場合、 557 * ABC%DEF という文字列は、オリジナルでないので、マークアップされません。 558 * ※instrType属性の指定により条件の生成方法を変更することができます。 559 * 詳細については、instrType属性のドキュメントを参照下さい。 560 * 561 * @param val 複合条件作成のための設定値 562 * @see #setInstrType 563 * @see ColumnMarkerTag#setInstrVals( String ) 564 */ 565 public void setInstrVals( final String val ) { 566 instrVals = val; 567 } 568 569 /** 570 * 【TAG】valueの条件作成を判定します。(JDBCParepared用) 571 * 572 * @og.tag 573 * value="CLM=?" placeHolder="{@CLM}"と指定されていた場合、 574 * {@CLM}に値が存在する場合のみ、CLM=?が指定されます。 575 * ※?に設定されえる値はplaceHolderを指定する値には関係なく、 576 * 親のqueryタグに指定した、names属性の値になります。 577 * 578 * {@xxx}形式での指定のみ可能です。 579 * 580 * @og.rev 5.10.2.1 (2018/08/18) 新規追加 581 * 582 * @param val 値 583 */ 584 public void setPlaceHolder( final String val) { 585 // リクエスト変数対応はここでは行わない 586 placeHolder = val; 587 } 588 589 /** 590 * 【TAG】instrValsで複数の値を条件にする際の方法を指定します(初期値:and)。 591 * 592 * @og.tag 593 * 通常、instrValsに指定された値は、スペース区切りで分割した各値をLIKE条件としてand結合します。 594 * しかし、instrType属性を変更することで、この条件式の生成方法を変更 595 * することができます。 596 * 具体的には、以下の通りです。 597 * @instrTypeに"and"が指定されている場合(初期値) 598 * タグの記述 : value="CLM" instrVals="ABC DEF GHI" 599 * 生成文字列 : "( CLM LIKE '%ABC%' AND CLM LIKE '%DEF%' AND CLM LIKE '%GHI%' )" 600 * AinstrTypeに"or"が指定されている場合 601 * タグの記述 : value="CLM" instrVals="ABC DEF GHI" 602 * 生成文字列 : "( CLM LIKE '%ABC%' OR CLM LIKE '%DEF%' OR CLM LIKE '%GHI%' )" 603 * BinstrTypeに"in"が指定されている場合 604 * タグの記述 : value="CLM" instrVals="ABC DEF GHI" 605 * 生成文字列 : "( CLM LIKE 'ABC' OR CLM LIKE 'DEF5' OR CLM LIKE 'GHI' )" 606 * CinstrTypeに"notin"が指定されている場合 607 * タグの記述 : value="CLM" instrVals="ABC DEF GHI" 608 * 生成文字列 : "( CLM NOT LIKE 'ABC' AND CLM NOT LIKE 'DEF5' AND CLM NOT LIKE 'GHI' )" 609 * ※この属性を指定しない場合は、@のLIKE条件でのand結合となります。 610 * ※BCについて、LIKE条件で%を自動付加しないことにより、画面からの入力値に応じて、 611 * 前方一致、後方一致、前後方一致の制御を行うことができます。 612 * 613 * @og.rev 5.5.1.1 (2012/04/06) notin対応(コメント修正) 614 * 615 * @param tp 条件方法[and/or/in/notin] 616 * @see #setInstrVals( String ) 617 */ 618 public void setInstrType( final String tp ) { 619 instrType = nval( getRequestParameter( tp ),tp ); 620 } 621 622 /** 623 * 【TAG】複数の引数に対して処理するかどうか[true/false]を設定します(初期値:false)。 624 * 625 * @og.tag 626 * {@XXXX} 変数に、値が複数含まれている場合の処理を規定します。 627 * multi="true" に設定すると、複数の引数は、'xx1','xx2','xx3', ・・・ という 628 * 形式に変換します。 629 * where 条件で言うと、 "where PN in ( {@PN} )" という文字列に対して、 630 * "where PN in ( 'xx1','xx2','xx3' )" を作成することになります。 631 * 初期値は、 false (マルチ変換しない) です。 632 * 633 * @param flag マルチ変換 [true:する/それ以外:しない 634 * @see #setSeparator( String ) 635 */ 636 public void setMulti( final String flag ) { 637 multi = nval( flag,multi ); 638 } 639 640 /** 641 * 【TAG】multi アクション時の文字列を分割する項目区切り文字をセットします。 642 * 643 * @og.tag 644 * multi="true" の場合、複数のリクエストを連結して、 in 句で問合せを行う文字列を 645 * 作成しますが、separator を指定すると、さらに、separator で文字列を分割して、 646 * in 句の引数を構築します。 647 * 具体的には、分割後の文字列が、複数の個々のリクエスト変数と同じ形式に加工されます。 648 * この機能は、multi="true" を指定した場合のみ有効になります。 649 * 初期値は、null です。つまり、分割処理は行いません。 650 * 651 * @og.rev 5.2.2.0 (2010/11/01) 新規追加 652 * 653 * @param sepa 項目区切り文字 654 * @see #setMulti( String ) 655 */ 656 public void setSeparator( final String sepa ) { 657 separator = nval( getRequestParameter( sepa ),separator ); 658 } 659 660 /** 661 * 【TAG】リクエスト情報の クォーティション(') 存在チェックを実施するかどうか[true/false]を設定します 662 * (初期値:USE_SQL_INJECTION_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK}])。 663 * 664 * @og.tag 665 * SQLインジェクション対策の一つとして、暫定的ではありますが、SQLのパラメータに 666 * 渡す文字列にクォーティション(') を許さない設定にすれば、ある程度は防止できます。 667 * 数字タイプの引数には、 or 5=5 などのクォーティションを使用しないコードを埋めても、 668 * 数字チェックで検出可能です。文字タイプの場合は、必ず (')をはずして、 669 * ' or 'A' like 'A のような形式になる為、(')チェックだけでも有効です。 670 * (') が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。 671 * (初期値:システム定数のUSE_SQL_INJECTION_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK}])。 672 * 673 * @og.rev 4.0.0.0 (2005/08/31) 新規追加 674 * 675 * @param flag クォーティションチェック [true:する/それ以外:しない] 676 * @see org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK 677 */ 678 public void setQuotCheck( final String flag ) { 679 quotCheck = nval( getRequestParameter( flag ),quotCheck ); 680 } 681 682 /** 683 * 【TAG】リクエスト情報の HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します 684 * (初期値:USE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}])。 685 * 686 * @og.tag 687 * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。 688 * (><) が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。 689 * (初期値:システム定数のUSE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}])。 690 * 691 * @og.rev 5.0.0.2 (2009/09/15) 新規追加 692 * 693 * @param flag XSSチェック [true:する/false:しない] 694 * @see org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK 695 */ 696 public void setXssCheck( final String flag ) { 697 xssCheck = nval( getRequestParameter( flag ),xssCheck ); 698 } 699 700 /** 701 * 【TAG】このタグ自体を利用するかどうかの条件キーを指定します。 702 * 703 * @og.tag 704 * matchKey.matches( matchVal ) の値が、true の場合は、このタグは使用されます。 705 * false の場合は、このタグは使用されません。 706 * value 値に、{@XXXX} 変数が含まれている場合と同じ効果を得られます。 707 * 何も指定しない場合、または、引数が null の場合は、true と同じで使用されます。 708 * 709 * @og.rev 5.1.9.0 (2010/08/01) 新規追加 710 * @og.rev 5.2.2.0 (2010/11/01) 廃止(caseKey,caseVal属性を使用してください。) 711 * 712 * @param mkey String 713 */ 714// public void setMatchKey( final String mkey ) { 715// matchKey = nval( getRequestParameter( mkey ),matchKey ); 716// } 717 718 /** 719 * 【TAG】このタグ自体を利用するかどうかの条件値を指定します。 720 * 721 * @og.tag 722 * matchKey.matches( matchVal ) の値が、true の場合は、このタグは使用されます。 723 * false の場合は、このタグは使用されません。 724 * value 値に、{@XXXX} 変数が含まれている場合と同じ効果を得られます。 725 * 何も指定しない場合、または、引数が null の場合は、true と同じで使用されます。 726 * 727 * @og.rev 5.1.9.0 (2010/08/01) 新規追加 728 * @og.rev 5.2.2.0 (2010/11/01) 廃止(caseKey,caseVal属性を使用してください。) 729 * 730 * @param mval String 731 */ 732// public void setMatchVal( final String mval ) { 733// matchVal = nval( getRequestParameter( mval ),matchVal ); 734// } 735 736 /** 737 * タグの名称を、返します。 738 * 自分自身のクラス名より、自動的に取り出せないため、このメソッドをオーバーライドします。 739 * 740 * @og.rev 4.0.0.0 (2005/01/31) 新規追加 741 * 742 * @return タグの名称 743 */ 744 @Override 745 protected String getTagName() { 746 return "and" ; 747 } 748 749 /** 750 * このオブジェクトの文字列表現を返します。 751 * 基本的にデバッグ目的に使用します。 752 * 753 * @return このクラスの文字列表現 754 */ 755 @Override 756 public String toString() { 757 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 758 .println( "VERSION" ,VERSION ) 759 .println( "startKey" ,startKey ) 760 .println( "value" ,value ) 761 .println( "instrVals" ,instrVals ) 762 .println( "multi" ,multi ) 763 .println( "quotCheck" ,quotCheck ) 764 .println( "placeHolder" ,placeHolder) // 5.10.2.0 (2018/08/03) ADD 765 .println( "Other..." ,getAttributes().getAttribute() ) 766 .fixForm().toString() ; 767 } 768}