1 /** 2 * Copyright (c) 2006, James Seigel, Calgary, AB., Canada 3 * Copyright (c) 2003,2004, Stefan Haustein, Oberhausen, Rhld., Germany 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * of this software and associated documentation files (the "Software"), to deal 7 * in the Software without restriction, including without limitation the rights 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 * sell copies of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 package org.ksoap2.transport; 25 26 import java.util.HashMap; 27 import java.util.Iterator; 28 import java.util.List; 29 import java.io.*; 30 import java.net.MalformedURLException; 31 import java.net.Proxy; 32 import java.net.URL; 33 34 import libcore.util.XmlObjectFactory; 35 36 import org.ksoap2.*; 37 import org.xmlpull.v1.*; 38 39 /** 40 * Abstract class which holds common methods and members that are used by the 41 * transport layers. This class encapsulates the serialization and 42 * deserialization of the soap messages, leaving the basic communication 43 * routines to the subclasses. 44 */ 45 abstract public class Transport { 46 47 /** 48 * Added to enable web service interactions on the emulator to be debugged 49 * with Fiddler2 (Windows) but provides utility for other proxy 50 * requirements. 51 */ 52 protected Proxy proxy; 53 protected String url; 54 protected int timeout = ServiceConnection.DEFAULT_TIMEOUT; 55 /** Set to true if debugging */ 56 public boolean debug = true; 57 /** String dump of request for debugging. */ 58 public String requestDump; 59 /** String dump of response for debugging */ 60 public String responseDump; 61 private String xmlVersionTag = ""; 62 63 protected static final String CONTENT_TYPE_XML_CHARSET_UTF_8 = "text/xml;charset=utf-8"; 64 protected static final String CONTENT_TYPE_SOAP_XML_CHARSET_UTF_8 = 65 "application/soap+xml;charset=utf-8"; 66 protected static final String USER_AGENT = "ksoap2-android/2.6.0+"; 67 68 private int bufferLength = ServiceConnection.DEFAULT_BUFFER_SIZE; 69 70 private HashMap prefixes = new HashMap(); 71 72 public HashMap getPrefixes() { 73 return prefixes; 74 } 75 76 public Transport() { 77 } 78 79 public Transport(String url) { 80 this(null, url); 81 } 82 83 public Transport(String url, int timeout) { 84 this.url = url; 85 this.timeout = timeout; 86 } 87 88 public Transport(String url, int timeout, int bufferLength) { 89 this.url = url; 90 this.timeout = timeout; 91 this.bufferLength = bufferLength; 92 } 93 94 /** 95 * Construct the transport object 96 * 97 * @param proxy 98 * Specifies the proxy server to use for accessing the web 99 * service or <code>null</code> if a direct connection is 100 * available 101 * @param url 102 * Specifies the web service url 103 * 104 */ 105 public Transport(Proxy proxy, String url) { 106 this.proxy = proxy; 107 this.url = url; 108 } 109 110 public Transport(Proxy proxy, String url, int timeout) { 111 this.proxy = proxy; 112 this.url = url; 113 this.timeout = timeout; 114 } 115 116 public Transport(Proxy proxy, String url, int timeout, int bufferLength) { 117 this.proxy = proxy; 118 this.url = url; 119 this.timeout = timeout; 120 this.bufferLength = bufferLength; 121 } 122 123 /** 124 * Sets up the parsing to hand over to the envelope to deserialize. 125 */ 126 protected void parseResponse(SoapEnvelope envelope, InputStream is) 127 throws XmlPullParserException, IOException { 128 // Android-changed: Use XmlObjectFactory instead of a specific implementation. 129 // XmlPullParser xp = new KXmlParser(); 130 XmlPullParser xp = XmlObjectFactory.newXmlPullParser(); 131 xp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); 132 xp.setInput(is, null); 133 envelope.parse(xp); 134 /* 135 * Fix memory leak when running on android in strict mode. Issue 133 136 */ 137 is.close(); 138 } 139 140 /** 141 * Serializes the request. 142 */ 143 protected byte[] createRequestData(SoapEnvelope envelope, String encoding) 144 throws IOException { 145 ByteArrayOutputStream bos = new ByteArrayOutputStream(bufferLength); 146 byte result[] = null; 147 bos.write(xmlVersionTag.getBytes()); 148 // Android-changed: Use XmlObjectFactory instead of a specific implementation. 149 // XmlSerializer xw = new KXmlSerializer(); 150 XmlSerializer xw = XmlObjectFactory.newXmlSerializer(); 151 152 final Iterator keysIter = prefixes.keySet().iterator(); 153 xw.setOutput(bos, encoding); 154 while (keysIter.hasNext()) { 155 String key = (String) keysIter.next(); 156 xw.setPrefix(key, (String) prefixes.get(key)); 157 } 158 envelope.write(xw); 159 xw.flush(); 160 bos.write('\r'); 161 bos.write('\n'); 162 bos.flush(); 163 result = bos.toByteArray(); 164 xw = null; 165 bos = null; 166 return result; 167 } 168 169 /** 170 * Serializes the request. 171 */ 172 protected byte[] createRequestData(SoapEnvelope envelope) 173 throws IOException { 174 return createRequestData(envelope, null); 175 } 176 177 /** 178 * Set the target url. 179 * 180 * @param url 181 * the target url. 182 */ 183 public void setUrl(String url) { 184 this.url = url; 185 } 186 187 public String getUrl() { 188 return url; 189 } 190 191 192 /** 193 * Sets the version tag for the outgoing soap call. Example <?xml 194 * version=\"1.0\" encoding=\"UTF-8\"?> 195 * 196 * @param tag 197 * the xml string to set at the top of the soap message. 198 */ 199 public void setXmlVersionTag(String tag) { 200 xmlVersionTag = tag; 201 } 202 203 /** 204 * Attempts to reset the connection. 205 */ 206 public void reset() { 207 } 208 209 /** 210 * Perform a soap call with a given namespace and the given envelope 211 * providing any extra headers that the user requires such as cookies. 212 * Headers that are returned by the web service will be returned to the 213 * caller in the form of a <code>List</code> of <code>HeaderProperty</code> 214 * instances. 215 * 216 * @param soapAction 217 * the namespace with which to perform the call in. 218 * @param envelope 219 * the envelope the contains the information for the call. 220 * @param headers 221 * <code>List</code> of <code>HeaderProperty</code> headers to 222 * send with the SOAP request. 223 * 224 * @return Headers returned by the web service as a <code>List</code> of 225 * <code>HeaderProperty</code> instances. 226 */ 227 abstract public List call(String soapAction, SoapEnvelope envelope, 228 List headers) throws IOException, XmlPullParserException; 229 230 /** 231 * Perform a soap call with a given namespace and the given envelope 232 * providing any extra headers that the user requires such as cookies. 233 * Headers that are returned by the web service will be returned to the 234 * caller in the form of a <code>List</code> of <code>HeaderProperty</code> 235 * instances. 236 * 237 * @param soapAction 238 * the namespace with which to perform the call in. 239 * @param envelope 240 * the envelope the contains the information for the call. 241 * @param headers 242 * <code>List</code> of <code>HeaderProperty</code> headers to 243 * send with the SOAP request. 244 * @param outputFile 245 * a file to stream the response into rather than parsing it, 246 * streaming happens when file is not null 247 * 248 * @return Headers returned by the web service as a <code>List</code> of 249 * <code>HeaderProperty</code> instances. 250 */ 251 abstract public List call(String soapAction, SoapEnvelope envelope, 252 List headers, File outputFile) throws IOException, 253 XmlPullParserException; 254 255 /** 256 * Perform a soap call with a given namespace and the given envelope. 257 * 258 * @param soapAction 259 * the namespace with which to perform the call in. 260 * @param envelope 261 * the envelope the contains the information for the call. 262 */ 263 public void call(String soapAction, SoapEnvelope envelope) 264 throws IOException, XmlPullParserException { 265 call(soapAction, envelope, null); 266 } 267 268 /** 269 * Return the name of the host that is specified as the web service target 270 * 271 * @return Host name 272 */ 273 public String getHost() throws MalformedURLException { 274 275 return new URL(url).getHost(); 276 } 277 278 /** 279 * Return the port number of the host that is specified as the web service 280 * target 281 * 282 * @return Port number 283 */ 284 public int getPort() throws MalformedURLException { 285 286 return new URL(url).getPort(); 287 } 288 289 /** 290 * Return the path to the web service target 291 * 292 * @return The URL's path 293 */ 294 public String getPath() throws MalformedURLException { 295 296 return new URL(url).getPath(); 297 } 298 299 abstract public ServiceConnection getServiceConnection() throws IOException; 300 } 301