Home | History | Annotate | Download | only in transport
      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