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.fukurou.transfer;
017    
018    import java.io.IOException;
019    
020    import org.opengion.fukurou.db.Transaction;
021    import org.opengion.fukurou.util.StringUtil;
022    import org.opengion.fukurou.util.URLConnect;
023    
024    /**
025     * ä¼é?è¦æ±‚ã«å¯¾ã—ã¦ã®HTTP経由ã§ä¼é?処ç?‚’実行ã—ã¾ã™ã?
026     *
027     * èª­å–æ–¹æ³•ã«ã‚ˆã‚Šèª­ã¿å–ã£ãŸãƒ‡ãƒ¼ã‚¿ã‚’POSTãƒ??ã‚¿ã¨ã—ã¦é€ä¿¡ã—ã?リモートã?スト上ã§
028     * ä¼é?処ç?‚’実行ã—ã¾ã™ã?
029     *
030     * 処ç??æµã‚Œã¨ã—ã¦ã¯ä»¥ä¸‹ã?よã†ã«ãªã‚Šã¾ã™ã?
031     * â‘?TTPã§ä¼é?処ç?‚’実行ã™ã‚‹ãŸã‚ã?サーブレãƒ?ƒˆã‚’呼ã³å‡ºã™ã?
032     * â‘¡â‘?§å‘¼ã³å‡ºã—ã•れãŸã‚µãƒ¼ãƒ–レãƒ?ƒˆãŒã?ä¼é?処ç?‚’実行ã™ã‚‹ãŸã‚ã?オブジェクトを生æ?ã—ã?
033     *   ä¼é?処ç?‚’実行ã™ã‚‹ã?
034     * ③処ç?µ‚äº?¾Œã?ä¼é?プロセスã«åˆ¶å¾¡ãŒæˆ»ã‚Šã?èª­å–æ–¹æ³•ã«åŸºã¥ã後å?ç?完äº??ç?¾ãŸã?
035     *   エラー処ç?ãŒå®Ÿè¡Œã•れã¾ã™ã?
036     *
037     * ã¾ãšâ‘ ã«ã¤ã?¦ã€å‘¼ã³å‡ºã—ã•れるサーブレãƒ?ƒˆã¯ã€?
038     *   [リモート接続å?URL]servlet/remoteControl?class=TransferExecWrapper ã«ãªã‚Šã¾ã™ã?
039     *   [リモート接続å?URL]ã¯ã€http://[ホストå]:[ãƒã?ト番å·]/[コンãƒ?‚­ã‚¹ãƒˆå]ã®å½¢å¼ã«ãªã‚Šã¾ã™ãŒã€?
040     *   ã“れã«ã¤ã?¦ã¯ã€å®Ÿè¡Œå¯¾è±¡ã§æŒ?®šã—ã¾ã™ã?
041     * 次ã«â‘¡ã«ã¤ã?¦ã€ã‚µãƒ¼ãƒ–レãƒ?ƒˆçµŒç”±ã§å®Ÿè¡Œã•れるä¼é?処ç?«ã¤ã?¦ã€ãã®å®Ÿè¡Œæ–¹æ³•ã?ã€?
042     *   具体的ã«ã¯ã€ã‚µãƒ–クラスã®ã‚¯ãƒ©ã‚¹åã«å¯¾ã—ã¦ã€ã“ã®ã‚¯ãƒ©ã‚¹(親クラス)ã®ã‚¯ãƒ©ã‚¹å?"_" を除外ã—ãŸéƒ¨åˆ?Œ
043     *   実行方法ã¨ã—ã¦èªè­˜ã•れã¾ã™ã?
044     *   具体的ã«ã¯ã€ã‚¯ãƒ©ã‚¹åã?æœ?¾Œã?"_"(アンãƒ??ãƒã?)以é™ãŒå®Ÿè¡Œæ–¹æ³•ã¨ã—ã¦èªè­˜ã•れã?
045     *   例ã¨ã—ã¦ã€ã‚µãƒ–クラスåãŒTransferExec_HTTP_CB01ã®å ´åˆã?接続å?ã«ãŠã‘る実行方法ã?
046     *   æ—§ä¼é?DB登録(CB01)ã¨ãªã‚Šã¾ã™ã?
047     *   ã¾ãŸã?リモートã?スト上ã§å®Ÿè¡Œã•れるä¼é?処ç??[リモート実行対象]ã¯ã€å?ã®å®Ÿè¡Œå¯¾è±¡ã§è¨­å®šã—ã¾ã™ã?
048     *   ã“ã?ã“ã¨ã‹ã‚‰ã€HTTP経由ã§ä¼é?処ç?‚’実行ã™ã‚‹å?åˆã?å…??実行対象ã«ã¯ã€[リモート接続å?URL]ã¨
049     *   [リモート実行対象]ã®2ã¤ã‚’設定ã™ã‚‹å¿?¦ãŒã‚りã¾ã™ã?
050     *   具体的ãªè¨­å®šæ–¹æ³•ã«ã¤ã?¦ã¯å?‚µãƒ–クラスã®JavaDocã‚’å‚ç…§ã—ã¦ä¸‹ã•ã??
051     * æœ?¾Œã«â‘¢ã«ã¤ã?¦ã€æŽ¥ç¶šæ™‚ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸå?åˆã‚„ã€ãƒ¬ã‚¹ãƒãƒ³ã‚¹ãƒ??ã‚¿ã«å¯¾ã—ã¦"row_error"ã¨ã?†
052     *   æ–?­—å?ãŒå­˜åœ¨ã™ã‚‹å ´åˆã?ã€ã‚¨ãƒ©ãƒ¼ã¨ã—ã¦å‡¦ç?—ã¾ã™ã?
053     *   ãれ以外ã?å ´åˆã?ã€æ­£å¸¸çµ‚äº?¨ã—ã¦å‡¦ç?—ã¾ã™ã?
054     *
055     * HTTP接続時ã«ã¯ã€ä»¥ä¸‹ã?ãƒã‚¹ãƒˆãƒ‡ãƒ¼ã‚¿ãŒé?ä¿¡ã•れã¾ã™ã?
056     * [ãƒã‚¹ãƒˆãƒ‡ãƒ¼ã‚¿]
057     * ・KBREAD                     (èª­å–æ–¹æ³?
058     * ・READOBJ            (読å–対象)
059     * ・READPRM            (読å–パラメーター)
060     * ・KBEXEC                     (実行方æ³? â€»ã‚µãƒ–ã‚¯ãƒ©ã‚¹ã®æœ?¾Œã?"_"(アンãƒ??ãƒã?)以é™ã?æ–?­—å?
061     * ・EXECDBID           (実行接続å?DBID)
062     * ・EXECOBJ            (リモート実行対象) ※ローカルã®å®Ÿè¡Œå¯¾è±¡ã‹ã‚‰ãƒªãƒ¢ãƒ¼ãƒˆæŽ¥ç¶šå?URLを除ã?Ÿæ–?­—å?
063     * ・EXECPRM            (実行パラメーター)
064     * ・ERROR_SENDTO       (読ã¿å–りå…??ストコーãƒ?
065     * ・HFROM (読ã¿å–りå…??ストコーãƒ?
066     * ・n (�?タ件数)
067     * ・v1?žvn (ãƒ??ã‚¿)
068     *
069     * @og.group ä¼é?シスãƒ?ƒ 
070     *
071     * @version  5.0
072     * @author   Hiroki.Nakamura
073     * @since    JDK1.6
074     */
075    public abstract class TransferExec_HTTP implements TransferExec {
076    
077            // リモート制御サーブレãƒ?ƒˆå?
078            private static final String REMOTE_SERVLET = "servlet/remoteControl?class=TransferExecWrapper";
079    
080            /**
081             * URL接続を実行ã—ã¾ã™ã?
082             *
083             * @param vals ä¼é?ãƒ??ã‚¿(é…å?)
084             * @param config ä¼é?設定オブジェクãƒ?
085             * @param tran トランザクションオブジェク�
086             */
087            @Override
088            public void execute( final String[] vals, final TransferConfig config, final Transaction tran ) {
089                    URLConnect conn = null;
090                    try {
091                            splitExecObj( config.getExecObj() );
092                            conn = new URLConnect( getRemoteHost() + REMOTE_SERVLET, TransferConfig.HTTP_AUTH_USER_PASS );
093                            if( config.getProxyHost() != null && config.getProxyHost().length() > 0 ) {
094                                    conn.setProxy( config.getProxyHost(), config.getProxyPort() );
095                            }
096    
097                            conn.setCharset( "UTF-8" );
098                            // ãƒã‚¹ãƒˆãƒ‡ãƒ¼ã‚¿ã‚’生æˆã—ã¾ã™ã?
099                            conn.setPostData( getPostData( vals, config ) );
100    
101                            conn.connect();
102    
103                            String readData = conn.readData();
104                            // è¿”ã•れãŸãƒ??タ中ã«"row_error"ãŒå­˜åœ¨ã™ã‚‹å ´åˆã?エラーã¨ã—ã¦å‡¦ç?—ã¾ã™ã?
105                            if( readData != null && readData.indexOf( "row_error" ) >= 0 ) {
106                                    throw new RuntimeException( readData );
107                            }
108                    }
109                    catch( IOException ex ) {
110                            String errMsg = "URL接続時ã«ä¾‹å¤–ãŒç™ºç”Ÿã—ã¾ã—ãŸã€?;
111                            throw new RuntimeException( errMsg, ex );
112                    }
113                    finally {
114                            if( conn != null ) { conn.disconnect(); }
115                    }
116            }
117    
118            /**
119             * ローカルã®å®Ÿè¡Œå¯¾è±¡ã‚’ã?リモート接続å?ã®å®Ÿè¡Œå¯¾è±¡ã¨ãƒªãƒ¢ãƒ¼ãƒˆæŽ¥ç¶šå?URLã«åˆ?§£ã—ã¾ã™ã?
120             *
121             * @param localExecObj ローカルã®å®Ÿè¡Œå¯¾è±¡
122             */
123            protected abstract void splitExecObj( final String localExecObj );
124    
125            /**
126             * リモート接続å?URLã‚’è¿”ã—ã¾ã™ã?
127             * ã“ã?メソãƒ?ƒ‰ã¯ã€{@link #splitExecObj(String)}ã®å¾Œã«å‘¼ã³å‡ºã—ã™ã‚‹å¿?¦ãŒã‚りã¾ã™ã?
128             *
129             * @return リモート接続å?URL
130             */
131            protected abstract String getRemoteHost();
132    
133            /**
134             * リモート接続å?ã®å®Ÿè¡Œå¯¾è±¡ã‚’è¿”ã—ã¾ã™ã?
135             * ã“ã?メソãƒ?ƒ‰ã¯ã€{@link #splitExecObj(String)}ã®å¾Œã«å‘¼ã³å‡ºã—ã™ã‚‹å¿?¦ãŒã‚りã¾ã™ã?
136             *
137             * @return 接続URL
138             */
139            protected abstract String getRemoteExecObj();
140    
141            /**
142             * ä¼é?ãƒ??ã‚¿åŠã?ä¼é?設定をPOSTãƒ??ã‚¿ã¨ã—ã¦ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚ºã—ã¾ã™ã?
143             *
144             * @param vals ä¼é?ãƒ??ã‚¿(é…å?)
145             * @param config ä¼é?設定オブジェクãƒ?
146             *
147             * @return ãƒã‚¹ãƒˆãƒ‡ãƒ¼ã‚¿
148             */
149            private String getPostData( final String[] vals, final TransferConfig config ) {
150                    // サブクラスåã‹ã‚‰è¦ªã‚¯ãƒ©ã‚¹å?"_"を除ã?Ÿéƒ¨åˆ?‚’実行方法ã¨ã™ã‚‹ã€?
151                    String kbExec = getClass().getName().replace( getClass().getSuperclass().getName() + "_", "" );
152    
153                    StringBuilder buf = new StringBuilder();
154                    buf.append( "KBREAD="           ).append( StringUtil.urlEncode( config.getKbRead() ) );
155                    buf.append( "&READOBJ="             ).append( StringUtil.urlEncode( config.getReadObj() ) );
156                    buf.append( "&READPRM="             ).append( StringUtil.urlEncode( config.getReadPrm() ) );
157                    buf.append( "&KBEXEC="              ).append( StringUtil.urlEncode( kbExec ) );
158                    buf.append( "&EXECDBID="    ).append( StringUtil.urlEncode( config.getExecDbid() )  );
159                    buf.append( "&EXECOBJ="             ).append( StringUtil.urlEncode( getRemoteExecObj() ) );
160                    buf.append( "&EXECPRM="             ).append( StringUtil.urlEncode( config.getExecPrm() ) );
161                    buf.append( "&ERROR_SENDTO=").append( StringUtil.urlEncode( config.getErrorSendto() ) );
162                    buf.append( "&HFROM="               ).append( StringUtil.urlEncode( config.getHfrom() ) ) ;
163    
164                    if( vals != null && vals.length > 0 ) {
165                            buf.append( "&n=" ).append( vals.length );
166                            for( int i=0; i<vals.length; i++ ) {
167                                    buf.append( "&v" ).append( i ).append( "=" );
168                                    buf.append( StringUtil.urlEncode( vals[i] ) );
169                            }
170                    }
171                    else {
172                            buf.append( "&n=0" );
173                    }
174    
175                    return buf.toString();
176            }
177    }