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.ByteArrayInputStream;
019 import java.io.IOException;
020 import java.util.ArrayList;
021 import java.util.List;
022
023 import javax.xml.parsers.DocumentBuilder;
024 import javax.xml.parsers.DocumentBuilderFactory;
025
026 import org.opengion.fukurou.db.Transaction;
027 import org.opengion.fukurou.util.ApplicationInfo;
028 import org.opengion.fukurou.util.StringUtil;
029 import org.opengion.fukurou.util.URLConnect;
030 import org.w3c.dom.Document;
031 import org.w3c.dom.Element;
032 import org.w3c.dom.Node;
033 import org.w3c.dom.NodeList;
034
035 /**
036 * ä¼é?è¦æ±‚ã«å¯¾ã—ã¦ã€HTTP経由ã§ãƒ??ã‚¿ã‚’èªå–ã—ã¾ã™ã?
037 *
038 * èªå–方法ã«ã‚ˆã‚Šèªã¿å–ã£ãŸãƒ‡ãƒ¼ã‚¿ã‚’POSTãƒ??ã‚¿ã¨ã—ã¦é€ä¿¡ã—ã?リモートã?スト上ã§
039 * ä¼é?処ç?‚’実行ã—ã¾ã™ã?
040 *
041 * 処ç??æµã‚Œã¨ã—ã¦ã¯ä»¥ä¸‹ã?よã†ã«ãªã‚Šã¾ã™ã?
042 * â‘?TTPã§èªå–å?ç?‚’実行ã™ã‚‹ãŸã‚ã?サーブレãƒ?ƒˆã‚’呼ã³å‡ºã™ã?
043 * â‘¡â‘?§å‘¼ã³å‡ºã—ã•れãŸã‚µãƒ¼ãƒ–レãƒ?ƒˆãŒã?èªå–å?ç?‚’実行ã™ã‚‹ãŸã‚ã?オブジェクトを生æ?ã—ã?
044 * èªå–å?ç?‚’実行ã™ã‚‹ã?
045 * â‘¢èªå–ã—ãŸçµæžœXMLをパースã—ã?ãã?èªå–データをä¼é?ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã«æ¸¡ã—ä¼é?処ç?‚’実行ã™ã‚‹ã?
046 * â‘£ä¼é?処ç?®Ÿè¡Œå¾Œã?â‘¢ã®çµæžœXMLã‹ã‚‰å¾—られる更新ã‚ー(é…å?)ã‚’Postãƒ??ã‚¿ã¨ã—ã¦æ¸¡ã—ã?
047 * HTTP経由ã§å¾Œå?ç?完äº??ç?¾ãŸã?エラー処ç?を実行ã™ã‚‹ã?
048 *
049 * ã¾ãšâ‘ ã«ã¤ã?¦ã€å‘¼ã³å‡ºã—ã•れるサーブレãƒ?ƒˆã¯ã€?
050 * [リモート接続å?URL]servlet/remoteControl?class=TransferReadWrapper&type=read ã«ãªã‚Šã¾ã™ã?
051 * [リモート接続å?URL]ã¯ã€http://[ホストå]:[ãƒã?ト番å·]/[コンãƒ?‚ストå]ã®å½¢å¼ã«ãªã‚Šã¾ã™ãŒã€?
052 * ã“れã«ã¤ã?¦ã¯ã€èªå–å¯¾è±¡ã§æŒ?®šã—ã¾ã™ã?
053 * 接続時ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸå?åˆã‚„ã€ãƒ¬ã‚¹ãƒãƒ³ã‚¹ãƒ??ã‚¿ã«å¯¾ã—ã¦"row_error"ã¨ã?†
054 * æ–?—å?ãŒå˜åœ¨ã™ã‚‹å ´åˆã?ã€ã‚¨ãƒ©ãƒ¼ã¨ã—ã¦å‡¦ç?—ã¾ã™ã?
055 * ãれ以外ã?å ´åˆã?ã€æ£å¸¸çµ‚äº?¨ã—ã¦å‡¦ç?—ã¾ã™ã?
056 * 次ã«â‘¡ã«ã¤ã?¦ã€ã‚µãƒ¼ãƒ–レãƒ?ƒˆçµŒç”±ã§è¡Œã‚れるä¼é?処ç?«ã¤ã?¦ã€ãã®èªå–方法ã?ã€?
057 * ã“ã?クラスを継承ã—ãŸå?‚µãƒ–クラスã®ã‚¯ãƒ©ã‚¹åã«ã‚ˆã‚Šæ±ºå®šã•れã¾ã™ã?
058 * 具体的ã«ã¯ã€ã‚µãƒ–クラスã®ã‚¯ãƒ©ã‚¹åã«å¯¾ã—ã¦ã€ã“ã®ã‚¯ãƒ©ã‚¹(親クラス)ã®ã‚¯ãƒ©ã‚¹å?"_" を除外ã—ãŸéƒ¨åˆ?Œ
059 * èªå–方法ã¨ã—ã¦èªè˜ã•れã¾ã™ã?
060 * 例ã¨ã—ã¦ã€ã‚µãƒ–クラスåãŒTransferRead_HTTP_CB01ã®å ´åˆã?接続å?ã«ãŠã‘ã‚‹èªå–方法ã?
061 * æ—§ä¼é?DBèªå?CB01)ã¨ãªã‚Šã¾ã™ã?
062 * ã¾ãŸã?リモートã?スト上ã§å®Ÿè¡Œã•れるä¼é?処ç??[リモートèªå–対象]ã¯ã€å?ã®èªå–対象ã§è¨å®šã—ã¾ã™ã?
063 * ã“ã?ã“ã¨ã‹ã‚‰ã€HTTP経由ã§èªå–å?ç?‚’行ã†å ´åˆã?å…??èªå–対象ã«ã¯ã€[リモート接続å?URL]ã¨
064 * [リモートèªå–対象]ã®2ã¤ã‚’è¨å®šã™ã‚‹å¿?¦ãŒã‚りã¾ã™ã?
065 * 具体的ãªè¨å®šæ–¹æ³•ã«ã¤ã?¦ã¯å?‚µãƒ–クラスã®JavaDocã‚’å‚ç…§ã—ã¦ä¸‹ã•ã??
066 * â‘¢ã«ã¤ã?¦ã€è¿”ã•れるXMLãƒ??ã‚¿ã¯[レスãƒãƒ³ã‚¹ãƒ??ã‚¿ã®XMLæ§‹é?]ã®å½¢å¼ã«ãªã‚Šã¾ã™ã?
067 * ã“ã“ã§ã€dataListã¯ã€ä¼é?å®Ÿè¡Œã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã«æ¸¡ã•れるデータã«ãªã‚Šã¾ã™ã?
068 * ã¾ãŸã?keyListã«ã¤ã?¦ã¯ã€ä¼é?実行終äº?¾Œã?HTTP経由ã§å®Œäº??ç?‚’行ã†ãŸã‚ã®æ›´æ–°ã‚ーã«ãªã‚Šã¾ã™ã?
069 * (ãƒãƒ¼ã‚«ãƒ«ã®ä¼é?èªå–オブジェクトã?トランザクションã«å¯¾ã—ã¦åŒä¸?‚ªãƒ–ジェクトã«ãªã‚Šã¾ã™ãŒã€?
070 * HTTP接続å?ã§ã‚µãƒ¼ãƒ–レãƒ?ƒˆçµŒç”±ã§ç”Ÿæ?ã•れるã?リモートã?ä¼é?èªå–オブジェクトã?ã€?
071 * èªå–å?ç?¨å®Œäº?エラー処ç?§ç•°ãªã‚Šã¾ã™ã?ã“ã?ãŸã‚ã€èªå–ã—ãŸãƒ‡ãƒ¼ã‚¿ã®ã‚ーをãƒãƒ¼ã‚«ãƒ«ã«ä¿æŒã—ã?
072 * æœ?¾Œã?完äº?エラー処ç??éš›ã«ã€èªå–ã—ãŸãƒ‡ãƒ¼ã‚¿ã®ã‚ー(æ›´æ–°ã‚ー)ã‚’PostDataã¨ã—ã¦æ¸¡ã™ã“ã¨ã§ã€?
073 * æ£ã—ã完äº?エラー処ç?Œè¡Œã‚れるよã†ã«å¯¾å¿œã—ã¦ã?¾ã?
074 * æœ?¾Œã«â‘£ã«ã¤ã?¦ã€å‘¼ã³å‡ºã—ã•れるサーブレãƒ?ƒˆã¯ã€?
075 * [リモート接続å?URL]servlet/remoteControl?class=TransferReadWrapper&type=complete (æ£å¸¸çµ‚äº?™‚)
076 * [リモート接続å?URL]servlet/remoteControl?class=TransferReadWrapper&type=error (エラー発生時)
077 * ã¨ãªã‚Šã¾ã™ã?
078 *
079 * HTTP接続時ã«ã¯ã€ä»¥ä¸‹ã?ãƒã‚¹ãƒˆãƒ‡ãƒ¼ã‚¿ãŒé?ä¿¡ã•れã¾ã™ã?
080 * [ãƒã‚¹ãƒˆãƒ‡ãƒ¼ã‚¿]
081 * ・KBREAD (èªå–æ–¹æ³? â€»ã‚µãƒ–ã‚¯ãƒ©ã‚¹ã®æœ?¾Œã?"_"(アンãƒ??ãƒã?)以é™ã?æ–?—å?
082 * ・READOBJ (リモートèªå–対象) ※ãƒãƒ¼ã‚«ãƒ«ã®èªå–対象ã‹ã‚‰ãƒªãƒ¢ãƒ¼ãƒˆæŽ¥ç¶šå?URLを除ã?Ÿæ–?—å?
083 * ・READPRM (èªå–パラメーター)
084 * ・KBEXEC (実行方�
085 * ・EXECDBID (実行接続å?DBID)
086 * ・EXECOBJ (実行対象)
087 * ・EXECPRM (実行パラメーター)
088 * ・ERROR_SENDTO (èªã¿å–りå…??ストコーãƒ?
089 * ・HFROM (èªã¿å–りå…??ストコーãƒ?
090 * ・n (ã‚ー件数)
091 * ・k1?žkn (ã‚ー)
092 *
093 * ã¾ãŸã?ãƒ??ã‚¿èªå–時ã«è¿”ã•れるXMLã¯ä»¥ä¸‹ã?æ§‹é?ã‚’ã—ã¦ã?¾ã™ã?
094 * [レスãƒãƒ³ã‚¹ãƒ??ã‚¿ã®XMLæ§‹é?]
095 * <root>
096 * <dataList>
097 * <data>aaa</data>
098 * <data>bbb</data>
099 * <data>ccc</data>
100 * <data>ddd</data>
101 * <data>eee</data>
102 * </dataList>
103 * <keyList>
104 * <key>KEY1</key>
105 * <key>KEY2</key>
106 * <key>KEY3</key>
107 * </keyList>
108 * </root>
109 *
110 * @og.group ä¼é?シスãƒ?ƒ
111 *
112 * @version 5.0
113 * @author Hiroki.Nakamura
114 * @since JDK1.6
115 */
116 public abstract class TransferRead_HTTP implements TransferRead {
117
118 // リモート制御サーブレãƒ?ƒˆå?
119 private static final String REMOTE_SERVLET = "servlet/remoteControl?class=TransferReadWrapper";
120
121 // 更新対象ã®ã‚ー
122 private String[] keys = null;
123
124 /**
125 * URL接続を行ã„ãƒ??ã‚¿ã‚’èªã¿å–りã¾ã™ã?
126 * 接続パラメータã«ã¯ã€?type=read"ãŒä»˜åŠ ã•れã¾ã™ã?
127 *
128 * @param config ä¼é?è¨å®šã‚ªãƒ–ジェクãƒ?
129 * @param tran トランザクションオブジェク�
130 *
131 * @return èªã¿å–りã—ãŸãƒ??ã‚¿(é…å?)
132 */
133 @Override
134 public String[] read( final TransferConfig config, final Transaction tran ) {
135 splitReadObj( config.getReadObj() );
136 String url = getRemoteHost() + REMOTE_SERVLET+ "&type=read";
137 String postData = getPostData( keys, config );
138 URLConnect conn = null;
139 String data = null;
140 try {
141 conn = connect( url, postData, config );
142 data = readData( conn );
143 }
144 catch( IOException ex ) {
145 String errMsg = "URL接続時ã«ä¾‹å¤–ãŒç™ºç”Ÿã—ã¾ã—ãŸã€?URL=" + url + "]";
146 throw new RuntimeException( errMsg, ex );
147 }
148 finally {
149 if( conn != null ) { conn.disconnect(); }
150 }
151
152 List<String> valList = new ArrayList<String>();
153 List<String> keyList = new ArrayList<String>();
154
155 DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
156 Document doc = null;
157 try {
158 DocumentBuilder builder = dbfactory.newDocumentBuilder();
159 doc = builder.parse( new ByteArrayInputStream( data.getBytes( "UTF-8" ) ) );
160 }
161 catch( Exception ex ) {
162 String errMsg = "XMLパã?ス時ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€?;
163 throw new RuntimeException( errMsg, ex );
164 }
165 Element root = doc.getDocumentElement();
166
167 // ãƒ??タ部åˆ?‚’å–å¾—ã—ã¾ã™ã?
168 NodeList dataChilds = root.getElementsByTagName( "dataList" ).item(0).getChildNodes();
169 int numDataChild = dataChilds.getLength();
170 for( int i=0; i<numDataChild; i++ ) {
171 Node nd = dataChilds.item(i);
172 if( nd.getNodeType() == Node.ELEMENT_NODE ) {
173 if( "data".equals( ((Element)nd).getTagName() ) ) {
174 valList.add( nd.getTextContent() );
175 }
176 }
177 }
178
179 // 以é™ã?処ç?§ãƒ??ã‚¿ã‚’æ›´æ–°ã™ã‚‹ãŸã‚ã®ã‚ーをå–å¾—ã—ã¾ã™ã?
180 NodeList keyChilds = root.getElementsByTagName( "keyList" ).item(0).getChildNodes();
181 int numKeyChild = keyChilds.getLength();
182 for( int i=0; i<numKeyChild; i++ ) {
183 Node nd = keyChilds.item(i);
184 if( nd.getNodeType() == Node.ELEMENT_NODE ) {
185 if( "key".equals( ((Element)nd).getTagName() ) ) {
186 keyList.add( nd.getTextContent() );
187 }
188 }
189 }
190 // keys = keyList.toArray( new String[0] );
191 keys = keyList.toArray( new String[keyList.size()] );
192
193 // return valList.toArray( new String[0] );
194 return valList.toArray( new String[valList.size()] );
195 }
196
197 /**
198 * èªå–ã—ãŸãƒ‡ãƒ¼ã‚¿ã«å¯¾ã—ã¦å®Œäº??ç?‚’行ã„ã¾ã™ã?
199 * 接続パラメータã«ã¯ã€?type=complete"ãŒä»˜åŠ ã•れã¾ã™ã?
200 *
201 * @param config ä¼é?è¨å®šã‚ªãƒ–ジェクãƒ?
202 * @param tran トランザクションオブジェク�
203 */
204 @Override
205 public void complete( final TransferConfig config, final Transaction tran ) {
206 splitReadObj( config.getReadObj() );
207 String url = getRemoteHost() + REMOTE_SERVLET + "&type=complete";
208 String postData = getPostData( keys, config );
209 URLConnect conn = null;
210 try {
211 conn = connect( url, postData, config );
212 }
213 catch( IOException ex ) {
214 String errMsg = "URL接続時ã«ä¾‹å¤–ãŒç™ºç”Ÿã—ã¾ã—ãŸã€?URL=" + url + "]";
215 throw new RuntimeException( errMsg, ex );
216 }
217 finally {
218 if( conn != null ) { conn.disconnect(); }
219 }
220 }
221
222 /**
223 * èªå–ã—ãŸãƒ‡ãƒ¼ã‚¿ã«å¯¾ã—ã¦ã‚¨ãƒ©ãƒ¼å‡¦ç?‚’行ã„ã¾ã™ã?
224 * 接続パラメータã«ã¯ã€?type=error"ãŒä»˜åŠ ã•れã¾ã™ã?
225 *
226 * @param config ä¼é?è¨å®šã‚ªãƒ–ジェクãƒ?
227 * @param appInfo DBæŽ¥ç¶šæƒ…å ±
228 */
229 @Override
230 public void error( final TransferConfig config, final ApplicationInfo appInfo ) {
231 splitReadObj( config.getReadObj() );
232 String url = getRemoteHost() + REMOTE_SERVLET + "&type=error";
233 String postData = getPostData( keys, config );
234 URLConnect conn = null;
235 try {
236 conn = connect( url, postData, config );
237 }
238 catch( IOException ex ) {
239 String errMsg = "URL接続時ã«ä¾‹å¤–ãŒç™ºç”Ÿã—ã¾ã—ãŸã€?URL=" + url + "]";
240 throw new RuntimeException( errMsg, ex );
241 }
242 finally {
243 if( conn != null ) { conn.disconnect(); }
244 }
245 }
246
247 /**
248 * (ã“ã?クラスã§ã¯ã€ã‚µãƒã?トã•れã¦ã¾ã›ã‚“ã€?
249 *
250 * @return æ›´æ–°ã‚ー(é…å?)
251 */
252 @Override
253 public String[] getKeys() {
254 String errMsg = "ã“ã?クラスã§ã¯ã€ã‚µãƒã?トã•れã¦ã¾ã›ã‚“ã€?;
255 throw new RuntimeException( errMsg );
256 }
257
258 /**
259 * (ã“ã?クラスã§ã¯ã€ã‚µãƒã?トã•れã¦ã¾ã›ã‚“ã€?
260 *
261 * @param keys æ›´æ–°ã‚ー(é…å?)
262 */
263 @Override
264 public void setKeys( final String[] keys ) {
265 String errMsg = "ã“ã?クラスã§ã¯ã€ã‚µãƒã?トã•れã¦ã¾ã›ã‚“ã€?;
266 throw new RuntimeException( errMsg );
267 }
268
269 /**
270 * ãƒãƒ¼ã‚«ãƒ«ã®èªå–対象をã?リモート接続å?ã®èªå–対象ã¨ãƒªãƒ¢ãƒ¼ãƒˆæŽ¥ç¶šå?URLã«åˆ?§£ã—ã¾ã™ã?
271 *
272 * @param localReadObj ãƒãƒ¼ã‚«ãƒ«ã®èªå–対象
273 */
274 protected abstract void splitReadObj( final String localReadObj );
275
276 /**
277 * リモート接続å?URLã‚’è¿”ã—ã¾ã™ã?
278 * ã“ã?メソãƒ?ƒ‰ã¯ã€{@link #splitReadObj(String)}ã®å¾Œã«å‘¼ã³å‡ºã—ã™ã‚‹å¿?¦ãŒã‚りã¾ã™ã?
279 *
280 * @return リモート接続å?URL
281 */
282 protected abstract String getRemoteHost();
283
284 /**
285 * リモート接続å?ã®èªå–対象を返ã—ã¾ã™ã?
286 * ã“ã?メソãƒ?ƒ‰ã¯ã€{@link #splitReadObj(String)}ã®å¾Œã«å‘¼ã³å‡ºã—ã™ã‚‹å¿?¦ãŒã‚りã¾ã™ã?
287 *
288 * @return 接続URL
289 */
290 protected abstract String getRemoteReadObj();
291
292 /**
293 * æŒ?®šã?URLã«æŽ¥ç¶šã—ã¾ã™ã?
294 *
295 * @param url 接続URL
296 * @param postData POSTã™ã‚‹ãƒ??ã‚¿
297 * @param config ä¼é?è¨å®šã‚ªãƒ–ジェクãƒ?
298 *
299 * @return 接続オブジェク�
300 * @throws IOException ãªã‚“らã‹ã?エラーãŒç™ºç”Ÿã—ãŸå?åˆã?
301 */
302 protected URLConnect connect( final String url, final String postData, final TransferConfig config ) throws IOException {
303 URLConnect conn = new URLConnect( url, TransferConfig.HTTP_AUTH_USER_PASS );
304 if( config.getProxyHost() != null && config.getProxyHost().length() > 0 ) {
305 conn.setProxy( config.getProxyHost(),config.getProxyPort() );
306 }
307 conn.setCharset( "UTF-8" );
308 conn.setPostData( postData );
309 conn.connect();
310 return conn;
311 }
312
313 /**
314 * æŒ?®šã?URLã«æŽ¥ç¶šã—レスãƒãƒ³ã‚¹ãƒ??ã‚¿ã‚’è¿”ã—ã¾ã™ã?
315 *
316 * @param conn URL接続オブジェク�
317 *
318 * @return レスãƒãƒ³ã‚¹ãƒ??ã‚¿
319 */
320 private String readData( final URLConnect conn ) throws IOException {
321 String readData = conn.readData();
322 // è¿”ã•れãŸãƒ??ã‚¿ä¸ã«"row_error"ãŒå˜åœ¨ã™ã‚‹å ´åˆã?エラーã¨ã—ã¦å‡¦ç?—ã¾ã™ã?
323 if( readData != null && readData.indexOf( "row_error" ) >= 0 ) {
324 throw new RuntimeException( readData );
325 }
326 return readData;
327 }
328
329 /**
330 * ä¼é?è¨å®šã‚ªãƒ–ジェクトをURLパラメーターã«å¤‰æ›ã—ã¾ã™ã?
331 *
332 * @param keys æ›´æ–°ã‚ー(é…å?)
333 * @param config ä¼é?è¨å®šã‚ªãƒ–ジェクãƒ?
334 *
335 * @return URLパラメーター
336 */
337 protected String getPostData( final String[] keys, final TransferConfig config ) {
338 // サブクラスåã‹ã‚‰è¦ªã‚¯ãƒ©ã‚¹å?"_"を除ã?Ÿéƒ¨åˆ?‚’èªå–方法ã¨ã™ã‚‹ã€?
339 String kbRead = getClass().getName().replace( getClass().getSuperclass().getName() + "_", "" );
340
341 StringBuilder buf = new StringBuilder();
342 buf.append( "KBREAD=" ).append( StringUtil.urlEncode( kbRead ) );
343 buf.append( "&READOBJ=" ).append( StringUtil.urlEncode( getRemoteReadObj() ) );
344 buf.append( "&READPRM=" ).append( StringUtil.urlEncode( config.getReadPrm() ) );
345 buf.append( "&KBEXEC=" ).append( StringUtil.urlEncode( config.getKbExec() ) );
346 buf.append( "&EXECDBID=" ).append( StringUtil.urlEncode( config.getExecDbid() ) );
347 buf.append( "&EXECOBJ=" ).append( StringUtil.urlEncode( config.getExecObj() ) );
348 buf.append( "&EXECPRM=" ).append( StringUtil.urlEncode( config.getExecPrm() ) );
349 buf.append( "&ERROR_SENDTO=").append( StringUtil.urlEncode( config.getErrorSendto() ) );
350 buf.append( "&HFROM=" ).append( StringUtil.urlEncode( config.getHfrom() ) );
351
352 if( keys != null && keys.length > 0 ) {
353 buf.append( "&n=" ).append( keys.length );
354 for( int i=0; i<keys.length; i++ ) {
355 buf.append( "&k" ).append( i ).append( "=" );
356 buf.append( StringUtil.urlEncode( keys[i] ) );
357 }
358 }
359 else {
360 buf.append( "&n=0" );
361 }
362
363 return buf.toString();
364 }
365 }