/*
* Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The
* University of Hong Kong (HKU). All Rights Reserved.
*
* This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1]
*
* [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/
package hk.hku.cecid.piazza.commons.soap;
import hk.hku.cecid.piazza.commons.io.IOHandler;
import hk.hku.cecid.piazza.commons.net.ConnectionException;
import hk.hku.cecid.piazza.commons.net.HttpConnector;
import hk.hku.cecid.piazza.commons.util.Headers;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import javax.servlet.http.HttpServletResponse;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* SOAPHttpConnector is an HTTP connector for making HTTP SOAP connections to an
* endpoint.
*
* @author Hugo Y. K. Lam
*
*/
public class SOAPHttpConnector extends HttpConnector {
private static final Logger LOG = LoggerFactory.getLogger(SOAPHttpConnector.class);
/**
* Creates a new instance of SOAPHttpConnector.
*
* @param endpoint the end point, either in String or URL format.
* @throws MalformedURLException if the end point is malformed.
*/
public SOAPHttpConnector(Object endpoint) throws MalformedURLException {
super(endpoint);
}
/**
* Sends an HTTP SOAP request.
*
* @param request the SOAP request message.
* @return the SOAP reply message responsed from the host.
* @throws ConnectionException if failed in sending the HTTP SOAP request or
* creating a new connection.
*/
public SOAPMessage send(SOAPMessage request) throws ConnectionException {
return send(request, createConnection());
}
/**
* Sends an HTTP SOAP request using the given HTTP connection.
*
* @param request the SOAP request message.
* @param connection the HTTP connection for sending the request.
* @return the SOAP reply message responsed from the host.
* @throws ConnectionException if failed in sending the HTTP SOAP request.
*/
public SOAPMessage send(SOAPMessage request, HttpURLConnection connection) throws ConnectionException {
OutputStream outstream = null;
try {
Headers headers = new Headers(connection);
ByteArrayOutputStream soapStream = new ByteArrayOutputStream();
request.writeTo(soapStream);
byte[] soapBytes = soapStream.toByteArray();
soapStream.close();
headers.putMimeHeaders(request.getMimeHeaders());
InputStream instream;
try {
connection.setDoOutput(true);
outstream = connection.getOutputStream();
IOHandler.writeBytes(soapBytes, outstream);
connection.connect();
instream = connection.getInputStream();
}
catch (Exception e) {
// no guarantee server is connected or useful data is sent through error stream
/*
if (connection.getResponseCode() >= 400) {
instream = connection.getErrorStream();
}
else throw e;
*/
throw e;
}
MimeHeaders responseHeaders = headers.getMimeHeaders();
MessageFactory msgFactory = MessageFactory.newInstance();
byte[] responseBytes = IOHandler.readBytes(instream);
int responseCode = connection.getResponseCode();
if (responseBytes.length > 0 && responseCode != HttpServletResponse.SC_NO_CONTENT) {
instream = new ByteArrayInputStream(responseBytes);
try {
//This assumes that any response returned should be a SOAP response
//What if it isn't?
return msgFactory.createMessage(responseHeaders, instream);
}
catch(SOAPException ex) {
//TODO: Should probably throw a custom exception to communicate failure to parse response
LOG.error("HTTP Response code: {} - Unable to parse response: {}",responseCode,ex.getMessage());
LOG.debug("",ex);
}
}
return null;
}
catch (Exception e) {
throw new ConnectionException("Unable to send HTTP SOAP request", e);
}
finally {
try {
if (outstream != null) {
outstream.close();
}
} catch (Exception e) {
}
}
}
}