View Javadoc

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 }