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 org.opengion.hayabusa.common.HybsSystem; 019import org.opengion.hayabusa.db.DBColumn; 020import org.opengion.hayabusa.db.DBTableModel; 021import org.opengion.fukurou.model.ArrayDataModel; 022import org.opengion.fukurou.model.DataModel; // 8.2.1.0 (2022/07/15) 023import org.opengion.fukurou.model.Formatter; 024import org.opengion.fukurou.util.Attributes; 025import org.opengion.fukurou.util.ErrorMessage; 026import org.opengion.fukurou.util.ToString; // 6.1.1.0 (2015/01/17) 027import org.opengion.fukurou.util.StringUtil ; // 6.2.0.0 (2015/02/27) 028import org.opengion.fukurou.util.ArraySet; // 6.4.3.4 (2016/03/11) 029 030import static org.opengion.fukurou.util.StringUtil.nval ; 031 032import java.util.List; 033import java.util.ArrayList; 034import java.util.Enumeration; 035import java.util.Locale ; 036import java.util.Set; // 6.4.3.4 (2016/03/11) 037 038/** 039 * 検索結果の DBTableModelオブジェクトに値を設定するタグです。 040 * 041 * columnSet と共に使用する場合は、entryタグ の command属性と、columnSetタグ の command属性が 042 * 一致した場合のみ、処理されます。 043 * entryタグは、そのコマンドにより、DBTableModelオブジェクトの値を設定します。 044 * たとえば、command="INSERT" ならば、1行分のデータを選択された行番号の次に挿入します。 045 * また、追加、変更、削除された、DBTableModelオブジェクト でも、内部には元のデータを 046 * 持っているため、command="RESET" で元の状態に戻すことが可能です。 047 * 048 * @og.formSample 049 * ●形式: 050 * ・<og:entry command="…"> 051 * <og:columnSet command="…" /> 052 * </og:entry> 053 * ・<og:entry command="…" /> 054 * ・・・columnSetを使わない場合でもresult.jspから次画面(insert,modify,copy.jsp等)に 055 * にDBTableModelをもっていく場合には、必ず2を書いてください。 056 * (取消のとき、エンジン内でDBTableModelを操作するのに使用する為) 057 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します) 058 * 059 * ●Tag定義: 060 * <og:entry 061 * command ○【TAG】コマンド (INSERT/COPY/MODIFY/DELETE/ENTRY/CHANGE/RESET/ALLRESET/ALLACTION/RESETDATA/INSERTONE/REALDELETE/REQENTRY/RAWSET)を設定します(必須) 062 * scope 【TAG】キャッシュする場合のスコープ[request/page/session/application]を指定します(初期値:session) 063 * repeatCount 【TAG】指定の回数分だけ、繰り返し処理を行う回数を指定します(初期値:1) 064 * tableId 【TAG】(通常は使いません)sessionから所得する DBTableModelオブジェクトの ID 065 * useConsistency 【TAG】Consistency キー による整合性チェックを行うかどうかを指定します(初期値:true) 066 * selectedAll 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false) 067 * strictCheck 【TAG】(通常は使いません)カラムIDの存在チェックを行うかどうか[true/false]を指定します(初期値:true) 068 * noTransition 【TAG】(通常は使いません)画面遷移を行わない形式の登録方法を使用するかを指定します 069 * useSLabel 【TAG】7.0.7.0 (2019/12/13) エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false) 070 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 071 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 072 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない) 073 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない) 074 * caseIf 【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない) 075 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 076 * > ... Body ... 077 * </og:entry> 078 * 079 * ●使用例 080 * <og:entry command="{@command}" > 081 * <og:columnSet command="{@command}" columnId="ECNO" action="CLEAR" /> 082 * <og:columnSet command="{@command}" columnId="JYOKYO" action="SET" value="1" /> 083 * </og:entry> 084 * 085 * <og:entry command="MODIFY" rows="1" > 086 * <og:columnSet command="MODIFY" columnId="key" action="TBLSET" value="[key][lang]"/> 087 * </og:entry> 088 * 089 * action="ADD" は、DBTypeに依存した方法で、既存の値を、+1 します。 090 * <og:entry command="{@command}" repeatCount="5" > 091 * <og:columnSet command="{@command}" columnId="YKNO" action="ADD" /> 092 * </og:entry> 093 * 094 * action="ADD" は、DBTypeに依存した方法で、既存の値に、value の値を加算します。 095 * <og:entry command="{@command}" repeatCount="5" > 096 * <og:columnSet command="{@command}" columnId="YKNO" action="ADD" value="5" /> 097 * </og:entry> 098 * 099 * command属性 は、columnSetタグのcommand属性と同一の場合のみ、処理します。 100 * [command属性] 101 * INSERT 新規 102 * COPY 複写 103 * MODIFY 変更 104 * DELETE 削除 105 * ENTRY エントリー 106 * CHANGE チェンジ 107 * RESET リセット (RESET_ACTION_ALL_USE=true で、ALLRESET が呼ばれます) 108 * ALLRESET 全件リセット 109 * ALLACTION オールアクション 110 * RESETDATA リセットデータ 111 * INSERTONE 新規(1行のみ) 112 * REALDELETE 物理削除 113 * REQENTRY リクエスト変数設定 114 * RAWSET DBTableModelに直接セット 7.2.9.0 (2020/10/12) 115 * 116 * command属性 は、columnSetタグで指定します。 117 * [action属性] 118 * DEFAULT カラムリソースで定義した初期値をセットします。 119 * CLEAR 値をクリア(ゼロストリング "" )します。 120 * ADD 現在の値を +1 します。 0 ⇒ 1 , A ⇒ B , 9 ⇒ 10。value属性と併用すれば、指定の値を加算できます。 121 * SET value で設定した値を 新しい値として登録します。 122 * NULLSET 元の値が NULL の場合だけ、value で設定した新しい値を登録します。 123 * LOWER 小文字に変換します。 124 * UPPER 大文字に変換します。 125 * COPY value にコピー元のカラムIDをセットすれば、その値を代入します。 126 * TBLSET DBTableModel の内容を取り込んで指定の columnId カラムに設定します。[カラム名] で指定できます。 127 * また、これは文字列を解析して、 value を作成しますので,文字列連結等に使用できます。 128 * TBLNULLSET 元の値が NULL の場合だけ、TBLSETを実行します。 6.9.9.0 (2018/08/20) 追加 129 * WRTCTRL writableControl を使用したカラムデータの先頭アンダーバーを削除します。 130 * DBMENU DBMENUでパラメータ設定(コロン連結文字)を使用したカラムデータの先頭データのみにします。 131 * REQSET valueで指定したカラムの値をキーに、リクエスト変数から値を取出し、セットします。 132 * SEQSET valueの初期値を利用して、1レコードごとに、+1した値をセットします。 133 * PREFIX valueの値を後ろから検索し、指定のカラム値の前半部分を取得します(記号は含みません)。 134 * SUFIX valueの値を後ろから検索し、指定のカラム値の後半部分を取得します(記号は含みません)。 135 * その他 カラムのDBType の valueAction メソッドを呼び出します。自由に設定可能です。 136 * 137 * [strictCheck属性]は、カラムIDの存在チェックを行うかどうかを指定します(初期値:true) 138 * true カラムIDがDBTableModel に存在しない場合は、エラーになる。 139 * false カラムIDがDBTableModel に存在しない場合は、無視する。 140 * 141 * @og.group 画面登録 142 * 143 * @version 4.0 144 * @author Kazuhiko Hasegawa 145 * @since JDK5.0, 146 */ 147public class EntryTag extends CommonTagSupport { 148 /** このプログラムのVERSION文字列を設定します。 {@value} */ 149 private static final String VERSION = "7.2.9.0 (2020/10/12)" ; 150 private static final long serialVersionUID = 729020201012L ; 151 152 /** command 引数に渡す事の出来る コマンド 新規 {@value} */ 153 public static final String CMD_INSERT = "INSERT" ; 154 /** command 引数に渡す事の出来る コマンド 複写 {@value} */ 155 public static final String CMD_COPY = "COPY" ; 156 /** command 引数に渡す事の出来る コマンド 変更 {@value} */ 157 public static final String CMD_MODIFY = "MODIFY" ; 158 /** command 引数に渡す事の出来る コマンド 削除 {@value} */ 159 public static final String CMD_DELETE = "DELETE" ; 160 /** command 引数に渡す事の出来る コマンド エントリー {@value} */ 161 public static final String CMD_ENTRY = "ENTRY" ; 162 /** command 引数に渡す事の出来る コマンド チェンジ {@value} */ 163 public static final String CMD_CHANGE = "CHANGE" ; 164 /** command 引数に渡す事の出来る コマンド リセット {@value} */ 165 public static final String CMD_RESET = "RESET" ; 166 /** command 引数に渡す事の出来る コマンド 全件リセット {@value} */ 167 public static final String CMD_ALLRESET = "ALLRESET" ; // 3.5.6.3 (2004/07/12) 168 /** command 引数に渡す事の出来る コマンド オールアクション{@value} */ 169 public static final String CMD_ALLACTION = "ALLACTION" ; 170 /** command 引数に渡す事の出来る コマンド リセット(データのみ){@value} */ 171 public static final String CMD_RESETDATA = "RESETDATA" ; // 4.3.3.0 (2008/10/01) 172 /** command 引数に渡す事の出来る コマンド 追加(1行のみ){@value} */ 173 public static final String CMD_INSERTONE = "INSERTONE" ; // 5.1.5.0 (2010/04/01) 174 /** command 引数に渡す事の出来る コマンド 物理削除 {@value} */ 175 public static final String CMD_REALDELETE = "REALDELETE" ; // 5.1.6.0 (2010/05/01) 176 /** command 引数に渡す事の出来る コマンド リクエスト変数設定 {@value} */ 177 public static final String CMD_REQENTRY = "REQENTRY" ; // 5.6.1.2 (2013/02/22) 178 /** command 引数に渡す事の出来る コマンド DBTableModelに直接セット {@value} */ 179 public static final String CMD_RAWSET = "RAWSET" ; // 7.2.9.0 (2020/10/12) 180 // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。 181 182 private static final Set<String> COMMAND_SET = new ArraySet<>( 183 CMD_INSERT,CMD_COPY,CMD_MODIFY,CMD_DELETE,CMD_ENTRY,CMD_CHANGE,CMD_ALLACTION, 184 CMD_RESET,CMD_ALLRESET,CMD_RESETDATA,CMD_INSERTONE,CMD_REALDELETE,CMD_REQENTRY,CMD_RAWSET ); 185 186 /** action 引数に渡す事の出来る アクションコマンド 初期値:{@value} */ 187 public static final String ACT_DEFAULT = "DEFAULT" ; 188 /** action 引数に渡す事の出来る アクションコマンド クリア {@value} */ 189 public static final String ACT_CLEAR = "CLEAR" ; 190 /** action 引数に渡す事の出来る アクションコマンド +1 {@value} */ 191 public static final String ACT_ADD = "ADD" ; 192 /** action 引数に渡す事の出来る アクションコマンド 小文字化{@value} */ 193 public static final String ACT_LOWER = "LOWER" ; 194 /** action 引数に渡す事の出来る アクションコマンド 大文字化{@value} */ 195 public static final String ACT_UPPER = "UPPER" ; 196 /** action 引数に渡す事の出来る アクションコマンド コピー {@value} */ 197 public static final String ACT_COPY = "COPY" ; 198 /** action 引数に渡す事の出来る アクションコマンド セット {@value} */ 199 public static final String ACT_SET = "SET" ; 200 // 3.4.0.3 (2003/09/10) NULLSET Action を追加します。 201 /** action 引数に渡す事の出来る アクションコマンド NULLセット {@value} */ 202 public static final String ACT_NULLSET = "NULLSET" ; 203 /** action 引数に渡す事の出来る アクションコマンド テーブルセット {@value} */ 204 public static final String ACT_TBLSET = "TBLSET" ; 205 /** action 引数に渡す事の出来る アクションコマンド テーブルNULLセット {@value} */ 206 public static final String ACT_TBLNULLSET = "TBLNULLSET" ; // 6.9.9.0 (2018/08/20) 207 /** action 引数に渡す事の出来る アクションコマンド ライトコントロール {@value} */ 208 public static final String ACT_WRTCTRL = "WRTCTRL" ; // 3.8.1.5 (2006/03/30) 209 /** action 引数に渡す事の出来る アクションコマンド DBメニュー {@value} */ 210 public static final String ACT_DBMENU = "DBMENU" ; // 3.8.5.3 (2006/08/07) 211 /** action 引数に渡す事の出来る アクションコマンド リクエスト値セット {@value} */ 212 public static final String ACT_REQSET = "REQSET" ; // 5.4.2.1 (2011/12/09) 213 /** action 引数に渡す事の出来る アクションコマンド 連番値セット {@value} */ 214 public static final String ACT_SEQSET = "SEQSET" ; // 5.6.5.2 (2013/06/21) 215 /** action 引数に渡す事の出来る アクションコマンド PREFIX値セット {@value} */ 216 public static final String ACT_PREFIX = "PREFIX" ; // 5.6.6.1 (2013/07/12) 217 /** action 引数に渡す事の出来る アクションコマンド SUFIX値セット {@value} */ 218 public static final String ACT_SUFIX = "SUFIX" ; // 5.6.6.1 (2013/07/12) 219 220 // 3.5.6.0 (2004/06/18) すべてを protected から private に変更します。 221 private transient DBTableModel table ; 222 private transient List<Attributes> values ; // 6.3.9.0 (2015/11/06) transient 追加 223 224 private String tableId = HybsSystem.TBL_MDL_KEY; 225 private String command ; 226 private int[] rowNo ; 227 228 // 3.5.4.2 (2003/12/15) 指定の回数繰り返す機能を追加します。 229 private int repeatCount = 1; 230 231 // 3.5.5.7 (2004/05/10) Consistency キー による整合性チェックを行うかどうかを指定します。 232 // 6.9.5.0 (2018/04/23) USE_CONSISTENCY 廃止(true固定) 233// private boolean useConsistency = HybsSystem.sysBool( "USE_CONSISTENCY" ); 234 private boolean useConsistency = true; // 6.9.5.0 (2018/04/23) 235 236 // 3.8.1.1 (2005/11/21) 全件選択されたこととして、処理します。 237 private boolean selectedAll ; 238 239 // 3.5.6.4 (2004/07/16) RESET コマンドのデフォルト処理 に、ALLRESET を 240 // 使用するかどうかを指定します(初期値:false(使用しない))。 241 // 6.2.6.0 (2015/06/19) 初期値:true(使用する)にします。 242 private final boolean RESET_ACTION_ALL_USE = HybsSystem.sysBool( "RESET_ACTION_ALL_USE" ); 243 244 // 4.0.0 (2006/09/31) カラムIDの存在チェックを行うかどうかを指定します。 245 private boolean strictCheck = true; 246 247 private boolean noTransition; // 4.3.3.0 (2008/10/01) 追加 248 249 // 5.6.5.2 (2013/06/21) SEQSET アクションのカウンター 250 private int seqsetCnt ; 251 252 // 7.0.7.0 (2019/12/13) エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false) 253 private boolean useSLabel ; 254 255 /** 256 * デフォルトコンストラクター 257 * 258 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 259 */ 260 public EntryTag() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 261 262 /** 263 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 264 * 265 * @og.rev 5.1.9.0 (2010/08/01) 戻り値を、EVAL_BODY_INCLUDE → EVAL_BODY_BUFFERED に変更 266 * @og.rev 6.3.4.0 (2015/08/01) caseKey,caseVal,caseNN,caseNull,caseIf 属性対応 267 * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。 268 * 269 * @return 後続処理の指示 270 */ 271 @Override 272 public int doStartTag() { 273 // 6.3.4.0 (2015/08/01) useTag() の追加と、if条件の反転 274 // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method 275 return useTag() && check( command, COMMAND_SET ) ? EVAL_BODY_BUFFERED : SKIP_BODY; 276 } 277 278 /** 279 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 280 * 281 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 282 * @og.rev 3.5.5.5 (2004/04/23) 登録時の 整合性パラメータチェックを行います。 283 * @og.rev 3.5.5.6 (2004/04/27) JSP画面の作成不具合。ENTRY系で、command を投げた場合は、無視します。 284 * @og.rev 3.5.5.7 (2004/05/10) Consistency キー による整合性チェックを行うかどうかを指定します。 285 * @og.rev 3.5.5.8 (2004/05/20) Consistency キー による整合性チェックを checkConsistency() に集約します。 286 * @og.rev 3.6.0.8 (2004/11/19) DBTableModel をセーブする時に、トランザクションチェックを行います。 287 * @og.rev 4.3.3.0 (2008/10/01) noTransition 属性を追加します。 288 * @og.rev 4.3.8.0 (2009/08/01) noTransition値取得のメソッド名変更 289 * @og.rev 5.1.3.0 (2010/02/01) noTransitionのコントロールは、requestで行う。 290 * @og.rev 6.3.4.0 (2015/08/01) caseKey,caseVal,caseNN,caseNull,caseIf 属性対応 291 * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。 292 * 293 * @return 後続処理の指示 294 */ 295 @Override 296 public int doEndTag() { 297 debugPrint(); // 4.0.0 (2005/02/28) 298 if( !useTag() ) { return EVAL_PAGE ; } // 6.3.4.0 (2015/08/01) 299 300 // noTransition = isNoTransitionRequest() || noTransition; // 4.3.3.0 (2008/10/01) 追加 301 noTransition = isNoTransitionRequest(); // 5.1.3.0 (2010/02/01) 302 startQueryTransaction( tableId ); // 3.6.0.8 (2004/11/19) 303 table = (DBTableModel)getObject( tableId ); 304 if( table != null && check( command, COMMAND_SET ) ) { 305 if( ! checkConsistency() ) { return SKIP_PAGE ; } 306 if( rowNo == null ) { rowNo = getParameterRows(); } // 4.0.0 (2005/01/31) 307 308 commandExec( command ); 309 310 // 3.6.0.8 (2004/11/19) トランザクションチェックを行います。 311 if( ! commitTableObject( tableId, table ) ) { 312 jspPrint( "EntryTag Query処理が割り込まれました。DBTableModel は登録しません。" ); 313 return SKIP_PAGE; 314 } 315 } 316 317 return EVAL_PAGE ; 318 } 319 320 /** 321 * タグリブオブジェクトをリリースします。 322 * 323 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 324 * 325 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加 326 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 327 * @og.rev 3.5.4.2 (2003/12/15) 指定の回数繰り返す機能を追加します。 328 * @og.rev 3.5.5.7 (2004/05/10) Consistency キー による整合性チェックを行うかどうかを指定します。 329 * @og.rev 3.8.1.1 (2005/11/21) selectedAll 追加。全件選択されたこととして、処理します。 330 * @og.rev 4.0.0.0 (2006/09/31) strictCheck 追加。 331 * @og.rev 4.3.3.0 (2008/10/01) noTransition 属性を追加します。 332 * @og.rev 5.6.5.2 (2013/06/21) seqsetCnt 属性を追加します。 333 * @og.rev 6.9.5.0 (2018/04/23) USE_CONSISTENCY 廃止(true固定) 334 * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。 335 */ 336 @Override 337 protected void release2() { 338 super.release2(); 339 tableId = HybsSystem.TBL_MDL_KEY; 340 table = null; 341 command = null; 342 rowNo = null; 343 values = null; 344 repeatCount = 1; // 3.5.4.2 (2003/12/15) 345// useConsistency = HybsSystem.sysBool( "USE_CONSISTENCY" ); // 3.5.5.7 (2004/05/10) 346 useConsistency = true; // 6.9.5.0 (2018/04/23) true固定 347 selectedAll = false; // 3.8.1.1 (2005/11/21) 348 strictCheck = true; // 4.0.0 (2006/09/31) 349 noTransition = false; // 4.3.3.0 (2008/10/01) 追加 350 seqsetCnt = 0; // 5.6.5.2 (2013/06/21) SEQSET アクションのカウンター 351 useSLabel = false; // 7.0.7.0 (2019/12/13) エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false) 352 } 353 354 /** 355 * 内部タグの ColumnSetTag より、個々のカラムの値を書き換える為の属性を指定します。 356 * 357 * 複数の値を受け取って、後ほど、すべてのカラムに対して処理を行います。 358 * 359 * @og.rev 3.1.0.0 (2003/03/20) Vector を使用している箇所で、非同期でも構わない箇所を、ArrayList に置換え。 360 * @og.rev 3.1.2.0 (2003/04/07) taglib パッケージ内部で使用している箇所を protected 化する。 361 * 362 * @param attri 属性リスト 363 */ 364 protected void setAttributes( final Attributes attri ) { 365 if( values == null ) { values = new ArrayList<>(); } 366 if( command.equalsIgnoreCase( attri.get( "command" ) ) ) { 367 values.add( attri ); 368 } 369 } 370 371 /** 372 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 373 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 374 * 375 * @og.tag 376 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 377 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 378 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 379 * この tableId 属性を利用して、メモリ空間を分けます。 380 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 381 * 382 * @param id テーブルID (sessionに登録する時のID) 383 */ 384 public void setTableId( final String id ) { 385 tableId = nval( getRequestParameter( id ),tableId ); // 3.8.0.9 (2005/10/17) 386 } 387 388 /** 389 * 【TAG】コマンド (INSERT/COPY/MODIFY/DELETE/ENTRY/CHANGE/RESET/ALLRESET/ALLACTION/RESETDATA/INSERTONE/REALDELETE/REQENTRY/RAWSET)を設定します。 390 * 391 * @og.tag 392 * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される 393 * フィールド定数値のいづれかを、指定できます。 394 * 395 * @param cmd コマンド (public static final 宣言されている文字列) 396 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.EntryTag.CMD_INSERT">コマンド定数</a> 397 */ 398 public void setCommand( final String cmd ) { 399 final String cmd2 = getRequestParameter( cmd ); 400 if( cmd2 != null && cmd2.length() > 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); } 401 } 402 403 /** 404 * コマンドを実行します。 405 * 406 * コマンドは,HTMLから(get/post)指定されますので,setCommand()メソッドで 407 * 登録します。 408 * コマンドを登録すると同時に,実行も行ないます。 409 * 410 * @og.rev 3.5.6.3 (2004/07/12) ALLRESET コマンドを追加する。 411 * @og.rev 4.3.3.0 (2008/10/01) RESETDATA コマンドを追加する。 412 * @og.rev 5.1.5.0 (2010/04/01) INSERTONE コマンドを追加する。 413 * @og.rev 5.1.6.0 (2010/05/01) REALDELETE コマンドを追加する。 414 * @og.rev 5.6.1.2 (2013/02/22) REQENTRY コマンドを追加する。 415 * @og.rev 7.2.9.0 (2020/10/12) RAWSET コマンドを追加する。 416 * 417 * @param command コマンド (public static final 宣言されている文字列) 418 */ 419 private void commandExec( final String command ) { 420 421 table.setDefaultRowWritable( false ); 422 table.setDefaultRowChecked( false ); 423 424 if( CMD_INSERT.equals( command ) ) { insert() ; } 425 else if( CMD_COPY.equals( command ) ) { copy() ; } 426 else if( CMD_MODIFY.equals( command ) ) { modify() ; } 427 else if( CMD_CHANGE.equals( command ) ) { change() ; } 428 else if( CMD_DELETE.equals( command ) ) { delete() ; } 429 else if( CMD_ENTRY.equals( command ) ) { entry() ; } 430 else if( CMD_RESET.equals( command ) ) { 431 if( RESET_ACTION_ALL_USE ) { allReset() ; } // 3.5.6.4 (2004/07/16) 432 else { reset() ; } 433 } 434 else if( CMD_ALLRESET.equals( command ) ) { allReset() ; } // 3.5.6.3 (2004/07/12) 435 else if( CMD_ALLACTION.equals( command ) ) { allAction() ; } 436 else if( CMD_RESETDATA.equals( command ) ) { resetData() ; } // 4.3.3.0 (2008/10/01) 437 else if( CMD_INSERTONE.equals( command ) ) { insertOne() ; } // 5.1.5.0 (2010/04/01) 438 else if( CMD_REALDELETE.equals( command ) ) { realDelete() ; } // 5.1.6.0 (2010/05/01) 439 else if( CMD_REQENTRY.equals( command ) ) { reqEntry() ; } // 5.6.1.2 (2013/02/22) 440 else if( CMD_RAWSET.equals( command ) ) { rawSet() ; } // 7.2.9.0 (2020/10/12) 441 } 442 443 /** 444 * DBTableModelに行を追加します。 445 * 446 * 注意:writableカラムの暫定対応が入っています。単純な空白データを 447 * インサートすると、カラムデータが null になる為、 制御がおかしく 448 * なります。 449 * 450 * @og.rev 3.5.4.2 (2003/12/15) repeatCount による繰り返し処理を追加 451 * @og.rev 4.3.3.0 (2008/10/01) noTransition 属性対応 452 * 453 */ 454 private void insert() { 455 if( rowNo.length == 0 ) { rowNo = new int[] { -1 }; } 456 457 final boolean rowWritableFlag = "WRITABLE".equalsIgnoreCase( table.getColumnName( 0 ) ); // writable 対策 458 // src の作成は、各チェック毎に行う必要はない。最初の一度だけでよい。 459 String[] src = new String[ table.getColumnCount() ]; 460 for( int j=0; j<src.length; j++ ) { 461 final DBColumn dbColumn = table.getDBColumn( j ); 462 src[j] = dbColumn.getDefault(); 463 } 464 if( rowWritableFlag ) { src[0] = "true"; } // writable 対策 465 466 final int rowCount = table.getRowCount(); 467 468 // 逆順にINSERTしないと、行番号がずれてしまう。 469 for( int i=rowNo.length-1; i>=0; i-- ) { 470 int row = rowNo[i]; 471 for( int cnt=0; cnt<repeatCount; cnt++ ) { 472 if( cnt >= 1 ) { // 2回目以降 473 src = table.getValues( row ); 474 } 475 476 String[] dst = new String[ table.getColumnCount() ]; 477 System.arraycopy( src,0,dst,0,dst.length ); 478 dst = setColumnValues( dst ); 479 480 // 4.3.3.0 (2008/10/01) noTransition属性対応 481 if( noTransition ) { row = rowCount; } 482 else { row ++; } // 指定行の下に追加する。 483 table.addValues( dst,row ); 484 table.setRowWritable( row,true ); 485 table.setRowChecked( row,true ); 486 } 487 } 488 } 489 490 /** 491 * DBTableModelに行を追加し、チェックされた行の値をセットします。 492 * 493 * @og.rev 3.5.4.2 (2003/12/15) repeatCount による繰り返し処理を追加 494 * @og.rev 4.3.3.0 (2008/10/01) noTransition 属性対応 495 * 496 */ 497 private void copy() { 498 if( rowNo.length == 0 ) { insert() ; return ;} 499 500 final int rowCount = table.getRowCount(); 501 502 // 逆順にCOPYしないと、行番号がずれてしまう。 503 for( int i=rowNo.length-1; i>=0; i-- ) { 504 for( int cnt=0; cnt<repeatCount; cnt++ ) { 505 final String[] src = table.getValues( rowNo[i]+cnt ); 506 String[] dst = new String[ table.getColumnCount() ]; 507 System.arraycopy( src,0,dst,0,dst.length ); 508 dst = setColumnValues( dst ); 509 510 // 4.3.3.0 (2008/10/01) noTransition属性対応 511 int row = -1; 512 if( noTransition ) { row = rowCount; } 513 else { row = rowNo[i] + cnt + 1; } // 指定行の下に追加する。 514 515 table.addValues( dst,row ); 516 table.setRowWritable( row,true ); 517 table.setRowChecked( row,true ); 518 } 519 } 520 } 521 522 /** 523 * DBTableModelの行を書込み可とます。 524 * 525 * @og.rev 4.3.4.6 (2009/01/15) 画面遷移なし登録で既に改廃Cがセットされている場合は、columnSetタグの処理を行わない。 526 * 527 */ 528 private void modify() { 529 for( int i=0; i<rowNo.length; i++ ) { 530 final String[] src = table.getValues( rowNo[i] ); 531 String[] dst = new String[ table.getColumnCount() ]; 532 System.arraycopy( src,0,dst,0,dst.length ); 533 534 // 4.3.4.6 (2009/01/15) 535 // 画面遷移なし登録の場合、既に改廃Cが付いている(編集されている)場合は、 536 // columnSetによる値のセットを行わない。 537 // (同じコマンドで複数のボタンを割り当てている場合、複数回の変更・削除によって、先に登録された 538 // 値が削除されてしまうため。 539 if( !( noTransition && table.getModifyType( rowNo[i] ) != null && table.getModifyType( rowNo[i] ).length() > 0 ) ){ 540 dst = setColumnValues( dst ); 541 } 542 543 table.setValues( dst,rowNo[i] ); 544 table.setRowWritable( rowNo[i],true ); 545 table.setRowChecked( rowNo[i],true ); 546 } 547 } 548 549 /** 550 * DBTableModelの行を変更します。 551 552 * @og.rev 4.3.4.6 (2009/01/15) 画面遷移なし登録で既に改廃Cがセットされている場合は、columnSetタグの処理を行わない。 553 * 554 */ 555 private void change() { 556 for( int i=0; i<rowNo.length; i++ ) { 557 final String[] src = table.getValues( rowNo[i] ); 558 String[] dst = new String[ table.getColumnCount() ]; 559 System.arraycopy( src,0,dst,0,dst.length ); 560 561 // 4.3.4.6 (2009/01/15) 562 if( !( noTransition && table.getModifyType( rowNo[i] ) != null && table.getModifyType( rowNo[i] ).length() > 0 ) ){ 563 dst = setColumnValues( dst ); 564 } 565 566 table.setValues( dst,rowNo[i] ); 567 } 568 } 569 570 /** 571 * DBTableModelの行を削除します。 572 * 573 * @og.rev 3.5.4.2 (2003/12/15) DELETE時にも値の書き換えができるようにします。 574 * @og.rev 4.3.4.6 (2009/01/15) 画面遷移なし登録で既に改廃Cがセットされている場合は、columnSetタグの処理を行わない。 575 * 576 */ 577 private void delete() { 578 for( int i=0; i<rowNo.length; i++ ) { 579 // 3.5.4.2 (2003/12/15) 書き換え処理を追加 580 final String[] src = table.getValues( rowNo[i] ); 581 String[] dst = new String[ table.getColumnCount() ]; 582 System.arraycopy( src,0,dst,0,dst.length ); 583 584 // 4.3.4.6 (2009/01/15) 585 if( !( noTransition && table.getModifyType( rowNo[i] ) != null && table.getModifyType( rowNo[i] ).length() > 0 ) ){ 586 dst = setColumnValues( dst ); 587 } 588 589 table.rowDelete( dst,rowNo[i] ); 590 table.setRowWritable( rowNo[i],true ); 591 table.setRowChecked( rowNo[i],true ); 592 } 593 } 594 595 /** 596 * リクエスト情報から、セットされたカラム名と値を取り出し、設定します。 597 * 598 * 設定値は、個々のキー+"__" + 行番号 です。 599 * よって、値は,一つだけ設定されています。 600 * 601 * @og.rev 3.5.3.1 (2003/10/31) チェックボックスカラムを指定します。 602 * @og.rev 3.6.0.6 (2004/10/22) chboxNames 属性は廃止します。 603 * @og.rev 5.6.1.2 (2013/02/22) setRequestValuesメソッドの互換性の対応。 604 */ 605 private void entry() { 606 if( rowNo.length > 0 ) { 607 setRequestValues( false ); // 5.6.1.2 (2013/02/22) 互換性 608 for( int i=0; i<rowNo.length; i++ ) { 609 final String[] src = table.getValues( rowNo[i] ); 610 String[] dst = new String[ table.getColumnCount() ]; 611 System.arraycopy( src,0,dst,0,dst.length ); 612 dst = setColumnValues( dst ); 613 614 table.setValues( dst,rowNo[i] ); 615 table.setRowWritable( rowNo[i],true ); 616 table.setRowChecked( rowNo[i],true ); 617 } 618 } 619 } 620 621 /** 622 * リクエスト情報のテーブルモデルデータを、リセットします。 623 * 624 * @og.rev 5.6.5.2 (2013/06/21) 行ループを 0~最終行の 降順で廻します。 625 * @og.rev 6.9.3.1 (2018/04/02) RESET時に、must,mustAny属性をクリアします。 626 */ 627 private void reset() { 628 for( int i=rowNo.length-1; i>=0; i-- ) { 629 table.resetRow( rowNo[i] ); 630 } 631 table.addMustType( -1,"clear" ); // 6.9.3.1 (2018/04/02) RESET時に、must,mustAny属性をクリアします。 632 } 633 634 /** 635 * テーブルモデルデータを、全件リセットします。 636 * 637 * @og.rev 3.5.6.3 (2004/07/12) 新規作成 638 * @og.rev 5.6.5.2 (2013/06/21) 行ループを 0~最終行の 降順で廻します。 639 * @og.rev 6.2.6.0 (2015/06/19) 行ループを 0~最終行の 降順で廻してなかった。 640 * @og.rev 6.9.3.1 (2018/04/02) RESET時に、must,mustAny属性をクリアします。 641 */ 642 private void allReset() { 643 final int rowCount = table.getRowCount(); 644 for( int row=rowCount-1; row>=0; row-- ) { 645 table.resetRow( row ); 646 } 647 table.addMustType( -1,"clear" ); // 6.9.3.1 (2018/04/02) RESET時に、must,mustAny属性をクリアします。 648 } 649 650 /** 651 * DBTableModelの全ての行に対して,値をセットします。 652 * 653 * @og.rev 5.6.5.2 (2013/06/21) 行ループを 0~最終行の 降順で廻します。 654 * @og.rev 6.2.6.0 (2015/06/19) 行ループを 0~最終行の 降順で廻してなかった。 655 */ 656 private void allAction() { 657 final int rowCount = table.getRowCount(); 658 for( int row=rowCount-1; row>=0; row-- ) { 659 final String[] src = table.getValues( row ); 660 String[] dst = new String[ table.getColumnCount() ]; 661 System.arraycopy( src,0,dst,0,dst.length ); 662 dst = setColumnValues( dst ); 663 664 table.setValues( dst,row ); 665 table.setRowWritable( row,true ); 666 table.setRowChecked( row,true ); 667 } 668 } 669 670 /** 671 * リクエスト情報のテーブルモデルデータを、リセットします。 672 * (但し、リセットされた行は、チェックされた状態のままになります) 673 * 674 * @og.rev 4.3.3.0 (2008/10/01) 新規作成 675 * @og.rev 5.6.5.2 (2013/06/21) 行ループを 0~最終行の 降順で廻します。 676 * @og.rev 6.2.6.0 (2015/06/19) 行ループを 0~最終行の 降順で廻してなかった。 677 */ 678 private void resetData() { 679 for( int i=rowNo.length-1; i>=0; i-- ) { 680 final String cdkh = table.getModifyType( rowNo[i] ); 681 table.resetRow( rowNo[i] ); 682 // 更新又は、削除の時のみ書き込み可能になる。 683 if( DBTableModel.UPDATE_TYPE.equals( cdkh ) || DBTableModel.DELETE_TYPE.equals( cdkh ) ) { 684 table.setRowWritable( rowNo[i],true ); 685 table.setRowChecked( rowNo[i],true ); 686 } 687 } 688 } 689 690 /** 691 * DBTableModelに行を追加します。(1行のみ) 692 * 693 * 行が選択されているかどうかに関わらず、1行のみを追加します。 694 * (動きとしては、行が選択されていない状態でINSERTコマンドを発行した場合と同じです) 695 * 696 * @og.rev 5.1.5.0 (2010/04/01) 新規作成 697 * 698 */ 699 private void insertOne() { 700 rowNo = new int[0]; 701 insert(); 702 } 703 704 /** 705 * DBTableModelの行を物理削除します。 706 * 707 * 通常のデータベース等で削除する場合は、DELETE行も残しておかないと、どの行を削除するか 708 * 判らなくなります。また、アプリケーションによっては、削除ではなく、フラグだけを立てる 709 * ケースもあるため、現在の commend="DELETE" では、論理削除+値の書き換えも可能になっています。 710 * ここでの物理削除は、WriteTable など、ファイル出力時には、その行そのものをなくしておくほうが 711 * 良いケースがあるためです。 712 * 713 * @og.rev 5.1.6.0 (2010/05/01) REALDELETE コマンドを追加する。 714 */ 715 private void realDelete() { 716 // 逆順にしないと、行番号がずれてしまう。 717 for( int i=rowNo.length-1; i>=0; i-- ) { 718 table.removeValue( rowNo[i] ); 719 } 720 } 721 722 /** 723 * リクエスト情報から、セットされたカラム名と値を取り出し、設定します。 724 * 725 * 設定値は、個々のキー+"__" + 行番号 です。 726 * ENTRYコマンドとの違いは、h_rowSel と無関係に、リクエストされた変数すべてを 727 * 処理します。 728 * 729 * @og.rev 5.6.1.2 (2013/02/22) 新規追加 730 */ 731 private void reqEntry() { 732 setRequestValues( true ); // リクエストされた変数すべてを処理 733 final int rowCount = table.getRowCount(); 734 for( int row=0; row<rowCount; row++ ) { 735 final String[] src = table.getValues( row ); 736 String[] dst = new String[ table.getColumnCount() ]; 737 System.arraycopy( src,0,dst,0,dst.length ); 738 dst = setColumnValues( dst ); 739 740 table.setValues( dst,row ); 741 table.setRowWritable( row,true ); 742 table.setRowChecked( row,true ); 743 } 744 } 745 746 /** 747 * DBTableModelに直接データをセットします。 748 * 749 * 改廃コードは付きません。 750 * 751 * @og.rev 7.2.9.0 (2020/10/12) RAWSET コマンドを追加する。 752 */ 753 private void rawSet() { 754 if( rowNo.length > 0 ) { 755 setRequestValues( false ); // 5.6.1.2 (2013/02/22) 互換性 756 for( int i=0; i<rowNo.length; i++ ) { 757 final String[] src = table.getValues( rowNo[i] ); 758 setColumnValues( src ); 759 } 760 } 761 } 762 763 /** 764 * リクエスト情報から、セットされたカラム名と値を取り出し、設定します。 765 * 766 * 設定値は、個々のキー+"__" + 行番号 です。 767 * よって、値は,一つだけ設定されています。 768 * 引数のフラグは、選択行番号に関係なく、全件処理するかどうか[true:する/false:しない]を指定できます。 769 * 770 * @og.rev 3.1.0.0 (2003/03/20) 名前と行番号の区切り記号を "^" から "__" に変更。 771 * @og.rev 3.5.5.0 (2004/03/12) 名前と行番号の区切り記号("__")を、HybsSystem.JOINT_STRING に変更。 772 * @og.rev 3.6.0.6 (2004/10/22) chboxNames 属性は廃止します。 773 * @og.rev 3.8.0.1 (2005/06/17) チェックボックス対応で、エラーチェックをPL/SQLで行う場合の処理機能の追加 774 * @og.rev 3.8.0.2 (2005/07/11) チェックボックス対応で、判定を DBColumnのgetEditor()を使用します 775 * @og.rev 4.0.0.0 (2006/09/31) strictCheck 追加。 776 * @og.rev 4.3.7.3 (2009/06/22) HSQLDB対応でリクエストが空文字の場合はnull文字に変換する 777 * @og.rev 5.0.0.2 (2009/09/15) XSS対応(ALLはチェックしない) 778 * @og.rev 5.6.1.2 (2013/02/22) isAllRow 引数追加 779 * 780 * @param isAllRows 全件処理 [true:する/false:しない] 781 */ 782 private void setRequestValues( final boolean isAllRows ) { 783 final Enumeration<?> enume = getParameterNames(); // 4.3.3.6 (2008/11/15) Generics警告対応 784 785 while( enume.hasMoreElements() ) { 786 final String key = (String)(enume.nextElement()); 787 final int idx = key.lastIndexOf(HybsSystem.JOINT_STRING); 788 789 if( idx > 0 ) { 790 final String column = key.substring(0,idx); 791 final int clmNo = table.getColumnNo( column,strictCheck ); 792 if( clmNo < 0 ) { continue; } // strictCheck 対応 793 final DBColumn dbColumn = table.getDBColumn( clmNo ); 794 final int row = Integer.parseInt( key.substring(idx + 2) ); 795 // 5.0.0.2 (2009/09/15) 文字種別ALLはXSSチェックしない 796 // String val = dbColumn.valueSet( getRequestValue( key ) ); 797 String val = null; 798 if( "ALL".equals( dbColumn.getDbType() ) ){ 799 val = dbColumn.valueSet( getRequestValue( key, false ) ); 800 } 801 else{ 802 val = dbColumn.valueSet( getRequestValue( key ) ); 803 } 804 805 // 3.6.0.6 (2004/10/22) チェックボックスはマルチでデータが来ます。 806 // 3.8.0.2 (2005/07/11) 判定を DBColumnのgetEditor()を使用 807 if( "0".equals(val) && "CHBOX".equals( dbColumn.getEditor() ) ) { 808 final String[] vals = getRequestValues( key ); 809 if( vals != null ) { 810 for( int i=0; i<vals.length; i++ ) { 811 if( "1".equals( vals[i] ) ) { val = "1"; break; } 812 } 813 } 814 } 815 816 // 5.6.1.2 (2013/02/22) リクエスト変数すべてのデータを設定 817 if( isAllRows ) { 818 // 4.3.7.3 (2009/06/22) HSQLDB対応 819 if( val != null && val.isEmpty() ){ 820 val = null; 821 } 822 table.setValue(row, column, val ); 823 } 824 // 従来のロジック(チェックを外してSUBMITするケースを想定している。) 825 else { 826 // rowNo は、getParameterRows メソッドでソートされているので、 827 // java.util.Arrays#binarySearch(int[] a, int key) が使えるはず。 828 // 十分にテストしていないため、今は変更しない。 829 for( int i=0; i<rowNo.length; i++ ) { 830 if( rowNo[i] == row ) { 831 // 4.3.7.3 (2009/06/22) HSQLDB対応 832 if( val != null && val.isEmpty() ){ 833 val = null; 834 } 835 table.setValue(row, column, val ); 836 } 837 } 838 } 839 } 840 } 841 } 842 843 /** 844 * 変換タイプを考慮した変換処理を行います。 845 * 846 * 変換タイプ(#:ラベル $:レンデラー !:値そのもの)は、カラム名の先頭に付けます。 847 * 848 * @og.rev 7.2.9.0 (2020/10/12) type(#,$,!)を考慮した関数型I/F対応 849 * 850 * @param val 変換元の文字列 851 * @param type 変換タイプ(#:ラベル $:レンデラー !:値そのもの) 852 * @param prm ラベル変換時のパラメータ 853 * @param clmNo レンデラー作成時のカラム番号(DBColumnをDBTableModelから取得するのに使用する) 854 * 855 * @return 変更後の文字列 856 */ 857 private String getFormtVal( final String val, final char type, final String prm, final int clmNo ) { 858 final String rtn ; 859 switch( type ) { 860 case '#' : if( prm == null || prm.isEmpty() ) { rtn = getLabel( val ) ; } 861 else { rtn = getLabel( val + ' ' + prm ) ; } 862 break; 863 case '$' : final DBColumn dbColumn = table.getDBColumn( clmNo ); 864 rtn = dbColumn.getRendererValue( val ) ; 865 break; 866 case '!' : rtn = val ; break; 867 default : rtn = val ; break ; 868 } 869 return rtn ; 870 } 871 872 /** 873 * ColumnSetTag で指定された条件を元に、その行の値を書き換えます。 874 * 875 * @og.rev 3.6.0.6 (2004/10/22) conditionKey と、 conditionList 属性を追加 876 * @og.rev 3.8.1.5 (2006/03/30) writableControl を使用したカラムデータの先頭アンダーバーを削除します。 877 * @og.rev 4.0.0.0 (2006/09/31) strictCheck 追加。 878 * @og.rev 4.3.7.3 (2009/06/22) HSQLDB対応で空文字→NULL 879 * @og.rev 5.6.5.2 (2013/06/21) valueの初期値を利用して、1レコードごとに、+1した値をセットします。 880 * @og.rev 5.7.8.0 (2014/07/04) actionExec の引数を columnId ではなく、DBColumnオブジェクト に変更します。 881 * @og.rev 6.4.3.4 (2016/03/11) Formatterに新しいコンストラクターを追加する。 882 * @og.rev 6.9.9.0 (2018/08/20) action に、TBLNULLSETを追加。 883 * @og.rev 7.2.9.0 (2020/10/12) type(#,$,!)を考慮した関数型I/F対応 884 * 885 * @param val 指定行データ配列 886 * 887 * @return 変更後の指定行データ配列 888 */ 889 private String[] setColumnValues( final String[] val ) { 890 if( values != null ) { 891 final int size = values.size(); 892 for( int i=0; i<size; i++ ) { 893 final Attributes attri = values.get( i ); 894 final String columnId = attri.get( "columnId" ); 895 final int clmNo = table.getColumnNo( columnId,strictCheck ); 896 if( clmNo < 0 ) { continue; } // strictCheck 対応 897 final String action = attri.get( "action" ); 898 final String newVal = attri.get( "value" ); 899 final String oldVal = val[clmNo]; 900 901 // 3.6.0.6 (2004/10/22) 条件による処理の実行可否判定 902 final String conditionList = attri.get( "conditionList" ); 903 if( conditionList != null ) { // null の場合は、無条件実行 904 final String conditionKey = attri.get( "conditionKey" ); 905 final int condClmNo = table.getColumnNo( conditionKey ); 906 final String condValue = "|" + val[condClmNo] + "|"; 907 if( conditionList.indexOf( condValue ) < 0 ) { 908 continue; 909 } 910 } 911 912 if( ACT_COPY.equals( action ) ) { 913 final int copyClmNo = table.getColumnNo( newVal ); // newVal はコピー元カラム名 914 val[clmNo] = val[copyClmNo]; 915 } 916 else if( ACT_TBLSET.equals( action ) ) { 917// final ArrayDataModel model = new ArrayDataModel( table.getNames() ); 918 final DataModel<String> model = new ArrayDataModel( table.getNames() ); // 8.2.1.0 (2022/07/15) 919 model.setValues( val,0 ); 920 final Formatter format = new Formatter( model,newVal ); // 6.4.3.4 (2016/03/11) 921// val[clmNo] = format.getFormatString( 0 ); 922 val[clmNo] = format.getFormatString( 0,null,(vl,tp,pm) -> getFormtVal(vl,tp,pm,clmNo) ); // 7.2.9.0 (2020/10/12) 923 } 924 // 6.9.9.0 (2018/08/20) action に、TBLNULLSETを追加。 925 else if( ACT_TBLNULLSET.equals( action ) ) { 926 if( val[clmNo] == null || val[clmNo].isEmpty() ) { 927// final ArrayDataModel model = new ArrayDataModel( table.getNames() ); 928 final DataModel<String> model = new ArrayDataModel( table.getNames() ); // 8.2.1.0 (2022/07/15) 929 model.setValues( val,0 ); 930 final Formatter format = new Formatter( model,newVal ); // 6.4.3.4 (2016/03/11) 931// val[clmNo] = format.getFormatString( 0 ); 932 val[clmNo] = format.getFormatString( 0,null,(vl,tp,pm) -> getFormtVal(vl,tp,pm,clmNo) ); // 7.2.9.0 (2020/10/12) 933 } 934 } 935 // 3.8.1.5 (2006/03/30) writableControl を使用したカラムデータの先頭アンダーバーを削除します。 936 else if( ACT_WRTCTRL.equals( action ) ) { 937 if( StringUtil.startsChar( oldVal , '_' ) ) { // 6.2.0.0 (2015/02/27) 1文字 String.startsWith 938 val[clmNo] = oldVal.substring( 1 ); 939 } 940 } 941 // 3.8.5.3 (2006/08/07) DBMENUでパラメータ設定(コロン連結文字)を使用したカラムデータの先頭データのみにします。 942 else if( ACT_DBMENU.equals( action ) ) { 943 if( oldVal != null && oldVal.length() > 0 ) { 944 final int adrs = oldVal.indexOf( ':' ); 945 if( adrs >= 0 ) { 946 val[clmNo] = oldVal.substring( 0,adrs ); 947 } 948 } 949 } 950 // 5.4.2.1 (2011/12/09) valueで指定したカラムの値をキーに、リクエスト変数から値を取出し、セットします。 951 else if( ACT_REQSET.equals( action ) ) { 952 if( newVal != null && newVal.length() > 0 ) { 953 final int reqClmNo = table.getColumnNo( newVal ); // newVal はリクエスト取得元カラム名 954 String reqClm = val[reqClmNo]; // この時点では、コロン引数が付いている可能性がある。 955 956 final int adrs = reqClm.indexOf( ':' ); // 先頭がカラム名 957 if( adrs >= 0 ) { 958 reqClm = reqClm.substring( 0,adrs ); // コロンより前方の分だけ取り出す。 959 } 960 val[clmNo] = getRequestValue( reqClm ); 961 } 962 } 963 // 5.6.5.2 (2013/06/21) valueの初期値を利用して、1レコードごとに、+1した値をセットします。 964 else if( ACT_SEQSET.equals( action ) ) { 965 int intVal = seqsetCnt ; 966 if( newVal != null && newVal.length() > 0 ) { 967 intVal += Integer.parseInt( newVal ); // value の設定値 968 } 969 val[clmNo] = String.valueOf( intVal ); 970 } 971 else { 972 // 5.7.8.0 (2014/07/04) actionExec の引数を columnId ではなく、DBColumnオブジェクト に変更します。 973 final DBColumn dbClm = table.getDBColumn( clmNo ); 974 val[clmNo] = actionExec( action,dbClm,oldVal,newVal ); 975 } 976 977 // 4.3.7.3 (2009/06/22) HSQLDB対応 978 if( val[clmNo] != null && val[clmNo].isEmpty()){ 979 val[clmNo] = null; 980 } 981 } 982 } 983 seqsetCnt ++ ; // // 5.6.5.2 (2013/06/21) SEQSET のカウンター。 984 985 return val; 986 } 987 988 /** 989 * アクションを実行します。 990 * 991 * アクションは,指定のアクションコマンドに対応する処理を入力データに対して行います。 992 * 993 * @og.rev 3.4.0.3 (2003/09/10) NULLSET Action を追加します。 994 * @og.rev 5.6.0.3 (2012/01/24) ADD Action に、value引数の値を加算する機能を追加します。 995 * @og.rev 5.6.6.1 (2013/07/12) action に、PREFIX,SUFIX を追加します。 996 * @og.rev 5.7.8.0 (2014/07/04) columnId ではなく、DBColumnオブジェクト に変更します。 997 * 998 * @param action アクションコマンド 999 * @param dbColumn DBColumnオブジェクト 1000 * @param oldValue 入力データ(旧データ) 1001 * @param newValue 入力データ(新データ) 1002 * 1003 * @return 実行後のデータ 1004 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.EntryTag.ACT_DEFAULT">アクション定数</a> 1005 */ 1006 private String actionExec( final String action,final DBColumn dbColumn,final String oldValue,final String newValue ) { 1007 String rtnVal = oldValue; 1008 1009 if( ACT_DEFAULT.equals( action ) ) { rtnVal = dbColumn.getDefault(); } 1010 else if( ACT_CLEAR.equals( action ) ) { rtnVal = ""; } 1011 else if( ACT_SET.equals( action ) ) { rtnVal = dbColumn.valueSet( newValue ); } 1012 else if( ACT_ADD.equals( action ) ) { rtnVal = dbColumn.valueAdd( oldValue,newValue ); } // 5.6.0.3 (2012/01/24) 1013 else if( ACT_LOWER.equals( action ) ) { 1014 if( oldValue == null ) { rtnVal = dbColumn.getDefault(); } 1015 else { rtnVal = oldValue.toLowerCase(Locale.JAPAN); } 1016 } 1017 else if( ACT_UPPER.equals( action ) ) { 1018 if( oldValue == null ) { rtnVal = dbColumn.getDefault(); } 1019 else { rtnVal = oldValue.toUpperCase(Locale.JAPAN); } 1020 } 1021 // 3.4.0.3 (2003/09/10) NULLSET Action を追加します。 1022 else if( ACT_NULLSET.equals( action ) ) { 1023 if( oldValue == null || oldValue.isEmpty() ) { 1024 rtnVal = dbColumn.valueSet( newValue ); 1025 } 1026 } 1027 // 5.6.6.1 (2013/07/12) PREFIX Action を追加します。 1028 else if( ACT_PREFIX.equals( action ) ) { 1029 if( oldValue != null && oldValue.length() > 0 && newValue != null && newValue.length() > 0 ) { 1030 final int indx = oldValue.lastIndexOf( newValue ); 1031 if( indx >= 0 ) { 1032 rtnVal = oldValue.substring( 0,indx ); 1033 } 1034 } 1035 } 1036 // 5.6.6.1 (2013/07/12) SUFIX Action を追加します。 1037 else if( ACT_SUFIX.equals( action ) ) { 1038 if( oldValue != null && oldValue.length() > 0 && newValue != null && newValue.length() > 0 ) { 1039 final int indx = oldValue.lastIndexOf( newValue ); 1040 if( indx >= 0 ) { 1041 rtnVal = oldValue.substring( indx+1 ); // 分割記号は含まないので+1する。 1042 } 1043 } 1044 } 1045 else { 1046 rtnVal = dbColumn.valueAction( action,oldValue,newValue ); 1047 } 1048 1049 if( rtnVal == null ) { rtnVal = dbColumn.getDefault(); } 1050 1051 return rtnVal; 1052 } 1053 1054 /** 1055 * 【TAG】指定の回数分だけ、繰り返し処理を行う回数を指定します(初期値:1)。 1056 * 1057 * @og.tag 1058 * 追加や複写時に、指定の回数分だけ、処理を繰り返して、新規に行を 1059 * 作成します。 1060 * 繰り返しは、指定の行に対して行われ、繰り返し毎に、直前に作成された 1061 * 行を元に処理します。これは、例えば、columnSet で、action="ADD"の場合に、 1062 * 繰り返す毎に、ADD処理が実行されることを意味します。 1063 * 行が指定されていない場合は、先頭空行に追加します。 1064 * 初期値は、1回です。 1065 * 1066 * @og.rev 3.5.4.2 (2003/12/15) 新規追加 1067 * 1068 * @param rc 繰り返し処理回数(初期値:1) 1069 */ 1070 public void setRepeatCount( final String rc ) { 1071 repeatCount = nval( getRequestParameter( rc ),repeatCount ); 1072 } 1073 1074 /** 1075 * 【TAG】Consistency キー による整合性チェックを行うかどうか[true/false]を指定します(初期値:true)。 1076 * 1077 * @og.tag 1078 * 検索結果を DBTableModel にセットする時に、整合性キーの Consistency キーを 1079 * 作成します。これを、Viewタグでhidden出力しておき、Entryタグでデータ書き換え時に 1080 * 整合性チェックを行います。これは、IEの戻るボタンで戻った場合に、画面の 1081 * キーと検索結果の DBTableModel の内容が一致しない場合のエラーチェックに 1082 * なります。 1083 * この属性は、何らかのケースで、このエラーチェックを行いたくない場合に、 1084 * false に設定することで、整合性チェックを行いません。 1085 * 初期値は、true(整合性チェックを行う)です。 1086 * 1087 * @og.rev 3.5.5.7 (2004/05/10) 新規登録 1088 * 1089 * @param ck 整合性チェック [true:行う/false:行わない] 1090 */ 1091 public void setUseConsistency( final String ck ) { 1092 useConsistency = nval( getRequestParameter( ck ),useConsistency ); 1093 } 1094 1095 /** 1096 * DBTableModel の 整合性パラメータとリクエスト情報を比較チェックします。 1097 * リクエスト情報は、その DBTableModel が出力された view で hidden 属性で 1098 * 設定されます。 1099 * 設定されるキーは、tableId が変更されていなければ、HybsSystem.CONSISTENCY_KEY です。 1100 * 変更されていれば、HybsSystem.CONSISTENCY_KEY + tableId です。 1101 * 1102 * @og.rev 3.5.5.8 (2004/05/20) Consistency キー による整合性チェックを checkConsistency() に集約します。 1103 * @og.rev 6.4.2.1 (2016/02/05) useConsistency の判定条件を見直します。 1104 * @og.rev 6.9.8.0 (2018/05/28) consistencyKey に、tableId を考慮します。 1105 * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。 1106 * 1107 * @return チェック結果 true:正常/false:異常 1108 * @see org.opengion.hayabusa.common.HybsSystem#CONSISTENCY_KEY 1109 */ 1110 private boolean checkConsistency() { 1111 boolean rtn = true; 1112 1113 // 6.4.2.1 (2016/02/05) useConsistency の判定条件を、見直します。 1114 if( useConsistency ) { 1115 // 6.9.8.0 (2018/05/28) consistencyKey に、tableId を考慮します。 1116 final String name = HybsSystem.TBL_MDL_KEY.equals( tableId ) 1117 ? HybsSystem.CONSISTENCY_KEY 1118 : HybsSystem.CONSISTENCY_KEY + tableId ; 1119// final String consisKey = getRequestValue( HybsSystem.CONSISTENCY_KEY ); 1120 final String consisKey = getRequestValue( name ); // 6.9.8.0 (2018/05/28) 1121 if( consisKey != null && consisKey.length() > 0 ) { 1122 if( ! consisKey.equals( table.getConsistencyKey() ) ) { 1123 final ErrorMessage errMsgObj = new ErrorMessage( "Consistency Key Check Error!" ); 1124 errMsgObj.addMessage( 0,ErrorMessage.NG,"ERR0033.1" ); // 画面とデータの整合性チェックでエラーが出ました。 1125 errMsgObj.addMessage( 0,ErrorMessage.NG,"ERR0033.2" ); // すでにデータは更新されている為、その画面からは登録できません。 1126 errMsgObj.addMessage( 0,ErrorMessage.NG,"ERR0033.3" ); // ブラウザの戻るボタンで戻り、登録すると、このエラーが出ます。 1127// jspPrint( TaglibUtil.makeHTMLErrorTable( errMsgObj,getResource() ) ); 1128 jspPrint( TaglibUtil.makeHTMLErrorTable( errMsgObj,getResource(),useSLabel ) ); // 7.0.7.0 (2019/12/13) 1129 rtn = false; 1130 } 1131 } 1132 else { 1133 System.out.println( "EntryTag:Consistency Key is null" ); 1134 } 1135 } 1136 return rtn ; 1137 } 1138 1139 /** 1140 * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を処理の対象とします。 1141 * 1142 * @og.rev 3.8.1.1 (2005/11/21) selectedAll 追加。全件選択されたこととして、処理します。 1143 * @og.rev 4.0.0.0 (2005/01/31) getParameterRows() を使用するように変更 1144 * 1145 * @return 選択行の配列 1146 * @og.rtnNotNull 1147 */ 1148 @Override 1149 protected int[] getParameterRows() { 1150 final int[] rowNo ; 1151 if( selectedAll ) { 1152 final int rowCnt = table.getRowCount(); // 3.5.5.7 (2004/05/10) 1153 rowNo = new int[ rowCnt ]; 1154 for( int i=0; i<rowCnt; i++ ) { 1155 rowNo[i] = i; 1156 } 1157 } else { 1158 rowNo = super.getParameterRows(); // 4.0.0 (2005/01/31) 1159 } 1160 return rowNo ; 1161 } 1162 1163 /** 1164 * 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)。 1165 * 1166 * @og.tag 1167 * 全てのデータを選択済みデータとして扱って処理します。 1168 * 全件処理する場合に、(true/false)を指定します。 1169 * 初期値は false です。 1170 * 1171 * @param all 全件選択済み処理 [true:全件選択済み/false:通常] 1172 */ 1173 public void setSelectedAll( final String all ) { 1174 selectedAll = nval( getRequestParameter( all ),selectedAll ); 1175 } 1176 1177 /** 1178 * 【TAG】(通常は使いません)カラムIDの存在チェックを行うかどうか[true/false]を指定します(初期値:true)。 1179 * 1180 * @og.tag 1181 * true の場合、カラムIDがDBTableModel に存在しない場合は、エラーになります。 1182 * false の場合、カラムIDがDBTableModel に存在しない場合は、無視します。 1183 * これは、検索条件によって、設定されるカラムが異なる場合でも、entryタグを 1184 * 正常に動作させたい場合に、使用します。 1185 * 初期値は true (チェックを行う) です。 1186 * 1187 * @param check 存在チェック [true:行う/false:行わない] 1188 */ 1189 public void setStrictCheck( final String check ) { 1190 strictCheck = nval( getRequestParameter( check ),strictCheck ); 1191 } 1192 1193 /** 1194 * 【TAG】(通常は使いません)画面遷移を行わない形式の登録方法を使用するかを指定します。 1195 * 1196 * @og.tag 1197 * 画面遷移なしの登録を行うかどうかを指定します。 1198 * trueが指定された場合、entryタグでは、行の追加・複写時にDBTableModel上の最終行にデータを 1199 * 追加します。 1200 * 画面遷移なしモードの場合、途中行に挿入された場合、既にクライアントに出力されている 1201 * チェックボックスの行番号や各入力フィールドの変数名との整合性を合わせるためには、 1202 * 編集行以降の各変数値を全て再計算する必要があります。 1203 * この処理は、レスポンス悪化に繋がるため、DBTableModel上は、中間に行の挿入を行いません。 1204 * 但し画面表示上は、通常通り選択行の直下に行が挿入されるため、DBTableModelの順番と標準順が 1205 * 異なります。(エンジン側では、各チェックボックスの値で行を識別しているため、問題は発生しません) 1206 * 1207 * この値は、og:headタグで設定値、または前画面からの値を継承するため、通常、この属性ではセットしません。 1208 * 1209 * @og.rev 4.3.3.0 (2008/10/01) 新規追加 1210 * @og.rev 5.1.3.0 (2010/02/01) noTransition、ajaxSubmitのコントロールは、requestで行う。 1211 * 1212 * @param noTrnstn 画面遷移を行わない形式の登録方法を使用するか 1213 */ 1214 public void setNoTransition( final String noTrnstn ) { 1215 setNoTransitionRequest( nval( getRequestParameter( noTrnstn ), isNoTransitionRequest() ) ); 1216 } 1217 1218 /** 1219 * 【TAG】エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false)。 1220 * 1221 * @og.tag 1222 * 通常のエラーメッセージは、ラベル(長)が使われますが、これをラベル(短)を使いたい場合に、true にセットします。 1223 * ここでのラベル(短)は、タグ修飾なしの、ラベル(短)です。 1224 * 標準はfalse:利用しない=ラベル(長)です。 1225 * true/false以外を指定した場合はfalse扱いとします。 1226 * 1227 * ラベルリソースの概要説明があれば表示しますが、useSLabel="true" 時は、概要説明を表示しません。 1228 * 1229 * @og.rev 7.0.7.0 (2019/12/13) 新規追加 1230 * 1231 * @param prm SLABEL利用 [true:利用する/false:利用しない] 1232 */ 1233 public void setUseSLabel( final String prm ) { 1234 useSLabel = nval( getRequestParameter( prm ),useSLabel ); 1235 } 1236 1237 /** 1238 * このオブジェクトの文字列表現を返します。 1239 * 基本的にデバッグ目的に使用します。 1240 * 1241 * @return このクラスの文字列表現 1242 * @og.rtnNotNull 1243 */ 1244 @Override 1245 public String toString() { 1246 return ToString.title( this.getClass().getName() ) 1247 .println( "VERSION" ,VERSION ) 1248 .println( "tableId" ,tableId ) 1249 .println( "command" ,command ) 1250 .println( "rowNo" ,rowNo ) 1251 .println( "repeatCount" ,repeatCount ) 1252 .println( "useConsistency" ,useConsistency ) 1253 .println( "selectedAll" ,selectedAll ) 1254 .println( "strictCheck" ,strictCheck ) 1255 .println( "noTransition" ,noTransition ) 1256 .println( "RESET_ACTION_ALL_USE" ,RESET_ACTION_ALL_USE ) 1257 .println( "Other..." ,getAttributes().getAttribute() ) 1258 .fixForm().toString() ; 1259 } 1260}