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 }