| /* |
| * Copyright 2001-2004 The Apache Software Foundation. |
| * |
| * Licensed 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.axis ; |
| |
| import java.io.PrintStream; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.Vector; |
| import java.io.PrintWriter; |
| import java.io.StringWriter; |
| |
| import javax.xml.namespace.QName; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.rpc.soap.SOAPFaultException; |
| |
| import org.apache.axis.components.logger.LogFactory; |
| import org.apache.axis.encoding.SerializationContext; |
| import org.apache.axis.message.SOAPEnvelope; |
| import org.apache.axis.message.SOAPFault; |
| import org.apache.axis.message.SOAPHeaderElement; |
| import org.apache.axis.soap.SOAPConstants; |
| import org.apache.axis.utils.JavaUtils; |
| import org.apache.axis.utils.XMLUtils; |
| import org.apache.axis.utils.NetworkUtils; |
| import org.apache.commons.logging.Log; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Text; |
| |
| /** |
| * An exception which maps cleanly to a SOAP fault. |
| * This is a base class for exceptions which are mapped to faults. |
| * SOAP faults contain |
| * <ol> |
| * <li>A fault string |
| * <li>A fault code |
| * <li>A fault actor |
| * <li>Fault details; an xml tree of fault specific stuff |
| * </ol> |
| * @author Doug Davis (dug@us.ibm.com) |
| * @author James Snell (jasnell@us.ibm.com) |
| * @author Steve Loughran |
| */ |
| |
| public class AxisFault extends java.rmi.RemoteException { |
| /** |
| * The <code>Log</code> used by this class for all logging. |
| */ |
| protected static Log log = |
| LogFactory.getLog(AxisFault.class.getName()); |
| |
| protected QName faultCode ; |
| /** SOAP1.2 addition: subcodes of faults; a Vector of QNames */ |
| protected Vector faultSubCode ; |
| protected String faultString = ""; |
| protected String faultActor ; |
| protected Vector faultDetails ; // vector of Element's |
| protected String faultNode ; |
| |
| /** SOAP headers which should be serialized with the Fault. */ |
| protected ArrayList faultHeaders = null; |
| |
| /** |
| * Make an AxisFault based on a passed Exception. If the Exception is |
| * already an AxisFault, simply use that. Otherwise, wrap it in an |
| * AxisFault. If the Exception is an InvocationTargetException (which |
| * already wraps another Exception), get the wrapped Exception out from |
| * there and use that instead of the passed one. |
| * |
| * @param e the <code>Exception</code> to build a fault for |
| * @return an <code>AxisFault</code> representing <code>e</code> |
| */ |
| public static AxisFault makeFault(Exception e) |
| { |
| if (e instanceof InvocationTargetException) { |
| Throwable t = ((InvocationTargetException)e).getTargetException(); |
| if (t instanceof Exception) { |
| e = (Exception)t; |
| } |
| } |
| |
| if (e instanceof AxisFault) { |
| return (AxisFault)e; |
| } |
| |
| return new AxisFault(e); |
| } |
| |
| /** |
| * Make a fault in the <code>Constants.NS_URI_AXIS</code> namespace. |
| * |
| * @param code fault code which will be passed into the Axis namespace |
| * @param faultString fault string |
| * @param actor fault actor |
| * @param details details; if null the current stack trace and classname is |
| * inserted into the details. |
| */ |
| public AxisFault(String code, String faultString, |
| String actor, Element[] details) { |
| this(new QName(Constants.NS_URI_AXIS, code), |
| faultString, actor, details); |
| } |
| |
| /** |
| * Make a fault in any namespace. |
| * |
| * @param code fault code which will be passed into the Axis namespace |
| * @param faultString fault string |
| * @param actor fault actor |
| * @param details details; if null the current stack trace and classname is |
| * inserted into the details. |
| */ |
| public AxisFault(QName code, String faultString, |
| String actor, Element[] details) { |
| super (faultString); |
| setFaultCode( code ); |
| setFaultString( faultString ); |
| setFaultActor( actor ); |
| setFaultDetail( details ); |
| if (details == null) { |
| initFromException(this); |
| } |
| } |
| |
| /** |
| * Make a fault in any namespace. |
| * |
| * @param code fault code which will be passed into the Axis namespace |
| * @param subcodes fault subcodes which will be pased into the Axis namespace |
| * @param faultString fault string |
| * @param actor fault actor, same as fault role in SOAP 1.2 |
| * @param node which node caused the fault on the SOAP path |
| * @param details details; if null the current stack trace and classname is |
| * inserted into the details. |
| * @since axis1.1 |
| */ |
| public AxisFault(QName code, QName[] subcodes, String faultString, |
| String actor, String node, Element[] details) { |
| super (faultString); |
| setFaultCode( code ); |
| if (subcodes != null) { |
| for (int i = 0; i < subcodes.length; i++) { |
| addFaultSubCode( subcodes[i] ); |
| } |
| } |
| setFaultString( faultString ); |
| setFaultActor( actor ); |
| setFaultNode( node ); |
| setFaultDetail( details ); |
| if (details == null) { |
| initFromException(this); |
| } |
| } |
| |
| // fixme: docs says private, access says protected |
| /** |
| * Wrap an AxisFault around an existing Exception. This is private |
| * to force everyone to use makeFault() above, which sanity-checks us. |
| * |
| * @param target the target <code>Exception</code> |
| */ |
| protected AxisFault(Exception target) { |
| super ("", target); |
| // ? SOAP 1.2 or 1.1 ? |
| setFaultCodeAsString( Constants.FAULT_SERVER_USER ); |
| initFromException(target); |
| |
| // if the target is a JAX-RPC SOAPFaultException init |
| // AxisFault with the values from the SOAPFaultException |
| if ( target instanceof SOAPFaultException ) { |
| //strip out the hostname as we want any new one |
| removeHostname(); |
| initFromSOAPFaultException((SOAPFaultException) target); |
| //but if they left it out, add it |
| addHostnameIfNeeded(); |
| } |
| |
| } |
| |
| /** |
| * create a simple axis fault from the message. Classname and stack trace |
| * go into the fault details. |
| * @param message |
| */ |
| public AxisFault(String message) |
| { |
| super (message); |
| setFaultCodeAsString(Constants.FAULT_SERVER_GENERAL); |
| setFaultString(message); |
| initFromException(this); |
| } |
| |
| /** |
| * No-arg constructor for building one from an XML stream. |
| */ |
| public AxisFault() |
| { |
| super(); |
| setFaultCodeAsString(Constants.FAULT_SERVER_GENERAL); |
| initFromException(this); |
| } |
| |
| /** |
| * create a fault from any throwable; |
| * When faulting a throwable (as opposed to an exception), |
| * stack trace information does not go into the fault. |
| * @param message any extra text to with the fault |
| * @param t whatever is to be turned into a fault |
| */ |
| public AxisFault (String message, Throwable t) |
| { |
| super (message, t); |
| setFaultCodeAsString(Constants.FAULT_SERVER_GENERAL); |
| setFaultString(getMessage()); |
| addHostnameIfNeeded(); |
| } |
| |
| /** |
| * fill in soap fault details from the exception, unless |
| * this object already has a stack trace in its details. Which, given |
| * the way this private method is invoked, is a pretty hard situation to ever achieve. |
| * This method adds classname of the exception and the stack trace. |
| * @param target what went wrong |
| */ |
| private void initFromException(Exception target) |
| { |
| //look for old stack trace |
| Element oldStackTrace = lookupFaultDetail(Constants.QNAME_FAULTDETAIL_STACKTRACE); |
| if (oldStackTrace != null) { |
| // todo: Should we replace it or just let it be? |
| return; |
| } |
| |
| // Set the exception message (if any) as the fault string |
| setFaultString( target.toString() ); |
| |
| |
| // Put the exception class into the AXIS SPECIFIC HACK |
| // "exceptionName" element in the details. This allows |
| // us to get back a correct Java Exception class on the other side |
| // (assuming they have it available). |
| // NOTE: This hack is obsolete! We now serialize exception data |
| // and the other side uses *that* QName to figure out what exception |
| // to use, because the class name may be completly different on the |
| // client. |
| if ((target instanceof AxisFault) && |
| (target.getClass() != AxisFault.class)) { |
| addFaultDetail(Constants.QNAME_FAULTDETAIL_EXCEPTIONNAME, |
| target.getClass().getName()); |
| } |
| |
| //add stack trace |
| if (target == this) { |
| // only add stack trace. JavaUtils.stackToString() call would |
| // include dumpToString() info which is already sent as different |
| // elements of this fault. |
| addFaultDetail(Constants.QNAME_FAULTDETAIL_STACKTRACE, |
| getPlainStackTrace()); |
| } else { |
| addFaultDetail(Constants.QNAME_FAULTDETAIL_STACKTRACE, |
| JavaUtils.stackToString(target)); |
| } |
| |
| //add the hostname |
| addHostnameIfNeeded(); |
| } |
| |
| /** |
| * Initiates the AxisFault with the values from a SOAPFaultException |
| * @param fault SOAPFaultException |
| */ |
| private void initFromSOAPFaultException(SOAPFaultException fault) { |
| |
| // faultcode |
| if ( fault.getFaultCode() != null ) { |
| setFaultCode(fault.getFaultCode()); |
| } |
| |
| // faultstring |
| if ( fault.getFaultString() != null ) { |
| setFaultString(fault.getFaultString()); |
| } |
| |
| // actor |
| if ( fault.getFaultActor() != null ) { |
| setFaultActor(fault.getFaultActor()); |
| } |
| |
| if ( null == fault.getDetail() ) { |
| return; |
| } |
| |
| // We get an Iterator but we need a List |
| Vector details = new Vector(); |
| Iterator detailIter = fault.getDetail().getChildElements(); |
| while (detailIter.hasNext()) { |
| details.add( detailIter.next()); |
| } |
| |
| // Convert the List in an Array an return the array |
| setFaultDetail( XMLUtils.asElementArray(details)); |
| } |
| |
| /** |
| * Init the fault details data structure; does nothing |
| * if this exists already. |
| */ |
| private void initFaultDetails() { |
| if (faultDetails == null) { |
| faultDetails = new Vector(); |
| } |
| } |
| |
| /** |
| * Clear the fault details list. |
| */ |
| public void clearFaultDetails() { |
| faultDetails=null; |
| } |
| |
| /** |
| * Dump the fault info to the log at debug level. |
| */ |
| public void dump() { |
| log.debug(dumpToString()); |
| } |
| |
| |
| /** |
| * turn the fault and details into a string, with XML escaping. |
| * subclassers: for security (cross-site-scripting) reasons, |
| * escape everything that could contain caller-supplied data. |
| * @return stringified fault details |
| */ |
| public String dumpToString() |
| { |
| StringBuffer buf = new StringBuffer("AxisFault"); |
| buf.append(JavaUtils.LS); |
| buf.append(" faultCode: "); |
| buf.append(XMLUtils.xmlEncodeString(faultCode.toString())); |
| buf.append(JavaUtils.LS); |
| buf.append(" faultSubcode: "); |
| if (faultSubCode != null) { |
| for (int i = 0; i < faultSubCode.size(); i++) { |
| buf.append(JavaUtils.LS); |
| buf.append(faultSubCode.elementAt(i).toString()); |
| } |
| } |
| buf.append(JavaUtils.LS); |
| buf.append(" faultString: "); |
| try { |
| buf.append(XMLUtils.xmlEncodeString(faultString)); |
| } catch (RuntimeException re) { |
| buf.append(re.getMessage()); |
| } |
| buf.append(JavaUtils.LS); |
| buf.append(" faultActor: "); |
| buf.append(XMLUtils.xmlEncodeString(faultActor)); |
| buf.append(JavaUtils.LS); |
| buf.append(" faultNode: "); |
| buf.append(XMLUtils.xmlEncodeString(faultNode)); |
| buf.append(JavaUtils.LS); |
| buf.append(" faultDetail: "); |
| if (faultDetails != null) { |
| for (int i=0; i < faultDetails.size(); i++) { |
| Element e = (Element) faultDetails.get(i); |
| buf.append(JavaUtils.LS); |
| buf.append("\t{"); |
| buf.append(null == e.getNamespaceURI() ? "" : e.getNamespaceURI()); |
| buf.append("}"); |
| buf.append(null == e.getLocalName() ? "" : e.getLocalName()); |
| buf.append(":"); |
| buf.append(XMLUtils.getInnerXMLString(e)); |
| } |
| } |
| buf.append(JavaUtils.LS); |
| return buf.toString(); |
| } |
| |
| /** |
| * Set the fault code. |
| * |
| * @param code a new fault code |
| */ |
| public void setFaultCode(QName code) { |
| faultCode = code ; |
| } |
| |
| /** |
| * Set the fault code (as a String). |
| * |
| * @param code a new fault code |
| * @deprecated expect to see this go away after 1.1, use |
| * setFaultCodeAsString instead! |
| */ |
| |
| public void setFaultCode(String code) { |
| setFaultCodeAsString(code); |
| } |
| |
| /** |
| * set a fault code string that is turned into a qname |
| * in the SOAP 1.1 or 1.2 namespace, depending on the current context |
| * @param code fault code |
| */ |
| public void setFaultCodeAsString(String code) { |
| SOAPConstants soapConstants = MessageContext.getCurrentContext() == null ? |
| SOAPConstants.SOAP11_CONSTANTS : |
| MessageContext.getCurrentContext().getSOAPConstants(); |
| |
| faultCode = new QName(soapConstants.getEnvelopeURI(), code); |
| } |
| |
| /** |
| * Get the fault code <code>QName</code>. |
| * |
| * @return fault code QName or null if there is none yet. |
| */ |
| public QName getFaultCode() { |
| return( faultCode ); |
| } |
| |
| /** |
| * Add a fault sub-code with the local name <code>code</code> and namespace |
| * <code>Constants.NS_URI_AXIS</code>. |
| * This is new in SOAP 1.2, ignored in SOAP 1.1 |
| * |
| * @param code the local name of the code to add |
| * @since axis1.1 |
| */ |
| public void addFaultSubCodeAsString(String code) { |
| initFaultSubCodes(); |
| faultSubCode.add(new QName(Constants.NS_URI_AXIS, code)); |
| } |
| |
| /** |
| * Do whatever is needed to create the fault subcodes |
| * data structure, if it is needed. |
| */ |
| protected void initFaultSubCodes() { |
| if (faultSubCode == null) { |
| faultSubCode = new Vector(); |
| } |
| } |
| |
| /** |
| * Add a fault sub-code. |
| * This is new in SOAP 1.2, ignored in SOAP 1.1. |
| * |
| * @param code the <code>QName</code> of the fault sub-code to add |
| * @since axis1.1 |
| */ |
| public void addFaultSubCode(QName code) { |
| initFaultSubCodes(); |
| faultSubCode.add(code); |
| } |
| |
| /** |
| * Clear all fault sub-codes. |
| * This is new in SOAP 1.2, ignored in SOAP 1.1. |
| * |
| * @since axis1.1 |
| */ |
| public void clearFaultSubCodes() { |
| faultSubCode = null; |
| } |
| |
| /** |
| * get the fault subcode list; only used in SOAP 1.2 |
| * @since axis1.1 |
| * @return null for no subcodes, or a QName array |
| */ |
| public QName[] getFaultSubCodes() { |
| if (faultSubCode == null) { |
| return null; |
| } |
| QName[] q = new QName[faultSubCode.size()]; |
| return (QName[])faultSubCode.toArray(q); |
| } |
| |
| |
| /** |
| * Set a fault string. |
| * @param str new fault string; null is turned into "" |
| */ |
| public void setFaultString(String str) { |
| if (str != null) { |
| faultString = str ; |
| } else { |
| faultString = ""; |
| } |
| } |
| |
| /** |
| * Get the fault string; this will never be null but may be the |
| * empty string. |
| * |
| * @return a fault string |
| */ |
| public String getFaultString() { |
| return( faultString ); |
| } |
| |
| /** |
| * This is SOAP 1.2 equivalent of {@link #setFaultString(java.lang.String)}. |
| * |
| * @param str the fault reason as a <code>String</code> |
| * @since axis1.1 |
| */ |
| public void setFaultReason(String str) { |
| setFaultString(str); |
| } |
| |
| /** |
| * This is SOAP 1.2 equivalent of {@link #getFaultString()}. |
| * @since axis1.1 |
| * @return the fault <code>String</code> |
| */ |
| public String getFaultReason() { |
| return getFaultString(); |
| } |
| |
| /** |
| * Set the fault actor. |
| * |
| * @param actor fault actor |
| */ |
| public void setFaultActor(String actor) { |
| faultActor = actor ; |
| } |
| |
| /** |
| * get the fault actor |
| * @return actor or null |
| */ |
| public String getFaultActor() { |
| return( faultActor ); |
| } |
| |
| /** |
| * This is SOAP 1.2 equivalent of {@link #getFaultActor()}. |
| * @since axis1.1 |
| * @return the name of the fault actor |
| */ |
| public String getFaultRole() { |
| return getFaultActor(); |
| } |
| |
| // fixme: both faultRole and faultActor refer to the other one - can we |
| // break the circularity here? |
| /** |
| * This is SOAP 1.2 equivalent of {@link #setFaultActor(java.lang.String)}. |
| * @since axis1.1 |
| */ |
| public void setFaultRole(String role) { |
| setFaultActor(role); |
| } |
| |
| /** |
| * Get the fault node. |
| * |
| * This is new in SOAP 1.2 |
| * @since axis1.1 |
| * @return |
| */ |
| public String getFaultNode() { |
| return( faultNode ); |
| } |
| |
| /** |
| * Set the fault node. |
| * |
| * This is new in SOAP 1.2. |
| * |
| * @param node a <code>String</code> representing the fault node |
| * @since axis1.1 |
| */ |
| public void setFaultNode(String node) { |
| faultNode = node; |
| } |
| |
| /** |
| * Set the fault detail element to the arrary of details. |
| * |
| * @param details list of detail elements, can be null |
| */ |
| public void setFaultDetail(Element[] details) { |
| if ( details == null ) { |
| faultDetails=null; |
| return ; |
| } |
| faultDetails = new Vector( details.length ); |
| for ( int loop = 0 ; loop < details.length ; loop++ ) { |
| faultDetails.add( details[loop] ); |
| } |
| } |
| |
| /** |
| * set the fault details to a string element. |
| * @param details XML fragment |
| */ |
| public void setFaultDetailString(String details) { |
| clearFaultDetails(); |
| addFaultDetailString(details); |
| } |
| |
| /** |
| * add a string tag to the fault details. |
| * @param detail XML fragment |
| */ |
| public void addFaultDetailString(String detail) { |
| initFaultDetails(); |
| try { |
| Document doc = XMLUtils.newDocument(); |
| Element element = doc.createElement("string"); |
| Text text = doc.createTextNode(detail); |
| element.appendChild(text); |
| faultDetails.add(element); |
| } catch (ParserConfigurationException e) { |
| // This should not occur |
| throw new InternalException(e); |
| } |
| } |
| |
| /** |
| * Append an element to the fault detail list. |
| * |
| * @param detail the new element to add |
| * @since Axis1.1 |
| */ |
| public void addFaultDetail(Element detail) { |
| initFaultDetails(); |
| faultDetails.add(detail); |
| } |
| |
| /** |
| * Create an element of the given qname and add it to the details. |
| * |
| * @param qname qname of the element |
| * @param body string to use as body |
| */ |
| public void addFaultDetail(QName qname,String body) { |
| Element detail = XMLUtils.StringToElement(qname.getNamespaceURI(), |
| qname.getLocalPart(), |
| body); |
| |
| addFaultDetail(detail); |
| } |
| |
| // fixme: should we be returning null for none or a zero length array? |
| /** |
| * Get all the fault details. |
| * |
| * @return an array of fault details, or null for none |
| */ |
| public Element[] getFaultDetails() { |
| if (faultDetails == null) { |
| return null; |
| } |
| Element result[] = new Element[faultDetails.size()]; |
| for (int i=0; i<result.length; i++) { |
| result[i] = (Element) faultDetails.elementAt(i); |
| } |
| return result; |
| } |
| |
| /** |
| * Find a fault detail element by its qname. |
| * @param qname name of the node to look for |
| * @return the matching element or null |
| * @since axis1.1 |
| */ |
| public Element lookupFaultDetail(QName qname) { |
| if (faultDetails != null) { |
| //extract details from the qname. the empty namespace is represented |
| //by the empty string |
| String searchNamespace = qname.getNamespaceURI(); |
| String searchLocalpart = qname.getLocalPart(); |
| //now spin through the elements, seeking a match |
| Iterator it=faultDetails.iterator(); |
| while (it.hasNext()) { |
| Element e = (Element) it.next(); |
| String localpart= e.getLocalName(); |
| if(localpart==null) { |
| localpart=e.getNodeName(); |
| } |
| String namespace= e.getNamespaceURI(); |
| if(namespace==null) { |
| namespace=""; |
| } |
| //we match on matching namespace and local part; empty namespace |
| //in an element may be null, which matches QName's "" |
| if(searchNamespace.equals(namespace) |
| && searchLocalpart.equals(localpart)) { |
| return e; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Find and remove a specified fault detail element. |
| * |
| * @param qname qualified name of detail |
| * @return true if it was found and removed, false otherwise |
| * @since axis1.1 |
| */ |
| public boolean removeFaultDetail(QName qname) { |
| Element elt=lookupFaultDetail(qname); |
| if(elt==null) { |
| return false; |
| } else { |
| return faultDetails.remove(elt); |
| } |
| } |
| |
| /** |
| * Add this fault and any needed headers to the output context. |
| * |
| * @param context |
| * @throws Exception |
| */ |
| public void output(SerializationContext context) throws Exception { |
| |
| SOAPConstants soapConstants = Constants.DEFAULT_SOAP_VERSION; |
| if (context.getMessageContext() != null) { |
| soapConstants = context.getMessageContext().getSOAPConstants(); |
| } |
| |
| SOAPEnvelope envelope = new SOAPEnvelope(soapConstants); |
| |
| SOAPFault fault = new SOAPFault(this); |
| envelope.addBodyElement(fault); |
| |
| // add any headers we need |
| if (faultHeaders != null) { |
| for (Iterator i = faultHeaders.iterator(); i.hasNext();) { |
| SOAPHeaderElement header = (SOAPHeaderElement) i.next(); |
| envelope.addHeader(header); |
| } |
| } |
| |
| envelope.output(context); |
| } |
| |
| /** |
| * Stringify this fault as the current fault string. |
| * |
| * @return the fault string, possibly the empty string, but never null |
| */ |
| public String toString() { |
| return faultString; |
| } |
| |
| /** |
| * Gets the stack trace as a string. |
| */ |
| private String getPlainStackTrace() { |
| StringWriter sw = new StringWriter(512); |
| PrintWriter pw = new PrintWriter(sw); |
| super.printStackTrace(pw); |
| pw.close(); |
| return sw.toString(); |
| } |
| |
| /** |
| * The override of the base class method prints out the |
| * fault info before the stack trace. |
| * |
| * @param ps where to print |
| */ |
| public void printStackTrace(PrintStream ps) { |
| ps.println(dumpToString()); |
| super.printStackTrace(ps); |
| } |
| |
| /** |
| * The override of the base class method prints out the |
| * fault info before the stack trace. |
| * |
| * @param pw where to print |
| */ |
| public void printStackTrace(java.io.PrintWriter pw) { |
| pw.println(dumpToString()); |
| super.printStackTrace(pw); |
| } |
| |
| /** |
| * Add a SOAP header which should be serialized along with the |
| * fault. |
| * |
| * @param header a SOAPHeaderElement containing some fault-relevant stuff |
| */ |
| public void addHeader(SOAPHeaderElement header) { |
| if (faultHeaders == null) { |
| faultHeaders = new ArrayList(); |
| } |
| faultHeaders.add(header); |
| } |
| |
| /** |
| * Get the SOAP headers associated with this fault. |
| * |
| * @return an ArrayList containing any headers associated with this fault |
| */ |
| public ArrayList getHeaders() { |
| return faultHeaders; |
| } |
| |
| /** |
| * Clear all fault headers. |
| */ |
| public void clearHeaders() { |
| faultHeaders = null; |
| } |
| |
| |
| /** |
| * Writes any exception data to the faultDetails. |
| * |
| * This can be overridden (and is) by emitted exception clases. |
| * The base implementation will attempt to serialize exception data the |
| * fault was created from an Exception and a type mapping is found for it. |
| * |
| * @param qname the <code>QName</code> to write this under |
| * @param context the <code>SerializationContext</code> to write this fault |
| * to |
| * @throws java.io.IOException if we can't write ourselves for any reason |
| */ |
| public void writeDetails(QName qname, SerializationContext context) |
| throws java.io.IOException { |
| Object detailObject = this.detail; |
| if (detailObject == null) { |
| return; |
| } |
| |
| boolean haveSerializer = false; |
| try { |
| if (context.getTypeMapping().getSerializer(detailObject.getClass()) != null) { |
| haveSerializer = true; |
| } |
| } catch (Exception e) { |
| // swallow this exception, it means that we don't know how to serialize |
| // the details. |
| } |
| if (haveSerializer) { |
| boolean oldMR = context.getDoMultiRefs(); |
| context.setDoMultiRefs(false); |
| context.serialize(qname, null, detailObject); |
| context.setDoMultiRefs(oldMR); |
| } |
| } |
| |
| /** |
| * add the hostname of the current system. This is very useful for |
| * locating faults on a cluster. |
| * @since Axis1.2 |
| */ |
| public void addHostnameIfNeeded() { |
| //look for an existing declaration |
| if(lookupFaultDetail(Constants.QNAME_FAULTDETAIL_HOSTNAME)!=null) { |
| //and do nothing if it exists |
| return; |
| } |
| addHostname(NetworkUtils.getLocalHostname()); |
| } |
| |
| /** |
| * add the hostname string. If one already exists, remove it. |
| * @param hostname string name of a host |
| * @since Axis1.2 |
| */ |
| public void addHostname(String hostname) { |
| //add the hostname |
| removeHostname(); |
| addFaultDetail(Constants.QNAME_FAULTDETAIL_HOSTNAME, |
| hostname); |
| } |
| |
| /** |
| * strip out the hostname on a message. This |
| * is useful for security reasons. |
| */ |
| public void removeHostname() { |
| removeFaultDetail(Constants.QNAME_FAULTDETAIL_HOSTNAME); |
| } |
| } |