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     */
016    package org.opengion.hayabusa.taglib;
017    
018    import org.opengion.hayabusa.common.HybsSystem;
019    import org.opengion.hayabusa.common.HybsSystemException;
020    import org.opengion.hayabusa.db.DBTableModel;
021    import org.opengion.hayabusa.db.Query;
022    import org.opengion.hayabusa.resource.GUIInfo;
023    
024    import org.opengion.fukurou.util.StringUtil ;
025    import static org.opengion.fukurou.util.StringUtil.nval ;
026    
027    /**
028     * 【å»?­¢】SQLæ–?‚’直接æŒ?®šして、データベã?スに追åŠ?更新/削除を行いまã�?queryType="JDBCPrepared")ã€?
029     *
030     * 存在チェãƒ?‚¯を行う場合ã?、tableExist タグと併用してくださいã€?
031     * è¤?›‘な処ç�?�Œå¿?¦�な場合ã?、従来より使用してã�?�¾すã?PLSQLをCALLするã€?
032     * plsqlUpdateタグを使用してくださいã€?
033     *
034     * ※ こã?タグは、Transaction タグの対象ですã?
035     *
036     * @og.formSample
037     * ●形式ï¼?lt;og:update command="…" names="…" queryType="JDBCPrepared" >
038     *             {@SQL}
039     *         </og:update>
040     * ●body?šあã‚?EVAL_BODY_BUFFERED:BODYを評価しã?{@XXXX} を解析しまã�?
041     *
042     * ●Tag定義??
043     *   <og:update
044     *       queryType          【å»?­¢】Query を発行する為のクラスIDを指定しまã�?初期値:JDBCPrepared)
045     *       command            【TAG】コマンãƒ?NEW,RENEW)をセãƒ?ƒˆしまã�?PlsqlUpdateTag,UpdateTag の場合ã?、ENTRY)
046     *       scope              【TAG】キャãƒ?‚·ュする場合ã?スコープ[request/page/session/applicaton]を指定しまã�?初期値:session)
047     *       displayMsg         【TAG】検索結果を画面上に表示するメãƒ?‚»ージリソースIDを指定しまã�?(初期値:VIEW_DISPLAY_MSG[=])
048     *       names              【TAG】PL/SQLを利用する場合ã?引数にセãƒ?ƒˆすべã�?ãƒ??タの名称をCSV形式でè¤?•°æŒ?®šしまã�?
049     *       quotCheck          【TAG】リクエスト情報の クォーãƒ?‚£ション(') 存在チェãƒ?‚¯を実施するかどã�?�‹[true/false]を設定しまã�?初期値:USE_SQL_INJECTION_CHECK)
050     *       tableId            【TAGã€?通常は使ã�?�¾せん)結果のDBTableModelをã?sessionに登録するときã?キーを指定しまã�?
051     *       dbid               【TAGã€?通常は使ã�?�¾せん)Queryオブジェクトを作æ?する時ã?DB接続IDを指定しまã�?
052     *       xssCheck           【TAG】リクエスト情報の HTMLTag開å§?終äº?–‡å­?><) 存在チェãƒ?‚¯を実施するかどã�?�‹[true/false]を設定しまã�?(初期値:USE_XSS_CHECK[=true])
053     *       debug              【TAG】デバッグæƒ??をå?力するかどã�?�‹[true/false]を指定しまã�?初期値:false)
054     *   >   ... Body ...
055     *   </og:update>
056     *
057     * ●使用ä¾?
058     *    ・引数/プロシジャーを他ã?JSPから渡すå?å�?
059     *    【copy.jspã€?
060     *        <og:value scope="session" key="names" value="CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG" />
061     *        <og:value scope="session" key="SQL" >
062     *          INSERT INTO GE41
063     *               (CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG,
064     *               FGJ,DYSET,DYUPD,USRSET,USRUPD,PGUPD)
065     *          VALUES
066     *               (?,?,?,?,?,?,
067     *               '1','{@USER.YMDH}','{@USER.YMDH}','{@USER.ID}','{@USER.ID}','{@GUI.KEY}')
068     *        </og:value>
069     *
070     *    【entry.jspã€?
071     *        <og:update
072     *            command   = "{@command}"
073     *            queryType = "JDBCPrepared"
074     *            names     = "{@names}"  >
075     *        {@SQL}
076     *        </og:update>
077     *
078     *        <!-- 前画面でæŒ?®šã?SQLæ–?‚’削除しますã?(scope="session"なので削除がå¿?¦�ã?) -->
079     *        <og:value scope="session" key="names" command="REMOVE" />
080     *        <og:value scope="session" key="SQL"   command="REMOVE" />
081     *
082     *    ・引数/プロシジャーを直接書くå?å�?
083     *    【entry.jspã€?
084     *        <og:update
085     *            command   = "{@command}"
086     *            queryType = "JDBCPrepared"
087     *            names     = "CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG"
088     *        >
089     *            INSERT INTO GE41
090     *                (CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG,
091     *                 FGJ,DYSET,DYUPD,USRSET,USRUPD,PGUPD)
092     *            VALUES
093     *                (?,?,?,?,?,?,
094     *                 '1','{@USER.YMDH}','{@USER.YMDH}','{@USER.ID}','{@USER.ID}','{@GUI.KEY}')
095     *        </og:update>
096     *
097     * @og.rev 4.0.0.0 (2005/01/31) å»?­¢
098     * @og.group (å»?­¢)?¤?¢登録
099     *
100     * @deprecated 4.0.0 (2005/01/31) å»?­¢。tableUpdate を利用するようにしてくださいã€?
101     * @version  4.0
102     * @author   Kazuhiko Hasegawa
103     * @since    JDK5.0,
104     */
105    @Deprecated public class UpdateTag extends QueryTag {
106            //* こã?プログラãƒ??VERSIONæ–?­—å?を設定しますã?       {@value} */
107            private static final String VERSION = "4.0.0.0 (2005/01/31)" ;
108    
109            private static final long serialVersionUID = 400020050131L ;
110    
111            /** command 引数に渡す事ã?出来ã‚?コマンãƒ? 登録{@value} */
112            public static final String CMD_ENTRY  = "ENTRY" ;
113            /** command 引数に渡す事ã?出来ã‚?コマンãƒ?リスãƒ? */
114            private static final String COMMAND_LIST = CMD_ENTRY;
115    
116            /**
117             * Taglibの開始タグが見つかったときに処ç�?�™ã‚?doStartTag() ã‚?オーバã?ライドしますã?
118             *
119             * @return      後続å?ç�??æŒ?¤º
120             */
121            @Override
122            public int doStartTag() {
123                    dyStart = System.currentTimeMillis();
124    
125                    table = (DBTableModel)getObject( tableId );
126                    if( table == null || table.getRowCount() == 0 ||
127                            ! check( command, COMMAND_LIST ) ) { return(SKIP_BODY); }
128                    return( EVAL_BODY_BUFFERED );   // Body を評価するã€? extends BodyTagSupport æ™?
129            }
130    
131            /**
132             * Taglibの終äº?‚¿グが見つかったときに処ç�?�™ã‚?doEndTag() ã‚?オーバã?ライドしますã?
133             *
134             * @og.rev 3.5.5.8 (2004/05/20) ErrorMessage オブジェクトを、正常終äº?™‚、クリア
135             *
136             * @return      後続å?ç�??æŒ?¤º
137             */
138            @Override
139            public int doEndTag() {
140                    debugPrint();           // 4.0.0 (2005/02/28)
141    
142                    if( check( command, COMMAND_LIST ) ) {
143                            removeSessionAttribute( errMsgId );
144                    }
145    
146                    executeCount = getParameterRows().length ;              // チェãƒ?‚¯行ã?数が登録件数と仮å®?
147    
148                    // 4.0.0 (2005/01/31) 処ç�?™‚間集è¨?
149                    long dyTime = System.currentTimeMillis()-dyStart;
150    
151                    // 4.0.0 (2005/01/31) セキュリãƒ?‚£チェãƒ?‚¯(ãƒ??タアクセス件数登録)
152                    GUIInfo guiInfo = (GUIInfo)getSessionAttribute( HybsSystem.GUIINFO_KEY );
153                    if( guiInfo != null ) { guiInfo.addWriteCount( executeCount,dyTime,sql ); }
154    
155                    return(EVAL_PAGE);
156            }
157    
158            /**
159             * Query を実行しますã?
160             *
161             * @og.rev 2.1.2.3 (2002/12/02) ãƒ??タベã?ス更新時に、更新フラグをセãƒ?ƒˆするように変更
162             * @og.rev 3.4.0.0 (2003/09/01) 登録エラー時ã?キーと値を表示するように変更ã€?
163             * @og.rev 3.5.0.0 (2003/09/17) カラãƒ?��ではなくã?カラãƒ?•ª号をå?に求めておく方式に変更ã€?
164             * @og.rev 3.5.6.0 (2004/06/18) DBRowHeader のパッケージプライベã?ト化に伴なã�?¤‰更
165             * @og.rev 4.0.0.0 (2005/01/31) getParameterRows() を使用するように変更
166             *
167             * @param   query オブジェクãƒ?
168             */
169            @Override
170            protected void execute( final Query query ) {
171                    // long st = System.currentTimeMillis();
172                    String[] values    = null;
173                    int row = 0;
174                    try {
175                            if( names == null ) {
176                                    query.execute( null );
177                            }
178                            else {
179                                    int[] rowNo = getParameterRows();               // 4.0.0 (2005/01/31)
180                                    if( rowNo.length > 0 ) {
181                                            int[] clmNo = getTableColumnNo( StringUtil.csv2Array( names ) );
182                                            values    = null;
183                                            // é€??にDELETEしなã�?�¨、行番号がずれてしまã�??
184                                            for( int j=rowNo.length-1; j>=0; j-- ) {
185                                                    row = rowNo[j];
186                                                    values = getTableModelData( clmNo,row );        // 3.5.0.0
187                                                    query.execute( values );
188                                                    if( DBTableModel.DELETE_TYPE.equals( table.getModifyType( row ) ) ) {
189                                                            table.removeValue( row );
190                                                    }
191                                                    else {
192                                                            table.resetModify( row );
193                                                    }
194                                            }
195                                    }
196                            }
197    //                      if( query.getUpdateFlag() ) { query.commit(); }
198                            if( query.isUpdate() ) { query.commit(); }
199                    }
200                    catch( HybsSystemException ex ) {
201                            query.rollback();
202            // 3.4.0.0 (2003/09/01) 登録エラー時ã?キーと値を表示するように変更ã€?
203                            String errMsg = "DATABASE ERROR! "
204                                    + "rowNo=[" + ( row ) + "] " + HybsSystem.CR
205                                    + "nameArray=[" + names + "]" + HybsSystem.CR
206                                    + "values=[" + StringUtil.array2csv( values ) + "]" + HybsSystem.CR ;
207                            throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並びé ?¤‰更
208                    }
209                    finally {
210                            if( query != null ) { query.close(); }
211                    }
212                    // System.out.println( ( System.currentTimeMillis() - st ) + " ms" );
213            }
214    
215            /**
216             *  カラãƒ?��配å?(String[])より、対応するカラãƒ?o配å?(int[])を作æ?しますã?
217             *
218             * @og.rev 3.5.0.0 (2003/09/17) 新規追åŠ?
219             *
220             * @param       nameArray カラãƒ?��配å?
221             *
222             * @return      カラãƒ?o配å?
223             */
224            private int[] getTableColumnNo( final String[] nameArray ) {
225                    int[] clmNo = new int[ nameArray.length ];
226                    for( int i=0; i<clmNo.length; i++ ) {
227                            clmNo[i] = table.getColumnNo( nameArray[i] );
228                    }
229                    return clmNo;
230            }
231    
232            /**
233             *  æŒ?®šã?行番号の、カラãƒ?o配å?(int[])に対応したå?の配å?を返しますã?
234             *
235             * 表示ãƒ??タの HybsSystem.ROW_SEL_KEY をå?にã€?�¸ばれた 行を
236             * 処ç�??対象としますã?
237             *
238             * @og.rev 3.5.0.0 (2003/09/17) カラãƒ?��ではなくã?カラãƒ?•ª号を受け取るよã�?�«修正ã€?
239             *
240             * @param       clmNo   カラãƒ?o配å?
241             * @param       row             行番号
242             *
243             * @return      行番号とカラãƒ?o配å?に対応したã?値の配å?
244             */
245            private String[] getTableModelData( final int[] clmNo,final int row ) {
246                    String[] values = new String[ clmNo.length ];
247                    for( int i=0; i<values.length; i++ ) {
248                            values[i] = table.getValue( row,clmNo[i] ) ;
249                    }
250                    return values;
251            }
252    
253            /**
254             * 【å»?­¢】Query を発行する為のクラスIDを指定しまã�?{@og.doc03Link queryType 初期値:JDBCPrepared})ã€?
255             *
256             * @og.tag
257             * 登録を実行する手段は、Query インターフェースの実è£?‚¯ラスになりますã?
258             * こã?タグでは、Query.execute( String[] ) メソãƒ?ƒ‰がè¤?•°回呼ばれますã?
259             * これは、DBTableModelの選択された行に対して、繰り返し呼ばれますã?
260             *
261             * 通常、このタグを使用する場合ã?、queryType="JDBCPrepared" を指定しますã?
262             *
263             * タグにより使用できる?�å?来なã�?�Œありますが、これã?、org.opengion.hayabusa.db
264             * 以下ã? Query_**** クラスの **** を与えますã?
265             * これらã?、Query インターフェースを継承したサブクラスですã?
266             * {@og.doc03Link queryType Query_**** クラス}
267             *
268             * @og.rev 3.5.4.2 (2003/12/15) JavaDocコメント用にメソãƒ?ƒ‰追åŠ??
269             *
270             * @param       id Query を発行する為の実クラス ID
271             * @see         org.opengion.hayabusa.db.Query  Queryのサブクラス
272             * @see         org.opengion.hayabusa.db.Query#execute( String[] )
273             * @deprecated クラスがå»?­¢
274             */
275            @Deprecated public void setQueryType( final String id ) {
276                    super.setQueryType( nval( id,"JDBCPrepared" ) );
277            }
278    }