/* * 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.Sys; import hk.hku.cecid.piazza.commons.io.IOHandler; import hk.hku.cecid.piazza.commons.servlet.RequestListenerException; import hk.hku.cecid.piazza.commons.servlet.http.HttpRequestAdaptor; import hk.hku.cecid.piazza.commons.util.Headers; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.net.HttpURLConnection; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.soap.MessageFactory; import javax.xml.soap.MimeHeaders; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPFactory; import javax.xml.soap.SOAPMessage; /** * SOAPHttpAdaptor is both an HttpRequestListener and SOAPRequestListener. It is * an adaptor for handling SOAP on Http requests. * * @author Hugo Y. K. Lam * */ public abstract class SOAPHttpAdaptor extends HttpRequestAdaptor implements SOAPRequestListener { /** * A SOAP message factory. */ protected MessageFactory msgFactory; /** * A SOAP factory. */ protected SOAPFactory soapFactory; /** * Creates a new instance of MessageFactory. * * @throws RequestListenerException if unable to create MessageFactory. * @see hk.hku.cecid.piazza.commons.servlet.RequestListener#listenerCreated() */ public void listenerCreated() throws RequestListenerException { try { msgFactory = MessageFactory.newInstance(); soapFactory = SOAPFactory.newInstance(); } catch (Exception e) { throw new RequestListenerException( "Unable to create SOAP factories", e); } } /** * Cleans up resources. * * @see hk.hku.cecid.piazza.commons.servlet.RequestListener#listenerDestroyed() */ public void listenerDestroyed() throws RequestListenerException { msgFactory = null; } /** * Processes the HTTP request and transforms it into a SOAP request. * * @see hk.hku.cecid.piazza.commons.servlet.http.HttpRequestListener#processRequest(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ public String processRequest(HttpServletRequest request, HttpServletResponse response) throws RequestListenerException { try { Headers headers = new Headers(request, response); /* * Create a SOAP response object. */ SOAPResponse soapResponse = new SOAPResponse(response); SOAPMessage responseMessage = msgFactory.createMessage(); soapResponse.setMessage(responseMessage); try { /* * Create a SOAP request object. */ MimeHeaders mimeHeaders = headers.getMimeHeaders(); byte[] requestBytes; InputStream requestStream; if (isCacheEnabled()) { requestBytes = IOHandler.readBytes(request.getInputStream()); requestStream = new ByteArrayInputStream(requestBytes); } else { requestBytes = null; requestStream = request.getInputStream(); } SOAPMessage soapMessage; try { soapMessage = msgFactory.createMessage(mimeHeaders, requestStream); soapMessage.getSOAPPart().getEnvelope().getBody(); } catch (SOAPException e) { throw new SOAPFaultException( SOAPFaultException.SOAP_FAULT_CLIENT, "Invalid SOAP message: " + e.getMessage(), e); } SOAPRequest soapRequest = new SOAPRequest(request); soapRequest.setBytes(requestBytes); soapRequest.setHeaders(mimeHeaders); soapRequest.setMessage(soapMessage); /* * Prcoess the SOAP request. */ processRequest(soapRequest, soapResponse); } catch (Throwable e) { /* * If there is any exception, create a SOAP fault if SOAP fault * reporting is enabled. */ if (isSOAPFaultEnabled()) { Sys.main.log.error("SOAP fault exception trace", e); soapResponse.addFault(e); } else { throw e; } } /* * Process the SOAP response. */ SOAPMessage replyMessage = soapResponse.getMessage(); if (replyMessage != null) { if (replyMessage.saveRequired()) { replyMessage.saveChanges(); } /* * Set the content type if the SOAP message is not multipart. * Otherwise, unset the content type and let the mime headers * define it. */ if (replyMessage.countAttachments() == 0) { response.setContentType("text/xml;charset=UTF-8"); } else { response.setContentType(null); } headers.putMimeHeaders(replyMessage.getMimeHeaders()); /* * Write the response message. */ javax.servlet.ServletOutputStream servletOutputStream = response .getOutputStream(); replyMessage.writeTo(servletOutputStream); servletOutputStream.flush(); } else { response.setStatus(HttpURLConnection.HTTP_NO_CONTENT); } return null; } catch (Throwable e) { throw new RequestListenerException( "Error in transforming the HTTP request into SOAP request", e); } } /** * Checks if errors in the request process should be reported as a SOAP * fault to the client. * * @return true if SOAP fault reporting is enabled. */ protected boolean isSOAPFaultEnabled() { return true; } /** * Checks if cache in memory should be enabled. If this method returns * false, it indicates that the SOAP request object will not provide a byte * array cache of the original SOAP request. * * @return true if cache in memory should be enabled. */ protected boolean isCacheEnabled() { return true; } }