package com.redhat.gss.valve;
import java.io.IOException;
import static org.jboss.web.CatalinaMessages.MESSAGES;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.catalina.valves.ErrorReportValve;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.util.RequestUtil;
import javax.servlet.http.HttpServletResponse;
import org.jboss.logging.Logger;
import java.io.Writer;
import javax.xml.namespace.QName;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.soap.SOAPFault;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
public class SoapErrorValve extends ErrorReportValve
{
private static Logger log = Logger.getLogger(SoapErrorValve.class);
private static final String SOAP = "http://schemas.xmlsoap.org/soap/envelope/";
private static final QName serverFault = new QName(SOAP, "Server");
private static final QName clientFault = new QName(SOAP, "Client");
private TransformerFactory transformerFactory = TransformerFactory.newInstance();
@Override
public void report(Request request, Response response, Throwable exception)
{
// Do nothing on non-HTTP responses
int statusCode = response.getStatus();
// Do nothing on a 1xx, 2xx and 3xx status
// Do nothing if anything has been written already
if ((statusCode < 400) || (response.getContentCount() > 0))
return;
String message = RequestUtil.filter(response.getMessage());
if (message == null)
message = "";
StringWriter result = new StringWriter();
try
{
SOAPMessage soapMessage = createNewSoapMessage();
SOAPPart requestSoapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = requestSoapPart.getEnvelope();
SOAPBody body = envelope.getBody();
SOAPFault fault = body.addFault(getFaultCode(statusCode),
getFaultString(statusCode, message, exception));
DOMSource source = new DOMSource(envelope);
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(source, new StreamResult(result));
}
catch(Exception e)
{
log.debug("Error creating SOAP fault", e);
//Delegate to the other ErrorReportValve
return;
}
try
{
try
{
response.setContentType("application/soap+xml");
response.setCharacterEncoding("utf-8");
}
catch (Throwable t)
{
if (container.getLogger().isDebugEnabled())
container.getLogger().debug("status.setContentType", t);
}
Writer writer = response.getReporter();
if (writer != null)
{
// If writer is null, it's an indication that the response has
// been hard committed already, which should never happen
writer.write(result.toString());
}
}
catch (IOException e)
{
}
catch (IllegalStateException e)
{
}
}
private QName getFaultCode(int statusCode)
{
if(statusCode < 500)
return clientFault;
else
return serverFault;
}
private String getFaultString(int statusCode, String message, Throwable t)
{
if(t == null && !message.equals(""))
return message;
else if(!message.equals(""))
return message + t.getMessage();
String report = null;
switch (statusCode) {
case 404: report = MESSAGES.http404(); break;
case 500: report = MESSAGES.http500(); break;
case 400: report = MESSAGES.http400(); break;
case 403: report = MESSAGES.http403(); break;
case 401: report = MESSAGES.http401(); break;
case 402: report = MESSAGES.http402(); break;
case 405: report = MESSAGES.http405(); break;
case 406: report = MESSAGES.http406(); break;
case 407: report = MESSAGES.http407(); break;
case 408: report = MESSAGES.http408(); break;
case 409: report = MESSAGES.http409(); break;
case 410: report = MESSAGES.http410(); break;
case 411: report = MESSAGES.http411(); break;
case 412: report = MESSAGES.http412(); break;
case 413: report = MESSAGES.http413(); break;
case 414: report = MESSAGES.http414(); break;
case 415: report = MESSAGES.http415(); break;
case 416: report = MESSAGES.http416(); break;
case 417: report = MESSAGES.http417(); break;
case 422: report = MESSAGES.http422(); break;
case 423: report = MESSAGES.http423(); break;
case 424: report = MESSAGES.http424(); break;
case 426: report = MESSAGES.http426(); break;
case 428: report = MESSAGES.http428(); break;
case 429: report = MESSAGES.http429(); break;
case 431: report = MESSAGES.http431(); break;
case 501: report = MESSAGES.http501(); break;
case 502: report = MESSAGES.http502(); break;
case 503: report = MESSAGES.http503(); break;
case 504: report = MESSAGES.http504(); break;
case 505: report = MESSAGES.http505(); break;
case 506: report = MESSAGES.http506(); break;
case 507: report = MESSAGES.http507(); break;
case 508: report = MESSAGES.http508(); break;
case 510: report = MESSAGES.http510(); break;
case 511: report = MESSAGES.http511(); break;
}
if(report != null)
return report;
else //just make something up
return "HTTP " + statusCode;
}
private SOAPMessage createNewSoapMessage()
{
try
{
MessageFactory factory = MessageFactory.newInstance();
return factory.createMessage();
}
catch (SOAPException e)
{
throw new RuntimeException("Error composing message: " + e.getMessage(), e);
}
}
}