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
24package org.ksoap2.transport;
25
26import java.util.List;
27import java.io.*;
28import java.net.Proxy;
29
30import org.ksoap2.*;
31import org.kxml2.io.*;
32import org.xmlpull.v1.*;
33
34/**
35 * Abstract class which holds common methods and members that are used by the
36 * transport layers. This class encapsulates the serialization and
37 * deserialization of the soap messages, leaving the basic communication
38 * routines to the subclasses.
39 */
40abstract public class Transport {
41
42    /**
43     * Added to enable web service interactions on the emulator
44     * to be debugged with Fiddler2 (Windows) but provides utility
45     * for other proxy requirements.
46     */
47    protected Proxy proxy;
48    protected String url;
49    protected int timeout = ServiceConnection.DEFAULT_TIMEOUT;
50    /** Set to true if debugging */
51    public boolean debug = true;
52    /** String dump of request for debugging. */
53    public String requestDump;
54    /** String dump of response for debugging */
55    public String responseDump;
56    private String xmlVersionTag = "";
57
58    protected static final String CONTENT_TYPE_XML_CHARSET_UTF_8 = "text/xml;charset=utf-8";
59    protected static final String CONTENT_TYPE_SOAP_XML_CHARSET_UTF_8 = "application/soap+xml;charset=utf-8";
60    protected static final String USER_AGENT = "ksoap2-android/2.6.0+";
61
62    private int bufferLength = ServiceConnection.DEFAULT_BUFFER_SIZE;
63
64    public Transport() {
65    }
66
67    public Transport(String url) {
68        this(null, url);
69    }
70
71    public Transport(String url, int timeout) {
72        this.url = url;
73        this.timeout = timeout;
74    }
75
76    public Transport(String url, int timeout, int bufferLength) {
77        this.url = url;
78        this.timeout = timeout;
79        this.bufferLength = bufferLength;
80    }
81
82    /**
83     * Construct the transport object
84     *
85     * @param proxy Specifies the proxy server to use for
86     * accessing the web service or <code>null</code> if a direct connection is available
87     * @param url Specifies the web service url
88     *
89     */
90    public Transport(Proxy proxy, String url) {
91        this.proxy = proxy;
92        this.url = url;
93    }
94
95    public Transport(Proxy proxy, String url, int timeout) {
96        this.proxy = proxy;
97        this.url = url;
98        this.timeout = timeout;
99    }
100
101    public Transport(Proxy proxy, String url, int timeout, int bufferLength) {
102        this.proxy = proxy;
103        this.url = url;
104        this.timeout = timeout;
105        this.bufferLength = bufferLength;
106    }
107
108    /**
109     * Sets up the parsing to hand over to the envelope to deserialize.
110     */
111    protected void parseResponse(SoapEnvelope envelope, InputStream is)
112            throws XmlPullParserException, IOException {
113        XmlPullParser xp = new KXmlParser();
114        xp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
115        xp.setInput(is, null);
116        envelope.parse(xp);
117    }
118
119    /**
120     * Serializes the request.
121     */
122    protected byte[] createRequestData(SoapEnvelope envelope, String encoding) throws IOException {
123        System.out.println("createRequestData");
124        ByteArrayOutputStream bos = new ByteArrayOutputStream(bufferLength);
125        byte result[] = null;
126        bos.write(xmlVersionTag.getBytes());
127        System.out.println("bos.write");
128        XmlSerializer xw = new KXmlSerializer();
129        System.out.println("new KXmlSerializer");
130        xw.setOutput(bos, encoding);
131        System.out.println("xw.setOutput");
132        envelope.write(xw);
133        System.out.println("envelope.write");
134        xw.flush();
135        bos.write('\r');
136        bos.write('\n');
137        bos.flush();
138        result = bos.toByteArray();
139        xw = null;
140        bos = null;
141        System.out.println("createRequestData end");
142        return result;
143    }
144
145    /**
146     * Serializes the request.
147     */
148    protected byte[] createRequestData(SoapEnvelope envelope) throws IOException {
149        return createRequestData(envelope, null);
150    }
151
152    /**
153     * Set the target url.
154     *
155     * @param url
156     *            the target url.
157     */
158    public void setUrl(String url) {
159        this.url = url;
160    }
161
162    /**
163     * Sets the version tag for the outgoing soap call. Example <?xml
164     * version=\"1.0\" encoding=\"UTF-8\"?>
165     *
166     * @param tag
167     *            the xml string to set at the top of the soap message.
168     */
169    public void setXmlVersionTag(String tag) {
170        xmlVersionTag = tag;
171    }
172
173    /**
174     * Attempts to reset the connection.
175     */
176    public void reset() {
177    }
178
179    /**
180     * Perform a soap call with a given namespace and the given envelope providing
181     * any extra headers that the user requires such as cookies. Headers that are
182     * returned by the web service will be returned to the caller in the form of a
183     * <code>List</code> of <code>HeaderProperty</code> instances.
184     *
185     * @param targetNamespace
186     *            the namespace with which to perform the call in.
187     * @param envelope
188     *            the envelope the contains the information for the call.
189     * @param headers
190     *   <code>List</code> of <code>HeaderProperty</code> headers to send with the SOAP request.
191     *
192     * @return Headers returned by the web service as a <code>List</code> of
193     * <code>HeaderProperty</code> instances.
194     */
195    abstract public List call(String targetNamespace, SoapEnvelope envelope, List headers)
196            throws IOException, XmlPullParserException;
197
198    /**
199     * Perform a soap call with a given namespace and the given envelope.
200     *
201     * @param targetNamespace
202     *            the namespace with which to perform the call in.
203     * @param envelope
204     *            the envelope the contains the information for the call.
205     */
206    public void call(String targetNamespace, SoapEnvelope envelope) throws IOException,
207            XmlPullParserException {
208        call(targetNamespace, envelope, null);
209    }
210
211    /**
212     * Return the name of the host that is specified as the web service target
213     *
214     * @return Host name
215     */
216    abstract public String getHost();
217
218    /**
219     * Return the port number of the host that is specified as the web service target
220     *
221     * @return Port number
222     */
223    abstract public int getPort();
224
225    /**
226     * Return the path to the web service target
227     *
228     * @return The URL's path
229     */
230    abstract public String getPath();
231
232    abstract public ServiceConnection getServiceConnection() throws IOException;
233}
234