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