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 }