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