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 */ 016 package org.opengion.hayabusa.taglib; 017 018 import org.opengion.hayabusa.common.HybsSystem; 019 import org.opengion.hayabusa.common.HybsSystemException; 020 import org.opengion.hayabusa.db.DBTableModel; 021 import org.opengion.hayabusa.db.TableFilter; 022 import org.opengion.fukurou.db.Transaction; 023 import org.opengion.fukurou.db.TransactionReal; 024 import org.opengion.fukurou.util.ErrorMessage; 025 import org.opengion.fukurou.util.StringUtil; 026 import static org.opengion.fukurou.util.StringUtil.nval ; 027 028 import java.io.ObjectOutputStream; 029 import java.io.ObjectInputStream; 030 import java.io.IOException; 031 import java.util.Map; 032 033 /** 034 * TableFilter のサブクラスをCALLしてDBTableModelにアクセスするタグです? 035 * 036 * DBTableModel ?TableFilter のサブクラス(classIdで??に渡して処?実行します? 037 * クラスを作?する場合?、org.opengion.hayabusa.db.TableFilter インターフェースを継承した 038 * クラスにする?があります?また?classId 属?には、シス?リソース で 039 * 設定し?TableFilter.XXXX の XXXX を指定します? 040 * 041 * BODY部??、SQLを記述する為?に使って?したが?CSS定義形式?書式で、keys,vals を記述 042 * できるようにします? 043 * これは、下記?ようなパラメータを?keys="KEY,KEY2,KEY3" vals='AAAA,"BB,CC,DD",EE' のような記述形式と 044 * { 045 * KEY1 : AAAA ; 046 * KEY2 : BB,CC,DD ; 047 * KEY3 : EE ; 048 * ・・・・・・ 049 * } 050 * のような、CSS形式に類似の形式でも記述できるようにしました? 051 * keys,vals と CSS定義形式パラメータを同時に?した?合?、両方とも有効です? 052 * ただし?キーが重?た?合?、不定と?てください? 053 * 現時点では、CSS定義形式パラメータが優先されますが、これ?、単に?パラメータMapへの 054 * 登録?、CSS定義形式パラメータが後?為、上書きされるためです? 055 * 056 * ※ こ?タグは、Transaction タグの対象です? 057 * 058 * @og.formSample 059 * ●形式?lt;og:tableFilter classId="…" /> 060 * ●body?あ?EVAL_BODY_BUFFERED:BODYを評価し?{@XXXX} を解析しま? 061 * 062 * ●Tag定義?? 063 * <og:tableFilter 064 * classId ○?TAG】データベ?ス処?実行するクラスパスを指定しま???)? 065 * tableId 【TAG?通常は使?せん)DBTableModel sessionに登録されて?キーを指定しま? 066 * modifyType 【TAG】データ処??方?A:追?C:更新 D:削除)を指定しま? 067 * keys 【TAG】リンク先に渡すキーを指定しま? 068 * vals 【TAG】keys属?に対応する?をCSV形式で??しま? 069 * selectedAll 【TAG】データを?件選択済みとして処?るかど?[true/false]を指定しま?初期値:false) 070 * stopZero 【TAG】検索結果が0件のとき??続行するかど?[true/false]を指定しま?初期値:false[続行する]) 071 * scope 【TAG】キャ?ュする場合?スコープ[request/page/session/applicaton]を指定しま?初期値:session) 072 * dbid 【TAG?通常は使?せん)Queryオブジェクトを作?する時?DB接続IDを指定しま? 073 * debug 【TAG】デバッグ??を?力するかど?[true/false]を指定しま?初期値:false) 074 * > ... Body ... 075 * </og:tableFilter> 076 * 077 * ●使用? 078 * ・引数/プロシジャーを直接書く?? 079 * 【entry.jsp? 080 * <og:tableFilter 081 * classId = "WL_LOGICSET" :TableFilter のサブクラス(実行クラス) 082 * tableId = "WL0000" :登録??DBTableModelのsession/request変数??取得キー 083 * keys = "AA,BB,CC" :実行クラスへの引数のキー 084 * vals = "{@AA},{@BB},{@CC}" :実行クラスへの引数の値 085 * selectedAll = "false/true" :処?象の行を全行選択するかど?(初期値:false) 086 * modifyType = "A/C/D" :処??方?A:追?C:更新 D:削除)を指定します?初期値は自動です? 087 * /> 088 * 089 * ・BODY部?、CSS形式?パラメータ??eys,vals?を記述する? 090 * 091 * <og:tableFilter 092 * classId = "WL_LOGICSET" :TableFilter のサブクラス(実行クラス) 093 * tableId = "WL0000" :登録??DBTableModelのsession/request変数??取得キー 094 * selectedAll = "false/true" :処?象の行を全行選択するかど?(初期値:false) 095 * modifyType = "A/C/D" :処??方?A:追?C:更新 D:削除)を指定します?初期値は自動です? 096 * > 097 * { 098 * AA : {@AA} 099 * BB : {@BB} 100 * CC : {@CC} 101 * } 102 * </og:tableFilter> 103 * 104 * @og.group そ?? 105 * @og.rev 3.8.5.0 (2006/03/20) 新規作? 106 * 107 * @version 0.9.0 2000/10/17 108 * @author Kazuhiko Hasegawa 109 * @since JDK1.1, 110 */ 111 public class TableFilterTag extends CommonTagSupport { 112 //* こ?プログラ??VERSION??を設定します? {@value} */ 113 private static final String VERSION = "5.7.6.2 (2014/05/16)" ; 114 115 private static final long serialVersionUID = 576220140516L ; 116 117 private static final String errMsgId = HybsSystem.ERR_MSG_KEY; 118 private transient DBTableModel table = null; 119 120 private String tableId = HybsSystem.TBL_MDL_KEY; 121 private String classId = null; 122 private String modifyType = null; 123 private String[] keys = null; 124 private String[] vals = null; 125 126 private String dbid = null ; // 4.2.4.0 (2008/06/23) 127 private String sql = null ; // 5.6.5.2 (2013/06/21) bodyからSQL??みを?り?す? 128 private Map<String,String> paramMap = null; // 5.6.5.2 (2013/06/21) bodyからparamMapを取りだし? 129 130 private boolean selectedAll = false; 131 private boolean stopZero = false; // 5.7.6.2 (2014/05/16) stopZero属?追? 132 133 /** 134 * Taglibの開始タグが見つかったときに処??doStartTag() ?オーバ?ライドします? 135 * 136 * @return 後続????( EVAL_BODY_BUFFERED ) 137 */ 138 @Override 139 public int doStartTag() { 140 table = (DBTableModel)getObject( tableId ); 141 142 if( keys != null && vals != null && keys.length != vals.length ) { 143 String errMsg = "keys と vals の設定?の数が異なります?: " + HybsSystem.CR 144 + "keys.length=[" + keys.length + "] , " 145 + "keys.length=[" + StringUtil.array2line( keys,"," ) + "]" 146 + HybsSystem.CR 147 + "vals.length=[" + vals.length + "] , " 148 + "vals.length=[" + StringUtil.array2line( vals,"," ) + "]"; 149 throw new HybsSystemException( errMsg ); 150 } 151 152 startQueryTransaction( tableId ); 153 return EVAL_BODY_BUFFERED ; // Body を評価する 154 } 155 156 /** 157 * Taglibのタグ本体を処??doAfterBody() ?オーバ?ライドします? 158 * 159 * @og.rev 5.6.5.2 (2013/06/21) bodyローカル化?sql、paramMap 追? 160 * 161 * @return 後続????(SKIP_BODY) 162 */ 163 @Override 164 public int doAfterBody() { 165 String body = nval( getBodyString(),null ); 166 167 // paramMapの取り出? 168 paramMap = StringUtil.cssParse( body ); 169 170 // SQL???出?classId="DBSELECT" の場合?みの処? 171 if( "DBSELECT".equalsIgnoreCase( classId ) && body != null ) { 172 int ad1 = body.indexOf( '{' ); 173 int ad2 = body.indexOf( '}' ); 174 175 if( ad1 >= 0 && ad2 >= 0 ) { 176 sql = body.substring( 0,ad1 ).trim() + body.substring( ad2+1 ).trim(); 177 } 178 else { 179 sql = body.trim(); 180 } 181 } 182 183 return SKIP_BODY ; 184 } 185 186 /** 187 * Taglibの終?グが見つかったときに処??doEndTag() ?オーバ?ライドします? 188 * 189 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設? 190 * @og.rev 4.2.3.0 (2008/06/23) DBIDとボディー部??記述を下位クラスに渡す用に修正 191 * @og.rev 4.3.7.4 (2009/07/01) Resouceオブジェクトを下位クラスに渡す用に修正 192 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対? 193 * @og.rev 5.2.1.0 (2010/10/01) debugPrint() メソ?の処?件見直? 194 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更 、Transaction対応で、close処?入れる? 195 * @og.rev 5.6.5.2 (2013/06/21) bodyローカル化?sql、paramMap 追? 196 * @og.rev 5.7.6.2 (2014/05/16) table件数が変わる?合?"DB.COUNT" キーでリクエストに再セ?する? 197 * 198 * @return 後続???? 199 */ 200 @Override 201 public int doEndTag() { 202 // ??時には、オブジェクト?部??を表示する? 203 debugPrint(); // 5.2.1.0 (2010/10/01) debugPrint() メソ?自体に、isDebug() が?込まれて?? 204 int rtnCode = EVAL_PAGE; // try ??finally の関係で、変数化しておく 205 206 int[] rowNo = getParameterRows(); 207 208 // 5.1.9.0 (2010/08/01) Transaction 対? 209 Transaction tran = null; 210 final TableFilter filter ; 211 // 5.3.7.0 (2011/07/01) Transaction対応で、close処?入れる? 212 try { 213 TransactionTag tranTag = (TransactionTag)findAncestorWithClass( this,TransactionTag.class ); 214 if( tranTag == null ) { 215 tran = new TransactionReal( getApplicationInfo() ); // 5.3.7.0 (2011/07/01) 引数変更 216 } 217 else { 218 tran = tranTag.getTransaction(); 219 } 220 221 // 5.7.6.2 (2014/05/16) table件数が変わる?合?"DB.COUNT" キーでリクエストに再セ?する? 222 int rowCnt1 = table == null ? -1 : table.getRowCount(); 223 224 String cls = HybsSystem.sys( "TableFilter_" + classId ); 225 filter = (TableFilter)HybsSystem.newInstance( cls ); 226 227 filter.setDBTableModel( table ); 228 filter.setParameterRows( rowNo ); 229 filter.setModifyType( modifyType ); 230 filter.setKeysVals( keys,vals ); 231 // filter.setApplicationInfo( getApplicationInfo() ); // 3.8.7.0 (2006/12/15) 232 filter.setTransaction( tran ); // 5.1.9.0 (2010/08/01) Transaction 対? 233 filter.setDebug( isDebug() ); 234 filter.setDbid( dbid ); // 4.2.4.0 (2008/06/23) 235 filter.setSql( sql ); // 5.6.5.2 (2013/06/21) sql 追? 236 filter.setParamMap( paramMap ); // 5.6.5.2 (2013/06/21) paramMap 追? 237 filter.setResource( getResource() ); // 4.3.7.4 (2009/07/01) 238 239 table = filter.execute(); 240 241 // 5.7.6.2 (2014/05/16) table件数が変わる?合?"DB.COUNT" キーでリクエストに再セ?する? 242 int rowCnt2 = table == null ? -1 : table.getRowCount(); 243 if( rowCnt1 != rowCnt2 ) { 244 setRequestAttribute( "DB.COUNT" , String.valueOf( rowCnt2 ) ); 245 } 246 247 int errCode = filter.getErrorCode(); 248 ErrorMessage errMessage = filter.getErrorMessage(); 249 250 if( errCode >= ErrorMessage.NG ) { // 異常 251 rtnCode = SKIP_PAGE; 252 } 253 254 // 5.7.6.2 (2014/05/16) 件数?件(また?、table==null)かつ stopZero = true 255 if( rowCnt2 <= 0 && stopZero ) { return SKIP_PAGE; } 256 257 String err = TaglibUtil.makeHTMLErrorTable( errMessage,getResource() ); 258 if( err != null && err.length() > 0 ) { 259 jspPrint( err ); 260 setSessionAttribute( errMsgId,errMessage ); 261 } 262 else { 263 removeSessionAttribute( errMsgId ); 264 } 265 } 266 finally { 267 if( tran != null ) { tran.close(); } 268 } 269 270 if( table != null && ! commitTableObject( tableId, table ) ) { 271 rtnCode = SKIP_PAGE ; 272 } 273 274 return rtnCode ; 275 } 276 277 /** 278 * タグリブオブジェクトをリリースします? 279 * キャ?ュされて再利用される?で、フィールド?初期設定を行います? 280 * 281 * @og.rev 5.6.5.2 (2013/06/21) body?、sql、paramMap 追? 282 * @og.rev 5.7.6.2 (2014/05/16) stopZero属?追? 283 */ 284 @Override 285 protected void release2() { 286 super.release2(); 287 table = null; 288 tableId = HybsSystem.TBL_MDL_KEY; 289 classId = null; 290 modifyType = null; 291 keys = null; 292 vals = null; 293 selectedAll = false; 294 stopZero = false; // 5.7.6.2 (2014/05/16) stopZero属?追? 295 dbid = null; // 4.2.4.0 (2008/06/23) 296 sql = null; // 5.6.5.2 (2013/06/21) bodyからSQL??みを?り?す? 297 paramMap = null; // 5.6.5.2 (2013/06/21) bodyからparamMapを取りだす? 298 } 299 300 /** 301 * 表示??タの HybsSystem.ROW_SEL_KEY を?に?ばれた 行を処??対象とします? 302 * 303 * @return 選択行?配? 304 */ 305 @Override 306 protected int[] getParameterRows() { 307 final int[] rowNo ; 308 if( selectedAll ) { 309 int rowCnt = table.getRowCount(); 310 rowNo = new int[ rowCnt ]; 311 for( int i=0; i<rowCnt; i++ ) { 312 rowNo[i] = i; 313 } 314 } else { 315 rowNo = super.getParameterRows(); // 4.0.0 (2005/01/31) 316 } 317 return rowNo; 318 } 319 320 /** 321 * 【TAG】データベ?ス処?実行するクラスパスを指定します? 322 * 323 * @og.tag 324 * ここで?するクラスIDは、シス?リソース にて TableFilter の 325 * サブクラス(インターフェース継承)として?する?があります? 326 * 327 * クラス自身は、org.opengion.hayabusa.db.TableFilter インターフェースを継承して??があります? 328 * {@og.doc03Link tableFilter TableFilter_**** クラス} 329 * 330 * @param id TableFilter インターフェースを継承して?実クラスの ID 331 * @see org.opengion.hayabusa.db.TableFilter TableFilter インターフェース 332 */ 333 public void setClassId( final String id ) { 334 classId = nval( getRequestParameter( id ),classId ); 335 } 336 337 /** 338 * 【TAG?通常は使?せん)結果のDBTableModelを?sessionに登録するとき?キーを指定しま? 339 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])? 340 * 341 * @og.tag 342 * 検索結果より、DBTableModelオブジェクトを作?します?これを?下流?viewタグ等に 343 * 渡す?合に??常は、session を利用します?そ?場合?登録キーです? 344 * query タグを同時に実行して、結果を求める?合?同?モリに配置される為? 345 * こ? tableId 属?を利用して、メモリ空間を?ます? 346 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])? 347 * 348 * @param id sessionに登録する時? ID 349 */ 350 public void setTableId( final String id ) { 351 tableId = nval( getRequestParameter( id ),tableId ); 352 } 353 354 /** 355 * 【TAG】データを?件選択済みとして処?るかど?[true/false]を指定しま?初期値:false)? 356 * 357 * @og.tag 358 * 全ての??タを選択済み??タとして扱って処?ます? 359 * 全件処?る?合に、指定します?(true/false) 360 * ?ォル?false です? 361 * 362 * @param all ??タを?件選択済み [true:全件選択済み/false:通常] 363 */ 364 public void setSelectedAll( final String all ) { 365 selectedAll = nval( getRequestParameter( all ),selectedAll ); 366 } 367 368 /** 369 * 【TAG】検索結果が0件のとき??続行するかど?[true/false]を指定しま?初期値:false[続行する])? 370 * 371 * @og.tag 372 * 初期値は、false(続行す?です? 373 * 374 * @og.rev 5.7.6.2 (2014/05/16) 新規追? 375 * 376 * @param cmd 検索結果が0件のとき?[true:処?中止する/false:続行する] 377 */ 378 public void setStopZero( final String cmd ) { 379 stopZero = nval( getRequestParameter( cmd ),stopZero ); 380 } 381 382 /** 383 * 【TAG】データ処??方?A:追?C:更新 D:削除)を指定します? 384 * 385 * @og.tag 386 * 通常は、DBTableModel に自動設定されて? modifyType を?に、データ処?法を 387 * 選別します?(A:追?C:更新 D:削除) 388 * こ?場合?行単位で modifyType の値を取得して判別する?がありますが、?には 389 * 処?象は、?件おな?modifyType である可能性が高いです? 390 * また?selectedAll などで強制?全件処?象とする場合?、modifyType に値? 391 * 設定さて?せん。その様な場合に外部より modifyType を指定します? 392 * 初期値は、?動判?です? 393 * 394 * @param type ??タ処??方?A:追?C:更新 D:削除) 395 */ 396 public void setModifyType( final String type ) { 397 modifyType = nval( getRequestParameter( type ),modifyType ); 398 399 if( modifyType != null && !"A".equals( modifyType ) && !"C".equals( modifyType ) && !"D".equals( modifyType ) ) { 400 String errMsg = "modifyType は A:追?C:更新 D:削除 のどれかを指定してください? " + HybsSystem.CR 401 + "modifyType=[" + modifyType + "]"; 402 throw new HybsSystemException( errMsg ); 403 } 404 } 405 406 /** 407 * 【TAG】リンク先に渡すキーを指定します? 408 * 409 * @og.tag 410 * 戻る時に、検索時?キャ?ュに?した引数以外に?したり、別の値に置き換えた? 411 * する場合?キーを設定できます?カンマ区?で??できます? 412 * vals 属?には、キーに対応する?を?設定してください? 413 * ?方法?、CSV変数を?に?してから、getRequestParameter で値を取得します? 414 * こうしな???タ自身にカンマを持って?場合に?をミスる為です? 415 * 416 * @param key リンク先に渡すキー 417 */ 418 public void setKeys( final String key ) { 419 keys = getCSVParameter( key ); 420 } 421 422 /** 423 * 【TAG】names属?に対応する?をCSV形式で??します? 424 * 425 * @og.tag 426 * キーに設定した?を?カンマ区??で?して出来ます? 427 * ??序?、キーと同じにしておいて下さ?? 428 * ?方法?、CSV変数を?に?してから、getRequestParameter で値を取得します? 429 * こうしな???タ自身にカンマを持って?場合に?をミスる為です? 430 * 431 * @param val names属?に対応する? 432 */ 433 public void setVals( final String val ) { 434 vals = getCSVParameter( val ); 435 } 436 437 /** 438 * 【TAG?通常は使?せん)Queryオブジェクトを作?する時?DB接続IDを指定します? 439 * 440 * @og.tag 441 * Queryオブジェクトを作?する時?DB接続IDを指定します? 442 * これは、シス?リソースで、DEFAULT_DB_URL 等で?して? ??タベ?ス接続? 443 * ??に、XX_DB_URL を定義することで?dbid="XX" とすると、この 接続?を使用して 444 * ??タベ?スにアクセスできます? 445 * 446 * @param id ??タベ?ス接続ID 447 */ 448 public void setDbid( final String id ) { 449 dbid = nval( getRequestParameter( id ),dbid ); 450 } 451 452 /** 453 * シリアライズ用のカスタ?リアライズ書き込みメソ? 454 * 455 * @og.rev 4.0.0.0 (2006/09/31) 新規追? 456 * @serialData ?のオブジェクト?、シリアライズされません? 457 * 458 * @param strm ObjectOutputStreamオブジェク? 459 * @throws IOException 入出力エラーが発生した?? 460 */ 461 private void writeObject( final ObjectOutputStream strm ) throws IOException { 462 strm.defaultWriteObject(); 463 } 464 465 /** 466 * シリアライズ用のカスタ?リアライズ読み込みメソ? 467 * 468 * ここでは、transient 宣?れた?変数の??初期化が?なフィールド?み設定します? 469 * 470 * @og.rev 4.0.0.0 (2006/09/31) 新規追? 471 * @serialData ?のオブジェクト?、シリアライズされません? 472 * 473 * @param strm ObjectInputStreamオブジェク? 474 * @see #release2() 475 * @throws IOException シリアライズに関する入出力エラーが発生した?? 476 * @throws ClassNotFoundException クラスを見つけることができなかった?? 477 */ 478 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 479 strm.defaultReadObject(); 480 } 481 482 /** 483 * こ?オブジェクト???表現を返します? 484 * 基本???目?使用します? 485 * 486 * @return こ?クラスの??表現 487 */ 488 @Override 489 public String toString() { 490 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 491 .println( "VERSION" ,VERSION ) 492 .println( "tableId" ,tableId ) 493 .println( "classId" ,classId ) 494 .println( "modifyType" ,modifyType ) 495 .println( "selectedAll" ,selectedAll ) 496 .println( "keys" ,keys ) 497 .println( "vals" ,vals ) 498 .println( "dbid" ,dbid ) // 4.2.4.0 (2008/06/23) 499 .println( "sql" ,sql ) // 5.6.5.2 (2013/06/21) 500 .fixForm().toString() ; 501 } 502 }