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