1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
package org.apache.xmlrpc.client; |
17 |
|
|
18 |
|
import java.io.ByteArrayInputStream; |
19 |
|
import java.io.ByteArrayOutputStream; |
20 |
|
import java.io.IOException; |
21 |
|
import java.io.InputStream; |
22 |
|
import java.io.OutputStream; |
23 |
|
import java.util.zip.GZIPInputStream; |
24 |
|
import java.util.zip.GZIPOutputStream; |
25 |
|
|
26 |
|
import javax.xml.parsers.ParserConfigurationException; |
27 |
|
import javax.xml.parsers.SAXParserFactory; |
28 |
|
|
29 |
|
import org.apache.xmlrpc.XmlRpcException; |
30 |
|
import org.apache.xmlrpc.XmlRpcRequest; |
31 |
|
import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig; |
32 |
|
import org.apache.xmlrpc.parser.XmlRpcResponseParser; |
33 |
|
import org.apache.xmlrpc.serializer.XmlRpcWriter; |
34 |
|
import org.xml.sax.ContentHandler; |
35 |
|
import org.xml.sax.InputSource; |
36 |
|
import org.xml.sax.SAXException; |
37 |
|
import org.xml.sax.XMLReader; |
38 |
|
|
39 |
|
|
40 |
|
|
41 |
|
|
42 |
|
|
43 |
|
|
44 |
1 |
public abstract class XmlRpcStreamTransport extends XmlRpcTransportImpl { |
45 |
|
private static final SAXParserFactory spf; |
46 |
|
static { |
47 |
1 |
spf = SAXParserFactory.newInstance(); |
48 |
1 |
spf.setNamespaceAware(true); |
49 |
1 |
spf.setValidating(false); |
50 |
|
} |
51 |
|
|
52 |
|
|
53 |
|
|
54 |
|
protected XmlRpcStreamTransport(XmlRpcClient pClient) { |
55 |
434 |
super(pClient); |
56 |
434 |
} |
57 |
|
|
58 |
|
|
59 |
|
|
60 |
|
|
61 |
|
protected abstract Object newConnection(XmlRpcStreamRequestConfig pConfig) throws XmlRpcClientException; |
62 |
|
|
63 |
|
|
64 |
|
|
65 |
|
protected abstract void closeConnection(Object pConnection) throws XmlRpcClientException; |
66 |
|
|
67 |
|
|
68 |
|
|
69 |
|
|
70 |
|
|
71 |
|
|
72 |
|
|
73 |
|
protected void initConnection(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws XmlRpcClientException { |
74 |
384 |
} |
75 |
|
|
76 |
|
|
77 |
|
|
78 |
|
|
79 |
|
|
80 |
|
|
81 |
|
|
82 |
|
protected abstract OutputStream newOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) |
83 |
|
throws XmlRpcClientException; |
84 |
|
|
85 |
|
|
86 |
|
|
87 |
|
|
88 |
|
|
89 |
|
|
90 |
|
protected void closeOutputStream(OutputStream pStream) throws XmlRpcClientException { |
91 |
|
try { |
92 |
384 |
pStream.close(); |
93 |
0 |
} catch (IOException e) { |
94 |
0 |
throw new XmlRpcClientException("Failed to close output stream.", e); |
95 |
|
} |
96 |
384 |
} |
97 |
|
|
98 |
|
protected OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) |
99 |
|
throws XmlRpcClientException { |
100 |
120 |
OutputStream result = newOutputStream(pConfig, pConnection); |
101 |
120 |
if (pConfig.isGzipCompressing()) { |
102 |
|
try { |
103 |
0 |
result = new GZIPOutputStream(result); |
104 |
0 |
} catch (IOException e) { |
105 |
0 |
throw new XmlRpcClientException("Failed to attach gzip encoding to output stream", e); |
106 |
|
} |
107 |
|
} |
108 |
120 |
return result; |
109 |
|
} |
110 |
|
|
111 |
|
|
112 |
|
|
113 |
|
|
114 |
|
|
115 |
|
|
116 |
|
|
117 |
|
protected abstract InputStream newInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) |
118 |
|
throws XmlRpcException; |
119 |
|
|
120 |
|
|
121 |
|
|
122 |
|
|
123 |
|
|
124 |
|
|
125 |
|
|
126 |
|
|
127 |
|
protected abstract InputStream newInputStream(XmlRpcStreamRequestConfig pConfig, |
128 |
|
Object pConnection, |
129 |
|
byte[] pContent) |
130 |
|
throws XmlRpcException; |
131 |
|
|
132 |
|
|
133 |
|
|
134 |
|
|
135 |
|
|
136 |
|
|
137 |
|
protected void closeInputStream(InputStream pStream) throws XmlRpcClientException { |
138 |
|
try { |
139 |
280 |
pStream.close(); |
140 |
0 |
} catch (IOException e) { |
141 |
0 |
throw new XmlRpcClientException("Failed to close output stream.", e); |
142 |
|
} |
143 |
280 |
} |
144 |
|
|
145 |
|
|
146 |
|
|
147 |
|
|
148 |
|
|
149 |
|
|
150 |
|
protected abstract boolean isResponseGzipCompressed(XmlRpcStreamRequestConfig pConfig, Object pConnection); |
151 |
|
|
152 |
|
protected InputStream getInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection, |
153 |
|
byte[] pContent) |
154 |
|
throws XmlRpcException { |
155 |
|
InputStream istream; |
156 |
280 |
if (pContent == null) { |
157 |
107 |
istream = newInputStream(pConfig, pConnection); |
158 |
|
} else { |
159 |
173 |
istream = newInputStream(pConfig, pConnection, pContent); |
160 |
|
} |
161 |
280 |
if (isResponseGzipCompressed(pConfig, pConnection)) { |
162 |
|
try { |
163 |
0 |
istream = new GZIPInputStream(istream); |
164 |
0 |
} catch (IOException e) { |
165 |
0 |
throw new XmlRpcClientException("Failed to attach gzip decompression to the response stream", e); |
166 |
|
} |
167 |
|
} |
168 |
280 |
return istream; |
169 |
|
} |
170 |
|
|
171 |
|
|
172 |
|
|
173 |
|
|
174 |
|
|
175 |
|
|
176 |
|
|
177 |
|
|
178 |
|
|
179 |
|
|
180 |
|
protected boolean isUsingByteArrayOutput(XmlRpcStreamRequestConfig pConfig) { |
181 |
48 |
return false; |
182 |
|
} |
183 |
|
|
184 |
|
public Object sendRequest(XmlRpcRequest pRequest) throws XmlRpcException { |
185 |
384 |
XmlRpcStreamRequestConfig config = (XmlRpcStreamRequestConfig) pRequest.getConfig(); |
186 |
384 |
Object connection = newConnection(config); |
187 |
|
try { |
188 |
384 |
initConnection(config, connection); |
189 |
|
OutputStream ostream; |
190 |
|
ByteArrayOutputStream baos; |
191 |
384 |
if (isUsingByteArrayOutput(config)) { |
192 |
264 |
baos = new ByteArrayOutputStream(); |
193 |
264 |
if (config.isGzipCompressing()) { |
194 |
|
try { |
195 |
0 |
ostream = new GZIPOutputStream(baos); |
196 |
0 |
} catch (IOException e) { |
197 |
0 |
throw new XmlRpcClientException("Failed to create GZIPOutputStream: " + e.getMessage(), e); |
198 |
|
} |
199 |
|
} else { |
200 |
264 |
ostream = baos; |
201 |
|
} |
202 |
|
} else { |
203 |
120 |
baos = null; |
204 |
120 |
ostream = getOutputStream(config, connection); |
205 |
|
} |
206 |
|
try { |
207 |
384 |
writeRequest(config, ostream, pRequest); |
208 |
280 |
closeOutputStream(ostream); |
209 |
280 |
ostream = null; |
210 |
104 |
} finally { |
211 |
384 |
if (ostream != null) { try { closeOutputStream(ostream); } catch (Throwable ignore) {} } |
212 |
104 |
} |
213 |
280 |
InputStream istream = getInputStream(config, connection, baos == null ? null : baos.toByteArray()); |
214 |
|
Object result; |
215 |
|
try { |
216 |
280 |
result = readResponse(config, istream); |
217 |
280 |
closeInputStream(istream); |
218 |
280 |
istream = null; |
219 |
0 |
} finally { |
220 |
280 |
if (istream != null) { try { closeInputStream(istream); } catch (Throwable ignore) {} } |
221 |
0 |
} |
222 |
280 |
closeConnection(connection); |
223 |
280 |
connection = null; |
224 |
560 |
return result; |
225 |
104 |
} finally { |
226 |
384 |
if (connection != null) { try { closeConnection(connection); } catch (Throwable ignore) {} } |
227 |
104 |
} |
228 |
|
} |
229 |
|
|
230 |
|
protected XMLReader newXMLReader() throws XmlRpcClientException { |
231 |
|
try { |
232 |
280 |
return spf.newSAXParser().getXMLReader(); |
233 |
0 |
} catch (ParserConfigurationException e) { |
234 |
0 |
throw new XmlRpcClientException("Failed to create XMLReader: " + e.getMessage(), e); |
235 |
0 |
} catch (SAXException e) { |
236 |
0 |
throw new XmlRpcClientException("Failed to create XMLReader: " + e.getMessage(), e); |
237 |
|
} |
238 |
|
} |
239 |
|
|
240 |
|
protected Object readResponse(XmlRpcStreamRequestConfig pConfig, InputStream pStream) throws XmlRpcException { |
241 |
|
if (true) { |
242 |
280 |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
243 |
|
try { |
244 |
280 |
byte[] buffer = new byte[1024]; |
245 |
280 |
for (;;) { |
246 |
560 |
int res = pStream.read(buffer); |
247 |
560 |
if (res == -1) { |
248 |
280 |
break; |
249 |
280 |
} else if (res > 0) { |
250 |
280 |
baos.write(buffer, 0, res); |
251 |
|
} |
252 |
|
} |
253 |
0 |
} catch (IOException e) { |
254 |
0 |
throw new XmlRpcClientException(e.getMessage(), e); |
255 |
|
} |
256 |
280 |
pStream = new ByteArrayInputStream(baos.toByteArray()); |
257 |
|
} |
258 |
|
|
259 |
280 |
InputSource isource = new InputSource(pStream); |
260 |
280 |
XMLReader xr = newXMLReader(); |
261 |
|
XmlRpcResponseParser xp; |
262 |
|
try { |
263 |
280 |
xp = new XmlRpcResponseParser(pConfig, getClient().getTypeFactory()); |
264 |
280 |
xr.setContentHandler(xp); |
265 |
280 |
xr.parse(isource); |
266 |
0 |
} catch (SAXException e) { |
267 |
0 |
throw new XmlRpcClientException("Failed to parse servers response: " + e.getMessage(), e); |
268 |
0 |
} catch (IOException e) { |
269 |
0 |
throw new XmlRpcClientException("Failed to read servers response: " + e.getMessage(), e); |
270 |
|
} |
271 |
280 |
if (xp.isSuccess()) { |
272 |
280 |
return xp.getResult(); |
273 |
|
} else { |
274 |
0 |
throw new XmlRpcException(xp.getErrorCode(), xp.getErrorMessage()); |
275 |
|
} |
276 |
|
} |
277 |
|
|
278 |
|
protected void writeRequest(XmlRpcStreamRequestConfig pConfig, OutputStream pStream, XmlRpcRequest pRequest) |
279 |
|
throws XmlRpcException { |
280 |
384 |
ContentHandler h = getClient().getXmlWriterFactory().getXmlWriter(pConfig, pStream); |
281 |
384 |
XmlRpcWriter xw = new XmlRpcWriter(pConfig, h, getClient().getTypeFactory()); |
282 |
|
try { |
283 |
384 |
xw.write(pRequest); |
284 |
104 |
} catch (SAXException e) { |
285 |
104 |
Exception ex = e.getException(); |
286 |
104 |
if (ex != null && ex instanceof XmlRpcException) { |
287 |
104 |
throw (XmlRpcException) ex; |
288 |
|
} else { |
289 |
0 |
throw new XmlRpcClientException("Failed to send request: " + e.getMessage(), e); |
290 |
|
} |
291 |
|
} |
292 |
280 |
} |
293 |
|
} |