    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.hayabusa.taglib;
    017
    018import java.util.ArrayList;
    019import java.util.List;
    020import java.util.Set;                                                                                   // 6.4.3.4 (2016/03/11)
    021import java.util.regex.Pattern;                                                                 // 7.0.1.8 (2019/01/28)
    022
    023import org.opengion.fukurou.util.ErrorMessage;
    024import org.opengion.fukurou.util.ToString;                                              // 6.1.1.0 (2015/01/17)
    025import org.opengion.fukurou.util.ArraySet;                                              // 6.4.3.4 (2016/03/11)
    026import org.opengion.hayabusa.common.HybsSystem;
    027import org.opengion.hayabusa.common.HybsSystemException;
    028import org.opengion.hayabusa.db.DBTableModel;
    029import org.opengion.hayabusa.db.Query;
    030import org.opengion.hayabusa.resource.GUIInfo;
    031
    032import static org.opengion.fukurou.util.StringUtil.nval;
    033import static org.opengion.fukurou.system.HybsConst.BR;                 // 6.1.0.0 (2014/12/26) refactoring
    034
    035/**
    036 * SQL文を直接指定して、データベースに追加/更新/削除を行います(queryType="JDBCTableUpdate")。
    037 *
    038 * 存在チェックを行う場合は、tableExist タグと併用してください。
    039 * 複雑な処理が必要な場合は、従来より使用しています、PLSQLをCALLする、
    040 * plsqlUpdateタグを使用してください。
    041 * また、tableUpdateParam タグを使用する事で、テーブル名とsqlTypeの指定で動的に
    042 * SQL文を自動生成できます。これにより、追加、更新、削除やテーブルに関して、
    043 * 単一のJSP画面ですべて対応できるようになります。
    044 *
    045 * 7.2.9.3 (2020/11/06)
    046 *   queryType="JDBCTableMerge" と、"JDBCTableUpdate" を相互運用します。
    047 *   tableUpdateParam ﾀｸﾞのsqlType="MERGE" を指定しておくと、
    048 *   UPDATE文とINSERT文を両方とも作成して、有れば更新なければ追加処理を行います。
    049 *   その場合、queryTypeを、JDBCTableMerge に変更します。
    050 *   sqlType が従来の"INSERT"や"UPDATE" の場合は、queryTypeを、JDBCTableUpdate
    051 *   に変更します。
    052 *   この変換は、"JDBCTableMerge" と、"JDBCTableUpdate" を相互運用します。
    053 *
    054 * ※ このタグは、Transaction タグの対象です。
    055 *
    056 * @og.formSample
    057 * ●形式：&lt;og:tableUpdate command="…" names="…" queryType="JDBCTableUpdate" &gt;
    058 *             {&#064;SQL}
    059 *         &lt;/og:update&gt;
    060 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    061 *
    062 * ●Tag定義：
    063 *   &lt;og:tableUpdate
    064 *       queryType          【TAG】Query を発行する為のクラスID(JDBCTableUpdate,JDBCTableMerge)を指定します({@og.doc03Link queryType 初期値:JDBCTableUpdate})
    065 *       sqlType            【TAG】BODY部に書かれている Param の SQLタイプを指定します(INSERT,COPY,UPDATE,MODIFY,DELETE,MERGE,無指定)
    066 *       command            【TAG】コマンド (NEW,RENEW)をセットします(PlsqlUpdateTag,UpdateTag の場合は、ENTRY)
    067 *       scope              【TAG】キャッシュする場合のスコープ[request/page/session/application]を指定します(初期値:session)
    068 *       displayMsg         【TAG】検索結果を画面上に表示するメッセージリソースIDを指定します (初期値:VIEW_DISPLAY_MSG[=])
    069 *       resourceType       【特殊】クリアするリソースの種類[GEA03/GEA04/GEA08]を指定します
    070 *       conditionKey       【TAG】条件判定するカラムＩＤを指定します(初期値:null)
    071 *       conditionList      【TAG】条件判定する値のリストを、"|"で区切って登録します(初期値:無条件) 7.0.1.8 (2019/01/28) 正規表現に変更
    072 *       tableId            【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
    073 *       dbid               【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します
    074 *       selectedAll        【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)
    075 *       commitTableModel   【特殊】SQL実行後に結果をDBTableModelに反映させるかどうか[true/false]を指定します(初期値:true)
    076 *       followCdkh         【TAG】DBTableModelの改廃Cに従って処理を行うかを指定します
    077 *       quotCheck          【TAG】リクエスト情報の シングルクォート(') 存在チェックを実施するかどうか[true/false]を設定します(初期値:false)
    078 *       useTimeView        【TAG】処理時間を表示する TimeView を表示するかどうかを指定します
    079 *                                                                              (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。
    080 *       useSLabel          【TAG】7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)
    081 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
    082 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
    083 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
    084 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
    085 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
    086 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    087 *   &gt;   ... Body ...
    088 *   &lt;/og:tableUpdate&gt;
    089 *
    090 * ●使用例
    091 *    ・QUERYを他のJSPから渡す場合
    092 *    【copy.jsp】
    093 *        &lt;og:hidden name=&quot;SQL&quot; &gt;
    094 *          INSERT INTO GE41
    095 *               (CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG,
    096 *               FGJ,DYSET,DYUPD,USRSET,USRUPD,PGUPD)
    097 *          VALUES
    098 *               ([CLM],[NAME_JA],[LABEL_NAME],[KBSAKU],[SYSTEM_ID],[LANG],
    099 *               &#39;1&#39;,&#39;{&#064;USER.YMDH}&#39;,&#39;{&#064;USER.YMDH}&#39;,&#39;{&#064;USER.ID}&#39;,&#39;{&#064;USER.ID}&#39;,&#39;{&#064;GUI.KEY}&#39;)
    100 *        &lt;/og:value&gt;
    101 *
    102 *    【entry.jsp】
    103 *        &lt;og:tableUpdate
    104 *            command   = &quot;{&#064;command}&quot;
    105 *            queryType = &quot;JDBCTableUpdate&quot;
    106 *        {&#064;SQL}
    107 *        &lt;/og:tableUpdate&gt;
    108 *
    109 *    ・tableUpdateParamを使用する場合
    110 *    【entry.jsp】
    111 *        &lt;og:tableUpdate
    112 *            command   = &quot;{&#064;command}&quot;
    113 *            queryType = &quot;JDBCTableUpdate&quot;
    114 *            sqlType   = &quot;{&#064;sqlType}&quot;        // tableUpdateParam の sqlType と一致
    115 *        &gt;
    116 *            &lt;og:tableUpdateParam
    117 *                sqlType     = &quot;{&#064;sqlType}"       // INSERT,COPY,UPDATE,MODIFY,DELETE,MERGE
    118 *                table       = &quot;{&#064;TABLE_NAME}"    // 処理対象のテーブル名
    119 *                names       = &quot;{&#064;names}"         // 処理対象のカラム名
    120 *                omitNames   = &quot;{&#064;omitNames}"     // 処理対象外のカラム名
    121 *                where       = &quot;{&#064;where}"         // 処理対象を特定するキー
    122 *                constKeys   = &quot;{&#064;constKeys}"     // 処理カラム名の中の固定情報カラム名
    123 *                constVals   = &quot;{&#064;constVals}"     // 処理カラム名の中の固定情報設定値
    124 *            /&gt;
    125 *        &lt;/og:tableUpdate&gt;
    126 *
    127 *    ・処理の可否を指定する場合
    128 *    【entry.jsp】
    129 *        &lt;og:tableUpdate
    130 *            command   = &quot;{&#064;command}&quot;
    131 *            queryType = &quot;JDBCTableUpdate&quot;
    132 *            conditionKey  ="…"      : 条件判定するカラムＩＤを指定(初期値は columnId )
    133 *            conditionList ="…"      : 条件判定する値のリストを、"|"で区切って登録(初期値は、無条件)
    134 *        {&#064;SQL}
    135 *        &lt;/og:tableUpdate&gt;
    136 *
    137 *    ・JDBCTableUpdate のまま、sqlType="MERGE" を指定する場合。
    138 *      一つのtableUpdateParamで、両方(UPDATE,INSERT)の処理を実行します。
    139 *    【entry.jsp】
    140 *        &lt;og:tableUpdate
    141 *            command   = "{&#064;command}"
    142 *            queryType = "JDBCTableUpdate"
    143 *            &lt;og:tableUpdateParam
    144 *                sqlType     = "MERGE"                // INSERT or UPDATE
    145 *                table       = "{&#064;TABLE_NAME}"    // 処理対象のテーブル名
    146 *                names       = "{&#064;names}"         // 処理対象のカラム名
    147 *                omitNames   = "{&#064;omitNames}"     // 処理対象外のカラム名
    148 *                where       = "{&#064;where}"         // 処理対象を特定するキー（INSERT時には使われず、UPDAET時に使われる。）
    149 *                constKeys   = "{&#064;constKeys}"     // 処理カラム名の中の固定情報カラム名
    150 *                constVals   = "{&#064;constVals}"     // 処理カラム名の中の固定情報設定値
    151 *            /&gt;
    152 *        &lt;/og:tableUpdate&gt;
    153 *
    154 * @og.rev 3.8.8.0 (2007/12/22) 新規作成
    155 * @og.group ＤＢ登録
    156 *
    157 * @version  4.0
    158 * @author   Kazuhiko Hasegawa
    159 * @since    JDK5.0,
    160 */
    161public class TableUpdateTag extends QueryTag {
    162        /** このプログラムのVERSION文字列を設定します。   {@value} */
    163        private static final String VERSION = "7.2.9.1 (2020/10/23)" ;
    164        private static final long serialVersionUID = 729120201023L ;
    165
    166        /** command 引数に渡す事の出来る コマンド  登録{@value} */
    167        public static final String CMD_ENTRY  = "ENTRY" ;
    168        // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    169        private static final Set<String> COMMAND_SET = new ArraySet<>( CMD_ENTRY );
    170
    171        // 処理を行う、リソースの種類を指定します。(GEA03,GEA04,GEA08 のどれか)
    172        private String  sqlType                 ;                       // INSERT,COPY,UPDATE,MODIFY,DELETE,MERGE
    173        private String  resourceType    ;
    174        private int             resTypeColNo    = -1;
    175        private String  conditionKey    ;                       // 条件判定するカラムＩＤを指定(初期値は columnId )
    176        private String  conditionList   ;                       // 条件判定する値のリストを、"|"で区切って登録(初期値は、無条件) 7.0.1.8 (2019/01/28) 正規表現に変更
    177        private boolean selectedAll             ;
    178        private boolean commitTableModel= true;         // 4.0.2.0 (2007/12/25)
    179        private boolean followCdkh              ;                       // 4.3.2.0 (2008/09/09).
    180        private boolean quotCheck               ;                       // 5.1.7.0 (2010/06/01) quotCheckを指定できるようにする。※但し、初期値はfalse固定。タイミングを見て修正要
    181
    182        /**
    183         * デフォルトコンストラクター
    184         *
    185         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    186         */
    187        public TableUpdateTag() { super(); }            // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    188
    189        /**
    190         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    191         *
    192         * @og.rev 4.0.0.0 (2007/11/14) 0件の場合でもstartQueryTransactionを通すように変更
    193         * @og.rev 5.1.7.0 (2010/06/01) quotCheckを指定できるようにする。※但し、初期値はfalse固定。
    194         * @og.rev 6.3.4.0 (2015/08/01) caseKey,caseVal,caseNN,caseNull,caseIf 属性対応
    195         *
    196         * @return      後続処理の指示( EVAL_BODY_BUFFERED )
    197         */
    198        @Override
    199        public int doStartTag() {
    200                if( !useTag() ) { return SKIP_BODY ; }  // 6.3.4.0 (2015/08/01)
    201                dyStart = System.currentTimeMillis();
    202
    203                table = (DBTableModel)getObject( tableId );
    204                startQueryTransaction( tableId );               // 4.0.0.0 (2007/11/14) 0件の場合でもdoEndでPAGE_SKIPしないように位置変更。
    205                if( table == null || table.getRowCount() == 0 ||
    206                        ! check( command, COMMAND_SET ) ) { return SKIP_BODY ; }
    207                super.quotCheck = quotCheck;
    208
    209                return EVAL_BODY_BUFFERED ;     // Body を評価する。( extends BodyTagSupport 時)
    210        }
    211
    212        /**
    213         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    214         *
    215         * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage ⇒ getResource().getLabel )
    216         * @og.rev 6.3.4.0 (2015/08/01) caseKey,caseVal,caseNN,caseNull,caseIf 属性対応
    217         * @og.rev 6.4.1.2 (2016/01/22) QueryTag.errMsgId  → QueryTag.ERR_MSG_ID  refactoring
    218         * @og.rev 6.9.9.0 (2018/08/20) ｢ERR0041:検索処理中に割り込みの検索要求がありました｣エラーを、標準のErrorMessageに追加するようにします。
    219         * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。
    220         *
    221         * @return      後続処理の指示
    222         */
    223        @Override
    224        public int doEndTag() {
    225                debugPrint();
    226                if( !useTag() ) { return EVAL_PAGE ; }  // 6.3.4.0 (2015/08/01)
    227
    228                String label  = "";                             // 4.0.0 (2005/11/30) 検索しなかった場合。
    229                if( check( command, COMMAND_SET ) ) {
    230                        final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    231                        if( executeCount > 0 && displayMsg != null && displayMsg.length() > 0 ) {
    232                                buf.append( executeCount )
    233                                        .append( getResource().getLabel( displayMsg ) )
    234                                        .append( BR );
    235                        }
    236
    237                        // 6.9.9.0 (2018/08/20) ｢ERR0041:検索処理中に割り込みの検索要求がありました｣エラーを、標準のErrorMessageに追加するようにします。
    238                        if( table != null && ! commitTableObject( tableId, table ) ) {
    239                                if( errMessage == null ) { errMessage = new ErrorMessage( "TableUpdateTag Query Error!" ); }
    240                                // ERR0041:検索処理中に割り込みの検索要求がありました。処理されません。
    241                                errMessage.addMessage( 0,ErrorMessage.NG,"ERR0041" );
    242                                errCode = ErrorMessage.NG;
    243                        }
    244
    245//                      final String err = TaglibUtil.makeHTMLErrorTable( errMessage,getResource() );
    246                        final String err = TaglibUtil.makeHTMLErrorTable( errMessage,getResource(),useSLabel );         // 7.0.7.0 (2019/12/13)
    247                        if( err != null && err.length() > 0 ) {
    248                                buf.append( err );
    249                                // 6.4.1.2 (2016/01/22) QueryTag.errMsgId  → QueryTag.ERR_MSG_ID  refactoring
    250                                setSessionAttribute( ERR_MSG_ID,errMessage );
    251                        }
    252                        else {
    253                                // 6.4.1.2 (2016/01/22) QueryTag.errMsgId  → QueryTag.ERR_MSG_ID  refactoring
    254                                removeSessionAttribute( ERR_MSG_ID );
    255                        }
    256                        label = buf.toString();
    257
    258//                      // 6.9.9.0 (2018/08/20) ｢ERR0041:検索処理中に割り込みの検索要求がありました｣エラーを、標準のErrorMessageに追加するようにします。
    259//                      if( table != null && ! commitTableObject( tableId, table )  ) {
    260//                              // 3.6.0.8 (2004/11/19) トランザクションチェックを行います。
    261//                              jspPrint( "TableUpdateTag Query処理が割り込まれました。DBTableModel は登録しません。" );
    262//                              return SKIP_PAGE ;
    263//                      }
    264                }
    265
    266                jspPrint( label );
    267
    268                // セキュリティチェック(データアクセス件数登録)
    269                final long dyTime = System.currentTimeMillis()-dyStart;
    270                final GUIInfo guiInfo = (GUIInfo)getSessionAttribute( HybsSystem.GUIINFO_KEY );
    271                if( guiInfo != null ) { guiInfo.addWriteCount( executeCount,dyTime,sql ); }
    272
    273                if( useTimeView ) {             // 6.3.6.0 (2015/08/16)
    274                        jspPrint( "<div id=\"queryTime\" value=\"" + (dyTime) + "\"></div>" );  // 3.5.6.3 (2004/07/12)
    275                }
    276                return errCode >= ErrorMessage.NG ? SKIP_PAGE : EVAL_PAGE ;
    277        }
    278
    279        /**
    280         * タグリブオブジェクトをリリースします。
    281         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    282         *
    283         * @og.rev 4.0.2.0 (2007/12/25) commitTableModel追加
    284         * @og.rev 4.1.2.0 (2008/03/12) sqlType追加
    285         * @og.rev 5.1.7.0 (2010/06/01) quotCheckを指定できるようにする。※但し、初期値はfalse固定。
    286         * @og.rev 7.2.9.1 (2020/10/23) TableUpdateParamTag のマージ(UPDATE,INSERT)対応
    287         */
    288        @Override
    289        protected void release2() {
    290                super.release2();
    291                sqlType                 = null;         // INSERT,COPY,UPDATE,MODIFY,DELETE,MERGE
    292                resourceType    = null;
    293                resTypeColNo    = -1;
    294                conditionKey    = null;         // 条件判定するカラムＩＤを指定(初期値は columnId )
    295                conditionList   = null;         // 条件判定する値のリストを、"|"で区切って登録(初期値は、無条件) 7.0.1.8 (2019/01/28) 正規表現に変更
    296                selectedAll             = false;
    297                commitTableModel= true;         // 4.0.2.0 (2007/12/25)
    298                followCdkh              = false;        // 4.3.2.0 (2008/09/09)
    299                quotCheck               = false;        // 5.1.7.0 (2010/06/01)
    300        }
    301
    302        /**
    303         * Query を実行します。
    304         *
    305         * @og.rev 4.0.2.0 (2007/12/25) commitTableModel追加
    306         * @og.rev 6.3.6.1 (2015/08/28) close(),realClose() 廃止。Queryはキャッシュしません。
    307         *
    308         * @param   query オブジェクト
    309         */
    310        @Override
    311        protected void execute( final Query query ) {
    312                final int[] rowNo = getParameterRows();         // 4.0.0 (2005/01/31)
    313                if( rowNo.length > 0 ) {
    314                        query.execute( rowNo,table );
    315
    316                        errCode = query.getErrorCode();
    317                        errMessage = query.getErrorMessage();
    318
    319                        // リソースクリア処理
    320                        if( resourceType != null ) {
    321                                resTypeColNo = table.getColumnNo( "CLM" );              // キーは、CLM
    322                        }
    323
    324                        // 逆順にDELETEしないと、行番号がずれてしまう。
    325                        int row;
    326                        for( int j=rowNo.length-1; j>=0; j-- ) {
    327                                row = rowNo[j];
    328                                if( resTypeColNo >= 0 ) {
    329                                        clearResourceData( table.getValue( row,resTypeColNo ) );                // リソースのクリア
    330                                }
    331
    332                                if( commitTableModel ) {        // 4.0.2.0 (2007/12/25)
    333                                        if( DBTableModel.DELETE_TYPE.equals( table.getModifyType( row ) ) ) {
    334                                                table.removeValue( row );
    335                                        }
    336                                        else {
    337                                                table.resetModify( row );
    338                                        }
    339                                }
    340                        }
    341                }
    342        }
    343
    344        /**
    345         * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行番号の
    346         * 配列を返します。
    347         * ここでは、conditionKey に値が設定されている場合は、そのカラムの値が
    348         * conditionList にマッチする場合のみ対象選択行として返します。
    349         * 値がセットされていない場合は、通常のCommonTagSupport#getParameterRows()
    350         * が呼ばれます。
    351         * なにも選ばれていない場合は、サイズ０の配列を返します。
    352         *
    353         * @og.rev 4.3.2.0 (2008/09/09) followCdkh属性対応
    354         * @og.rev 7.0.1.8 (2019/01/28) conditionListの判定を、正規表現に変更
    355         *
    356         * @return       (選ばれていない場合は、サイズ０の配列を返す)
    357         * @og.rtnNotNull
    358         */
    359        @Override
    360        protected int[] getParameterRows() {
    361                int[] rowNo ;
    362                if( selectedAll ) {
    363                        final int rowCnt = table.getRowCount();         // 3.5.5.7 (2004/05/10)
    364                        rowNo = new int[ rowCnt ];
    365                        for( int i=0; i<rowCnt; i++ ) {
    366                                rowNo[i] = i;
    367                        }
    368                } else {
    369                        rowNo = super.getParameterRows();               // 4.0.0 (2005/01/31)
    370                }
    371
    372                // 7.0.1.8 (2019/01/28) conditionListの判定を、正規表現に変更
    373                if( conditionKey != null && conditionList != null ) {                   // 7.0.1.8 (2019/01/28)
    374                        final int col = table.getColumnNo( conditionKey );
    375                        final List<Integer> list = new ArrayList<>();
    376                        final Pattern ptn = Pattern.compile( conditionList );           // 7.0.1.8 (2019/01/28)
    377                        for( int i=0; i<rowNo.length; i++ ) {
    378                                final String val = nval( table.getValue( rowNo[i],col ) , "" );         // 7.0.1.8 (2019/01/28)
    379                                if( ptn.matcher( val ).matches() ) {
    380                                        list.add( Integer.valueOf( rowNo[i] ) );
    381                                }
    382                        }
    383
    384                        final int size = list.size();
    385                        rowNo = new int[size];
    386                        for( int i=0; i<size; i++ ) {
    387                                rowNo[i] = list.get(i).intValue();
    388                        }
    389                }
    390
    391                // 4.3.2.0 (2008/09/09)
    392                if( sqlType != null && sqlType.length() > 0 && followCdkh ) {
    393                        final List<Integer> flist = new ArrayList<>();
    394                        for( int i=0; i<rowNo.length; i++ ) {
    395                                final String cdkh = table.getModifyType( rowNo[i] );
    396                                // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
    397                                if(     ( "INSERT".equals( sqlType ) || "COPY".equals(   sqlType ) )    && DBTableModel.INSERT_TYPE.equals( cdkh )
    398//                                      ||      ( "UPDATE".equals( sqlType ) || "CHANGE".equals( sqlType ) )    && DBTableModel.UPDATE_TYPE.equals( cdkh )              // 7.2.9.1 (2020/10/23) CHANGE ⇒ MODIFY
    399                                        ||      ( "UPDATE".equals( sqlType ) || "MODIFY".equals( sqlType ) )    && DBTableModel.UPDATE_TYPE.equals( cdkh )
    400                                        ||        "DELETE".equals( sqlType )                                                                    && DBTableModel.DELETE_TYPE.equals( cdkh ) ) {
    401                                                flist.add( Integer.valueOf( rowNo[i] ) );
    402                                }
    403                        }
    404
    405                        final int size = flist.size();
    406                        rowNo = new int[size];
    407                        for( int i=0; i<size; i++ ) {
    408                                rowNo[i] = flist.get(i).intValue();
    409                        }
    410                }
    411
    412                return rowNo;
    413        }
    414
    415//      /**
    416//       * BODY部の TableUpdateParamTag に書かれたquery文を受け取ります。
    417//       *
    418//       * typeには、UPDATEかINSERTが指定され、それに応じたqueryを各変数にセットします。
    419//       *
    420//       * @og.rev 7.2.9.1 (2020/10/23) TableUpdateParamTag のマージ(UPDATE,INSERT)対応
    421//       * @og.rev 7.2.9.3 (2020/11/06) QueryTag に移動
    422//       *
    423//       * @param       type    Queryタイプ(UPDATE,INSERT,その他)
    424//       * @param       query   SQL文
    425//       */
    426//      protected void setQuery( final String type , final String query ) {
    427//              sql = query;                                                                                                    // とりあえず、セットしておく
    428//              sqlCnt++ ;                                                                                                              // 0の場合はBODYから、1の場合はそのまま、それ以上の場合は、マージ処理。QueryTag のprotected属性
    429//
    430//              if( "UPDATE".equalsIgnoreCase( type ) ) {
    431//                      updQuery = query;                                                                                       // 上位の QueryTag のprotected属性
    432//              }
    433//              else if( "INSERT".equalsIgnoreCase( type ) ) {
    434//                      insQuery = query;                                                                                       // 上位の QueryTag のprotected属性
    435//              }
    436//      }
    437
    438        /**
    439         * 【TAG】Query を発行する為のクラスID(JDBCTableUpdate,JDBCTableMerge)を指定します({@og.doc03Link queryType 初期値:JDBCTableUpdate})。
    440         *
    441         * @og.tag
    442         * 引数指定のUPDATE,INSERT,DELETE文を実行する場合の、queryType 属性を使用します。
    443         * このタグでは、execute( int[] ,DBTableModel )を実行します。
    444         * 代表的なクラスとして、"JDBCTableUpdate" が標準で用意されています。
    445         *
    446         * タグにより使用できる／出来ないがありますが、これは、org.opengion.hayabusa.db
    447         * 以下の Query_**** クラスの **** を与えます。
    448         * これらは、Query インターフェースを継承したサブクラスです。
    449         * {@og.doc03Link queryType Query_**** クラス}
    450         *
    451         * @param       id Queryタイプ
    452         * @see         org.opengion.hayabusa.db.Query  Queryのサブクラス
    453         * @see         org.opengion.hayabusa.db.Query#execute( int[] ,DBTableModel )
    454         */
    455        @Override
    456        public void setQueryType( final String id ) {
    457                super.setQueryType( nval( id,"JDBCTableUpdate" ) );
    458        }
    459
    460        /**
    461         * resourceType が設定されたときのみ使用される、キャッシュの初期化メソッドです。
    462         *
    463         * @param       key     初期化を行うキー
    464         */
    465        private void clearResourceData( final String key ) {
    466                getResource().clear( key );
    467        }
    468
    469        /**
    470         * 【特殊】クリアするリソースの種類[GEA03/GEA04/GEA08]を指定します。
    471         *
    472         * @og.tag
    473         * 注意：この属性は、リソース関連DBのメンテナンス時にのみ、内部リソースキャッシュを
    474         * クリアする目的で使用します。一般の属性としては、使用することはないため、
    475         * ご注意ください。
    476         * リソース関連のテーブルを更新した場合、リソースキャッシュをクリアして
    477         * 置かないと、データベースの値が反映されません。
    478         * 昔は、リソースの更新ごとに、全件クリアしていましたが、部分クリアが
    479         * できるようになったため、部分クリアを行います。
    480         * こでは、(GEA03,GEA04,GEA08) のどれかを指定してください。
    481         *
    482         * @param       type    クリアリソースタイプ [GEA03/GEA04/GEA08]
    483         */
    484        public void setResourceType( final String type ) {
    485                resourceType = nval( getRequestParameter(type),resourceType );
    486
    487                if( resourceType != null &&
    488                        "|GEA03|GEA04|GEA08|".indexOf( "|" + resourceType + "|" ) < 0 ) {
    489                                final String errMsg = "resourceTypeは GEA03,GEA04,GEA08 のどれかです。"
    490                                                        + "resourceType=" + type ;
    491                                throw new HybsSystemException( errMsg );
    492                }
    493        }
    494
    495        /**
    496         * 【TAG】条件判定するカラムＩＤを指定します(初期値:null)。
    497         *
    498         * @og.tag
    499         * 指定のカラムＩＤの値と、conditionList の値を比較して、
    500         * 存在する場合は、Query 処理を実行します。
    501         * 例えば、conditionKey="CDKH" として、conditionList="A" とすれば、
    502         * 改廃コードが"A"のデータで、かつ選択されたデータのみを処理します。
    503         * 設定しない場合は、通常の処理と同様に、選択行のみ処理されます。
    504         *
    505         * @param       key 条件判定カラム
    506         * @see         #setConditionList( String )
    507         */
    508        public void setConditionKey( final String key ) {
    509                conditionKey = nval( getRequestParameter( key ),null ) ;
    510        }
    511
    512        /**
    513         * 【TAG】条件判定する値のリストを、"|"で区切って登録します(初期値:無条件)。
    514         *
    515         * @og.tag
    516         * conditionKey とペアで指定します。ここには、カラムの設定値のリストを
    517         * 指定することで、複数条件(ＯＲ結合)での比較を行い、リストにカラム値が
    518         * 存在する場合のみ、Query 処理を実行します。
    519         * 値が設定されている場合は、その値とマッチする必要があります。なにもセット
    520         * されない場合、または、null の場合は、null データとマッチする場合のみ処理
    521         * されますので、ご注意ください。
    522         *
    523         * @og.rev 7.0.1.8 (2019/01/28) conditionListの判定を、正規表現に変更
    524         *
    525         * @param       list    条件判定値 ("|"区切のリスト)
    526         * @see         #setConditionKey( String )
    527         */
    528        public void setConditionList( final String list ) {
    529//              conditionList = "|" + nval( getRequestParameter( list ),"" ) + "|" ;
    530                conditionList = nval( getRequestParameter( list ),"" ) ;
    531        }
    532
    533        /**
    534         * 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)。
    535         *
    536         * @og.tag
    537         * 全てのデータを選択済みデータとして扱って処理します。
    538         * 全件処理する場合に、(true/false)を指定します。
    539         * 初期値は false です。
    540         *
    541         * @param  all データを全件選択済み [true:全件選択済み/false:通常]
    542         */
    543        public void setSelectedAll( final String all ) {
    544                selectedAll = nval( getRequestParameter( all ),selectedAll );
    545        }
    546
    547        /**
    548         * 【特殊】SQL実行後に結果をDBTableModelに反映させるかどうか[true/false]を指定します(初期値:true)。
    549         *
    550         * @og.tag
    551         * 注意：この属性は、リソース関連DBのメンテナンス時に、複数DBへの登録を行うための、
    552         * 暫定対応として定義しています。
    553         * falseにした場合は、実データとDBTableModelの整合性が取れなくなるため、使用には十分注して下さい。
    554         * 初期値は true です。
    555         *
    556         * @og.rev 4.0.2.0 (2007/12/25) 新規作成
    557         *
    558         * @param  commitTblMdl 反映有無 [true:反映する/false:反映しない]
    559         */
    560        public void setCommitTableModel( final String commitTblMdl ) {
    561                commitTableModel = nval( getRequestParameter( commitTblMdl ),commitTableModel );
    562        }
    563
    564        /**
    565         * 引数の名称配列。
    566         *
    567         * @return      名称配列
    568         */
    569        protected String[] getNames() {
    570                return table.getNames() ;
    571        }
    572
    573        /**
    574         * 【TAG】BODY部に書かれている Param の SQLタイプを指定します。
    575         *
    576         * @og.tag
    577         * TableUpdateParamTag は、上位の TableUpdateTag の sqlType 属性 と同じ
    578         * sqlType 属性の場合のみ、SQL文を合成・出力します。
    579         * つまり、TableUpdateTag側のsqlType 属性をパラメータに、TableUpdateParamTag
    580         * の sqlType 属性を固定値にすることで、どのパラメータを使用するかを
    581         * 選択できる機能を実現する事が可能です。
    582         *
    583         * 7.2.9.3 (2020/11/06)
    584         *   複数指定できるようにします。
    585         *
    586         * @og.rev 4.1.2.0 (2008/03/12) 新規追加
    587         *
    588         * @param       type SQLタイプ
    589         */
    590        public void setSqlType( final String type ) {
    591                sqlType = nval( getRequestParameter( type ),sqlType );
    592        }
    593
    594        /**
    595         * 【TAG】DBTableModelの改廃Cに従って処理を行うかを指定します。
    596         *
    597         * @og.tag
    598         * この属性は、sqlTypeが指定されている場合のみ有効です。
    599         * sqlTypeが指定されている場合、そのsqlTypeに対応した、改廃Cが設定されている
    600         * 行のみを処理します。
    601         * 対応関係は、以下の通りです。
    602         *  sqlType = "INSERT" or "COPY" ⇒ 改廃C='A'のみ処理
    603//       *  sqlType = "UPDATE" or "CHANGE" ⇒ 改廃C='C'のみ処理
    604         *  sqlType = "UPDATE" or "MODIFY" ⇒ 改廃C='C'のみ処理
    605         *  sqlType = "DELETE" ⇒ 改廃C='D'のみ処理
    606         *
    607         * @og.rev 4.3.2.0 (2008/09/09) 新規追加
    608         *
    609         * @param       flag 改廃C処理 [true:行う/false:行わない]
    610         */
    611        public void setFollowCdkh( final String flag ) {
    612                followCdkh = nval( getRequestParameter( flag ),followCdkh );
    613        }
    614
    615        /**
    616         * 【TAG】リクエスト情報の シングルクォート(') 存在チェックを実施するかどうか[true/false]を設定します(初期値:false)。
    617         *
    618         * @og.tag
    619         * ＳＱＬインジェクション対策の一つとして、暫定的ではありますが、SQLのパラメータに
    620         * 渡す文字列にシングルクォート(') を許さない設定にすれば、ある程度は防止できます。
    621         * 数字タイプの引数には、 or 5=5 などのシングルクォートを使用しないコードを埋めても、
    622         * 数字チェックで検出可能です。文字タイプの場合は、必ず (')をはずして、
    623         * ' or 'A' like 'A のような形式になる為、(')チェックだけでも有効です。
    624         * (') が含まれていたエラーにする(true)／かノーチェックか(false)を指定します。
    625         * ※(他のタグは、システムリソースのUSE_SQL_INJECTION_CHECK[={@og.value SystemData#USE_SQL_INJECTION_CHECK}])
    626         * ですが、JSPの互換性を考慮し、初期値を固定でfalseにしています)
    627         *
    628         * @og.rev 5.1.7.0 (2010/06/01) 新規追加
    629         *
    630         * @param   flag クォートチェック [true:する/それ以外:しない]
    631         */
    632        @Override
    633        public void setQuotCheck( final String flag ) {
    634                quotCheck = nval( getRequestParameter( flag ),quotCheck );
    635        }
    636
    637        /**
    638         * SQLタイプを返します。
    639         *
    640         * @og.rev 4.1.2.0 (2008/03/12) 新規追加
    641         *
    642         * @return      SQLタイプ
    643         */
    644        protected String getSqlType() {
    645                return sqlType ;
    646        }
    647
    648        /**
    649         * このオブジェクトの文字列表現を返します。
    650         * 基本的にデバッグ目的に使用します。
    651         *
    652         * @og.rev 4.0.2.0 (2007/12/25) resourceColumn、commitTableModel追加
    653         *
    654         * @return このクラスの文字列表現
    655         * @og.rtnNotNull
    656         */
    657        @Override
    658        public String toString() {
    659                return ToString.title( this.getClass().getName() )
    660                                .println( "VERSION"                     ,VERSION                )
    661                                .println( "resourceType"        ,resourceType   )
    662                                .println( "resTypeColNo"        ,resTypeColNo   )
    663                                .println( "conditionKey"        ,conditionKey   )
    664                                .println( "conditionList"       ,conditionList  )
    665                                .println( "followCdkh"          ,followCdkh             )
    666                                .println( "CMD_ENTRY"           ,CMD_ENTRY              )
    667                                .println( "commitTabelModel",commitTableModel )         // 4.0.2.0 (2007/12/25)
    668                                .println( "sql"                         ,sql                    )               // 4.1.2.0 (2008/03/12)
    669                                .println( "Other..."    ,getAttributes().getAttribute() )
    670                                .fixForm().toString()
    671                        + CR
    672                        + super.toString() ;
    673        }
    674}