1 package org.codehaus.xfire.fault; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import javax.xml.parsers.DocumentBuilder; 7 import javax.xml.parsers.DocumentBuilderFactory; 8 import javax.xml.parsers.ParserConfigurationException; 9 10 import org.w3c.dom.Document; 11 import org.w3c.dom.Element; 12 13 /*** 14 * <p> 15 * In XFire, applications throw their own declared exceptions which are 16 * then turned into faults. The XFireFault class wraps these exceptions 17 * extracting out the details for the fault message. 18 * </p> 19 * <p> 20 * If the developer wishes to generate their own custom fault messages, 21 * they can either override XFireFault to provide the FaultHandlers with 22 * the necessary information or write a new FaultHandler. 23 * </p> 24 * <p> 25 * TODO Add i18n support 26 * </p> 27 * 28 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a> 29 * @since Feb 14, 2004 30 */ 31 public class XFireFault 32 extends Exception 33 { 34 /*** Fault codes. */ 35 public final static String VERSION_MISMATCH = "VersionMismatch"; 36 public final static String MUST_UNDERSTAND = "MustUnderstand"; 37 public final static String DATA_ENCODING_UNKNOWN = "DataEncodingUnknown"; 38 39 /*** 40 * "The message was incorrectly formed or did not contain the appropriate 41 * information in order to succeed." -- SOAP 1.2 Spec 42 */ 43 public final static String SENDER = "Sender"; 44 45 /*** 46 * <p> 47 * A SOAP 1.2 only fault code. 48 * </p> 49 * <p> 50 * "The message could not be processed for reasons attributable to the 51 * processing of the message rather than to the contents of the message itself." 52 * -- SOAP 1.2 Spec 53 * </p> 54 */ 55 public final static String RECEIVER = "Receiver"; 56 57 private String faultCode; 58 59 private String subCode; 60 61 private Element detail; 62 63 private Exception exception; 64 65 private DocumentBuilder docBuilder; 66 67 private Map namespaces; 68 69 /*** 70 * Create a fault. 71 * 72 * @param string The fault message. 73 * @param exception The exception which caused this fault. 74 * @param code The fault code. See XFireFault's static fields. 75 */ 76 public XFireFault( String message, 77 Exception exception, 78 String code ) 79 { 80 super( message, exception ); 81 this.faultCode = code; 82 this.namespaces = new HashMap(); 83 } 84 85 /*** 86 * Create a fault for the specified exception. The faultCode is 87 * set to RECEIVER. 88 * @param exception 89 */ 90 public XFireFault( Exception exception ) 91 { 92 super( exception ); 93 this.faultCode = RECEIVER; 94 this.namespaces = new HashMap(); 95 } 96 97 /*** 98 * Create a fault with the specified faultCode. The exception 99 * message is used for the fault message. 100 * 101 * @param exception The exception that caused this fault. 102 * @param code The fault code. See XFireFault's static fields. 103 */ 104 public XFireFault(Exception exception, String code) 105 { 106 super( exception.getMessage(), exception ); 107 this.faultCode = code; 108 this.namespaces = new HashMap(); 109 } 110 111 /*** 112 * Create an exception wih the specified fault message 113 * and faultCode. 114 * 115 * @param message The fault message. 116 * @param code The fault code. See XFireFault's static fields. 117 */ 118 public XFireFault(String message, String code) 119 { 120 super( message ); 121 this.faultCode = code; 122 this.namespaces = new HashMap(); 123 } 124 125 public static XFireFault createFault( Exception e ) 126 { 127 XFireFault fault = null; 128 129 if ( e instanceof XFireFault ) 130 { 131 fault = (XFireFault) e; 132 } 133 else 134 { 135 fault = new XFireFault( e ); 136 } 137 138 return fault; 139 } 140 141 /*** 142 * @return 143 */ 144 public String getCode() 145 { 146 return faultCode; 147 } 148 149 public String getReason() 150 { 151 return getMessage(); 152 } 153 154 /*** 155 * Returns the SubCode for the Fault Code. 156 * 157 * @return The SubCode element as detailed by the SOAP 1.2 spec. 158 */ 159 public String getSubCode() 160 { 161 return subCode; 162 } 163 164 public Element getDetailElement() 165 { 166 if ( detail == null ) 167 { 168 try 169 { 170 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 171 DocumentBuilder b = factory.newDocumentBuilder(); 172 173 Document doc = b.newDocument(); 174 detail = doc.createElement("detail"); 175 } 176 catch (ParserConfigurationException e) 177 { 178 throw new RuntimeException("Couldn't find a DOM parser.", e); 179 } 180 } 181 return detail; 182 } 183 184 public void setSubCode(String subCode) 185 { 186 this.subCode = subCode; 187 } 188 189 public String getFaultCode() 190 { 191 return faultCode; 192 } 193 194 public void setFaultCode(String faultCode) 195 { 196 this.faultCode = faultCode; 197 } 198 199 /*** 200 * User defined namespaces which will be written out 201 * on the resultant SOAP Fault (for use easy with SubCodes and Detail) 202 * elements. 203 * 204 * @return 205 */ 206 public Map getNamespaces() 207 { 208 return namespaces; 209 } 210 211 public void addNamespace( String prefix, String ns ) 212 { 213 namespaces.put(prefix, ns); 214 } 215 216 /*** 217 * @return 218 */ 219 public boolean hasDetails() 220 { 221 if ( detail == null ) 222 return false; 223 224 return true; 225 } 226 }