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 java.util.Arrays; 019import java.util.Enumeration; 020import java.util.Locale; 021import java.util.Set; 022import java.util.TreeSet; 023 024import org.opengion.fukurou.util.ErrorMessage; 025import org.opengion.fukurou.util.StringUtil; 026import org.opengion.hayabusa.common.HybsSystem; 027import org.opengion.hayabusa.common.HybsSystemException; 028import org.opengion.hayabusa.db.DBColumn; 029import org.opengion.hayabusa.db.DBTableModel; 030import org.opengion.hayabusa.resource.ResourceManager; // 6.4.0.2 (2015/12/11) 031import org.opengion.fukurou.util.ToString; // 6.1.1.0 (2015/01/17) 032import static org.opengion.fukurou.util.StringUtil.nval; 033 034/** 035 * 登録データの物理チェック(整合性チェック、nullチェック)を行うタグです。 036 * 037 * コマンドに対応したチェック方式で、指定のカラムをチェックします。 038 * command="NEW" の場合は、columns 引数にCSV形式で指定したカラム名より 039 * リクエスト情報を取得して、値をチェックします。 040 * 引数チェックでは、"%" や "_" などのあいまい検索時に指定する記号を 041 * 含むとエラーになるカラムはチェック対象からはずす必要がある為、 042 * チェックすべきカラムを指定する必要があります。 043 * command="ENTRY" の場合は、columns 引数に無関係に、全てのリクエストされたカラム 044 * の値をチェックします。これは、先の検索時の場合と異なり、ENTRYでは 045 * データベースに値を設定する為、無条件にチェックする必要があります。 046 * nullCheck は、command に無関係に指定のカラムが null (ゼロ文字列)かどうかを 047 * 判定します。 048 * maxRowCount は、一覧検索時のチェックされた件数が、指定の値を超えた場合に 049 * エラーになります。minRowCount は、同様に、最小選択件数(設定値を含む)の指定です。 050 * このタグは、エラー時には、それ以降のJSP画面を評価しません。BODY 部に記述された 051 * 値は、エラー時のみ表示され、正常時には、なにも表示されません。これは、エラー時の 052 * メッセージや、ユーザーにエラー時のアクションを行ってもらう場合の処理(例えば、 053 * 画面を戻る為のボタンなど)を表示させます。 054 * useColumnLabel を true にセットすると、エラー時のカラム名(ラベル)を、カラムオブジェクトから 055 * 取得するようになります。動的カラム実行時や、DBTableModelに対して、ColumnEditor等で 056 * ラベルを書き換えた場合に、有効です。false の場合は、基本的にはラベルリソースからの 057 * 取得になりますが、ケースによっては、カラムオブジェクトから取得している場合もあります。 058 * この属性は、互換性を重視し、初期値が、false になっています。 059 * 060 * command="MODIFY" , "DELETE" 時には、強制的に、minRowCount="1" で処理します。 061 * 062 * @og.formSample 063 * ●形式:<og:columnCheck command = "…" /> 064 * ●形式:<og:columnCheck command = "…" >エラー時のみ処理 </og:columnCheck> 065 * ●body:なし/あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します) 066 * 067 * ●Tag定義: 068 * <og:columnCheck 069 * command 【TAG】コマンド[NEW/RENEW/ENTRY]をセットします(初期値:NEW) 070 * columns 【TAG】チェックすべきカラム列をCSV形式(CSV形式)で指定します 071 * nullCheck 【TAG】NULL チェックすべきカラム列をカンマ区切(CSV形式)りで指定します 072 * mustAnyCheck 【TAG】選択必須カラム(指定のカラムの内最低ひとつがNULLでない)を"AA|BB|CC,XX|YY|ZZ" 形式で指定します 073 * checkType 【TAG】チェック対象のデータ[AUTO/NEW/ENTRY]を指定します(初期値:AUTO) 074 * maxRowCount 【TAG】ENTRY時にチェックで選択された行数の最大値を設定します 075 * minRowCount 【TAG】ENTRY時にチェックで選択された行数の最小値を設定します 076 * tableId 【TAG】(通常は使いません) sessionに登録されている DBTableModel を取り出すキーを指定します 077 * matchKeys 【TAG】正規表現でのマッチングを行うカラム列をCSV形式(CSV形式)で指定します 078 * matchVals 【TAG】正規表現でのマッチングを行うカラム列に対する値(正規表現)をCSV形式(CSV形式)で指定します 079 * realTime 【TAG】(通常は使いません)リアルタイムチェックを行う場合に有効にします(初期値:false) 080 * useStrict 【TAG】NEWの場合に、厳密にチェックするかどうか[true/false]を指定します(初期値:false) 081 * useColumnLabel 【TAG】カラムラベルを使用するかどうか[true/false]を指定します(初期値:false) 082 * checkNames 【TAG】リクエスト変数の正規化を行うカラムをCSV形式で複数指定します 083 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 084 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 085 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない) 086 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない) 087 * caseIf 【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない) 088 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 089 * > ... Body ... 090 * </og:columnCheck> 091 * 092 * ●使用例 093 * <og:columnCheck 094 * command = "{@command}" 095 * columns = "AAA,BBB,CCC" DB定義(DBColumnリソース)で定義した項目(桁数,タイプ等)でチェックします。 096 * maxRowCount = "1" チェックで選ばれた 最大選択件数(設定値を含む)を指定。 097 * minRowCount = "1" チェックで選ばれた 最小選択件数(設定値を含む)を指定。 098 * nullCheck = "AAA,CCC" NULLチェックを実行します。 099 * /> 100 * 101 * [エラー時に、BODY部に記述された内容を出力する。正常時には、このBODY部の記述は出力されません。] 102 * <og:columnCheck 103 * command = "{@command}" 104 * columns = "AAA,BBB,CCC" DB定義(DBColumnリソース)で定義した項目(桁数,タイプ等)でチェックします。 105 * nullCheck = "AAA,CCC" NULLチェックを実行します。 106 * > 107 * <form method="POST" action="forward.jsp" target="RESULT"> 108 * <og:input type="button" onClick="history.back()" msg="MSG0049" accesskey="R" td="false" /> 109 * </form> 110 * </og:columnCheck> 111 * 112 * mustAnyCheck 属性に、選択必須カラムを指定します。 113 * 例:mustAnyCheck="AA|BB|CC" 114 * AA,BB,CC のカラムで選択必須(すべてがnullならエラー) 115 * 例:mustAnyCheck="AA|BB|CC,XX|YY|ZZ" 116 * AA,BB,CC のセットと、XX,YY,ZZのセットでそれぞれ選択必須。 117 * 例:mustAnyCheck="AA|XX,AA|YY,AA|ZZ" 118 * AA に値があればすべて成立。そうでない場合は、XX と YY と ZZ がすべて必須。 119 * 例:mustAnyCheck="AA|BB,BB|CC,AA|CC" 120 * AA,BB,CC の内、どれか2つが必須。AAが成立すればBBかCCが必須。同様に、 121 * BBが成立すれば、AAかCCが必須。 122 * 123 * 例:query.jsp 124 * <og:column name="AA" mustAny="true" /> 125 * <og:column name="BB" mustAny="true" /> 126 * <og:column name="XX" mustAny="XYZ" /> 127 * <og:column name="YY" mustAny="XYZ" /> 128 * result.jsp 129 * <og:columnCheck mustAnyCheck="AA|BB,XX|YY" /> 130 * custom/custom.css 131 * .XYZ { background-color: Green; } 132 * 133 * 例:動的カラムで、entry.jsp でのチェックを行う場合。 134 * entry.jsp 135 * <og:columnCheck command="NEW" columns="*" useColumnLabel="true" /> 136 * 137 * useColumnLabel で、動的に作成されたカラム(SAVE=TRUEでキャッシュ済み)を使って 138 * チェックします。command="NEW" なので、対象カラムを指定するのに、"*" ですべてを選択します。 139 * 140 * @og.group 画面登録 141 * 142 * @version 4.0 143 * @author Kazuhiko Hasegawa 144 * @since JDK5.0, 145 */ 146public class ColumnCheckTag extends CommonTagSupport { 147 /** このプログラムのVERSION文字列を設定します。 {@value} */ 148 private static final String VERSION = "6.9.2.1 (2018/03/12)" ; 149 private static final long serialVersionUID = 692120180312L ; 150 151 /** command 引数に渡す事の出来る コマンド 新規 {@value} */ 152 public static final String CMD_NEW = "NEW" ; 153 /** command 引数に渡す事の出来る コマンド 再検索 {@value} */ 154 public static final String CMD_RENEW = "RENEW" ; 155 /** command 引数に渡す事の出来る コマンド エントリー {@value} */ 156 public static final String CMD_ENTRY = "ENTRY" ; 157 /** command 引数に渡す事の出来る コマンド リスト */ 158 159 // 6.4.3.2 (2016/02/19) ENTRY時にチェックする対象を、tableId指定のテーブルのカラムに限定します。 160 // 4.3.1.1 (2008/08/23) transient 追加 161 162 private String tableId = HybsSystem.TBL_MDL_KEY; // 3.5.4.3 (2004/01/05) 163 private String command = CMD_NEW; // 無指定時は、チェックを行う。 164 private String[] columns ; 165 private String[] nullCheck ; 166 private String[] mustAnyCheck; // 3.8.0.9 (2005/10/17) 167 private int maxRowCount = -1 ; // 初期値として,無制限を指定 168 private int minRowCount = -1 ; // 初期値として,無制限を指定 169 private String checkType = "AUTO"; 170 private String bodyString ; // 3.5.4.2 (2003/12/15) 171 private String[] matchKeys ; // 4.0.0 (2005/11/30) 172 private String[] matchVals ; // 4.0.0 (2005/11/30) 173 private boolean isRealTime ; // 4.3.7.0 (2009/06/01) 174 private boolean isStrict ; // 5.2.2.0 (2010/11/01) NEWの場合に、厳密にチェックするフラグを追加 175 176 private boolean isColumnLabel; // 5.4.3.4 (2012/01/12) true の場合に、カラムラベルを使用します。 177 178 private String checkNames ; // 5.4.3.8 (2012/01/24) 179 180 /** 181 * デフォルトコンストラクター 182 * 183 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 184 */ 185 public ColumnCheckTag() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 186 187 /** 188 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 189 * 190 * @og.rev 3.5.4.2 (2003/12/15) エラー時に、BODY部に記述された内容を出力する。 191 * @og.rev 5.0.0.2 (2009/09/15) xss対応⇒チェックする 192 * @og.rev 5.7.8.0 (2014/07/04) caseKey,caseVal,caseNN,caseNull 属性を追加 193 * 194 * @return 後続処理の指示( EVAL_BODY_BUFFERED ) 195 */ 196 @Override 197 public int doStartTag() { 198 // 5.0.0.2 (2009/09/15) XSSチェックしない⇒する 199 // useXssCheck( false ); 200 201 // 5.7.8.0 (2014/07/04) 追加 202 return useTag() ? EVAL_BODY_BUFFERED : SKIP_BODY ; 203 } 204 205 /** 206 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。 207 * 208 * @og.rev 3.5.4.2 (2003/12/15) エラー時に、BODY部に記述された内容を出力する。 209 * 210 * @return 後続処理の指示(SKIP_BODY) 211 */ 212 @Override 213 public int doAfterBody() { 214 bodyString = getBodyString(); 215 216 return SKIP_BODY ; 217 } 218 219 /** 220 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 221 * 222 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 223 * @og.rev 3.4.0.3 (2003/09/10) command="NEW" でエラー発生時には、DBTableModel をクリアする。 224 * @og.rev 3.5.4.2 (2003/12/15) HTMLTableViewForm クラス名変更(⇒ ViewForm_HTMLTable) 225 * @og.rev 3.5.4.2 (2003/12/15) エラー時に、BODY部に記述された内容を出力する。 226 * @og.rev 3.5.4.3 (2004/01/05) tableId 属性を追加。 227 * @og.rev 3.5.4.4 (2004/01/16) エラー結果を表示するテーブル形式のフォーム修正 228 * @og.rev 3.5.5.2 (2004/04/02) TaglibUtil.makeHTMLErrorTable メソッドを利用 229 * @og.rev 4.1.2.1 (2008/03/13) table 属性を追加。 230 * @og.rev 4.3.3.0 (2008/10/01) viewSimple属性追加 231 * @og.rev 4.3.7.0 (2009/06/01) viewSimple属性名称変更 ⇒ isRealTime 232 * @og.rev 5.6.8.3 (2013/09/27) checkTypeがAutoの場合のセットをここで行い、tableModelチェックをcheckTypeで行う。 233 * @og.rev 5.7.8.0 (2014/07/04) caseKey,caseVal,caseNN,caseNull 属性を追加 234 * @og.rev 6.4.3.2 (2016/02/19) ENTRY時にチェックする対象を、tableId指定のテーブルのカラムに限定します。 235 * 236 * @return 後続処理の指示 237 */ 238 @Override 239 public int doEndTag() { 240 debugPrint(); // 4.0.0 (2005/02/28) 241 242 // 5.7.8.0 (2014/07/04) caseKey,caseVal,caseNN,caseNull 属性を追加 243 if( !useTag() ) { return EVAL_PAGE ; } // ページの残りを評価する。 244 245 int rtnCode = EVAL_PAGE; 246 247 // 6.4.3.2 (2016/02/19) ENTRY時にチェックする対象を、tableId指定のテーブルのカラムに限定します。 248 249 // 5.6.8.3 (2013/09/27) チェックタイプのautoを入れる位置変更 250 if( "AUTO".equals( checkType ) ) { checkType = command; } 251 252 // 6.4.3.2 (2016/02/19) ENTRY時にチェックする対象を、tableId指定のテーブルのカラムに限定します。 253 // 3.5.5.2 (2004/04/02) TaglibUtil.makeHTMLErrorTable メソッドを利用 254 final ErrorMessage errMsg = makeErrorDBTable(); 255 if( errMsg.getKekka() >= ErrorMessage.NG ) { 256 if( bodyString != null ) { jspPrint( bodyString ); } // 3.5.4.2 (2003/12/15) 257 258 // 4.3.3.0 (2008/10/01) 259 // 4.3.7.0 (2009/06/01) 260 if( isRealTime ) { jspPrint( TaglibUtil.makeHTMLSimpleErrorList( errMsg, getResource() ) ); } 261 else { jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg, getResource() ) ); } 262 263 if( CMD_NEW.equals( command ) ) { 264 removeObject( tableId ); 265 } 266 rtnCode = SKIP_PAGE ; 267 } 268 else if( errMsg.getKekka() == ErrorMessage.WARNING ) { 269 // 4.3.3.0 (2008/10/01) 270 // 4.3.7.0 (2009/06/01) 271 if( isRealTime ) { jspPrint( TaglibUtil.makeHTMLSimpleErrorList( errMsg, getResource() ) ); } 272 else { jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg, getResource() ) ); } 273 } 274 275 return rtnCode ; 276 } 277 278 /** 279 * タグリブオブジェクトをリリースします。 280 * 281 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 282 * 283 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加 284 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 285 * @og.rev 3.5.4.2 (2003/12/15) エラー時に、BODY部に記述された内容を出力する。 286 * @og.rev 3.5.4.3 (2004/01/05) tableId 属性を追加。 287 * @og.rev 3.8.0.9 (2005/10/17) mustAnyCheck 属性を追加。 288 * @og.rev 4.1.2.1 (2008/03/13) table 属性を追加。 289 * @og.rev 4.3.3.0 (2008/10/01) viewSimple属性追加 290 * @og.rev 4.3.7.0 (2009/06/01) viewSimple属性名称変更 ⇒ isRealTime 291 * @og.rev 5.2.2.0 (2010/11/01) NEWの場合に、厳密にチェックするフラグを追加 292 * @og.rev 5.4.3.4 (2012/01/12) isColumnLabelを追加 293 * @og.rev 6.4.3.2 (2016/02/19) ENTRY時にチェックする対象を、tableId指定のテーブルのカラムに限定します。 294 */ 295 @Override 296 protected void release2() { 297 super.release2(); 298 command = CMD_NEW; // 無指定時は、チェックを行う。 299 columns = null; 300 nullCheck = null; 301 maxRowCount = -1 ; // 初期値として,無制限を指定 302 minRowCount = -1 ; // 初期値として,無制限を指定 303 checkType = "AUTO"; 304 bodyString = null ; // 3.5.4.2 (2003/12/15) 305 tableId = HybsSystem.TBL_MDL_KEY; // 3.5.4.3 (2004/01/05) 306 mustAnyCheck= null; // 3.8.0.9 (2005/10/17) 307 matchKeys = null; // 4.0.0 (2005/11/30) 308 matchVals = null; // 4.0.0 (2005/11/30) 309 isRealTime = false; // 4.3.7.0 (2009/06/01) 310 isStrict = false; // 5.2.2.0 (2010/11/01) NEWの場合に、厳密にチェックするフラグを追加 311 isColumnLabel= false; // 5.4.3.4 (2012/01/12) true の場合に、カラムラベルを使用します。 312 checkNames = null; // 5.4.3.8 (2012/01/24) 313 } 314 315 /** 316 * DBColumn オブジェクトを作成して、DBColumn#valueCheck( String )で 317 * チェックを行う。その結果の、ErrorMessage オブジェクトを DBTableModel に 318 * 取り込んで、エラーの場合は、その表示を行う。 319 * 表示方法は、そのまま ViewForm オブジェクトを作成して、表示を行う。 320 * 321 * @og.rev 3.5.5.2 (2004/04/02) リターン値を、DBTableModel から ErrorMessage に変更 322 * @og.rev 4.0.0.0 (2005/01/31) リターン値の ErrorMessage は、必ず存在する。 323 * @og.rev 4.1.2.1 (2008/03/13) command="MODIFY" , "DELETE" 時には、強制的に、minRowCount="1" で処理します。 324 * @og.rev 5.6.8.3 (2013/09/27) checkTypeのAuto時設定位置をdoEndTagでするように変更 325 * 326 * @return エラーメッセージのテーブルモデル 327 * @og.rtnNotNull 328 */ 329 private ErrorMessage makeErrorDBTable() { 330 ErrorMessage errMsg = new ErrorMessage(); 331 332 //if( "AUTO".equals( checkType ) ) { checkType = command; } // 5.6.8.3 (2013/09/27) move 333 if( CMD_ENTRY.equals( checkType ) ) { 334 errMsg.setTitle( "Request Column Error!" ); 335 errMsg = makeEntryErrorMessage( errMsg ); 336 errMsg = makeMaxRowCountErrorMessage( errMsg ); 337 errMsg = makeMinRowCountErrorMessage( errMsg ); 338 } 339 else if( CMD_NEW.equals( checkType ) ) { 340 errMsg.setTitle( "Entry Column Error!" ); 341 errMsg = makeErrorMessage( errMsg ); 342 errMsg = makeMaxRowCountErrorMessage( errMsg ); 343 errMsg = makeMinRowCountErrorMessage( errMsg ); 344 } 345 else if( minRowCount >= 0 || maxRowCount >= 0) { // -1 は制限無し 346 errMsg.setTitle( "Row Count Error Limited Error!" ); 347 errMsg = makeMaxRowCountErrorMessage( errMsg ); 348 errMsg = makeMinRowCountErrorMessage( errMsg ); 349 } 350 // 4.1.2.1 (2008/03/13) command="MODIFY" , "DELETE" 時には、強制的に、minRowCount="1" で処理します。 351 // 6.3.9.0 (2015/11/06) 条件は効果がない(findbugs) 352 else if( "MODIFY,DELETE".indexOf( checkType ) >= 0 ) { 353 minRowCount = 1; 354 errMsg = makeMinRowCountErrorMessage( errMsg ); 355 } 356 return errMsg; 357 } 358 359 /** 360 * ErrorMessageをセットします。 361 * 引数のカラム名配列よりリクエスト情報を取得して、値をチェックします。 362 * DBColumn#valueCheck( String ) の結果のErrorMessageをすべて append 363 * していきます。 364 * 365 * @og.rev 3.8.0.9 (2005/10/17) 選択必須 mustAnyCheck のチェック追加 366 * @og.rev 3.8.1.0 (2005/10/24) リクエスト情報の正規化変換(DBColumn#valueSet(String))中止 367 * @og.rev 3.8.5.3 (2006/06/30) リクエストに % , _ が含まれたときは、削除します。 368 * @og.rev 4.1.2.1 (2008/03/13) must , mustAny の自動取得追加 369 * @og.rev 5.0.0.2 (2009/09/15) 個別にxssチェックをfalse 370 * @og.rev 5.1.9.0 (2010/08/01) 同じ名前の項目は、1つにまとめる(ラジオボタン等) 371 * @og.rev 5.2.0.0 (2010/09/01) リアルタイムチェックの場合は、must,mustAnyの自動チェックは行わない 372 * @og.rev 5.2.2.0 (2010/11/01) DBColumn#valueCheck で、甘いチェックを行うように、引数に isStrict を追加 373 * @og.rev 5.4.3.4 (2012/01/12) getLabel( String )を、リソースからに統一するとともに、isColumnLabel 対応を行う。 374 * @og.rev 5.4.3.8 (2012/01/28) checkNames対応 375 * @og.rev 6.4.0.2 (2015/12/11) ResourceManagerの取得を、先に行っておく。 376 * @og.rev 6.8.4.2 (2017/12/25) カラムチェックで、#valueSet(String) で、エラーが発生した場合でも、#valueCheck(String) を行うようにします。 377 * 378 * @param errMsg ErrorMessageオブジェクト 379 * 380 * @return カラムキー + 値 のエラーメッセージオブジェクト 381 */ 382 private ErrorMessage makeErrorMessage( final ErrorMessage errMsg ) { 383 384 // 4.1.2.1 (2008/03/13) must , mustAny の自動取得追加 385 // request から取出す 注意:mustAny 以外の自由形式の値は所得していません。 386 // 5.2.0.0 (2010/09/01) リアルタイムチェックの場合は、must,mustAnyの自動チェックは行わない 387 // (基本的にパラメーターを送らない限り自動チェックは動かないが、RequestCacheにより動くことがある) 388 if( !isRealTime ) { 389 if( nullCheck == null ) { 390 nullCheck = getRequestValues( HybsSystem.MUST_KEY + "must" ); 391 // 5.1.9.0 (2010/08/01) 同じ名前の項目は、1つにまとめる(ラジオボタン等) 392 if( nullCheck != null ) { 393 final Set<String> ss = new TreeSet<>(); 394 ss.addAll( Arrays.asList( nullCheck ) ); 395 nullCheck = ss.toArray( new String[ss.size()] ); // 5.1.9.0 (2010/08/01) K.H 396 } 397 } 398 if( mustAnyCheck == null ) { 399 final String[] mustAnyReq = getRequestValues( HybsSystem.MUST_KEY + "mustAny" ); 400 if( mustAnyReq != null && mustAnyReq.length > 0 ) { 401 mustAnyCheck = new String[] { StringUtil.array2line( mustAnyReq,"|" ) }; 402 } 403 } 404 } 405 406 // 6.4.0.2 (2015/12/11) ResourceManagerの取得を、先に行っておく。 407 final ResourceManager resource = getResource(); 408 409 if( nullCheck != null && nullCheck.length != 0 ) { 410 for( int i=0; i<nullCheck.length; i++ ) { 411 final String clmKey = nullCheck[i]; // 5.4.3.4 (2012/01/12) 412 // String val = getRequestValue( nullCheck[i] ); 413 final String val = getRequestValue( clmKey, false ); // 5.0.0.2 (2009/09/15) 414 if( val == null || val.isEmpty() ) { 415 // 5.4.3.4 (2012/01/12) isColumnLabel 追加 416 final String label = isColumnLabel ? getDBColumn( clmKey ).getLabel() : resource.getLabel( clmKey ); 417 // ERR0012 : 指定のデータがセットされていません。(NULLエラー)。key={0} 418 errMsg.addMessage( 0,ErrorMessage.NG,"ERR0012",label ); 419 } 420 } 421 } 422 // 3.8.0.9 (2005/10/17) 選択必須 mustAnyCheck のチェック追加 423 if( mustAnyCheck != null && mustAnyCheck.length != 0 ) { 424 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); // 6.1.0.0 (2014/12/26) refactoring 425 for( int i=0; i<mustAnyCheck.length; i++ ) { 426 boolean flag = false; 427 final String[] mustSub = StringUtil.csv2Array( mustAnyCheck[i],'|' ); 428 for( int j=0; j<mustSub.length; j++ ) { 429 // String val = getRequestValue( mustSub[j] ); 430 final String val = getRequestValue( mustSub[j], false ); // 5.0.0.2 (2009/09/15) 431 if( val != null && val.length() > 0 ) { 432 flag = true; break; // ひとつでもnullでなければ、OK 433 } 434 } 435 if( ! flag ) { 436 buf.setLength(0); // 6.1.0.0 (2014/12/26) refactoring 437 for( int j=0; j<mustSub.length; j++ ) { 438 final String clmKey = mustSub[j]; // 5.4.3.4 (2012/01/12) 439 // 5.4.3.4 (2012/01/12) isColumnLabel 追加 440 final String label = isColumnLabel ? getDBColumn( clmKey ).getLabel() : resource.getLabel( clmKey ); 441 buf.append( label ).append( ',' ); // 6.0.2.5 (2014/10/31) char を append する。 442 } 443 // ERR0036 : 選択必須エラー。以下のデータの内どれかは入力してください。key={0} 444 errMsg.addMessage( 0,ErrorMessage.NG,"ERR0036",buf.toString() ); 445 } 446 } 447 } 448 if( columns != null && columns.length != 0 ) { 449 for( int i=0; i<columns.length; i++ ) { 450 // 3.8.1.0 (2005/10/24) リクエスト情報の正規化変換(DBColumn#valueSet(String))中止 451 // String clmVal = getRequestValue( columns[i] ); 452 String clmVal = getRequestValue( columns[i], false ); // 5.0.0.2 (2009/09/15) 453 if( clmVal != null && clmVal.length() > 0 ) { 454 clmVal = StringUtil.replace( clmVal,"%","" ); // 3.8.5.3 (2006/06/30) 455 clmVal = StringUtil.replace( clmVal,"_","" ); // 3.8.5.3 (2006/06/30) 456 final DBColumn dbColumn = getDBColumn( columns[i] ); 457 // 5.4.3.8 (2012/01/24) checkNames対応 458 if( ( "," + checkNames + "," ).indexOf( "," + columns[i] + "," ) >= 0 ) { 459 // 6.8.4.2 (2017/12/25) カラムチェックで、#valueSet(String) で、エラーが発生した場合でも、#valueCheck(String) を行うようにします。 460 try { 461 final String val = dbColumn.valueSet( clmVal ); 462 if( val != null ) { clmVal = val; } 463 } 464 catch( RuntimeException ex ) { 465 // #valueSet(String) で、エラーが発生した場合でも、#valueCheck(String) を行うようにします。 466 } 467 } 468 // 5.2.2.0 (2010/11/01) DBColumn#valueCheck で、甘いチェックを行うように、引数に isStrict を追加 469 errMsg.append( dbColumn.valueCheck( clmVal,isStrict ) ); 470 } 471 } 472 } 473 // 4.0.0 (2005/11/30) 正規表現チェックの追加 474 if( matchKeys != null && matchKeys.length != 0 ) { 475 for( int i=0; i<matchKeys.length; i++ ) { 476 final String clmKey = matchKeys[i]; // 5.4.3.4 (2012/01/12) 477 // String val = getRequestValue( matchKeys[i] ); 478 final String val = getRequestValue( clmKey, false ); // 5.0.0.2 (2009/09/15) 479 if( val != null && ! val.matches( matchVals[i] ) ) { 480 // 5.4.3.4 (2012/01/12) isColumnLabel 追加 481 final String label = isColumnLabel ? getDBColumn( clmKey ).getLabel() : resource.getLabel( clmKey ); 482 // ERR0037 : データ整合性エラー。指定のキーは整合性チェックの結果マッチしませんでした。key={0} val={1} regex={2} 483 errMsg.addMessage( 0,ErrorMessage.NG,"ERR0037",label,val,matchVals[i] ); 484 } 485 } 486 } 487 488 return errMsg; 489 } 490 491 /** 492 * エントリーデータのErrorMessageをセットします。 493 * 引数のカラム名配列よりエントリーデータ形式のリクエスト情報を取得して、 494 * 値をチェックします。 495 * DBColumn#valueCheck( String ) の結果のErrorMessageをすべて append 496 * していきます。 497 * 498 * @og.rev 3.1.0.0 (2003/03/20) 名前と行番号の区切り記号を "^" から "__" に変更。 499 * @og.rev 3.5.5.0 (2004/03/12) 名前と行番号の区切り記号("__")を、HybsSystem.JOINT_STRING に変更。 500 * @og.rev 3.8.0.9 (2005/10/17) 選択必須 mustAnyCheck のチェック追加 501 * @og.rev 4.1.2.1 (2008/03/13) must , mustAny の自動取得追加 502 * @og.rev 4.3.6.4 (2009/05/01) 削除時に必ずmustAnyチェックエラーになるバグを修正(書込み可能行のみを処理する 503 * @og.rev 4.3.7.0 (2009/06/01) リアルタイムチェックの場合は、must,mustAnyの自動チェックは行わない 504 * @og.rev 5.0.0.2 (2009/09/15) xssチェック 505 * @og.rev 5.4.3.4 (2012/01/12) getLabel( String )を、リソースからに統一するとともに、isColumnLabel 対応を行う。 506 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 507 * @og.rev 6.4.0.2 (2015/12/11) ResourceManagerの取得を、先に行っておく。 508 * @og.rev 6.4.3.2 (2016/02/19) ENTRY時にチェックする対象を、tableId指定のテーブルのカラムに限定します。 509 * @og.rev 6.8.4.2 (2017/12/25) カラムチェックで、#valueSet(String) で、エラーが発生した場合でも、#valueCheck(String) を行うようにします。 510 * 511 * @param errMsg ErrorMessageオブジェクト 512 * 513 * @return カラムキー + 値 のエラーメッセージオブジェクト 514 */ 515 private ErrorMessage makeEntryErrorMessage( final ErrorMessage errMsg ) { 516 final int[] rowNo = getParameterRows(); 517 if( rowNo.length == 0 ) { return errMsg; } 518 519 // 6.4.3.2 (2016/02/19) ENTRY時にチェックする対象を、tableId指定のテーブルのカラムに限定します。 520 final DBTableModel table = (DBTableModel)getObject( tableId ); 521 if( table == null ) { 522 final String errMsgStr = "検索結果のオブジェクトが存在しません。" 523 + " checkType=[" + checkType + "] , tableId=[" + tableId + "]" ; 524 throw new HybsSystemException( errMsgStr ); 525 } 526 527 // 4.1.2.1 (2008/03/13) must , mustAny の自動取得追加 528 // table から取出す (ソート済み) 529 // 4.3.7.0 (2009/06/01) リアルタイムチェックの場合は、must,mustAnyの自動チェックは行わない 530 if( !isRealTime ) { 531 if( nullCheck == null ) { nullCheck = table.getMustArray(); } 532 if( mustAnyCheck == null ) { mustAnyCheck = table.getMustAnyArray(); } 533 } 534 535 // 3.8.0.9 (2005/10/17) 選択必須 mustAnyCheck のチェック追加 536 boolean[][] rowAnyOne = null; 537 // 4.3.6.4 (2009/05/01) 538 boolean[] rowForCheck = null; 539 if( mustAnyCheck != null && mustAnyCheck.length != 0 ) { 540 rowAnyOne = new boolean[rowNo.length][mustAnyCheck.length]; 541 rowForCheck = new boolean[rowNo.length]; 542 // for( int i=0; i<rowNo.length; i++ ) { 543 // Arrays.fill( rowAnyOne[i],false ); 544 // } 545 } 546 547 // 6.4.3.2 (2016/02/19) tableId 単位にチェックするが、互換性のため、標準の tableId の処理は、従来どおりとする。 548 final boolean useTid = ! HybsSystem.TBL_MDL_KEY.equals( tableId ); // 反転:tableId を使っている=標準のtableIdではない。 549 550 DBColumn dbColumn = null; // 5.4.3.4 (2012/01/12) isColumnLabel 対応 551 final Enumeration<?> enume = getParameterNames(); // 4.3.3.6 (2008/11/15) Generics警告対応 552 while( enume.hasMoreElements() ) { 553 final String key = (String)(enume.nextElement()); 554 final int idx = key.lastIndexOf(HybsSystem.JOINT_STRING); 555 556 if( idx > 0 ) { 557 final String column = key.substring(0,idx); 558 // 6.4.3.2 (2016/02/19) ENTRY時にチェックする対象を、tableId指定のテーブルのカラムに限定します。 559 final int clmNo = table.getColumnNo( column,false ); // エラーを出さない。 560 if( useTid && clmNo < 0 ) { continue; } // 6.4.3.2 (2016/02/19) tableId指定のテーブルのカラムに存在しない場合は、スルーする。 561 562 final int row = Integer.parseInt( key.substring(idx + 2) ); 563 final String val = getRequestValue( key, false ); // 5.0.0.2 (2009/09/15) 564 565 final int i = Arrays.binarySearch( rowNo,row ); 566 if( i >= 0 ) { 567 // 5.4.3.4 (2012/01/12) isColumnLabel 対応 568 // 6.4.3.2 (2016/02/19) tableはnullチェック済みで、clmNoは先に求めている。 569 dbColumn = isColumnLabel && clmNo >= 0 ? table.getDBColumn( clmNo ) : getDBColumn( column ); 570 571 // 6.8.4.2 (2017/12/25) カラムチェックで、#valueSet(String) で、エラーが発生した場合でも、#valueCheck(String) を行うようにします。 572 String val2 = val; 573 try { 574 val2 = dbColumn.valueSet( val ); 575 } 576 catch( RuntimeException ex ) { 577 // #valueSet(String) で、エラーが発生した場合でも、#valueCheck(String) を行うようにします。 578 } 579 580 errMsg.append( row+1,dbColumn.valueCheck( val2 ) ); 581 if( nullCheck != null && nullCheck.length != 0 ) { 582 final int j = Arrays.binarySearch( nullCheck,column ); 583 if( j>=0 && ( val2 == null || val2.isEmpty() )) { 584 // ERR0012 : 指定のデータがセットされていません。(NULLエラー)。key={0} 585 errMsg.addMessage( row+1,ErrorMessage.NG,"ERR0012",dbColumn.getLabel() ); 586 } 587 } 588 // 3.8.0.9 (2005/10/17) 選択必須 mustAnyCheck のチェック追加 589 if( rowAnyOne != null ) { 590 for( int j=0; j<mustAnyCheck.length; j++ ) { 591 if( !rowAnyOne[i][j] && 592 mustAnyCheck[j].indexOf( column ) >= 0 && 593 val2 != null && val2.length() > 0 ) { 594 rowAnyOne[i][j] = true; // どれかが存在 595 } 596 } 597 // 4.3.6.4 (2009/05/01) 598 rowForCheck[i] = true; 599 } 600 601 // 4.0.0 (2005/11/30) 正規表現チェックの追加 602 if( matchKeys != null && matchKeys.length != 0 ) { 603 for( int j=0; j<matchKeys.length; j++ ) { 604 if( column.equals( matchKeys[j] ) ) { 605 if( val2 != null && ! val2.matches( matchVals[j] ) ) { 606 // 互換性はなくなっているが、正規表現チェックは余り使っていないので、統一しておく。 607 // 5.4.3.4 (2012/01/12) isColumnLabel 対応 608 // 6.4.3.2 (2016/02/19) dbColumnは、先に、取得済み。 609 610 // ERR0037 : データ整合性エラー。指定のキーは整合性チェックの結果マッチしませんでした。key={0} val={1} regex={2} 611 errMsg.addMessage( row+1,ErrorMessage.NG,"ERR0037",dbColumn.getLabel(),val2,matchVals[i] ); 612 } 613 break; // 発見すれば、ループ終了 614 } 615 } 616 } 617 } 618 } 619 } 620 621 // 6.4.0.2 (2015/12/11) ResourceManagerの取得を、先に行っておく。 622 final ResourceManager resource = getResource(); 623 624 // 3.8.0.9 (2005/10/17) 選択必須 mustAnyCheck のチェック追加 625 if( rowAnyOne != null ) { 626 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); // 6.1.0.0 (2014/12/26) refactoring 627 for( int row=0; row<rowAnyOne.length; row++ ) { 628 // 4.3.6.4 (2009/05/01) 書込み可能行のみを処理する 629 if( rowForCheck[row] ) { 630 for( int i=0; i<mustAnyCheck.length; i++ ) { 631 if( !rowAnyOne[row][i] ) { 632 final String[] mustSub = StringUtil.csv2Array( mustAnyCheck[i], '|' ); 633 634 buf.setLength(0); // 6.1.0.0 (2014/12/26) refactoring 635 buf.append( "row=[" ).append( rowNo[row]+1 ).append( "] " ); 636 for( int j=0; j<mustSub.length; j++ ) { 637 // ここの処理だけ、他と異なるのは、互換性重視のため。(選択必須は利用頻度が高いので。) 638 // 5.4.3.4 (2012/01/12) isColumnLabel 対応 639 String label = null ; 640 if( isColumnLabel && table != null ) { 641 final int clmNo = table.getColumnNo( mustSub[j],false ); // エラーを出さない。 642 if( clmNo >= 0 ) { 643 dbColumn = table.getDBColumn( clmNo ); 644 } 645 if( dbColumn == null ) { 646 dbColumn = getDBColumn( mustSub[j] ); 647 } 648 label = dbColumn.getLabel(); 649 } 650 else { 651 label = resource.getLabel( mustSub[j] ); // 6.4.0.2 (2015/12/11) 互換性のための処置。 652 } 653 buf.append( label ).append( '|' ); // 6.0.2.5 (2014/10/31) char を append する。 654 } 655 // ERR0036 : 選択必須エラー。以下のデータの内どれかは入力してください。key={0} 656 errMsg.addMessage( rowNo[row]+1, ErrorMessage.NG, "ERR0036", buf.toString() ); 657 } 658 } 659 } 660 } 661 } 662 663 return errMsg; 664 } 665 666 /** 667 * ErrorMessageをセットします。 668 * リクエストされた件数の最大値に制限を加えます。 669 * 1件だけにしたい場合は,通常はViewでチェックボックスを使用せずに 670 * ラジオボタンを使用してください。 671 * 672 * @param errMsg ErrorMessageオブジェクト 673 * 674 * @return カラムキー + 値 のエラーメッセージオブジェクト 675 */ 676 private ErrorMessage makeMaxRowCountErrorMessage( final ErrorMessage errMsg ) { 677 if( maxRowCount < 0 ) { return errMsg; } // 無制限 678 679 // 件数制限のチェック 680 final int[] rowNo = getParameterRows(); 681 final int rowCount = rowNo.length ; 682 if( rowCount > maxRowCount ) { 683 // ERR0017 : 選択エラー。選択行数({0} 件)が、最大制限値({1} 件)以上選ばれました。 684 final String arg0 = String.valueOf( rowCount ); 685 final String arg1 = String.valueOf( maxRowCount ); 686 errMsg.addMessage( 0,ErrorMessage.NG,"ERR0017",arg0,arg1 ); 687 } 688 689 return errMsg; 690 } 691 692 /** 693 * ErrorMessageをセットします。 694 * リクエストされた件数の最小値に制限を加えます。 695 * 1件だけにしたい場合は,通常はViewでチェックボックスを使用せずに 696 * ラジオボタンを使用してください。 697 * 698 * @param errMsg ErrorMessageオブジェクト 699 * 700 * @return カラムキー + 値 のエラーメッセージオブジェクト 701 */ 702 private ErrorMessage makeMinRowCountErrorMessage( final ErrorMessage errMsg ) { 703 if( minRowCount < 0 ) { return errMsg; } // 無制限 704 705 // 件数制限のチェック 706 final int[] rowNo = getParameterRows(); 707 final int rowCount = rowNo.length ; 708 if( rowCount < minRowCount ) { 709 // ERR0018 : 選択エラー。選択行数({0} 件)が、最小制限値({1} 件)以下選ばれました。 710 final String arg0 = String.valueOf( rowCount ); 711 final String arg1 = String.valueOf( minRowCount ); 712 errMsg.addMessage( 0,ErrorMessage.NG,"ERR0018",arg0,arg1 ); 713 } 714 715 return errMsg; 716 } 717 718 /** 719 * 【TAG】チェックすべきカラム列をCSV形式(CSV形式)で指定します。 720 * 721 * @og.tag columns="AAA,BBB,CCC,DDD" 722 * 分解方法は、通常のパラメータ取得後に、CSV分解します。 723 * "*" を指定すると、command="NEW" のときの判定にすべてのリクエスト文字列を 724 * チェック対象とします。通常は、必要分だけ指定しますが、動的カラムなどの 725 * 場合は、カラム名を予め指定できないため、"*" で指定できるようにします。 726 * その場合、"h_" , "hX_" , maxRowCount , command , pageSize , pagePlus , debug , 727 * GAMENID , BACK_JSPID , BACK_GAMENID の予約語は、対象から除きます。 728 * 729 * ※ 6.4.0.2 (2015/12/11) 730 * columns="*" のときのカラムは、リクエスト変数から、上記の予約語も除きますが、 731 * ResourceManager に存在しない(リソース未登録)カラムも除きます。 732 * 733 * @og.rev 3.5.6.2 (2004/07/05) 先に配列に分解してからリクエスト変数の値を取得 734 * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。 735 * @og.rev 5.4.3.4 (2012/01/12) command="NEW" のときの動的カラム対応( "*" ですべてのリクエスト) 736 * @og.rev 6.4.0.2 (2015/12/11) columns="*" のときのカラムは、リソースに存在する分のみとする。 737 * 738 * @param clms カラム列(CSV形式) 739 */ 740 public void setColumns( final String clms ) { 741 columns = StringUtil.csv2Array( getRequestParameter( clms ) ); 742 if( columns.length == 0 ) { columns = null; } 743 744 // 5.4.3.4 (2012/01/12) command="NEW" のときの動的カラム対応( "*" ですべてのリクエスト) 745 if( columns != null && "*".equals( columns[0] ) ) { 746 final Set<String> clmSet = new TreeSet<>(); // リクエストはバラバラなので、とりあえずソートしておきます。 747 748 // 6.4.0.2 (2015/12/11) columns="*" のときのカラムは、リソースに存在する分のみとする。 749 final ResourceManager resource = getResource(); 750 751 final Enumeration<?> enume = getParameterNames(); // Generics警告対応 752 while( enume.hasMoreElements() ) { 753 final String clm = (String)(enume.nextElement()); 754 // 予約語以外を登録します。 755 if( clm != null && !clm.isEmpty() && !clm.startsWith( "h_" ) && !clm.startsWith( "hX_" ) ) { 756 // 6.4.0.2 (2015/12/11) columns="*" のときのカラムは、リソースに存在する分のみとする。 757 if( resource.getDBColumn( clm ) != null ) { // 存在チェックのみで使わない。 758 clmSet.add( clm ); 759 } 760 } 761 } 762 // 予約語を削除します。 763 clmSet.remove( "maxRowCount" ); 764 clmSet.remove( "command" ); 765 clmSet.remove( "pageSize" ); 766 clmSet.remove( "pagePlus" ); 767 clmSet.remove( "debug" ); // 6.4.0.2 (2015/12/11) 768 clmSet.remove( "GAMENID" ); 769 clmSet.remove( "BACK_JSPID" ); 770 clmSet.remove( "BACK_GAMENID" ); 771 772 columns = clmSet.toArray( new String[clmSet.size()] ); 773 } 774 } 775 776 /** 777 * 【TAG】NULL チェックすべきカラム列をCSV形式(CSV形式)で指定します。 778 * 779 * @og.tag 780 * (must 属性のセットにより、自動処理されます) 781 * nullCheck="AAA,BBB,CCC,DDD" 782 * 分解方法は、通常のパラメータ取得後に、CSV分解します。 783 * 784 * @og.rev 3.5.6.2 (2004/07/05) 先に配列に分解してからリクエスト変数の値を取得 785 * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。 786 * 787 * @param clms カラム列(CSV形式) 788 */ 789 public void setNullCheck( final String clms ) { 790 nullCheck = StringUtil.csv2Array( getRequestParameter( clms ) ); 791 if( nullCheck.length == 0 ) { nullCheck = null; } 792 else { 793 Arrays.sort( nullCheck ); 794 } 795 } 796 797 /** 798 * 【TAG】選択必須カラム(指定のカラムの内最低ひとつがNULLでない)を"AA|BB|CC,XX|YY|ZZ" 形式で指定します。 799 * 800 * @og.tag 801 * (mustAny 属性のセットにより、自動処理されます) 802 * 複数のカラム属性の値のうち、どれかが null でない場合は正常とし、 803 * すべてが null の場合を警告します。 804 * 805 * 例:mustAnyCheck="AA|BB|CC" 806 * AA,BB,CC のカラムで選択必須(すべてがnullならエラー) 807 * 例:mustAnyCheck="AA|BB|CC,XX|YY|ZZ" 808 * AA,BB,CC のセットと、XX,YY,ZZのセットでそれぞれ選択必須。 809 * 例:mustAnyCheck="AA|XX,AA|YY,AA|ZZ" 810 * AA に値があればすべて成立。そうでない場合は、XX と YY と ZZ がすべて必須。 811 * 例:mustAnyCheck="AA|BB,BB|CC,AA|CC" 812 * AA,BB,CC の内、どれか2つが必須。AAが成立すればBBかCCが必須。同様に、 813 * BBが成立すれば、AAかCCが必須。 814 * 815 * 選択必須は、must と同様に、色づけを行う(query.jsp)画面では、mustAny 属性を 816 * セットします。チェックを行う(result.jsp)画面では、columnCheck タグの 817 * mustAnyCheck 属性に、選択必須カラムを指定します。(上記参照) 818 * column タグ等の mustAny 属性に、mustAny="true" とセットすると、生成される 819 * HTMLは、class="mustAny" が出力されます。エンジン標準では、default.css に 820 * .mustAny が定義されています。( background-color: #CCFFFF; ) 821 * なお、mustAny 属性に、true 以外の値をセットした場合(mustAny="XYZ")は、 822 * 生成されるHTMLに、class="XYZ" が出力されます。これは、複数のグループ間で 823 * 色を変えて、選択必須を指定する場合に使用します。色は、custom/custom.css 824 * で指定します。 825 * 分解方法は、通常のパラメータ取得後に、CSV分解します。 826 * 827 * @og.rev 3.8.0.9 (2005/10/17) 新規追加 828 * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。 829 * 830 * @param clms 選択必須カラム 831 */ 832 public void setMustAnyCheck( final String clms ) { 833 mustAnyCheck = StringUtil.csv2Array( getRequestParameter( clms ) ); 834 if( mustAnyCheck.length == 0 ) { mustAnyCheck = null; } 835 else { 836 Arrays.sort( mustAnyCheck ); 837 } 838 } 839 840 /** 841 * 【TAG】コマンド[NEW/RENEW/ENTRY]をセットします(初期値:NEW)。 842 * 843 * @og.tag 844 * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される 845 * フィールド定数値のいづれかを、指定できます。 846 * 何も設定されない、または、null の場合は、"NEW" が初期値にセットされます。 847 * 848 * @param cmd コマンド (public static final 宣言されている文字列) 849 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ColumnCheckTag.CMD_NEW">コマンド定数</a> 850 */ 851 public void setCommand( final String cmd ) { 852 final String cmd2 = getRequestParameter( cmd ); 853 if( cmd2 != null && cmd2.length() > 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); } 854 } 855 856 /** 857 * 【TAG】 チェック対象のタイプ[AUTO/NEW/ENTRY]を指定します(初期値:AUTO)。 858 * 859 * @og.tag 860 * 通常のリクエストデータタイプは、キーそのものですが,エントリデータは表形式の 861 * データを一括で登録する為、(キー+"__" + 行番号)形式を、バラす必要があります。 862 * 863 * ENTRY は、DBTableModelのリクエスト情報をチェックします。 864 * これは、全データが対象になります。(columns/nullCheck 属性は無効) 865 * AUTO は、command が、上記 NEW か ENTRY かを判断して処理を振り分けます。 866 * 初期値は、AUTO です。 867 * 868 * @param flag チェックタイプ [AUTO/NEW/ENTRY] 869 */ 870 public void setCheckType( final String flag ) { 871 final String ct = getRequestParameter( flag ); 872 if( ct != null && ct.length() > 0 ) { checkType = ct ; } 873 } 874 875 /** 876 * 【TAG】チェックで選択された行数の最大値を設定します(初期値:-1 無制限)。 877 * 878 * @og.tag 879 * 制限をかけたい行数(この件数と同じ場合は正常)を指定します。 880 * 最大選択件数を超えた場合は,エラーメッセージを返します。 881 * 例えば、1件のみを正常とする場合は、maxRowCount="1" とします。 882 * 883 * @param count 最大件数 884 */ 885 public void setMaxRowCount( final String count ) { 886 maxRowCount = nval( getRequestParameter( count ),maxRowCount ); 887 } 888 889 /** 890 * 【TAG】チェックで選択された行数の最小値を設定します(初期値:-1 無制限)。 891 * 892 * @og.tag 893 * 最小選択件数を超えない場合は、エラーメッセージを返します。 894 * 例えば、1件のみを正常とする場合は、minRowCount="1" とします。 895 * 896 * @param count 制限をかけたい行数 (この件数と同じ場合は正常) 897 */ 898 public void setMinRowCount( final String count ) { 899 minRowCount = nval( getRequestParameter( count ), minRowCount ); 900 } 901 902 /** 903 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 904 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 905 * 906 * @og.tag 907 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 908 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 909 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 910 * この tableId 属性を利用して、メモリ空間を分けます。 911 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 912 * 913 * @og.rev 6.4.3.2 (2016/02/19) ENTRY時にチェックする対象を、tableId指定のテーブルのカラムに限定します。 914 * 915 * @param id テーブルID (sessionに登録する時のID) 916 */ 917 public void setTableId( final String id ) { 918 tableId = nval( getRequestParameter( id ),tableId ); 919 } 920 921 /** 922 * 【TAG】正規表現でのマッチングを行うカラム列をCSV形式(CSV形式)で指定します。 923 * 924 * @og.tag matchKeys="AAA,BBB,CCC,DDD" 925 * matchKeys属性とmatchVals属性の個数は、同じでなければなりません。 926 * 先に配列に分解してからリクエスト変数の値を取得するようにします。 927 * こうする事で、リクエストにCSV形式の値を設定できるようになります。 928 * 929 * @og.rev 4.0.0.0 (2005/11/30) 新規作成 930 * 931 * @param keys カラム列(CSV形式) 932 * @see #setMatchVals( String ) 933 */ 934 public void setMatchKeys( final String keys ) { 935 matchKeys = getCSVParameter( keys ); 936 937 if( matchVals != null && matchKeys.length != matchVals.length ) { 938 final String errMsg = "matchKeys属性とmatchVals属性の個数が合いません。" 939 + CR 940 + " matchKeys=[" + matchKeys.length + "]:KEYS=" 941 + StringUtil.array2csv( matchKeys ) + CR 942 + " matchVals=[" + matchVals.length + "]:VLAS=" 943 + StringUtil.array2csv( matchVals ) + CR ; 944 throw new HybsSystemException( errMsg ); 945 } 946 } 947 948 /** 949 * 【TAG】正規表現でのマッチングを行うカラム列に対する値(正規表現)をCSV形式(CSV形式)で指定します。 950 * 951 * @og.tag matchVals="AAA,BBB,CCC,DDD" 952 * matchKeys属性とmatchVals属性の個数は、同じでなければなりません。 953 * 先に配列に分解してからリクエスト変数の値を取得するようにします。 954 * こうする事で、リクエストにCSV形式の値を設定できるようになります。 955 * 956 * @og.rev 4.0.0.0 (2005/11/30) 新規作成 957 * 958 * @param vals カラム列に対する値(正規表現)(CSV形式) 959 * @see #setMatchKeys( String ) 960 */ 961 public void setMatchVals( final String vals ) { 962 matchVals = getCSVParameter( vals ); 963 964 if( matchKeys != null && matchKeys.length != matchVals.length ) { 965 final String errMsg = "matchKeys属性とmatchVals属性の個数が合いません。" 966 + CR 967 + " matchKeys=[" + matchKeys.length + "]:KEYS=" 968 + StringUtil.array2csv( matchKeys ) + CR 969 + " matchVals=[" + matchVals.length + "]:VLAS=" 970 + StringUtil.array2csv( matchVals ) + CR ; 971 throw new HybsSystemException( errMsg ); 972 } 973 } 974 975 /** 976 * 【TAG】(通常は使いません)リアルタイムチェックを行う場合に有効にします(初期値:false)。 977 * 978 * @og.tag 979 * リアルタイムチェックを行う場合に有効にする属性です。 980 * trueが指定された場合、通常のチェックと比較し、以下の差異があります。 981 * ①エラー結果を簡易フォーマットで出力します。 982 * (ViewFormType="HTMLSimpleErrorList"で表示されます。) 983 * この簡易フォーマットで出力した場合は、ラベル(短)の定義で出力され、 984 * カラム名やデータ等は出力されません。 985 * ②must,mustAny属性のチェックを行いません。 986 * 必須及び選択必須は、視覚的に判別できるため、リアルタイムチェックの 987 * 対象外とします。 988 * 989 * @og.rev 4.3.3.0 (2008/10/01) 新規作成 990 * @og.rev 4.3.7.0 (2009/06/01) viewSimple属性名称変更 ⇒ isRealTime 991 * 992 * @param flag リアルタイムチェック [true:する/false:しない] 993 */ 994 public void setRealTime( final String flag ) { 995 isRealTime = nval( getRequestParameter( flag ),isRealTime ); 996 } 997 998 /** 999 * 【TAG】NEWの場合に、厳密にチェックするかどうか[true/false]を指定します(初期値:false)。 1000 * 1001 * @og.tag 1002 * データをチェックするに当たり、あいまい検索などで厳密にチェックすると 1003 * エラーになるケースがあるため、command="NEW" のチェック時には、甘い目の 1004 * チェックを行っています。DBColumn#valueCheck( String , false ) 1005 * command="ENTRY" のチェックは、厳密なチェックです。 1006 * このフラグは、検索時でも、厳密なチェックを行いたい場合に、true をセットします。 1007 * 1008 * @og.rev 5.2.2.0 (2010/11/01) 新規作成 1009 * 1010 * @param flag 厳密チェックか [true:厳密/false:甘い] 1011 */ 1012 public void setUseStrict( final String flag ) { 1013 isStrict = nval( getRequestParameter( flag ),isStrict ); 1014 } 1015 1016 /** 1017 * 【TAG】カラムラベルを使用するかどうか[true/false]を指定します(初期値:false)。 1018 * 1019 * @og.tag 1020 * カラムラベルはラベルローダーを利用せずにアプリケーション側で 1021 * 追加したラベルをResourceManagerにキャッシュしている所から取り出す 1022 * かどうかを指定します。 1023 * カラムラベルに存在しない場合は、通常のラベルから検索します。 1024 * 1025 * @og.rev 5.4.3.4 (2012/01/12) 新規作成 1026 * 1027 * @param flag カラムラベル使用 [true:する/false:しない] 1028 */ 1029 public void setUseColumnLabel( final String flag ) { 1030 isColumnLabel = nval( getRequestParameter( flag ),isColumnLabel ); 1031 } 1032 1033 /** 1034 * 【TAG】リクエスト変数の正規化を行うカラムをCSV形式で複数指定します。 1035 * 1036 * @og.tag 1037 * カラムチェックで正規化が行われていないプラグインに対して強制的に正規化を行います。 1038 * この属性を利用したチェックを行った場合は、queryタグでPL/SQLを動作させる場合にも 1039 * 同名属性でカラムの指定を行う必要があります。 1040 * (queryタグでcheckNamesを利用しない場合はこの属性はnullにしてください) 1041 * この属性はチェックタイプがNEWの場合のみ有効です。 1042 * リアルタイムチェックでこの機能を利用したい場合は、columnTag等のoptionAttributes 1043 * 属性にrtOption='checkNames=VIEW_DATE'のように記述してください。 1044 * 1045 * @og.rev 5.4.3.8 (2012/01/24) 新規追加 1046 * @og.rev 5.4.4.0 (2012/02/01) コメント修正 1047 * @og.rev 5.6.9.4 (2013/10/31) 空白削除を行う 1048 * @og.rev 6.9.2.1 (2018/03/12) 使用箇所が、1箇所だけなので、StringUtilから移動する。 1049 * 1050 * @param nm 正規化を行うカラム(CSV形式) 1051 */ 1052 public void setCheckNames( final String nm ) { 1053// checkNames = StringUtil.deleteWhitespace( nval( getRequestParameter( nm ),checkNames ) ); // 5.6.9.4 (2013/10/31) 1054 final String tmpNm = nval( getRequestParameter( nm ),checkNames ); 1055 checkNames = StringUtil.isNull( tmpNm ) ? checkNames : tmpNm.replaceAll( "\\s", "" ); // 6.9.2.1 (2018/03/12) 1056 } 1057 1058 /** 1059 * このオブジェクトの文字列表現を返します。 1060 * 基本的にデバッグ目的に使用します。 1061 * 1062 * @return このクラスの文字列表現 1063 * @og.rtnNotNull 1064 */ 1065 @Override 1066 public String toString() { 1067 return ToString.title( this.getClass().getName() ) 1068 .println( "VERSION" ,VERSION ) 1069 .println( "tableId" ,tableId ) 1070 .println( "command" ,command ) 1071 .println( "columns" ,columns ) 1072 .println( "nullCheck" ,nullCheck ) 1073 .println( "mustAnyCheck" ,mustAnyCheck ) 1074 .println( "maxRowCount" ,maxRowCount ) 1075 .println( "minRowCount" ,minRowCount ) 1076 .println( "checkType" ,checkType ) 1077 .println( "matchKeys" ,matchKeys ) 1078 .println( "matchVals" ,matchVals ) 1079 .println( "realTime" ,isRealTime ) 1080 .println( "bodyString" ,StringUtil.htmlFilter( bodyString ) ) 1081 .println( "Other..." ,getAttributes().getAttribute() ) 1082 .fixForm().toString() ; 1083 } 1084}