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.ArrayList; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Locale; 027import java.util.Map; 028 029import javax.script.ScriptEngine; 030import javax.script.ScriptEngineManager; 031import javax.script.ScriptException; 032import javax.servlet.ServletException; 033 034import org.opengion.fukurou.db.DBUtil; 035import org.opengion.fukurou.db.Transaction; 036import org.opengion.fukurou.db.TransactionReal; 037import org.opengion.fukurou.model.Formatter; 038import org.opengion.fukurou.util.ErrorMessage; 039import org.opengion.fukurou.util.StringUtil; 040import org.opengion.hayabusa.common.HybsSystem; 041import org.opengion.hayabusa.common.HybsSystemException; 042import org.opengion.hayabusa.db.DBTableModel; 043import org.opengion.hayabusa.resource.ResourceManager; 044 045/** 046 * 画面で入力されたデータのチェックを行うためのタグです。 047 * 048 * commandがNEWの場合は検索条件等のリクエストパラメータに対してチェックを行います。 049 * commandがENTRYの場合は、登録時のDBテーブルモデルに対するチェックを行います。 050 * (値の取得は、先に選択された行のみについて、実行されます。) 051 * 052 * チェックを行うための定義は、SQL文 又は JavaScriptの式が記述可能です。 053 * これらの式はタグのボディー部分に記述します。 054 * 055 * SQL文によりチェックを行う場合は、必ず件数が返されるように記述して下さい(select count(*) ・・・ 等) 056 * このSQL文で取得された件数とexistの属性値とを照合しチェックを行います。 057 * いずれの場合も、成立時は、正常とみなします。 058 * (「true:存在する」 には、データが存在した場合に、OKで、なければエラーです。) 059 * 060 * JavaScript式を記述する場合は、必ずtrue or falseを返す式を指定して下さい。 061 * この式を評価した結果falseが返される場合は、エラーとみなします。 062 * 式に不等号等を使用する場合は、CDATAセクションで囲うようにして下さい。 063 * 064 * また、いずれのチェック方法の場合でも、引数部に[カラム名]を用いたHybs拡張SQL文を 065 * 指定することが可能です。 066 * メッセージIDの{0},{1}にはそれぞれ[カラム名]指定されたカラム名及びデータがカンマ区切りで 067 * 自動的に設定されます。 068 * 069 * ※ このタグは、Transaction タグの対象です。 070 * 071 * @og.formSample 072 * <pre> 073 * ●形式: 074 * ・<og:dataCheck 075 * command = "{@command}" 076 * exist = "[auto|true|false|one|notuse]" 077 * errRemove = "[true|false]" 078 * lbl = "{@lbl}" 079 * lblParamKeys = "ZY03" : メッセージリソースのキーをカンマ区切りで指定。{2} 以降にセット 080 * sqlType = "{@sqlType}" 081 * execType = "INSERT|COPY|UPDATE|MODIFY|DELETE" : sqlType を含む場合、実行 082 * conditionKey = "FGJ" : 条件判定するカラムIDを指定(初期値は columnId ) 083 * conditionList = "0|1|8|9" : 条件判定する値のリストを、"|"で区切って登録(初期値は、無条件) 084 * uniqCheckKeys = "CLM,LANG" : DBTableModel内でのユニークキーチェックを行うためのカラム 085 * > 086 * 087 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します) 088 * (SQL文 又は JavaScript式) 089 * :なし( from属性、where属性を使用して、SQL文を内部で作成します) 090 * 091 * ●Tag定義: 092 * <og:dataCheck 093 * command 【TAG】コマンド(NEW or ENTRY)をセットします 094 * exist 【TAG】データベースのチェック方法[auto/true/false/one/notuse]を指定します(初期値:auto[自動]) 095 * tableId 【TAG】(通常は使いません)結果をDBTableModelに書き込んで、sessionに登録するときのキーを指定します 096 * dbid 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します 097 * lbl 【TAG】ラベルリソースIDを指定します 098 * lblParamKeys 【TAG】ラベルリソースの引数をカンマ区切りで指定します 099 * errRemove 【TAG】エラー時の選択行を取り除いて継続処理を行うかどうか[true/false]を指定します(初期値:false) 100 * sqlType 【TAG】このチェックを行う、SQLタイプ を指定します 101 * execType 【TAG】このチェックを行う、実行タイプ を指定します 102 * conditionKey 【TAG】条件判定するカラムIDを指定します 103 * conditionList 【TAG】条件判定する値のリストを、"|"で区切って登録します(初期値:無条件) 104 * uniqCheckClms 【TAG】指定されたキーに従って、メモリ上のテーブルに対してユニークキーチェックを行います 105 * beforeErrorJsp 【TAG】エラーが発生した際に、エラーメッセージの表示前にincludeするJSPを指定します 106 * afterErrorJsp 【TAG】エラーが発生した際に、エラーメッセージの表示後にincludeするJSPを指定します 107 * selectedAll 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false) 108 * msg 【廃止】メッセージIDを指定します(lbl 属性を使用してください) 109 * msgParamKeys 【廃止】メッセージリソースの引数をカンマ区切りで指定します(lblParamKeys 属性を使用してください) 110 * from 【TAG】tableExist タグ廃止に伴う、簡易機能追加。チェックするデータベース名(from 句)を指定します。 111 * where 【TAG】tableExist タグ廃止に伴う、簡易機能追加。チェックする検索条件(where句)を指定します。 112 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 113 * > ... Body ... 114 * </og:dataCheck> 115 * 116 * ●使用例 117 * ・<og:dataCheck 118 * command = "ENTRY" 119 * exist = "true" 120 * lbl = "MSG0001" 121 * > 122 * select count(*) from GEA03 where clm = [CLM] 123 * </og:dataCheck> 124 * 125 * ・exist 属性の値に応じて、チェック方法が異なります。 126 * [ auto , true , false , one , notuse が指定できます。] 127 * 128 * ・<og:dataCheck 129 * command = "ENTRY" 130 * lbl = "MSG0001" 131 * > 132 * <![CDATA[ 133 * [DYSTART] < [DY] && [DY] < [DYEND] 134 * ]]> 135 * </og:dataCheck> 136 * 137 * ・<og:dataCheck 138 * command = "ENTRY" 139 * lbl = "MSG0001" 140 * > 141 * <![CDATA[ 142 * [GOKEI] < [TANKA] * [RITU] 143 * ]]> 144 * </og:dataCheck> 145 * 146 * ※ og:tableExist タグが廃止されました。og:dataCheckタグで置き換えてください。 147 * ・<og:tableExist 148 * command = "{@command}" 149 * names = "USERID,SYSTEM_ID" 150 * from = "GE10" 151 * where = "USERID=? AND SYSTEM_ID=?" 152 * exist = "true" 153 * /> 154 * 155 * ⇒ 156 * ・<og:dataCheck 157 * command = "{@command}" 158 * exist = "true" 159 * from = "GE10" 160 * where = "USERID=[USERID] AND SYSTEM_ID=[SYSTEM_ID]" 161 * /> 162 * 163 * ・<og:tableExist 164 * command = "{@command}" 165 * from = "GE10" 166 * where = "USERID=[USERID] AND SYSTEM_ID=[SYSTEM_ID]" /> 167 * ⇒ 168 * ・<og:dataCheck 169 * command = "{@command}" 170 * from = "GE10" 171 * where = "USERID=[USERID] AND SYSTEM_ID=[SYSTEM_ID]" /> 172 * /> 173 * 174 * </pre> 175 * 176 * @og.rev 4.1.1.1 (2008/02/22) 新規作成 177 * @og.group DB登録 178 * 179 * @version 4.0 180 * @author Hiroki Nakamura 181 * @since JDK5.0, 182 */ 183public class DataCheckTag extends CommonTagSupport { 184 //* このプログラムのVERSION文字列を設定します。 {@value} */ 185 private static final String VERSION = "5.7.6.2 (2014/05/16)"; 186 187 private static final long serialVersionUID = 576220140516L ; 188 189 /** command 引数に渡す事の出来る コマンド {@value} */ 190 public static final String CMD_NEW = "NEW"; 191 192 /** command 引数に渡す事の出来る コマンド {@value} */ 193 public static final String CMD_ENTRY = "ENTRY"; 194 195 /** command 引数に渡す事の出来る コマンド リスト */ 196 private static final String[] COMMAND_LIST = { CMD_ENTRY, CMD_NEW }; 197 198 /** 内部変数 */ 199 private transient DBTableModel table = null; 200 private transient boolean isSql = false; 201 private transient boolean isUniqCheck = false; // 4.3.4.0 (2008/12/01) 追加 202 private transient ScriptEngine jsEngine = null; 203 private transient String bodyStr = null; // 4.3.4.0 (2008/12/01) 追加 204 205 /** タグで設定する属性 */ 206 private String command = CMD_ENTRY; 207 private String exist = "auto"; 208 private String tableId = HybsSystem.TBL_MDL_KEY; 209 private String dbid = null; 210 private String lbl = null; 211 private String[] lblParamKeys = null; // 4.2.0.1 (2008/03/27) 212 private boolean errRemove = false; 213 private String sqlType = null; // INSERT,COPY,UPDATE,MODIFY,DELETE 214 private String execType = null; // INSERT,COPY,UPDATE,MODIFY,DELETE 215 private boolean isExec = true; // 4.1.2.0 (2008/03/12) 216 217 private String conditionKey = null; // 4.2.0.1 (2008/03/27) 218 private String conditionList = null; // 4.2.0.1 (2008/03/27) 219 private String from = null; // 4.2.0.1 (2008/03/27) 220 private String where = null; // 5.7.6.2 (2014/05/16) tableExist タグに伴う便利機能追加 221 private String[] uniqCheckClms = null; // 4.3.4.0 (2008/12/01) 222 223 private String beforeErrorJsp = null; // 5.1.9.0 (2010/08/01) 224 private String afterErrorJsp = null; // 5.1.9.0 (2010/08/01) 225 private boolean selectedAll = false; // 5.1.9.0 (2010/08/01) 226 227 /** 228 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 229 * 230 * @og.rev 4.1.1.0 (2008/02/22) 新規作成 231 * @og.rev 4.1.2.0 (2008/03/12) sqlType,execType 判定 232 * 233 * @return 後続処理の指示 234 */ 235 @Override 236 public int doStartTag() { 237 isExec = sqlType == null || execType == null || execType.indexOf( sqlType ) >= 0 ; 238 239 if( isExec ) { 240 return EVAL_BODY_BUFFERED ; // Body を評価する 241 } 242 else { 243 return SKIP_BODY ; // Body を評価しない 244 } 245 } 246 247 /** 248 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。 249 * 250 * @og.rev 4.3.4.0 (2008/12/01) 新規追加 251 * 252 * @return 後続処理の指示(SKIP_BODY) 253 */ 254 @Override 255 public int doAfterBody() { 256 bodyStr = getBodyString().trim(); 257 return SKIP_BODY ; 258 } 259 260 /** 261 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 262 * 263 * @og.rev 4.1.1.0 (2008/02/22) 新規作成 264 * @og.rev 4.1.2.0 (2008/03/12) sqlType,execType 判定 265 * @og.rev 4.2.0.1 (2008/03/27) from を取得 266 * @og.rev 4.2.1.0 (2008/04/11) ErrMessageManager対応 267 * @og.rev 4.3.4.0 (2008/12/01) ユニークキーチェック対応。bodyContentの取得を#doAfterBody()で行う。 268 * @og.rev 5.1.9.0 (2010/08/01) エラーメッセージの表示前後にincludeするJSPを指定できるようにする。 269 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。 270 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更 、Transaction対応で、close処理を入れる。 271 * 272 * @return 後続処理の指示 273 */ 274 @Override 275 public int doEndTag() { 276 debugPrint(); 277 int rtnCode = EVAL_PAGE; 278 279 // 4.1.2.0 (2008/03/12) 実行条件 isExec を評価 280 if( isExec && check( command, COMMAND_LIST ) ) { 281 // exist="notuse"の場合はチェックしない 282 if( "notuse".equalsIgnoreCase( exist ) ) { return rtnCode; } 283 284 // パラメーターから処理のタイプを判別 285 checkParam(); 286 287 // エラーメッセージを管理するクラスを作成します。 288 ErrMessageManager manager = new ErrMessageManager(); 289 manager.setTitle( "Data Check Error!" ); 290 manager.setParamKeys( lblParamKeys ); 291 manager.setResourceManager( getResource() ); 292 manager.setFrom( from ); 293 294 // 5.1.9.0 (2010/08/01) TransactionTag 対応 295 Transaction tran = null ; 296 // 5.3.7.0 (2011/07/01) Transaction対応で、close処理を入れる。 297 try { 298 if( isSql ) { 299 TransactionTag tranTag = (TransactionTag)findAncestorWithClass( this,TransactionTag.class ); 300 if( tranTag == null ) { 301 tran = new TransactionReal( getApplicationInfo() ); // 5.3.7.0 (2011/07/01) 引数変更 302 } 303 else { 304 tran = tranTag.getTransaction(); 305 } 306 } 307 308 // command="NEW"の場合 309 if( CMD_NEW.equals( command ) ) { 310 if( isSql ) { 311 checkSql( bodyStr, manager, null, 0, DBTableModel.UPDATE_TYPE, tran ); // 5.1.9.0 (2010/08/01) 312 } 313 else { 314 checkJs( bodyStr, manager, null, 0, jsEngine ); 315 } 316 } 317 // command="ENTRY"の場合(テーブルモデルが存在しない場合は処理しない) 318 else if( CMD_ENTRY.equals( command ) ) { 319 table = (DBTableModel) getObject( tableId ); 320 if( table != null && table.getRowCount() > 0 ) { 321 manager.setDBTableModel( table ); 322 if( isUniqCheck ) { 323 checkUnique( manager ); 324 } 325 else { 326 checkRows( bodyStr, manager, tran ); // 5.1.9.0 (2010/08/01) 327 } 328 } 329 else { 330 System.out.println( "DBTableModel doesn't exist!! need this when command=\"ENTRY\"" ); 331 } 332 } 333 } 334 finally { 335 if( tran != null ) { tran.close(); } 336 } 337 338 // エラーが発生した場合は、エラーメッセージを表示して以降の処理を行わない。 339 ErrorMessage errMessage = manager.getErrMessage() ; 340 if( errMessage != null && !errMessage.isOK() && !errRemove ) { 341 rtnCode = SKIP_PAGE; 342 343 // 5.1.9.0 (2010/08/01) エラーメッセージの表示前にincludeするJSPを指定 344 if( beforeErrorJsp != null && beforeErrorJsp.length() > 0 ) { 345 includeJsp( beforeErrorJsp ); 346 } 347 348 jspPrint( TaglibUtil.makeHTMLErrorTable( errMessage, getResource() ) ); 349 350 // 5.1.9.0 (2010/08/01) エラーメッセージの表示後にincludeするJSPを指定 351 if( afterErrorJsp != null && afterErrorJsp.length() > 0 ) { 352 includeJsp( afterErrorJsp ); 353 } 354 } 355 } 356 357 return rtnCode ; 358 } 359 360 /** 361 * タグリブオブジェクトをリリースします。 362 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 363 * 364 * @og.rev 4.1.1.0 (2008/02/22) 新規作成 365 * @og.rev 4.1.2.0 (2008/03/12) sqlType , execType , isExec 追加 366 * @og.rev 4.2.0.1 (2008/03/27) conditionKey , conditionList , msgParamKeys 追加 367 * @og.rev 5.1.9.0 (2010/08/01) beforeErrorJsp , afterErrorJsp, selectedAll 追加 368 * @og.rev 5.7.6.2 (2014/05/16) where 追加。tableExist タグに伴う便利機能追加 369 */ 370 @Override 371 protected void release2() { 372 super.release2(); 373 tableId = HybsSystem.TBL_MDL_KEY; 374 dbid = null; 375 command = CMD_ENTRY; 376 table = null; 377 exist = "auto"; 378 errRemove = false; 379 lbl = null; 380 lblParamKeys = null; // 4.2.0.1 (2008/03/27) 381 isSql = false; 382 isUniqCheck = false; // 4.3.4.0 (2008/12/01) 383 jsEngine = null; 384 sqlType = null; // INSERT,COPY,UPDATE,MODIFY,DELETE 385 execType = null; // INSERT,COPY,UPDATE,MODIFY,DELETE 386 isExec = true; // 4.1.2.0 (2008/03/12) 387 conditionKey = null; // 4.2.0.1 (2008/03/27) 388 conditionList = null; // 4.2.0.1 (2008/03/27) 389 from = null; // 4.2.0.1 (2008/03/27) 390 where = null; // 5.7.6.2 (2014/05/16) tableExist タグに伴う便利機能追加 391 bodyStr = null; // 4.3.4.0 (2008/12/01)) 392 uniqCheckClms = null; // 4.3.4.0 (2008/12/01) 393 beforeErrorJsp = null; // 5.1.9.0 (2010/08/01) 394 afterErrorJsp = null; // 5.1.9.0 (2010/08/01) 395 selectedAll = false; // 5.1.9.0 (2010/08/01) 396 } 397 398 /** 399 * 引数及びボディー部分のチェックを行い、処理のタイプを判別します。 400 * 401 * @og.rev 5.5.8.0 (2012/11/01) タイプ判別変更 402 * @og.rev 5.6.1.1 (2013/02/08) FROM 部の切り出し位置修正 403 * @og.rev 5.7.6.2 (2014/05/16) tableExist タグに伴う便利機能追加。from属性とwhere属性追加 404 */ 405 private void checkParam() { 406 isUniqCheck = uniqCheckClms != null && uniqCheckClms.length > 0 ; 407 if( isUniqCheck ) { 408 if( !CMD_ENTRY.equals( command ) ) { 409 String errMsg = "ユニークキーチェックは、command=\"ENTRY\"の場合のみ使用可能です。" 410 + " command=" + command ; // 5.1.8.0 (2010/07/01) errMsg 修正 411 throw new HybsSystemException( errMsg ); 412 } 413 } 414 // 5.7.6.2 (2014/05/16) tableExist タグに伴う便利機能追加。from属性とwhere属性追加 415 else if( from != null ) { 416 StringBuilder buf = new StringBuilder(); 417 buf.append( "SELECT count(*) FROM " ).append( from ); 418 if( where != null ) { buf.append( " WHERE " ).append( where ); } 419 bodyStr = buf.toString(); 420 isSql = true; 421 } 422 else { 423 if( bodyStr == null || bodyStr.length() == 0 ) { 424 String errMsg = "Body部分にチェック定義を記述して下さい。"; 425 throw new HybsSystemException( errMsg ); 426 } 427 else { 428 // SQLチェックかJavaScriptによるチェックかの判定 429 String query = bodyStr.toUpperCase( Locale.JAPAN ); // 4.2.0.1 (2008/03/27) 430 if( query.indexOf( "SELECT" ) == 0 ) { // 5.5.8.0 (2012/11/01) 先頭に限定する。(trim済のため) 431 isSql = true; 432 int st = query.indexOf( "FROM" ) ; 433 int ed = query.indexOf( "WHERE" ) ; 434 if( st > 0 && st < ed ) { 435 from = query.substring( st+"FROM".length(),ed ).trim(); // 5.6.1.1 (2013/02/08) 436 } 437 } 438 else { 439 jsEngine = new ScriptEngineManager().getEngineByName( "JavaScript" ); 440 } 441 } 442 } 443 } 444 445 /** 446 * SQLによるデータチェックを行います。 447 * チェック方法は、exist属性の指定に依存します。 448 * autoの場合は、テーブルモデルの改廃Cから自動でチェック方法が決定されます。 449 * 450 * @param str 実行するSQL文 451 * @param manager ErrMessageManager オブジェクト 452 * @param values SQL文のパラメータ 453 * @param row 行番号 454 * @param modifyType 改廃C 455 * @param tran トランザクションオブジェクト 456 * 457 * @return 処理の成否 458 * 459 * @og.rev 4.1.1.0 (2008/02/22) 新規作成 460 * @og.rev 4.2.1.0 (2008/04/11) ErrMessageManager対応 461 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。 462 */ 463 private boolean checkSql( final String str, final ErrMessageManager manager, final String[] values 464 , final int row, final String modifyType, final Transaction tran ) { 465 466 int cnt = DBUtil.dbExist( str, values, tran, dbid ); // 5.1.9.0 (2010/08/01) 467 468 boolean okFlag = true; 469 String id = null; 470 if( ( "true".equalsIgnoreCase( exist ) || ( "auto".equalsIgnoreCase( exist ) 471 && ( DBTableModel.UPDATE_TYPE.equals( modifyType ) || DBTableModel.DELETE_TYPE.equals( modifyType ) ) ) ) && cnt <= 0 ) { 472 // ERR0025=データ未登録エラー。キー={0}、値={1} のデータは、存在していません。 473 id = ( lbl == null ? "ERR0025" : lbl ); 474 okFlag = false; 475 } 476 else if( ( "false".equalsIgnoreCase( exist ) || ( "auto".equalsIgnoreCase( exist ) 477 && DBTableModel.INSERT_TYPE.equals( modifyType ) ) ) && cnt > 0 ) { 478 // ERR0026=データ登録済みエラー。キー={0}、値={1} のデータは、すでに存在しています。 479 id = ( lbl == null ? "ERR0026" : lbl ); 480 okFlag = false; 481 } 482 else if( "one".equalsIgnoreCase( exist ) && cnt > 1 ) { 483 // ERR0027=データ2重登録エラー。キー={0}、値={1} のデータは、重複して存在しています。 484 id = ( lbl == null ? "ERR0027" : lbl ); 485 okFlag = false; 486 } 487 488 if( !okFlag ) { 489 manager.addMessage( row, id, values ); 490 491 } 492 return okFlag; 493 } 494 495 /** 496 * JavaScriptの式を実行します。 497 * 実行した結果がboolean型でない場合はエラーとなります。 498 * 499 * @param str 実行するSQL文 500 * @param manager オブジェクト 501 * @param values 値配列 502 * @param row 行番号 503 * @param engine JavaScriptエンジン 504 * 505 * @return 処理の成否 506 * 507 * @og.rev 4.1.1.0 (2008/02/22) 新規作成 508 * @og.rev 4.2.0.1 (2008/03/27) getClass().getName() から、instanceof に変更 509 * @og.rev 4.2.1.0 (2008/04/11) ErrMessageManager対応 510 */ 511 private boolean checkJs( final String str, final ErrMessageManager manager, final String[] values 512 , final int row, final ScriptEngine engine ) { 513 // JavaScriptエンジンによる評価 514 Object obj = null; 515 try { 516 obj = engine.eval( str ); 517 } 518 catch( ScriptException ex ) { 519 String errMsg = "JavaScript式のパースに失敗しました。[" + str + "]"; 520 throw new HybsSystemException( errMsg , ex ); 521 } 522 523 // 返り値がBoolean型かチェック 524 boolean okFlag = false; 525 // 4.2.0.1 (2008/03/27) instanceof に変更 526 if( obj instanceof Boolean ) { // 4.3.1.1 (2008/08/23) instanceof チェックは、nullチェック不要 527 okFlag = ((Boolean)obj).booleanValue(); 528 } 529 else { 530 String errMsg = "JavaScript式には true 若しくは false が返るように設定して下さい" 531 + " Object=" + obj ; // 5.1.8.0 (2010/07/01) errMsg 修正 532 throw new HybsSystemException( errMsg ); 533 } 534 535 if( !okFlag ) { 536 // ERR0030=入力したデータが不正です。key={0} value={1} 形式={2} 537 String id = ( lbl == null ? "ERR0030" : lbl ); 538 539 manager.addMessage( row, id, values ); 540 } 541 542 return okFlag; 543 } 544 545 /** 546 * DBテーブルモデルの各行に対してデータチェックを行います。 547 * 548 * @param str チェック対象の文字列 549 * @param manager ErrMessageManagerオブジェクト 550 * @param tran Transactionトランザクションオブジェクト 551 * 552 * @og.rev 4.1.1.0 (2008/02/22) 新規作成 553 * @og.rev 4.2.0.1 (2008/03/27) conditionKey,conditionList 対応 554 * @og.rev 4.2.1.0 (2008/04/11) ErrMessageManager対応 555 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。 556 */ 557 private void checkRows( final String str, final ErrMessageManager manager, final Transaction tran ) { 558 559 int[] rowNo = getParameterRows(); // 4.0.0 (2005/01/31) 560 if( rowNo.length == 0 ) { return; } 561 562 Formatter format = new Formatter( table ); 563 format.setFormat( str ); 564 int[] clmNo = format.getClmNos(); 565 // 4.2.0.1 (2008/03/27) カラム名のメッセージリソース文字列を作成します。 566 manager.setClmNos( clmNo ); 567 568 // SQL文の場合のみ[xxx]を?に変換したSQL文を取得(JavaScriptの場合はループ内で各行毎に取得 569 String query = null; 570 if( isSql ) { 571 query = format.getQueryFormatString(); 572 } 573 574 // 4.2.0.1 (2008/03/27) conditionKey,conditionList 対応 575 int cndKeyNo = -1; 576 if( conditionKey != null && conditionList != null ) { 577 cndKeyNo = table.getColumnNo( conditionKey ); // 不正指定はエラー 578 } 579 580 List<Integer> list = new ArrayList<Integer>(); 581 boolean okFlag = false; 582 for( int i = 0; i < rowNo.length; i++ ) { 583 int row = rowNo[i] ; 584 String[] values = getTableModelData( row, clmNo ); 585 // 4.2.0.1 (2008/03/27) 条件指定がされている場合に、 586 // Listに含まれない場合は、実行されない。 587 // 4.2.1.0 (2008/04/11) 厳密に処理します。 588 if( cndKeyNo >= 0 && conditionList.indexOf( table.getValue( row,cndKeyNo ) ) < 0 ) { 589 String conVal = "|" + table.getValue( row,cndKeyNo ) + "|" ; 590 if( conditionList.indexOf( conVal ) < 0 ) { continue; } 591 } 592 593 if( isSql ) { 594 okFlag = checkSql( query, manager, values, row, table.getModifyType( row ), tran ); 595 } 596 else { 597 String jsStr = format.getFormatString( row, "\"" ); 598 okFlag = checkJs( jsStr, manager, values, row, jsEngine ); 599 } 600 601 if( errRemove && okFlag ) { 602 list.add( row ); 603 } 604 } 605 606 if( errRemove ) { 607 Integer[] in = list.toArray( new Integer[list.size()] ); 608 int[] newRowNo = new int[in.length]; 609 for( int i = 0; i < in.length; i++ ) { 610 newRowNo[i] = in[i].intValue(); 611 } 612 setParameterRows( newRowNo ); 613 } 614 } 615 616 /** 617 * DBテーブルモデルの各行にユニークキーのチェックを行います。 618 * 619 * @og.rev 4.3.4.0 (2008/12/01) 新規作成 620 * 621 * @param manager ErrMessageManagerオブジェクト 622 */ 623 private void checkUnique( final ErrMessageManager manager ) { 624 int[] rowNo = getParameterRows(); 625 if( rowNo.length == 0 ) { return; } 626 627 int[] clmNo = new int[uniqCheckClms.length]; 628 for( int i=0; i<clmNo.length; i++ ) { 629 clmNo[i] = table.getColumnNo( uniqCheckClms[i] ); 630 } 631 632 manager.setClmNos( clmNo ); 633 634 List<Integer> list = new ArrayList<Integer>(); 635 Map<String,Integer> map = new HashMap<String,Integer>(); 636 for( int i = 0; i < rowNo.length; i++ ) { 637 int row = rowNo[i] ; 638 String[] values = getTableModelData( row, clmNo ); 639 String key = StringUtil.array2line( values, " + " ); 640 641 if( map.get( key ) == null ) { 642 map.put( key, 1 ); 643 if( errRemove ) { 644 list.add( row ); 645 } 646 } 647 else { 648 // ERR0027=データ2重登録エラー。キー={0}、値={1} のデータは、重複して存在しています。 649 id = ( lbl == null ? "ERR0027" : lbl ); 650 manager.addMessage( row, id, values ); 651 } 652 } 653 654 if( errRemove ) { 655 Integer[] in = list.toArray( new Integer[list.size()] ); 656 int[] newRowNo = new int[in.length]; 657 for( int i = 0; i < in.length; i++ ) { 658 newRowNo[i] = in[i].intValue(); 659 } 660 setParameterRows( newRowNo ); 661 } 662 } 663 664 /** 665 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 666 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 667 * 668 * @og.tag 669 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 670 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 671 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 672 * この tableId 属性を利用して、メモリ空間を分けます。 673 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 674 * 675 * @param id sessionに登録する時の ID 676 */ 677 public void setTableId( final String id ) { 678 tableId = nval( getRequestParameter( id ), tableId ); 679 } 680 681 /** 682 * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します。 683 * 684 * @og.tag Queryオブジェクトを作成する時のDB接続IDを指定します。 685 * 686 * @param id データベース接続ID 687 */ 688 public void setDbid( final String id ) { 689 dbid = nval( getRequestParameter( id ), dbid ); 690 } 691 692 /** 693 * 【TAG】コマンド(NEW or ENTRY)をセットします。 694 * 695 * @og.tag 696 * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される 697 * フィールド定数値のいづれかを、指定できます。 698 * 699 * @param cmd コマンド(public static final 宣言されている文字列) 700 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.DataCheckTag.CMD_NEW">コマンド定数</a> 701 */ 702 public void setCommand( final String cmd ) { 703 String cmd2 = getRequestParameter( cmd ); 704 if( cmd2 != null && cmd2.length() > 0 ) { 705 command = cmd2.toUpperCase( Locale.JAPAN ); 706 } 707 } 708 709 /** 710 * 【TAG】データベースのチェック方法[auto/true/false/one/notuse]を指定します(初期値:auto[自動])。 711 * 712 * @og.tag 713 * exist 属性に指定された 、「true:存在する」、「false:存在しない」、「one:ひとつ以下」、 714 * の値は、いずれの場合も、成立時は、正常とみなします。 715 * 「auto:自動」は、DBTableModeleのmodifyType(A,C,D)に応じて、チェックします。 716 * A,C,D は、entryタグにコマンドを渡してデータを作成したときに、内部で作成されます。 717 * (command="NEW"の場合は、trueと同じ動きになります。) 718 * notuse は、チェックを行いません。これは、このタグを共有使用する場合に、外部で 719 * チェックを行うかどうかを指定できるようにするために使用します。 720 * (「true:存在する」 には、データが存在した場合に、OKで、なければエラーです。) 721 * 初期値は、「auto:自動」です。 722 * 723 * @param ext チェック方法(「auto:自動」、「true:存在する」、「false:存在しない」、「one:ひとつ以下」、「notuse:チェックしない」) 724 */ 725 public void setExist( final String ext ) { 726 exist = nval( getRequestParameter( ext ), exist ); 727 if( !"auto".equalsIgnoreCase( exist ) 728 && !"true".equalsIgnoreCase( exist ) 729 && !"false".equalsIgnoreCase( exist ) 730 && !"one".equalsIgnoreCase( exist ) 731 && !"notuse".equalsIgnoreCase( exist ) ) { 732 String errMsg = "exist 属性は、(auto,true,false,one,notuse)を指定してください。 [" + exist + "]" + HybsSystem.CR; 733 throw new HybsSystemException( errMsg ); 734 } 735 } 736 737 /** 738 * 【TAG】エラー時の選択行を取り除いて継続処理を行うかどうか[true/false]を指定します(初期値:false)。 739 * 740 * @og.tag 741 * exist 属性に指定された 、「true:存在する」、「false:存在しない」、「one:ひとつ以下」、 742 * に対して、エラーが発生した選択行番号を、取り除いて以下の処理を継続するかどうかを 743 * 指定します。 744 * true に設定した場合は、エラーデータを削除し、継続処理を行うことができます。 745 * flase の場合は、エラーデータを表示して、継続処理を停止します。 746 * 初期値は、「false:エラー時停止」です。 747 * 748 * @param flag エラー時の継続処理 [true:エラー行番号を取り除き継続処理/false:エラー時停止] 749 */ 750 public void setErrRemove( final String flag ) { 751 errRemove = nval( getRequestParameter( flag ), errRemove ); 752 } 753 754 /** 755 * 【廃止】メッセージIDを指定します(lbl 属性を使用してください)。 756 * 757 * @og.tag メッセージIDを指定します。 758 * 各処理に応じた初期設定のメッセージIDは、以下の通りです。 759 * exist="true" ERR0025=データ未登録エラー。キー={0}、値={1} のデータは、存在していません。 760 * exist="false" ERR0026=データ登録済みエラー。キー={0}、値={1} のデータは、すでに存在しています。 761 * exist="one" ERR0027=データ2重登録エラー。キー={0}、値={1} のデータは、重複して存在しています。 762 * JavaScript ERR0030=入力したデータが不正です。key={0} value={1} 形式={2} 763 * 引数のパラメータには、通常、チェックに使用した実データが、DBTableModel から取得されます。 764 * 引数を変更する場合は、lblParamKeys を使用してください。 765 * 766 * @og.rev 5.2.2.0 (2010/11/01) 廃止します。lbl 属性を使用してください。 767 * 768 * @param id メッセージID 769 * @see #setMsgParamKeys( String ) 770 * @deprecated lbl 属性を使用してください。 771 */ 772 @Deprecated public void setMsg( final String id ) { 773 setLbl( id ); 774// msg = nval( getRequestParameter( id ), msg ); 775 } 776 777 /** 778 * 【TAG】ラベルリソースIDを指定します。 779 * 780 * @og.tag ラベルリソースIDを指定します。 781 * 各処理に応じた初期設定のラベルリソースIDは、以下の通りです。 782 * exist="true" ERR0025=データ未登録エラー。キー={0}、値={1} のデータは、存在していません。 783 * exist="false" ERR0026=データ登録済みエラー。キー={0}、値={1} のデータは、すでに存在しています。 784 * exist="one" ERR0027=データ2重登録エラー。キー={0}、値={1} のデータは、重複して存在しています。 785 * JavaScript ERR0030=入力したデータが不正です。key={0} value={1} 形式={2} 786 * 引数のパラメータには、通常、チェックに使用した実データが、DBTableModel から取得されます。 787 * 引数を変更する場合は、lblParamKeys を使用してください。 788 * 789 * @param id メッセージID 790 * @see #setLblParamKeys( String ) 791 */ 792 @Override 793 public void setLbl( final String id ) { 794 // 継承親のメソッドを使わない。 795 lbl = nval( getRequestParameter( id ), lbl ); 796 } 797 798 /** 799 * 【廃止】メッセージリソースの引数をカンマ区切りで指定します(lblParamKeys 属性を使用してください)。 800 * 801 * @og.tag 802 * メッセージリソースのキーをカンマ区切りで指定することで、設定します。 803 * メッセージに引数( {0},{1} など ) がある場合、ここで指定した値を 804 * 順番に、{0},{1},{2}・・・ に当てはめていきます。 805 * キーワードは、カンマ区切りで指定し、それを分解後、ラベルリソースで 806 * リソース変換を行います。(つまり、記述された値そのものでは在りません) 807 * PL/SQL では、"{#PN}" などと指定していた分は、同様に "PN" と指定しです。 808 * 内部的に、where 条件に指定されたキーと値は、@KEY と @VAL に、 809 * from と where の間の文字列は、@TBL に対応付けられます。 810 * {@XXXX} 変数も使用できます。実データの値を取出したい場合は、[PN]と 811 * すれば、DBTableModel の PN の値を取出します。 812 * なにも指定しない場合は、キー={0} 、値={1}、from={2} です。 813 * 814 * @og.rev 4.2.0.1 (2008/03/27) 新規追加 815 * @og.rev 5.2.2.0 (2010/11/01) 廃止します。lbl 属性を使用してください。 816 * 817 * @param keys メッセージリソースのキー(CSV) 818 * @see #setLbl( String ) 819 * @deprecated lblParamKeys 属性を使用してください。 820 */ 821 @Deprecated public void setMsgParamKeys( final String keys ) { 822 setLblParamKeys( keys ); 823// lblParamKeys = getCSVParameter( keys ); 824 } 825 826 /** 827 * 【TAG】ラベルリソースの引数をカンマ区切りで指定します。 828 * 829 * @og.tag 830 * ラベルリソースのキーをカンマ区切りで指定することで、設定します。 831 * ラベルに引数( {0},{1} など ) がある場合、ここで指定した値を 832 * 順番に、{0},{1},{2}・・・ に当てはめていきます。 833 * キーワードは、カンマ区切りで指定し、それを分解後、ラベルリソースで 834 * リソース変換を行います。(つまり、記述された値そのものでは在りません) 835 * PL/SQL では、"{#PN}" などと指定していた分は、同様に "PN" と指定しです。 836 * 内部的に、where 条件に指定されたキーと値は、@KEY と @VAL に、 837 * from と where の間の文字列は、@TBL に対応付けられます。 838 * {@XXXX} 変数も使用できます。実データの値を取出したい場合は、[PN]と 839 * すれば、DBTableModel の PN の値を取出します。 840 * なにも指定しない場合は、キー={0} 、値={1}、from={2} です。 841 * 842 * @og.rev 4.2.0.1 (2008/03/27) 新規追加 843 * 844 * @param keys メッセージリソースのキー(CSV) 845 * @see #setLbl( String ) 846 */ 847 public void setLblParamKeys( final String keys ) { 848 lblParamKeys = getCSVParameter( keys ); 849 } 850 851 /** 852 * 【TAG】このチェックを行う、SQLタイプ を指定します。 853 * 854 * @og.tag 855 * SQLタイプは、INSERT,COPY,UPDATE,MODIFY,DELETE などの記号を指定します。 856 * 一般には、result 画面から update 画面へ遷移するときの、command と 857 * 同じにしておけばよいでしょう。 858 * これは、execType とマッチした場合のみ、このチェックが処理されます。 859 * 簡易 equals タグの代役に使用できます。 860 * なにも指定しない場合は、チェックは実行されます。 861 * 862 * @og.rev 4.1.2.0 (2008/03/12) 新規追加 863 * 864 * @param type このチェックを行う、SQLタイプ 865 */ 866 public void setSqlType( final String type ) { 867 sqlType = nval( getRequestParameter( type ),sqlType ); 868 } 869 870 /** 871 * 【TAG】このチェックを行う、実行タイプ を指定します。 872 * 873 * @og.tag 874 * 実行タイプは、sqlType とマッチした場合のみ、このチェックが処理されます。 875 * 簡易 equals タグの代役に使用できます。 876 * execType は、複数指定が可能です。単純な文字列マッチで、sqlType を 877 * 含めば、実行されます。 878 * 例えば、sqlType={@sqlType} execType="INSERT|COPY" とすれば、 879 * sqlType に、INSERT または、COPY が登録された場合にチェックが掛かります。 880 * なにも指定しない場合は、チェックは実行されます。 881 * 882 * @og.rev 4.1.2.0 (2008/03/12) 新規追加 883 * 884 * @param type このチェックを行う、実行タイプ 885 */ 886 public void setExecType( final String type ) { 887 execType = nval( getRequestParameter( type ),execType ); 888 } 889 890 /** 891 * 【TAG】条件判定するカラムIDを指定します。 892 * 893 * @og.tag 894 * 指定のカラムIDの値と、conditionList の値を比較して、 895 * 存在する場合は、check処理を実行します。 896 * この処理が有効なのは、command="ENTRY" の場合のみです。 897 * 898 * @og.rev 4.2.0.1 (2008/03/27) 新規追加 899 * 900 * @param key カラムID 901 * @see #setConditionList( String ) 902 */ 903 public void setConditionKey( final String key ) { 904 conditionKey = nval( getRequestParameter( key ),null ) ; 905 } 906 907 /** 908 * 【TAG】条件判定する値のリストを、"|"で区切って登録します(初期値:無条件)。 909 * 910 * @og.tag 911 * conditionKey とペアで指定します。ここには、カラムの設定値のリストを 912 * 指定することで、複数条件(OR結合)での比較を行い、リストにカラム値が 913 * 存在する場合のみ、check処理を実行します。 914 * この処理が有効なのは、command="ENTRY" の場合のみです。 915 * 設定しない場合は、無条件に実行します。 916 * 917 * @og.rev 4.2.0.1 (2008/03/27) 新規追加 918 * 919 * @param list 条件判定する値("|"で区切) 920 * @see #setConditionKey( String ) 921 */ 922 public void setConditionList( final String list ) { 923 conditionList = nval( getRequestParameter( list ),null ) ; 924 if( conditionList != null ) { 925 conditionList = "|" + conditionList + "|" ; 926 } 927 } 928 929 /** 930 * 【TAG】指定されたキーに従って、メモリ上のテーブルに対してユニークキーチェックを行います。 931 * 932 * @og.tag 933 * ユニークキーチェックを行うキーを指定します。ここで、指定されたキーに対して、 934 * DBTableModelの値をチェックし、全てのキーに同じ値となっている行が存在すればエラーとなります。 935 * このチェックは、command="ENTRY"の場合のみ有効です。 936 * また、このチェックは他のチェック(DB存在チェックなど)と同時に処理することはできません。 937 * キーが指定され手いる場合は、ボディ部分に記述されている定義は無視されます。 938 * errRemoveの属性がtrueに指定されている場合、重複行は、DBTableModelの並び順から見て、 939 * 最初の行のみ処理され、2つめ以降の重複行は無視されます。 940 * なお、キーはカンマ区切り(CSV形式)で複数指定が可能です。 941 * 942 * @og.rev 4.3.4.0 (2008/12/01) 新規追加 943 * 944 * @param clm チェックキー(CSV形式) 945 */ 946 public void setUniqCheckClms( final String clm ) { 947 String tmp = nval( getRequestParameter( clm ),null ); 948 uniqCheckClms = StringUtil.csv2Array( tmp ); 949 } 950 951 /** 952 * 【TAG】エラーが発生した際に、エラーメッセージの表示前にincludeするJSPを指定します。 953 * 954 * @og.tag 955 * エラーが発生した際に、エラーメッセージの表示前にincludeするJSPを指定します。 956 * エラーが発生していない場合は、ここで指定されたJSPが処理されることはありません。 957 * 通常は、戻るリンクなどを指定します。 958 * 959 * 指定の方法は、相対パス、絶対パスの両方で指定することができます。 960 * 但し、絶対パスで指定した場合、その基点は、コンテキストのルートディレクトリになります。 961 * 例) beforeErrorJsp = "/jsp/common/history_back.jsp" 962 * 963 * @og.rev 5.1.9.0 (2010/08/01) 新規追加 964 * 965 * @param jsp 表示前にincludeするJSPファイル名 966 */ 967 public void setBeforeErrorJsp( final String jsp ) { 968 beforeErrorJsp = nval( getRequestParameter( jsp ),beforeErrorJsp ); 969 } 970 971 /** 972 * 【TAG】エラーが発生した際に、エラーメッセージの表示後にincludeするJSPを指定します。 973 * 974 * @og.tag 975 * エラーが発生した際に、エラーメッセージの表示前にincludeするJSPを指定します。 976 * エラーが発生していない場合は、ここで指定されたJSPが処理されることはありません。 977 * 978 * 指定の方法は、相対パス、絶対パスの両方で指定することができます。 979 * 但し、絶対パスで指定した場合、その基点は、コンテキストのルートディレクトリになります。 980 * 例) afterErrorJsp = "/jsp/common/history_back.jsp" 981 * 982 * @og.rev 5.1.9.0 (2010/08/01) 新規追加 983 * 984 * @param jsp 表示後にincludeするJSPファイル名 985 */ 986 public void setAfterErrorJsp( final String jsp ) { 987 afterErrorJsp = nval( getRequestParameter( jsp ),afterErrorJsp ); 988 } 989 990 /** 991 * 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)。 992 * 993 * @og.tag 994 * 全てのデータを選択済みデータとして扱って処理します。 995 * 全件処理する場合に、(true/false)を指定します。 996 * 初期値は false です。 997 * 998 * @og.rev 5.1.9.0 (2010/08/01) 新規追加 999 * 1000 * @param all 選択済みとして処理するかどうか[true:全件選択済み/false:通常] 1001 */ 1002 public void setSelectedAll( final String all ) { 1003 selectedAll = nval( getRequestParameter( all ),selectedAll ); 1004 } 1005 1006 /** 1007 * 【TAG】チェックするデータベース名(from 句)を指定します。 1008 * 1009 * @og.tag 1010 * これは、tableExist タグ廃止に伴う便利機能で、通常、BODYに記述された 1011 * SELECT count(*) from XXXX where XXXXX で、チェックしますが、 1012 * from 属性 と、where 属性を指定する事で、内部で、チェック用のSQL文を 1013 * 作成します。 1014 * from が指定された場合は、BODY は無視されますので、ご注意ください。 1015 * 1016 * @og.rev 5.7.6.2 (2014/05/16) 新規追加 1017 * 1018 * @param frm チェックするテーブルID 1019 */ 1020 public void setFrom( final String frm ) { 1021 from = nval( getRequestParameter( frm ),from ); 1022 } 1023 1024 /** 1025 * 【TAG】チェックする検索条件(where句)を指定します。 1026 * 1027 * @og.tag 1028 * これは、tableExist タグ廃止に伴う便利機能で、通常、BODYに記述された 1029 * SELECT count(*) from XXXX where XXXXX で、チェックしますが、 1030 * from 属性 と、where 属性を指定する事で、内部で、チェック用のSQL文を 1031 * 作成します。 1032 * where は、from が指定された場合のみ、有効ですし、where を指定しなければ、 1033 * 全件検索になります。 1034 * tableExist タグと異なるのは、where の指定の仕方で、tableExist タグでは、 1035 * names 属性と、対応する where には、? で記述していましたが、 1036 * dataCheck タグでは、通常の [] でDBTableModelの値を指定します。 1037 * 1038 * @og.rev 5.7.6.2 (2014/05/16) 新規追加 1039 * 1040 * @param whr チェックするWHERE 条件 1041 */ 1042 public void setWhere( final String whr ) { 1043 where = nval( getRequestParameter( whr ),where ); 1044 } 1045 1046 /** 1047 * 指定の行番号の、カラムNo配列(int[])に対応した値の配列を返します。 1048 * 1049 * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を 1050 * 処理の対象とします。 1051 * 1052 * @og.rev 4.2.0.1 (2008/03/27) row と clm を入れ替えます。(他とあわせます) 1053 * 1054 * @param row 行番号 1055 * @param clmNo カラムNo配列 1056 * 1057 * @return 行番号とカラムNo配列に対応した、値の配列 1058 */ 1059 private String[] getTableModelData( final int row, final int[] clmNo ) { 1060 String[] values = new String[clmNo.length]; 1061 for( int i = 0; i < values.length; i++ ) { 1062 values[i] = table.getValue( row, clmNo[i] ); 1063 } 1064 return values; 1065 } 1066 1067 /** 1068 * エラーメッセージの前後に処理するJSPをインクルードします。 1069 * 1070 * @og.rev 5.1.9.0 (2010/08/01) 新規作成 1071 * 1072 * @param jsp JSP名 1073 */ 1074 private void includeJsp( final String jsp ) { 1075 try { 1076 pageContext.include( jsp, false ); 1077 } catch ( IOException ex ) { 1078 String errMsg = jsp + " の include に失敗しました。 "; 1079 throw new HybsSystemException( errMsg,ex ); 1080 } catch ( ServletException ex ) { 1081 String errMsg = jsp + " の include に失敗しました。 "; 1082 throw new HybsSystemException( errMsg,ex ); 1083 } 1084 } 1085 1086 /** 1087 * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を処理の対象とします。 1088 * 1089 * @og.rev 5.1.9.0 (2010/08/01) 新規追加 1090 * 1091 * @return 選択行の配列 1092 */ 1093 @Override 1094 protected int[] getParameterRows() { 1095 final int[] rowNo ; 1096 if( selectedAll ) { 1097 int rowCnt = table.getRowCount(); 1098 rowNo = new int[ rowCnt ]; 1099 for( int i=0; i<rowCnt; i++ ) { 1100 rowNo[i] = i; 1101 } 1102 } else { 1103 rowNo = super.getParameterRows(); 1104 } 1105 return rowNo ; 1106 } 1107 1108 /** 1109 * ErrMessage を管理している メソッド集約型内部クラス 1110 * 1111 * 繰返し処理部と、固定部が混在したエラーメッセージで、固定部を先に処理し、 1112 * 繰返し部は、必要時に処理するようにしました。 1113 * また、実際にエラーが発生して必要になるまで、実行遅延させます。 1114 * 1115 * @og.rev 4.2.1.0 (2008/04/11) 新規追加 1116 * @og.rev 4.3.0.0 (2008/07/24) クラス宣言をstatic化 1117 */ 1118 private static final class ErrMessageManager { 1119 // 引数として初期設定される変数 1120 private String title = null; 1121 private String from = null; 1122 private String[] lblKeys = null; 1123 private ResourceManager resource = null; 1124 private DBTableModel table = null; 1125 private int[] clmNo = null; 1126 1127 // 内部引数として処理されたキャッシュ値 1128 private ErrorMessage errMessage = null; 1129 private String names = null; 1130 private String fromLbl = null; 1131 private String[] lblVals = null; 1132 1133 private boolean isFirst = true; // 初期化されていない=true 1134 1135 /** 1136 * ErrMessage のタイトルを設定します。 1137 * 1138 * @param title タイトル 1139 */ 1140 public void setTitle( final String title ) { this.title = title; } 1141 1142 /** 1143 * 処理対象のテーブル名を設定します。 1144 * 1145 * @param from テーブル名 1146 */ 1147 public void setFrom( final String from ) { this.from = from; } 1148 1149 /** 1150 * 処理対象のテーブルオブジェクトを設定します。 1151 * 1152 * @param table DBTableModelオブジェクト 1153 */ 1154 public void setDBTableModel( final DBTableModel table ) { this.table = table; } 1155 1156 /** 1157 * ResourceManagerオブジェクトを設定します。 1158 * 1159 * @param resource ResourceManagerオブジェクト 1160 */ 1161 public void setResourceManager( final ResourceManager resource ) { this.resource = resource; } 1162 1163 /** 1164 * lblParamKeys 属性の配列を設定します。 1165 * 1166 * @param lblKeys 属性の配列 1167 */ 1168 public void setParamKeys( final String[] lblKeys ) { this.lblKeys = lblKeys; } 1169 1170 /** 1171 * カラム名列を設定します。 1172 * 1173 * @param clmNo カラム名 1174 */ 1175 public void setClmNos( final int[] clmNo ) { this.clmNo = clmNo ; } 1176 1177 /** 1178 * 初期処理を行います。 1179 * エラー処理は、エラー時のみ実行する為、必要のない場合は、処理が不要です。 1180 * 最初のエラー出力までは、内部オブジェクトの構築処理を行いません。 1181 * 2回目以降は、内部変数にキャッシュされた変換値を利用して、高速化します。 1182 * 1183 * @og.rev 4.2.3.2 (2008/06/20) from が、null なら、なにもしない。 1184 */ 1185 private void firstExecute() { 1186 errMessage = new ErrorMessage( title ); 1187 1188 // テーブル(from) をキーにラベルリソースから値を取得します。 1189 // 4.2.3.2 (2008/06/20) from が、null なら、なにもしない。 1190 if( from != null ) { 1191 fromLbl = resource.getLabel( from ); 1192 } 1193 1194 // カラム番号配列から、カラム名のラベルリソース情報のCSV文字列を作成します。 1195 names = getKeysLabel( clmNo ); 1196 1197 if( lblKeys != null && lblKeys.length > 0 ) { 1198 int size = lblKeys.length; 1199 lblVals = new String[size] ; 1200 1201 for( int i=0; i<size; i++ ) { 1202 String key = lblKeys[i] ; 1203 if( key != null ) { 1204 if( "@KEY".equals( key ) ) { lblVals[i] = names; } 1205 else if( "@TBL".equals( key ) ) { lblVals[i] = fromLbl;} 1206 else if( key.startsWith( "{#" ) && key.endsWith( "}" ) ) { 1207 lblVals[i] = resource.getLabel( key.substring( 2,key.length()-1 )); 1208 } 1209 else { 1210 lblVals[i] = key; 1211 } 1212 } 1213 } 1214 } 1215 } 1216 1217 /** 1218 * カラムNo配列(int[])に対応したカラム名のメッセージリソース文字列を返します。 1219 * 1220 * @param clmNo カラムNo配列 1221 * @return カラムNo配列に対応した、カラム名のメッセージリソース 1222 */ 1223 private String getKeysLabel( final int[] clmNo ) { 1224 StringBuilder buf = new StringBuilder(); 1225 if( table != null && clmNo.length > 0 ) { 1226 String key = table.getColumnName( clmNo[0] ); 1227 buf.append( resource.getLabel( key ) ); 1228 for( int i=1; i<clmNo.length; i++ ) { 1229 key = table.getColumnName( clmNo[i] ); 1230 buf.append( "," ).append( resource.getLabel( key ) ); 1231 } 1232 } 1233 1234 return buf.toString(); 1235 } 1236 1237 /** 1238 * カラム名列を設定します。 1239 * 1240 * @og.rev 4.3.5.7 (2008/03/22) エラーメッセージの行番号を実際の行番号と一致させる。 1241 * 1242 * @param row カラム名 1243 * @param id カラム名 1244 * @param values 指定の行に対する値 1245 */ 1246 public void addMessage( final int row, final String id, final String[] values ) { 1247 if( isFirst ) { firstExecute(); isFirst = false; } 1248 1249 String vals = StringUtil.array2csv( values ); 1250 if( lblVals == null ) { 1251 errMessage.addMessage( row + 1, ErrorMessage.NG, id, names, vals, fromLbl ); 1252 } 1253 else { 1254 int size = lblKeys.length; 1255 String[] args = new String[size] ; 1256 1257 for( int i=0; i<size; i++ ) { 1258 String key = lblVals[i] ; 1259 if( key != null ) { 1260 if( "@VAL".equals( key ) ) { args[i] = vals; } 1261 else if( key.startsWith( "[" ) && key.endsWith( "]" ) ) { 1262 if( table != null ) { 1263 args[i] = table.getValue( row,key.substring( 1,key.length()-1 ) ); 1264 } 1265 } 1266 else { 1267 args[i] = key; 1268 } 1269 } 1270 } 1271 errMessage.addMessage( row + 1, ErrorMessage.NG, id, args ); 1272 } 1273 } 1274 1275 /** 1276 * ErrorMessageオブジェクトを返します。 1277 * 1278 * @return ErrorMessage オブジェクト 1279 */ 1280 public ErrorMessage getErrMessage() { return errMessage; } 1281 } 1282 1283 /** 1284 * シリアライズ用のカスタムシリアライズ書き込みメソッド 1285 * 1286 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 1287 * @serialData 一部のオブジェクトは、シリアライズされません。 1288 * 1289 * @param strm ObjectOutputStreamオブジェクト 1290 * @throws IOException シリアライズに関する入出力エラーが発生した場合 1291 */ 1292 private void writeObject( final ObjectOutputStream strm ) throws IOException { 1293 strm.defaultWriteObject(); 1294 } 1295 1296 /** 1297 * シリアライズ用のカスタムシリアライズ読み込みメソッド 1298 * 1299 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。 1300 * 1301 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 1302 * @serialData 一部のオブジェクトは、シリアライズされません。 1303 * 1304 * @param strm ObjectInputStreamオブジェクト 1305 * @see #release2() 1306 * @throws IOException シリアライズに関する入出力エラーが発生した場合 1307 * @throws ClassNotFoundException クラスを見つけることができなかった場合 1308 */ 1309 private void readObject( final ObjectInputStream strm ) throws IOException, ClassNotFoundException { 1310 strm.defaultReadObject(); 1311 } 1312 1313 /** 1314 * このオブジェクトの文字列表現を返します。 1315 * 基本的にデバッグ目的に使用します。 1316 * 1317 * @return このクラスの文字列表現 1318 */ 1319 @Override 1320 public String toString() { 1321 return org.opengion.fukurou.util.ToString.title(this.getClass().getName() ) 1322 .println( "VERSION", VERSION ) 1323 .println( "tableId", tableId ) 1324 .println( "dbid", dbid ) 1325 .println( "command", command ) 1326 .println( "exist", exist ) 1327 .println( "lbl", lbl ) 1328 .println( "Other...", getAttributes().getAttribute() ).fixForm().toString(); 1329 } 1330}