org.apache.xmlrpc.client.XmlRpcStreamTransport Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.xmlrpc.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.XmlRpcRequest;
import org.apache.xmlrpc.common.XmlRpcStreamConfig;
import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
import org.apache.xmlrpc.parser.XmlRpcResponseParser;
import org.apache.xmlrpc.serializer.XmlRpcWriter;
import org.apache.xmlrpc.util.SAXParsers;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/** Implementation of a transport class, which is based on an output
* stream for sending the request and an input stream for receiving
* the response,
*/
public abstract class XmlRpcStreamTransport extends XmlRpcTransportImpl {
protected interface ReqWriter {
/**
* Writes the requests data to the given output stream.
* The method ensures, that the target is being closed.
*
* @param pStream the output stream
* @throws XmlRpcException if an XML-RPC error occurs
* @throws IOException if an I/O error occurs
* @throws SAXException if a SAX error occurs
*/
void write(OutputStream pStream) throws XmlRpcException, IOException, SAXException;
}
protected class ReqWriterImpl implements ReqWriter {
private final XmlRpcRequest request;
protected ReqWriterImpl(XmlRpcRequest pRequest) {
request = pRequest;
}
/** Writes the requests uncompressed XML data to the given
* output stream. Ensures, that the output stream is being
* closed.
*
* @param pStream the output stream
* @throws XmlRpcException if an XML-RPC error occurs
* @throws IOException if an I/O error occurs
* @throws SAXException if a SAX error occurs
*/
public void write(OutputStream pStream)
throws XmlRpcException, IOException, SAXException {
final XmlRpcStreamConfig config = (XmlRpcStreamConfig) request.getConfig();
try {
ContentHandler h = getClient().getXmlWriterFactory().getXmlWriter(config, pStream);
XmlRpcWriter xw = new XmlRpcWriter(config, h, getClient().getTypeFactory());
xw.write(request);
pStream.close();
pStream = null;
} finally {
if (pStream != null) { try { pStream.close(); } catch (Throwable ignore) {} }
}
}
}
protected class GzipReqWriter implements ReqWriter {
private final ReqWriter reqWriter;
protected GzipReqWriter(ReqWriter pReqWriter) {
reqWriter = pReqWriter;
}
public void write(OutputStream pStream) throws XmlRpcException, IOException, SAXException {
try {
GZIPOutputStream gStream = new GZIPOutputStream(pStream);
reqWriter.write(gStream);
pStream.close();
pStream = null;
} catch (IOException e) {
throw new XmlRpcException("Failed to write request: " + e.getMessage(), e);
} finally {
if (pStream != null) { try { pStream.close(); } catch (Throwable ignore) {} }
}
}
}
/** Creates a new instance on behalf of the given client.
*
* @param pClient the client
*/
protected XmlRpcStreamTransport(XmlRpcClient pClient) {
super(pClient);
}
/** Closes the connection and ensures, that all resources are being
* released.
* @throws XmlRpcClientException if an RPC error occurs
*/
protected abstract void close() throws XmlRpcClientException;
/** Returns, whether the response is gzip compressed.
* @param pConfig The clients configuration.
* @return Whether the response stream is gzip compressed.
*/
protected abstract boolean isResponseGzipCompressed(XmlRpcStreamRequestConfig pConfig);
/** Returns the input stream, from which the response is
* being read.
* @return the input stream
* @throws XmlRpcClientException if an RPC error occurs
*/
protected abstract InputStream getInputStream() throws XmlRpcException;
protected boolean isCompressingRequest(XmlRpcStreamRequestConfig pConfig) {
return pConfig.isEnabledForExtensions()
&& pConfig.isGzipCompressing();
}
/**
* Creates a new instance of {@link ReqWriter}.
* @param pRequest the request
* @return the request writer
* @throws XmlRpcException Creating the instance failed.
* @throws IOException Creating the instance failed, because
* an {@link IOException} occurs.
* @throws SAXException Creating the instance failed, because
* the request could not be parsed.
*/
protected ReqWriter newReqWriter(XmlRpcRequest pRequest)
throws XmlRpcException, IOException, SAXException {
ReqWriter reqWriter = new ReqWriterImpl(pRequest);
if (isCompressingRequest((XmlRpcStreamRequestConfig) pRequest.getConfig())) {
reqWriter = new GzipReqWriter(reqWriter);
}
return reqWriter;
}
protected abstract void writeRequest(ReqWriter pWriter)
throws XmlRpcException, IOException, SAXException;
public Object sendRequest(XmlRpcRequest pRequest) throws XmlRpcException {
XmlRpcStreamRequestConfig config = (XmlRpcStreamRequestConfig) pRequest.getConfig();
boolean closed = false;
try {
ReqWriter reqWriter = newReqWriter(pRequest);
writeRequest(reqWriter);
InputStream istream = getInputStream();
if (isResponseGzipCompressed(config)) {
istream = new GZIPInputStream(istream);
}
Object result = readResponse(config, istream);
closed = true;
close();
return result;
} catch (IOException e) {
throw new XmlRpcException("Failed to read server's response: "
+ e.getMessage(), e);
} catch (SAXException e) {
Exception ex = e.getException();
if (ex != null && ex instanceof XmlRpcException) {
throw (XmlRpcException) ex;
}
throw new XmlRpcException("Failed to generate request: "
+ e.getMessage(), e);
} finally {
if (!closed) { try { close(); } catch (Throwable ignore) {} }
}
}
protected XMLReader newXMLReader() throws XmlRpcException {
return SAXParsers.newXMLReader();
}
protected Object readResponse(XmlRpcStreamRequestConfig pConfig, InputStream pStream) throws XmlRpcException {
InputSource isource = new InputSource(pStream);
XMLReader xr = newXMLReader();
XmlRpcResponseParser xp;
try {
xp = new XmlRpcResponseParser(pConfig, getClient().getTypeFactory());
xr.setContentHandler(xp);
xr.parse(isource);
} catch (SAXException e) {
throw new XmlRpcClientException("Failed to parse server's response: " + e.getMessage(), e);
} catch (IOException e) {
throw new XmlRpcClientException("Failed to read server's response: " + e.getMessage(), e);
}
if (xp.isSuccess()) {
return xp.getResult();
}
Throwable t = xp.getErrorCause();
if (t == null) {
throw new XmlRpcException(xp.getErrorCode(), xp.getErrorMessage());
}
if (t instanceof XmlRpcException) {
throw (XmlRpcException) t;
}
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
throw new XmlRpcException(xp.getErrorCode(), xp.getErrorMessage(), t);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy