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.nval; 019 020import java.io.IOException; 021import java.io.ObjectInputStream; 022import java.io.ObjectOutputStream; 023import java.util.Locale; 024 025import org.opengion.fukurou.db.DBUtil; 026import org.opengion.fukurou.db.Transaction; 027import org.opengion.fukurou.db.TransactionReal; 028import org.opengion.fukurou.util.ErrorMessage; 029import org.opengion.fukurou.util.StringUtil; 030import org.opengion.hayabusa.common.HybsSystem; 031import org.opengion.hayabusa.common.HybsSystemException; 032import org.opengion.hayabusa.db.DBColumn; 033import org.opengion.hayabusa.db.DBEditConfig; 034import org.opengion.hayabusa.db.DBTableModel; 035import org.opengion.hayabusa.db.Query; 036import org.opengion.hayabusa.db.QueryFactory; 037import org.opengion.hayabusa.resource.GUIInfo; 038 039/** 040 * データベースの検索を行うタグです。 041 * 042 * このタグの内容に、SQL文を記述します。 whereタグ、 andタグ を使うと引数に応じて 043 * 実行されるSQL文が異なります(使用例参照)。 044 * また、PL/SQLのSPで検索を行うときもこのタグを使います。 045 * SystemData の USE_SQL_INJECTION_CHECK が true か、quotCheck 属性が true の場合は、 046 * SQLインジェクション対策用のクォーティションチェックを行います。リクエスト引数に 047 * クォーティション(')が含まれると、エラーになります。 048 * 同様にUSE_XSS_CHECKがtrueか、xssCheck属性がtrueの場合は、 049 * クロスサイトススクリプティング(XSS)対策のためless/greater than signのチェックを行います。 050 * 051 * ※ このタグは、Transaction タグの対象です。 052 * 053 * @og.formSample 054 * ●形式: 055 * ・<og:query command="NEW" > 056 * SELECT文 057 * </og:query> 058 * ・<og:query command="NEW" names="・・・" queryType="JDBCErrMsg" > 059 * { call PL/SQL(?,?,?,? ) } 060 * </og:query> 061 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します) 062 * 063 * ●Tag定義: 064 * <og:query 065 * queryType 【TAG】Query を発行する為のクラスID(JDBC,JDBCCallable,JDBCErrMsg,JDBCUpdate)を指定します{@og.doc03Link queryType 初期値:JDBC}) 066 * command 【TAG】コマンド(NEW,RENEW)をセットします(PlsqlUpdateTag,UpdateTag の場合は、ENTRY) 067 * scope 【TAG】キャッシュする場合のスコープ[request/page/session/applicaton]を指定します(初期値:session) 068 * maxRowCount 【TAG】(通常は使いません)データの最大読み込み件数を指定します (初期値:DB_MAX_ROW_COUNT[=1000])(0:[無制限]) 069 * skipRowCount 【TAG】(通常は使いません)データの読み始めの初期値を指定します 070 * displayMsg 【TAG】検索結果を画面上に表示するメッセージリソースIDを指定します (初期値:VIEW_DISPLAY_MSG[=]) 071 * overflowMsg 【TAG】検索データが最大検索数をオーバーした場合に表示するメッセージリソースIDを指定します (初期値:MSG0007[検索結果が、制限行数を超えましたので、残りはカットされました]) 072 * notfoundMsg 【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした]) 073 * names 【TAG】PL/SQLを利用する場合の引数にセットすべき データの名称をCSV形式で複数指定します 074 * stopZero 【TAG】検索結果が0件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する]) 075 * tableId 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 076 * dbid 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します 077 * trace 【TAG】引数の SQL 文を EXPLAIN PLAN を[true:行う/それ以外:行わない]を指定します(初期値:false) 078 * checkNames 【TAG】リクエスト変数の正規化を行うカラムをCSV形式で複数指定します 079 * modifyType 【TAG】DB検索時の モディファイタイプを指定します[A:追加/C:更新/D:削除] 080 * quotCheck 【TAG】リクエスト情報の クォーティション(') 存在チェックを実施するかどうか[true/false]を設定します(初期値:USE_SQL_INJECTION_CHECK) 081 * stopError 【TAG】PLSQL/SQL処理エラーの時に処理を中止するかどうか[true/false]を設定します(初期値:true) 082 * xssCheck 【TAG】リクエスト情報の HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_XSS_CHECK[=true]) 083 * mainTrans 【TAG】(通常使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:true) 084 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 085 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 086 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true) 087 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true) 088 * useBeforeHtmlTag 【TAG】 処理時間(queryTime)などの情報出力[true:有効/false:無効]を指定します(初期値:true) 089 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 090 * > ... Body ... 091 * </og:query> 092 * 093 * ●使用例 094 * <og:query command="NEW"> 095 * select PN,YOBI,NMEN,HINM from XX01 where PN = '{@PN}' order by PN 096 * </og:query> 097 * 098 * ・検索条件が入力された時({@PN}がNOT NULLのとき) 099 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 where PN = 'AAA' order by PN 100 * ・検索条件が入力されなかった時({@PN}がNULLのとき) 101 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 where PN = '' order by PN 102 * 103 * <og:query command="NEW"> 104 * select PN,YOBI,NMEN,HINM from XX01 105 * <og:where> 106 * <og:and value="PN = '{@PN}%'" /> 107 * <og:and value="YOBI like '{@YOBI}%'" /> 108 * </og:where> 109 * order by PN 110 * </og:query> 111 * 112 * ・検索条件が入力された時({@PN}がNOT NULLのとき) 113 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 PN = 'AAA%' and YOBI like 'BBB%' order by PN 114 * ・検索条件が入力されなかった時({@PN}がNULLのとき) WHERE句がなくなる。 115 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 order by PN 116 * 117 * 注意:WhereTagを使った場合、下のようにはなりません。 118 * select PN,YOBI,NMEN,HINM from XX01 PN = '' and YOBI like '%' order by PN 119 * 120 * <og:query command="NEW"> 121 * select PN,YOBI,NMEN,HINM from XX01 where PN="11111" 122 * <og:where startKey="and"> 123 * <og:and value="YOBI like '{@PN}%'" /> 124 * </og:where> 125 * order by PN 126 * </og:query> 127 * 128 * ・検索条件が入力された時({@YOBI}がNOT NULLのとき) 129 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 PN = '11111' and YOBI like 'BBB%' order by PN 130 * ・検索条件が入力されなかった時({@YOBI}がNULLのとき) WHERE句がなくなる。 131 * 作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 PN = '11111' order by PN 132 * 133 * <og:query 134 * command = "NEW" 135 * names = "SYSTEM_ID,LANG,CLM,NAME_JA,LABEL_NAME,KBSAKU,USER.ID" 136 * checkNames = "CLM,NAME_JA" 137 * queryType = "JDBCErrMsg" 138 * displayMsg = ""> 139 * {call TYPE3B01.TYPE3B01(?,?,?,?)} 140 * </og:query> 141 * 142 * ・queryType に JDBCErrMsg を指定して、PL/SQL をコールできます。 143 * 引数は、names 属性をキーにリクエスト変数から読み込みます。 144 * ・checkNames にカラム名を指定すると、columns.valueSet による 145 * リクエスト変数の正規化を行います。 146 * 147 * @og.group DB検索 148 * @og.group DB登録 149 * 150 * @version 4.0 151 * @author Kazuhiko Hasegawa 152 * @since JDK5.0, 153 */ 154public class QueryTag extends CommonTagSupport { 155 //* このプログラムのVERSION文字列を設定します。 {@value} */ 156 private static final String VERSION = "5.6.5.3 (2013/06/28)" ; 157 158 private static final long serialVersionUID = 565320130628L ; 159 160 /** command 引数に渡す事の出来る コマンド 新規 {@value} */ 161 public static final String CMD_NEW = "NEW" ; 162 /** command 引数に渡す事の出来る コマンド 再検索 {@value} */ 163 public static final String CMD_RENEW = "RENEW" ; 164 /** command 引数に渡す事の出来る コマンド リスト */ 165 private static final String[] COMMAND_LIST = new String[] { CMD_NEW , CMD_RENEW }; 166 167 /** エラーメッセージID {@value} */ 168 protected static final String errMsgId = HybsSystem.ERR_MSG_KEY; 169 170 private String queryType = null; 171 // 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更 172// private String dbid = "DEFAULT"; 173 private String dbid = null ; 174 protected transient DBTableModel table = null; 175 protected transient ErrorMessage errMessage = null; 176 protected String tableId = HybsSystem.TBL_MDL_KEY; 177 protected String command = CMD_NEW; 178 protected int skipRowCount = 0; 179 protected int maxRowCount = -1; 180 protected String sql = null; 181 protected int executeCount = -1; // 検索/実行件数 182 protected String names = null; 183 protected boolean outMessage = true; 184 protected int errCode = ErrorMessage.OK; 185 protected boolean quotCheck = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" ); // 4.0.0 (2005/08/31) 186 private boolean trace = false; // 4.0.0 (2005/01/31) 廃止 187 private boolean stopZero = false; 188 private String modifyType = null; // 3.8.5.1 (2006/05/08) modifyType 属性を追加します。 189// private String displayMsg = "MSG0033"; // 件検索しました。 190 protected String displayMsg = HybsSystem.sys( "VIEW_DISPLAY_MSG" ); 191 private String overflowMsg = "MSG0007"; // 検索結果が、制限行数を超えましたので、残りはカットされました。 192 private String notfoundMsg = "MSG0077"; // 対象データはありませんでした。 193 private boolean isMainTrans = true; // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し 194 195 // 3.5.4.7 (2004/02/06) 実行時間測定用のDIV要素を出力します。 196 protected long dyStart = 0; 197 // 4.3.3.0 (2008/09/22) PLSQL/SQL実行エラーの際に、処理を中止するかどうか。 198 protected boolean stopError = true; 199 200 private StringBuilder debugMsg = null; // 3.5.6.0 (2004/06/18) 201 202 // 3.8.0.5 (2005/08/20) リクエスト変数の正規化を行います。 203 private String checkNames = null; 204 205 // 3.8.5.3 (2006/08/07) トレース時のメッセージ文字列を保存しておきます。 206 private String traceMsg = null; 207 208 protected boolean xssCheck = HybsSystem.sysBool( "USE_XSS_CHECK" ); // 5.0.0.2 (2009/09/15) 209 210 // 5.3.5.0 (2011/05/01) 処理時間(queryTime)などの情報出力の有効/無効を指定します。 211 private boolean useBeforeHtmlTag = true ; 212 213 /** 214 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 215 * 216 * @og.rev 3.5.4.7 (2004/02/06) 実行時間測定用に、開始時刻を取得します。 217 * @og.rev 3.5.6.5 (2004/08/09) 暫定的に、DBTableModelを先行削除します。 218 * @og.rev 3.6.0.0 (2004/09/24) DBTableModel の先行削除は、scope="session" の場合のみ。 219 * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は、DBTableModelが新規作成された処理でのみ行う。 220 * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 221 * 222 * @return 後続処理の指示 223 */ 224 @Override 225 public int doStartTag() { 226 // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 227 if( useTag() ) { 228 dyStart = System.currentTimeMillis(); 229 if( ! check( command, COMMAND_LIST ) ) { return(SKIP_BODY); } 230 231 useMainTrans( isMainTrans ); // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し 232 startQueryTransaction( tableId ); // 3.6.0.8 (2004/11/19) 233 234 // 3.5.6.5 (2004/08/09) 削除するのは、セッションのオブジェクトでよい。 235 // 3.6.0.0 (2004/09/24) 削除するのは、scope="session" の場合のみ。 236 if( "session".equals( getScope() ) ) { 237 removeSessionAttribute( tableId ); 238 removeSessionAttribute( HybsSystem.VIEWFORM_KEY ); 239 } 240 241 return( EVAL_BODY_BUFFERED ); // Body を評価する。( extends BodyTagSupport 時) 242 } 243 return ( SKIP_BODY ); // Body を評価しない 244 } 245 246 /** 247 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。 248 * 249 * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。 250 * @og.rev 3.6.0.8 (2004/11/19) エラー発生時に確実にリリースされるように try finally 追加 251 * @og.rev 3.8.5.3 (2006/08/07) USER.LASTSQL へのSQL文の保存は、実行前に行っておきます。 252 * @og.rev 3.8.6.3 (2006/11/30) SQL 文の前後のスペースを取り除きます。 253 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 254 * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更 255 * @og.rev 4.0.0.0 (2005/08/31) useQuotCheck() によるSQLインジェクション対策 256 * @og.rev 4.3.4.0 (2008/12/01) GE20(ユーザー定数)へ登録するかのフラグへの対応 257 * @og.rev 5.0.0.2 (2009/09/15) XSS対応 258 * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は、DBTableModelが新規作成された処理でのみ行う。 259 * @og.rev 5.1.9.0 (2010/08/01) TransactionTag 対応。上位に TransactionTag があれば、そこからConnection をもらう。 260 * @og.rev 5.3.6.0 (2011/06/01) 集計、合計などのEdit機能に対応します。 261 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更 262 * @og.rev 5.3.7.0 (2011/07/01) PL/SQLかつscope="request"で正しく出力するためqueryType,namesも保存する。 263 * @og.rev 5.3.8.0 (2011/08/01) Transaction発生箇所でclose() 264 * @og.rev 5.5.3.4 (2012/06/19) trace 時は、実際の検索処理を行わない様に変更。 265 * @og.rev 5.6.5.3 (2013/06/28) LASTQUERYTYPE ⇒ LASTSQLTYPE 変更。 266 * 267 * @return 後続処理の指示(SKIP_BODY) 268 */ 269 @Override 270 public int doAfterBody() { 271 272 // 4.0.0 (2005/08/31) useQuotCheck() によるSQLインジェクション対策 273 useQuotCheck( quotCheck ); 274 // 5.0.0.2 (2009/09/15) XSS対策 275 useXssCheck( xssCheck ); 276 277 sql = getBodyString().trim(); 278 279 // 3.2.1.0 (2003/05/28) 最終SQL文を、UserInfo に、キャッシュしておく。 280// setUserInfo( "LASTSQL", sql ); 281 // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し 282 if( isMainTrans ) { 283 setUserInfo( "LASTSQL", sql, false ); 284 // 5.3.7.0 (2011/07/01) PL/SQLかつscope="request"で正しく出力するためqueryType,namesも保存する。 285// setUserInfo( "LASTQUERYTYPE", queryType, false ); 286 setUserInfo( "LASTSQLTYPE", queryType, false ); // 5.6.5.3 (2013/06/28) 287 setUserInfo( "LASTNAMES", names, false ); 288 } 289 290 Query query = QueryFactory.newInstance( queryType ); 291 Transaction tran = null; 292 try { 293 if( maxRowCount < 0 ) { 294 maxRowCount = sysInt( "DB_MAX_ROW_COUNT" ); 295 } 296 297 // 5.1.9.0 (2010/08/01) TransactionTag 対応 298// final Transaction tran ; 299 TransactionTag tranTag = (TransactionTag)findAncestorWithClass( this,TransactionTag.class ); 300 if( tranTag == null ) { 301// tran = new TransactionReal( dbid,getApplicationInfo() ); 302 tran = new TransactionReal( getApplicationInfo() ); // 5.3.7.0 (2011/07/01) 引数変更 303 } 304 else { 305 tran = tranTag.getTransaction(); 306 } 307 query.setTransaction( dbid,tran ); // 5.1.9.0 (2010/08/01) TransactionTag 対応 308 309 query.setSkipRowCount( skipRowCount ); 310 query.setMaxRowCount( maxRowCount ); 311// query.setConnectionID( dbid ); 312 query.setResourceManager( getResource() ); // 4.0.0 (2005/01/31) 313 314 if( trace ) { 315// traceMsg = traceQuery( sql ); 316 traceMsg = traceQuery( sql,tran ); // 5.1.9.0 (2010/08/01) TransactionTag 対応 317 // 5.5.3.4 (2012/06/19) trace 時は、実際の検索処理を行わない様に変更 318// query.setMaxRowCount( 1 ); 319 return(SKIP_BODY); 320 } 321 query.setStatement( sql ); 322// query.setApplicationInfo( getApplicationInfo() ); // 3.8.7.0 (2006/12/15) 323 324 // 5.3.6.0 (2011/06/01) 集計、合計などのEdit機能に対応します。 325 if( isMainTrans ) { 326 String guikey = getGUIInfoAttri( "KEY" ); 327 String editName = getRequestValue( "editName" ); 328 DBEditConfig config = getUser().getEditConfig( guikey, editName ); 329 if( config != null ) { 330 query.setEditConfig( config ); 331 } 332 } 333 334 execute( query ); 335 336 executeCount = query.getExecuteCount(); 337 if( errCode < ErrorMessage.NG && executeCount >= 0 ) { // 異常以外の場合 338 table = query.getDBTableModel(); 339 // 3.8.5.1 (2006/05/08) modifyType 属性を追加します。 340 if( modifyType != null ) { 341 for( int row=0; row<executeCount; row++ ) { 342 table.setModifyType( row,modifyType ); 343 } 344 } 345 } 346 } 347 finally { 348// if( query != null ) { query.close(); } 349 QueryFactory.close( query ); 350 if( tran != null ) { tran.close(); } // 5.3.8.0 (2011/08/01) Transaction発生箇所でclose() 351 } 352 return(SKIP_BODY); 353 } 354 355 /** 356 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 357 * 358 * @og.rev 2.0.0.8 (2002/10/09) command="NEW" のときのみ、displayMsg を表示させます。 359 * @og.rev 2.1.1.4 (2002/11/25) デバッグ時に最終SQLをユーザー情報をセットするように変更。 360 * @og.rev 2.1.2.1 (2002/11/27) ErrorMessage をクリアしないように変更。 361 * @og.rev 3.1.1.0 (2003/03/28) JspWriter オブジェクトの使用箇所を、jspPrint() を使用するように変更。 362 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 363 * @og.rev 3.2.1.0 (2003/05/28) 最終SQL文を、UserInfo に、キャッシュしておく。 364 * @og.rev 3.3.3.3 (2003/08/06) 検索結果の件数を、"DB.COUNT" キーでリクエストにセットする。 365 * @og.rev 3.3.3.3 (2003/08/06) 検索結果を、"DB.ERR_CODE" キーでリクエストにセットする。 366 * @og.rev 3.5.4.7 (2004/02/06) 実行時間測定用のDIV要素を出力しておきます。 367 * @og.rev 3.5.4.9 (2004/02/25) 警告時に停止していましたが、継続処理させます。 368 * @og.rev 3.5.5.0 (2004/03/12) ErrorMessage オブジェクトを、query が成功した時にもクリアするように変更 369 * @og.rev 3.5.5.2 (2004/04/02) TaglibUtil.makeHTMLErrorTable メソッドを利用 370 * @og.rev 3.5.5.8 (2004/05/20) ErrorMessage オブジェクトを、コマンドが NEW の場合のみ、クリア 371 * @og.rev 3.5.6.0 (2004/06/18) debugMsg 属性を出力するように修正します。 372 * @og.rev 3.6.0.8 (2004/11/19) DBTableModel をセーブする時に、トランザクションチェックを行います。 373 * @og.rev 3.8.5.3 (2006/08/07) USER.LASTSQL へのSQL文の保存は、実行前に行っておきます。 374 * @og.rev 4.0.0.0 (2006/11/14) notfoundMsg 属性を追加。displayMsg は、VIEW_USE_DISPLAY_MSG で制御 375 * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage ⇒ getResource().getLabel ) 376 * @og.rev 4.3.3.0 (2008/09/22) 属性 stopError の設定により、JSP処理を中止するかどうかを制御します。 377 * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 378 * @og.rev 5.3.5.0 (2011/05/01) 処理時間(queryTime)などの情報出力の有効/無効を指定します。 379 * @og.rev 5.5.0.3 (2012/03/13) オーバーフローメッセージが存在しないときは、何もしない。(改行も入れない) 380 * @og.rev 5.5.3.4 (2012/06/19) trace 時は、実際の検索処理を行わない様に変更。 381 * @og.rev 5.6.3.0 (2013/04/01) エラー時メッセージ変更 382 * 383 * @return 後続処理の指示 384 */ 385 @Override 386 public int doEndTag() { 387 debugPrint(); // 4.0.0 (2005/02/28) 388 // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 389 if( !useTag() ) { return(EVAL_PAGE); } 390 391 if( trace ) { 392 jspPrint( traceMsg ); 393 return (SKIP_PAGE); // 5.5.3.4 (2012/06/19) trace 時は、実際の検索処理を行わない様に変更。 394 } 395 396 String label = ""; // 4.0.0 (2005/11/30) 検索しなかった場合。 397 if( check( command, COMMAND_LIST ) ) { 398 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL ); 399 400 // 実行件数の表示 command="NEW" のときのみ、displayMsg を表示させます。 401 // 4.0.0 (2005/11/30) 出力順の変更。一番最初に出力します。 402// boolean useStatusBar = HybsSystem.sysBool( "VIEW_USE_DISPLAY_MSG" ); 403 if( CMD_NEW.equals( command ) ) { 404// if( useStatusBar && executeCount > 0 && displayMsg != null && displayMsg.length() > 0 ) { 405 if( executeCount > 0 && displayMsg != null && displayMsg.length() > 0 ) { 406 buf.append( executeCount ); 407// buf.append( getResource().getMessage( displayMsg ) ); 408 buf.append( getResource().getLabel( displayMsg ) ); 409 buf.append( HybsSystem.BR ); 410 } 411 else if( executeCount == 0 && notfoundMsg != null && notfoundMsg.length() > 0 ) { 412// buf.append( getResource().getMessage( notfoundMsg ) ); 413 buf.append( getResource().getLabel( notfoundMsg ) ); 414 buf.append( HybsSystem.BR ); 415 } 416 } 417 418 // 3.3.3.3 (2003/08/06) 検索結果の件数を、"DB.COUNT" キーでリクエストにセットする。 419 setRequestAttribute( "DB.COUNT" , String.valueOf( executeCount ) ); 420 // 3.3.3.3 (2003/08/06) 検索結果を、"DB.ERR_CODE" キーでリクエストにセットする。 421 setRequestAttribute( "DB.ERR_CODE", String.valueOf( errCode ) ); 422 423 // オーバーフロー時のメッセージを表示 424// if( table != null && table.isOverflow() ) { 425 // 5.5.0.3 (2012/03/09) オーバーフローメッセージが存在しないときは、何もしない。(改行も入れない) 426 if( table != null && table.isOverflow() && overflowMsg != null && overflowMsg.length() > 0 ) { 427// buf.append( getResource().getMessage( overflowMsg ) ); 428 buf.append( getResource().getLabel( overflowMsg ) ); 429 buf.append( HybsSystem.BR ); 430 } 431 432 // 3.5.5.2 (2004/04/02) TaglibUtil.makeHTMLErrorTable メソッドを利用 433 String err = TaglibUtil.makeHTMLErrorTable( errMessage,getResource() ); 434 if( err != null && err.length() > 0 ) { 435 buf.append( err ); 436 setSessionAttribute( errMsgId,errMessage ); 437 } 438 else if( CMD_NEW.equals( command ) ) { // 3.5.5.8 (2004/05/20) 439 removeSessionAttribute( errMsgId ); 440 } 441 label = buf.toString(); 442 443 if( table != null && ! commitTableObject( tableId, table ) ) { 444 // 3.6.0.8 (2004/11/19) トランザクションチェックを行います。 445 // jspPrint( "QueryTag Query処理が割り込まれました。DBTableModel は登録しません。" ); 446 447 // 5.6.4.0 (2013/04/01) リソースから出力するように対応 448 ErrorMessage errMsgObj = new ErrorMessage( "QueryTag Query Error!" ); 449 errMsgObj.addMessage( 0,ErrorMessage.NG,"ERR0041" ); 450 jspPrint( TaglibUtil.makeHTMLErrorTable( errMsgObj,getResource() ) ); 451 452 return (SKIP_PAGE); 453 } 454 } 455 456 jspPrint( label ); 457 458 // 3.5.4.9 (2004/02/25) 警告時に停止していましたが、継続処理させます。 459// int rtnCode = EVAL_PAGE; 460 final int rtnCode ; 461 if( errCode >= ErrorMessage.NG ) { // 異常 462 if( stopError ) { // 4.3.3.0 (2008/09/22) 属性 stopError の設定により、処理を中止するかを判断します。 463 rtnCode = SKIP_PAGE; 464 } 465 else { 466 rtnCode = EVAL_PAGE; 467 } 468 } 469 else { 470 // 件数0件かつ stopZero = true 471 if( executeCount == 0 && stopZero ) { 472 rtnCode = SKIP_PAGE; 473 } 474 else { 475 rtnCode = EVAL_PAGE; 476 } 477 } 478 479 // 3.5.4.7 (2004/02/06) 480 long dyTime = System.currentTimeMillis()-dyStart; 481 482 // 5.3.5.0 (2011/05/01) 処理時間(queryTime)などの情報出力の有効/無効を指定します。 483 if( useBeforeHtmlTag ) { 484 jspPrint( "<div id=\"queryTime\" value=\"" + (dyTime) + "\"></div>" ); // 3.5.6.3 (2004/07/12) 485 } 486 487 // 4.0.0 (2005/01/31) セキュリティチェック(データアクセス件数登録) 488 GUIInfo guiInfo = (GUIInfo)getSessionAttribute( HybsSystem.GUIINFO_KEY ); 489 if( guiInfo != null ) { guiInfo.addReadCount( executeCount,dyTime,sql ); } 490 491 return( rtnCode ); 492 } 493 494 /** 495 * タグリブオブジェクトをリリースします。 496 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 497 * 498 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加 499 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 500 * @og.rev 3.5.4.7 (2004/02/06) 実行時間測定用に、dyStart を追加します。 501 * @og.rev 3.5.6.0 (2004/06/18) debugMsg 属性を追加します。 502 * @og.rev 3.8.0.5 (2005/08/20) checkNames 属性を追加します。 503 * @og.rev 3.8.5.1 (2006/05/08) modifyType 属性を追加します。 504 * @og.rev 3.8.5.1 (2006/05/08) traceMsg 属性(トレース時のメッセージ文字列)を追加します。 505 * @og.rev 4.0.0.0 (2005/08/31) quotCheck 属性の追加 506 * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更 507 * @og.rev 4.3.3.0 (2008/09/22) stopError 属性の追加 508 * @og.rev 5.0.0.2 (2009/09/15) XSS対応 509 * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は、DBTableModelが新規作成された処理でのみ行う。 510 * @og.rev 5.3.5.0 (2011/05/01) 処理時間(queryTime)などの情報出力の有効/無効を指定します。 511 * 512 */ 513 @Override 514 protected void release2() { 515 super.release2(); 516 tableId = HybsSystem.TBL_MDL_KEY; 517 queryType = null; 518// dbid = "DEFAULT"; 519 dbid = null; 520 command = CMD_NEW; 521 skipRowCount = 0; 522 maxRowCount = -1; 523 table = null; 524 sql = null; 525// displayMsg = "MSG0033"; // 件検索しました。 526 displayMsg = HybsSystem.sys( "VIEW_DISPLAY_MSG" ); 527 overflowMsg = "MSG0007"; // 検索結果が、制限行数を超えましたので、残りはカットされました。 528 notfoundMsg = "MSG0077"; // 対象データはありませんでした。 529 executeCount = -1; // 検索/実行件数 530 names = null; 531 outMessage = true; 532 trace = false; 533 errCode = ErrorMessage.OK; 534 errMessage = null; 535 stopZero = false; 536 stopError = true; // 4.3.3.0 (2008/09/22) 537 dyStart = 0; 538 debugMsg = null; // 3.5.6.0 (2004/06/18) 539 checkNames = null; // 3.8.0.5 (2005/08/20) 540 quotCheck = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" ); // 4.0.0 (2005/08/31) 541 modifyType = null; // 3.8.5.1 (2006/05/08) 542 traceMsg = null; // 3.8.5.3 (2006/08/07) 543 xssCheck = HybsSystem.sysBool( "USE_XSS_CHECK" ); // 5.0.0.2 (2009/09/15) 544 isMainTrans = true; // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し 545 useBeforeHtmlTag = true ; // 5.3.5.0 (2011/05/01) 546 } 547 548 /** 549 * Query を実行します。 550 * 551 * @og.rev 2.1.2.3 (2002/12/02) データベース更新時に、更新フラグをセットするように変更 552 * @og.rev 3.4.0.0 (2003/09/01) 登録エラー時のキーと値を表示するように変更。 553 * @og.rev 3.5.6.0 (2004/06/18) デバッグ情報出力用に、printDebug メソッドを追加。 554 * @og.rev 3.6.1.0 (2005/01/05) エラーコードによる commit/rollback の判断追加 555 * @og.rev 5.3.7.0 (2011/07/01) nameの判定にゼロ文字列を付加 556 * 557 * @param query オブジェクト 558 */ 559 protected void execute( final Query query ) { 560 String[] nameArray = null; 561 String[] values = null; 562 try { 563// if( names == null ) { 564 if( names == null || names.length() == 0 ) { 565 query.execute(); 566 } 567 else { 568 nameArray = StringUtil.csv2Array( names ); 569 values = getRequest( nameArray ); 570 // 3.5.6.0 (2004/06/18) デバッグ情報出力用 571 if( isDebug() ) { printDebug( nameArray,values ); } 572 query.execute( values ); 573 } 574 errCode = query.getErrorCode(); 575 errMessage = query.getErrorMessage(); 576 // 3.6.1.0 (2005/01/05) エラーコードによる commit/rollback の判断追加 577// if( query.getUpdateFlag() ) { 578 if( query.isUpdate() ) { 579 if( errCode < ErrorMessage.NG ) { // 異常以下の場合 580 query.commit(); 581 } 582 else { 583 query.rollback(); 584 } 585 } 586 } 587 catch( HybsSystemException ex ) { 588 query.rollback(); 589 590 // 4.0.0 (2005/02/28) エラー時の表示とデバッグ時の表示を統一する。 591 String errMsg = "DATABASE ERROR! " + HybsSystem.CR ; 592 if( nameArray != null ) { 593 printDebug( nameArray,values ); 594 errMsg += debugMsg; 595 } 596 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び順変更 597 } 598 finally { 599 if( query != null ) { query.close(); } 600 } 601 } 602 603 /** 604 * デバッグ用に、配列データを書き出します。 605 * 606 * @og.rev 3.5.6.0 (2004/06/18) 新規追加 607 * 608 * @param nms 引数 names の配列データ 609 * @param vals names に対応するリクエスト情報の配列 610 */ 611 private void printDebug( final String[] nms,final String[] vals ) { 612 if( debugMsg == null ) { debugMsg = new StringBuilder(); } 613 614 debugMsg.append( " names=[" ); 615 debugMsg.append( StringUtil.array2csv( nms ) ); 616 debugMsg.append( "]" ); 617 debugMsg.append( HybsSystem.CR ); 618 debugMsg.append( " values=[" ); 619 debugMsg.append( StringUtil.array2csv( vals ) ); 620 debugMsg.append( "]" ); 621 debugMsg.append( HybsSystem.CR ); 622 } 623 624 /** 625 * 名称配列を元に、リクエスト情報のデータを取得します。 626 * checkNames 属性に設定されているカラムがあれば、値を正規化します。 627 * 628 * @og.rev 3.8.0.5 (2005/08/20) リクエスト変数の正規化(checkNames)対応 629 * 630 * @param nameArray キーとなる名称の配列 631 * 632 * @return そのリクエスト情報の配列 633 */ 634 protected String[] getRequest( final String[] nameArray ) { 635 String[] rtn = new String[nameArray.length]; 636 637 for( int i=0; i<rtn.length; i++ ) { 638 rtn[i] = getRequestValue( nameArray[i] ); 639 640 // 3.8.0.5 (2005/08/20) checkNames があり、rtn[i] がある場合。 641 if( checkNames != null && checkNames.length() > 0 && rtn[i].length() > 0 ) { 642 if( ( "," + checkNames + "," ).indexOf( "," + nameArray[i] + "," ) >= 0 ) { 643 DBColumn dbColumn = getDBColumn( nameArray[i] ); 644 String val = dbColumn.valueSet( rtn[i] ); 645 if( val != null ) { rtn[i] = val; } 646 } 647 } 648 } 649 650 return rtn; 651 } 652 653 /** 654 * 【TAG】(通常は使いません)データの読み始めの初期値を指定します。 655 * 656 * @og.tag 657 * データベース自体の検索は,指定されたSQLの全件を検索しますが, 658 * DBTableModelのデータとしては、スキップ件数分は登録されません。 659 * サーバーのメモリ資源と応答時間の確保の為です。 660 * 661 * @param count 読み始めの初期値 662 */ 663 public void setSkipRowCount( final String count ) { 664 skipRowCount = nval( getRequestParameter( count ),skipRowCount ); 665 } 666 667 /** 668 * 【TAG】(通常は使いません)データの最大読み込み件数を指定します 669 * (初期値:DB_MAX_ROW_COUNT[={@og.value org.opengion.hayabusa.common.SystemData#DB_MAX_ROW_COUNT}])。 670 * 671 * @og.tag 672 * データベース自体の検索は,指定されたSQLの全件を検索しますが, 673 * DBTableModelのデータとして登録する最大件数をこの値に設定します。 674 * サーバーのメモリ資源と応答時間の確保の為です。 675 * 0 をセットすると、無制限(Integer.MAX_VALUE)になります。 676 * (初期値:ユーザー定数のDB_MAX_ROW_COUNT[={@og.value org.opengion.hayabusa.common.SystemData#DB_MAX_ROW_COUNT}])。 677 * 678 * @og.rev 5.5.8.5 (2012/11/27) 0を無制限として処理します。 679 * 680 * @param count 最大読み込み件数 681 * @see org.opengion.hayabusa.common.SystemData#DB_MAX_ROW_COUNT 682 */ 683 public void setMaxRowCount( final String count ) { 684 maxRowCount = nval( getRequestParameter( count ),maxRowCount ); 685 if( maxRowCount == 0 ) { maxRowCount = Integer.MAX_VALUE ; } // 5.5.8.5 (2012/11/27) 686 } 687 688 /** 689 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 690 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 691 * 692 * @og.tag 693 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 694 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 695 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 696 * この tableId 属性を利用して、メモリ空間を分けます。 697 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 698 * 699 * @param id sessionに登録する時の ID 700 */ 701 public void setTableId( final String id ) { 702 tableId = nval( getRequestParameter( id ),tableId ); // 3.8.0.9 (2005/10/17) 703 } 704 705 /** 706 * 【TAG】Query を発行する為のクラスID(JDBC,JDBCCallable,JDBCErrMsg,JDBCUpdate)を指定します({@og.doc03Link queryType 初期値:JDBC})。 707 * 708 * @og.tag 709 * 検索を実行する手段は、Query インターフェースの実装クラスになります。 710 * このタグでは、Query.execute( String[] ) メソッドが呼ばれます。 711 * 例えば、ストアドプロシージャ等を実行する場合に、queryType="JDBCErrMsg" 712 * を指定することができます。 713 * 初期値は、"JDBC" です。 714 * queryType は、システムリソースの Query_**** 宣言の **** を与えます。 715 * これらは、Query インターフェースを継承したサブクラスである必要があります。 716 * 標準で、org.opengion.hayabusa.db 以下の Query_**** クラスが、Query_**** 宣言 と 717 * して、定義されています。 718 * 属性クラス定義の {@link org.opengion.hayabusa.db.Query Query} を参照願います。 719 * {@og.doc03Link queryType Query_**** クラス} 720 * 721 * @param id Query を発行する為の実クラス ID 722 * @see org.opengion.hayabusa.db.Query Queryのサブクラス 723 * @see org.opengion.hayabusa.db.Query#execute( String[] ) 724 */ 725 public void setQueryType( final String id ) { 726 queryType = getRequestParameter( id ); 727 } 728 729 /** 730 * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します。 731 * 732 * @og.tag 733 * Queryオブジェクトを作成する時のDB接続IDを指定します。 734 * これは、システムリソースで、DEFAULT_DB_URL 等で指定している データベース接続先 735 * 情報に、XX_DB_URL を定義することで、 dbid="XX" とすると、この 接続先を使用して 736 * データベースにアクセスできます。 737 * 738 * @param id データベース接続ID 739 */ 740 public void setDbid( final String id ) { 741 dbid = nval( getRequestParameter( id ),dbid ); 742 } 743 744 /** 745 * 【TAG】コマンド(NEW,RENEW)をセットします(PlsqlUpdateTag,UpdateTag の場合は、ENTRY)。 746 * 747 * @og.tag 748 * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される 749 * フィールド定数値のいづれかを、指定できます。 750 * 751 * @param cmd コマンド(public static final 宣言されている文字列) 752 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.QueryTag.CMD_NEW">コマンド定数</a> 753 */ 754 public void setCommand( final String cmd ) { 755 String cmd2 = getRequestParameter( cmd ); 756 if( cmd2 != null && cmd2.length() >= 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); } 757 } 758 759 /** 760 * 【TAG】検索結果が0件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する])。 761 * 762 * @og.tag 763 * 初期値は、false(続行する)です。 764 * 765 * @param cmd 検索結果が0件のとき、[true:処理を中止する/false:続行する] 766 */ 767 public void setStopZero( final String cmd ) { 768 stopZero = nval( getRequestParameter( cmd ),stopZero ); 769 } 770 771 /** 772 * 【TAG】検索結果を画面上に表示するメッセージリソースIDを指定します 773 * (初期値:VIEW_DISPLAY_MSG[={@og.value org.opengion.hayabusa.common.SystemData#VIEW_DISPLAY_MSG}])。 774 * 775 * @og.tag 776 * ここでは、検索結果の件数や登録された件数をまず出力し、 777 * その次に、ここで指定したメッセージをリソースから取得して表示します。 778 * 件数を表示させたい場合は、displayMsg = "MSG0033"[ 件検索しました] をセットしてください。 779 * 表示させたくない場合は, displayMsg = "" をセットしてください。 780 * (初期値:システム定数のVIEW_DISPLAY_MSG[={@og.value org.opengion.hayabusa.common.SystemData#VIEW_DISPLAY_MSG}])。 781 * 782 * @param id ディスプレイに表示させるメッセージ ID 783 * @see org.opengion.hayabusa.common.SystemData#VIEW_DISPLAY_MSG 784 */ 785 public void setDisplayMsg( final String id ) { 786 String ids = getRequestParameter( id ); 787 if( ids != null ) { displayMsg = ids; } 788 } 789 790 /** 791 * 【TAG】検索データが最大検索数をオーバーした場合に表示するメッセージリソースIDを指定します 792 * (初期値:MSG0007[検索結果が、制限行数を超えましたので、残りはカットされました])。 793 * 794 * @og.tag 795 * 検索結果が、maxRowCount で設定された値より多い場合、何らかのデータは検索されず 796 * 切り捨てられたことになります。 797 * ここでは、displayMsg を表示した後、必要に応じて、このメッセージを表示します。 798 * 表示させたくない場合は, overflowMsg = "" をセットしてください。 799 * 初期値は、MSG0007[検索結果が、制限行数を超えましたので、残りはカットされました]です。 800 * 801 * @param id ディスプレイに表示させるメッセージ ID 802 */ 803 public void setOverflowMsg( final String id ) { 804 String ids = getRequestParameter( id ); 805 if( ids != null ) { overflowMsg = ids; } 806 } 807 808 /** 809 * 【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした])。 810 * 811 * @og.tag 812 * ここでは、検索結果がゼロ件の場合のみ、特別なメッセージを表示させます。 813 * 従来は、displayMsg と兼用で、『0 件検索しました』という表示でしたが、 814 * displayMsg の初期表示は、OFF になりましたので、ゼロ件の場合のみ別に表示させます。 815 * 表示させたくない場合は, notfoundMsg = "" をセットしてください。 816 * 初期値は、MSG0077[対象データはありませんでした]です。 817 * 818 * @param id ディスプレイに表示させるメッセージ ID 819 */ 820 public void setNotfoundMsg( final String id ) { 821 String ids = getRequestParameter( id ); 822 if( ids != null ) { notfoundMsg = ids; } 823 } 824 825 /** 826 * 【TAG】PL/SQLを利用する場合の引数にセットすべき データの名称をCSV形式で複数指定します。 827 * 828 * @og.tag 829 * 複数ある場合は、カンマ区切り文字で渡します。 830 * names 属性は、queryType に応じて設定可否が異なりますので、ご注意ください。 831 * names なし:JDBC,JDBCUpdate 832 * names あり:JDBCCallable,JDBCErrMsg,JDBCUpdate 833 * (JDBCUpdateは、names 属性のあり/なし両方に対応しています。) 834 * 835 * @og.rev 3.0.1.3 (2003/03/11) names 属性に null で渡す場合のバグを修正 836 * 837 * @param nm 引数の名称(複数ある場合は、カンマ区切り文字) 838 */ 839 public void setNames( final String nm ) { 840 names = nval( getRequestParameter( nm ),names ); 841 } 842 843 /** 844 * 【TAG】検索結果のメッセージを表示する/しない[true/false]を指定します(初期値:true)。 845 * 846 * @og.tag 847 * 初期値は、表示する:true です。 848 * 849 * @param flag [true:表示する/それ以外:含めない] 850 */ 851 public void setOutMessage( final String flag ) { 852 outMessage = nval( getRequestParameter( flag ),outMessage ); 853 } 854 855 /** 856 * 【TAG】引数の SQL 文を EXPLAIN PLAN を[true:行う/それ以外:行わない]を指定します(初期値:false)。 857 * 858 * @og.tag 859 * 860 * ここでは、以下の処理を行います。 861 * 1.引数の SQL 文を画面に表示します。 862 * 2.引数の SQL 文を EXPLAIN PLAN した結果を、画面に表示します。 863 * なお、以前は、セッションのトレースを行っていましたが、その機能は、廃止いたします。 864 * 初期値は、行わない:false です。 865 * 866 * @param flag トレース [true:行う/それ以外:行わない] 867 */ 868 public void setTrace( final String flag ) { 869 trace = nval( getRequestParameter( flag ),trace ); 870 } 871 872 /** 873 * 【TAG】リクエスト変数の正規化を行うカラムをCSV形式で複数指定します。 874 * 875 * @og.tag 876 * PL/SQLを利用する場合の引数にセットすべき データを、リクエスト変数の 877 * 値そのままではなく、カラムオブジェクトの valueSet メソッド経由で正規化 878 * した値を使用するようにします。 879 * 880 * @og.rev 3.8.0.5 (2005/08/20) 新規追加 881 * 882 * @param nm リクエスト変数の正規化を行うカラム 883 */ 884 public void setCheckNames( final String nm ) { 885 checkNames = nval( getRequestParameter( nm ),checkNames ); 886 } 887 888 /** 889 * 【TAG】DB検索時の モディファイタイプを指定します[A:追加/C:更新/D:削除]。 890 * 891 * @og.tag 892 * DB検索時に、そのデータをA(追加)、C(更新)、D(削除)のモディファイタイプを 893 * つけた状態にします。 894 * その状態で、そのまま、update する事が可能になります。 895 * 896 * @og.rev 3.8.5.1 (2006/05/08) 新規追加 897 * 898 * @param type DB検索時の モディファイタイプ [A:追加/C:更新/D:削除] 899 */ 900 public void setModifyType( final String type ) { 901 modifyType = nval( getRequestParameter( type ),modifyType ); 902 } 903 904 /** 905 * 【TAG】リクエスト情報の クォーティション(') 存在チェックを実施するかどうか[true/false]を設定します 906 * (初期値:USE_SQL_INJECTION_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK}])。 907 * 908 * @og.tag 909 * SQLインジェクション対策の一つとして、暫定的ではありますが、SQLのパラメータに 910 * 渡す文字列にクォーティション(') を許さない設定にすれば、ある程度は防止できます。 911 * 数字タイプの引数には、 or 5=5 などのクォーティションを使用しないコードを埋めても、 912 * 数字チェックで検出可能です。文字タイプの場合は、必ず (')をはずして、 913 * ' or 'A' like 'A のような形式になる為、(')チェックだけでも有効です。 914 * (') が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。 915 * 初期値は、SystemData#USE_SQL_INJECTION_CHECK です。 916 * 917 * @og.rev 4.0.0.0 (2005/08/31) 新規追加 918 * 919 * @param flag クォーティションチェック [true:する/それ以外:しない] 920 */ 921 public void setQuotCheck( final String flag ) { 922 quotCheck = nval( getRequestParameter( flag ),quotCheck ); 923 } 924 925 /** 926 * 【TAG】リクエスト情報の HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します 927 * (初期値:USE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}])。 928 * 929 * @og.tag 930 * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。 931 * (><) が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。 932 * (初期値:システム定数のUSE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}]) 933 * 934 * @og.rev 5.0.0.2 (2009/09/15) 新規追加 935 * 936 * @param flag XSSチェック [true:する/false:しない] 937 * @see org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK 938 */ 939 public void setXssCheck( final String flag ) { 940 xssCheck = nval( getRequestParameter( flag ),xssCheck ); 941 } 942 943 /** 944 * 【TAG】PLSQL/SQL処理エラーの時に処理を中止するかどうか[true/false]を設定します(初期値:true)。 945 * 946 * @og.tag 947 * false(中止しない)に設定する場合、後続処理では、{@DB.ERR_CODE}の値により、 948 * PLSQL/SQLの異常/正常終了によって分岐処理は可能となります。 949 * 初期値は、true(中止する)です。 950 * 951 * @og.rev 4.3.3.0 (2008/09/22) 新規追加 952 * 953 * @param flag [true:中止する/false:中止しない] 954 */ 955 public void setStopError( final String flag ) { 956 stopError = nval( getRequestParameter( flag ),stopError ); 957 } 958 959 /** 960 * 引数の SQL 文を EXPLAIN PLAN します。 961 * 962 * ここでは、以下の処理を行います。 963 * 1.引数の SQL 文を画面に表示します。 964 * 2.引数の SQL 文を EXPLAIN PLAN した結果を、画面に表示します。 965 * なお、この処理は、ORACLE 専用処理です。 966 * 967 * @og.rev 3.8.5.3 (2006/08/07) 新規追加 968 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 969 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。 970 * @og.rev 5.5.3.4 (2012/06/19) getUserInfo は、キー部分だけで処理します。 971 * 972 * @param sql EXPLAIN PLANするSQL 文 973 * @param tran Transactionオブジェクト 974 * 975 * @return トレース結果の文字列 976 */ 977// private String traceQuery( final String sql ) { 978 private String traceQuery( final String sql , final Transaction tran ) { 979// ApplicationInfo appInfo = getApplicationInfo(); 980 981// String userId = getUserInfo( "USER.ID" ) ; 982 String userId = getUserInfo( "ID" ) ; // 5.5.3.4 (2012/06/19) getUserInfo は、キー部分だけで処理します。 983 984 String[] arg1 = new String[] { userId }; 985// DBUtil.dbExecute( "DELETE FROM PLAN_TABLE WHERE STATEMENT_ID = ?",arg1,appInfo,dbid ); 986 DBUtil.dbExecute( "DELETE FROM PLAN_TABLE WHERE STATEMENT_ID = ?",arg1,tran,dbid ); // 5.1.9.0 (2010/08/01) 987 988 String explan1 = "EXPLAIN PLAN SET STATEMENT_ID = '" + userId + "' FOR " + sql ; 989// DBUtil.dbExecute( explan1,null,appInfo,dbid ); 990 DBUtil.dbExecute( explan1,null,tran,dbid ); // 5.1.9.0 (2010/08/01) 991 992 String[] arg2 = new String[] { userId,userId,userId }; 993// String explan2 = "SELECT LEVEL,LPAD(' ',LEVEL,' ') || RTRIM( OPERATION ) || ' ' ||" 994// + " RTRIM( OPTIONS ) || ' ' || RTRIM( OBJECT_NAME )" 995// + " FROM PLAN_TABLE" 996// + " WHERE STATEMENT_ID = ?" 997// + " CONNECT BY PRIOR ID = PARENT_ID" 998// + " AND STATEMENT_ID = ?" 999// + " START WITH ID = 0" 1000// + " AND STATEMENT_ID = ?" ; 1001 String explan2 = "select LEVEL as LVL" 1002 + ",lpad(' ',LEVEL,' ') || rtrim( OPERATION ) || ' ' || rtrim( OPTIONS ) || ' ' || rtrim( OBJECT_NAME ) as EXECUTION_PLAN" 1003 + ",OBJECT_NAME as OBJ_NAME" 1004 + ",DECODE(INSTR(OBJECT_TYPE,' '),0,OBJECT_TYPE,SUBSTR(OBJECT_TYPE,1,INSTR(OBJECT_TYPE,' ')-1)) as OBJ_TYPE" 1005 + ",OPTIMIZER as OPT" 1006 + ",COST as CST" 1007 + ",CARDINALITY as CARD" 1008 + ",BYTES as BYTE" 1009 + ",ACCESS_PREDICATES as ACCS" 1010 + ",FILTER_PREDICATES as FILTER" 1011 + " from PLAN_TABLE" 1012 + " where STATEMENT_ID = ?" 1013 + " start with ID = 0" 1014 + " and STATEMENT_ID = ?" 1015 + " connect by prior ID = PARENT_ID" 1016 + " and STATEMENT_ID = ?" ; 1017// String[][] plan = DBUtil.dbExecute( explan2,arg2,appInfo,dbid ); 1018// String[][] plan = DBUtil.dbExecute( explan2,arg2,tran,dbid ); // 5.1.9.0 (2010/08/01) 1019 1020// StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 1021// buf.append( "<pre>" ).append( sql ).append( "</pre>" ).append( HybsSystem.BR ); 1022// buf.append( "<table>" ); 1023// buf.append( "<tr class=\"row_h\"><th>LEVEL</th><th>EXECUTION_PLAN</th></tr>" ); 1024// for( int i=0; i<plan.length; i++ ) { 1025// buf.append( "<tr class=\"row_" ).append( i%2 ).append( "\">" ); 1026// buf.append( "<td>" ).append( plan[i][0] ).append( "</td>" ); 1027// buf.append( "<td><pre>" ).append( plan[i][1] ).append( "</td></tr>" ); 1028// } 1029// buf.append( "</table>" ).append( HybsSystem.BR ); 1030 1031 String[][] plan = DBUtil.dbExecute( explan2,arg2,tran,dbid,true ); // 5.5.3.4 (2012/06/19) ヘッダー情報も同時に取得する。 1032 1033 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 1034 buf.append( "<pre>" ).append( sql ).append( "</pre>" ).append( HybsSystem.BR ); 1035 buf.append( "<table>" ); 1036 // 1行目のヘッダーの出力 1037 int colsize = plan[0].length; 1038 buf.append( "<tr class=\"row_h\">" ); 1039 for( int j=0; j<colsize; j++ ) { 1040 buf.append( "<th>" ).append( plan[0][j] ).append( "</th>" ); 1041 } 1042 buf.append( "</tr>" ); 1043 1044 for( int i=1; i<plan.length; i++ ) { 1045 buf.append( "<tr class=\"row_" ).append( i%2 ).append( "\">" ); 1046 for( int j=0; j<colsize; j++ ) { 1047 if( j==1 ) { 1048 buf.append( "<td><pre>" ).append( plan[i][1] ).append( "</pre></td>" ); 1049 } 1050 else { 1051 buf.append( "<td>" ).append( plan[i][j] ).append( "</td>" ); 1052 } 1053 } 1054 buf.append( "</tr>" ); 1055 } 1056 buf.append( "</table>" ).append( HybsSystem.BR ); 1057 return buf.toString(); 1058 } 1059 1060 /** 1061 * 【TAG】(通常使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:true)。 1062 * 1063 * @og.tag 1064 * この値は、ファイルダウンロード処理に影響します。この値がtrueに指定された時にcommitされたDBTableModelが 1065 * ファイルダウンロードの対象の表になります。 1066 * 1067 * このパラメーターは、通常、各タグにより実装され、ユーザーが指定する必要はありません。 1068 * 但し、1つのJSP内でDBTableModelが複数生成される場合に、前に処理したDBTableModelについてファイルダウンロードをさせたい 1069 * 場合は、後ろでDBTableModelを生成するタグで、明示的にこの値をfalseに指定することで、ファイルダウンロード処理の対象から 1070 * 除外することができます。 1071 * 1072 * @og.rev 5.1.6.0 (2010/05/01) 新規作成 1073 * 1074 * @param flag メイントランザクションかどうか 1075 */ 1076 public void setMainTrans( final String flag ) { 1077 isMainTrans = nval( getRequestParameter( flag ),isMainTrans ); 1078 } 1079 1080 /** 1081 * 【TAG】 処理時間(queryTime)などの情報出力[true:有効/false:無効]を指定します(初期値:true)。 1082 * 1083 * @og.tag 1084 * Query で、検索する場合に、処理時間(queryTime)などの情報を出力していますが、 1085 * ViewForm で、CustomData などの 非HTML表示ビューを使用する場合、データとして、 1086 * 紛れ込んでしまうため、出力を抑制する必要があります。 1087 * true(有効)にすると、これらのHTMLが出力されます。false にすると、出力されません。 1088 * 初期値は、true(有効) です。 1089 * 1090 * @og.rev 5.3.5.0 (2011/05/01) 新規追加 1091 * 1092 * @param useTag 情報出力の有効/無効を指定 [true:有効/false:無効] 1093 */ 1094 public void setUseBeforeHtmlTag( final String useTag ) { 1095 useBeforeHtmlTag = nval( getRequestParameter( useTag ),useBeforeHtmlTag ); 1096 } 1097 1098 /** 1099 * シリアライズ用のカスタムシリアライズ書き込みメソッド 1100 * 1101 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 1102 * @serialData 一部のオブジェクトは、シリアライズされません。 1103 * 1104 * @param strm ObjectOutputStreamオブジェクト 1105 * @throws IOException 入出力エラーが発生した場合 1106 */ 1107 private void writeObject( final ObjectOutputStream strm ) throws IOException { 1108 strm.defaultWriteObject(); 1109 } 1110 1111 /** 1112 * シリアライズ用のカスタムシリアライズ読み込みメソッド 1113 * 1114 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。 1115 * 1116 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 1117 * @serialData 一部のオブジェクトは、シリアライズされません。 1118 * 1119 * @param strm ObjectInputStreamオブジェクト 1120 * @see #release2() 1121 * @throws IOException シリアライズに関する入出力エラーが発生した場合 1122 * @throws ClassNotFoundException クラスを見つけることができなかった場合 1123 */ 1124 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 1125 strm.defaultReadObject(); 1126 } 1127 1128 /** 1129 * このオブジェクトの文字列表現を返します。 1130 * 基本的にデバッグ目的に使用します。 1131 * 1132 * @return このクラスの文字列表現 1133 */ 1134 @Override 1135 public String toString() { 1136 return sql ; 1137 1138 // return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 1139 // .println( "VERSION" ,VERSION ) 1140 // .println( "tableId" ,tableId ) 1141 // .println( "queryType" ,queryType ) 1142 // .println( "dbid" ,dbid ) 1143 // .println( "command" ,command ) 1144 // .println( "skipRowCount" ,skipRowCount ) 1145 // .println( "maxRowCount" ,maxRowCount ) 1146 // .println( "sql" ,sql ) 1147 // .println( "displayMsg" ,displayMsg ) 1148 // .println( "overflowMsg" ,overflowMsg ) 1149 // .println( "executeCount" ,executeCount ) 1150 // .println( "names" ,names ) 1151 // .println( "outMessage" ,outMessage ) 1152 // .println( "trace" ,trace ) 1153 // .println( "errCode" ,errCode ) 1154 // .println( "stopZero" ,stopZero ) 1155 // .println( "quotCheck" ,quotCheck ) 1156 // .println( "dyStart" ,dyStart ) 1157 // .println( "checkNames" ,checkNames ) 1158 // .println( "Other..." ,getAttributes().getAttribute() ) 1159 // .fixForm().toString() ; 1160 } 1161}