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 }