View Javadoc

    1   package org.codehaus.xfire.fault;
    2
    3   import java.io.PrintStream;
    4   import java.io.PrintWriter;
    5   import java.util.HashMap;
    6   import java.util.Map;
    7
    8   import org.codehaus.xfire.XFireException;
    9   import org.codehaus.yom.Element;
    10
    11  /***
    12   * In XFire, applications throw their own declared exceptions which are then turned into faults.  The
    13   * <code>XFireFault</code> class wraps these exceptions extracting out the details for the fault message.
    14   * <p/>
    15   * If the developer wishes to generate their own custom fault messages, they can either override XFireFault to provide
    16   * the FaultHandlers with the necessary information or write a new FaultHandler. </p>
    17   * <p/>
    18   * TODO Add i18n support
    19   *
    20   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
    21   * @since Feb 14, 2004
    22   */
    23  public class XFireFault
    24          extends XFireException
    25  {
    26      /***
    27  	 * Serialization ID.
    28  	 */
    29  	private static final long serialVersionUID = 1L;
    30
    31  	/***
    32       * Fault codes.
    33       */
    34      public final static String VERSION_MISMATCH = "VersionMismatch";
    35      public final static String MUST_UNDERSTAND = "MustUnderstand";
    36      public final static String DATA_ENCODING_UNKNOWN = "DataEncodingUnknown";
    37
    38      /***
    39       * "The message was incorrectly formed or did not contain the appropriate information in order to succeed." -- SOAP
    40       * 1.2 Spec
    41       */
    42      public final static String SENDER = "Sender";
    43
    44      /***
    45       * A SOAP 1.2 only fault code.
    46       * <p/>
    47       * "The message could not be processed for reasons attributable to the processing of the message rather than to the
    48       * contents of the message itself." -- SOAP 1.2 Spec
    49       * <p/>
    50       * If this message is used in a SOAP 1.1 Fault it will most likely (depending on the FaultHandler) be mapped to
    51       * "Sender" instead.
    52       */
    53      public final static String RECEIVER = "Receiver";
    54
    55      private String faultCode;
    56      private String subCode;
    57      private String message;
    58      private String role;
    59      private Element detail;
    60      private Map namespaces;
    61      private Throwable cause;
    62
    63      /***
    64       * Creates a <code>XFireFault</code> from the given throwable. If the throwable is a <code>XFireFault</code>, it is
    65       * not wrapped.
    66       *
    67       * @param throwable the throwable
    68       * @return the fault
    69       */
    70      public static XFireFault createFault(Throwable throwable)
    71      {
    72          XFireFault fault = null;
    73
    74          if (throwable instanceof XFireFault)
    75          {
    76              fault = (XFireFault) throwable;
    77          }
    78          else
    79          {
    80              fault = new XFireFault(throwable);
    81          }
    82
    83          return fault;
    84      }
    85
    86      protected XFireFault()
    87      {
    88      }
    89
    90      /***
    91       * Create a fault for the specified exception. The faultCode is set to RECEIVER.
    92       *
    93       * @param throwable
    94       */
    95      public XFireFault(Throwable throwable)
    96      {
    97          this(throwable.getMessage(), throwable, RECEIVER);
    98      }
    99
    100     /***
    101      * Create a fault with the specified faultCode. The exception message is used for the fault message.
    102      *
    103      * @param throwable The exception that caused this fault.
    104      * @param code      The fault code. See XFireFault's static fields.
    105      */
    106     public XFireFault(Throwable throwable, String code)
    107     {
    108         this(throwable.getMessage(), throwable, code);
    109     }
    110
    111     /***
    112      * Create an exception wih the specified fault message and faultCode.
    113      *
    114      * @param message The fault message.
    115      * @param code    The fault code. See XFireFault's static fields.
    116      */
    117     public XFireFault(String message, String code)
    118     {
    119         this(message, null, code);
    120     }
    121
    122     /***
    123      * Create a fault.
    124      *
    125      * @param cause The exception which caused this fault.
    126      * @param code  The fault code. See XFireFault's static fields.
    127      */
    128     public XFireFault(String message,
    129                       Throwable cause,
    130                       String code)
    131     {
    132         this.message = message != null ? message : "Fault";
    133         this.faultCode = code;
    134         this.cause = cause;
    135         this.namespaces = new HashMap();
    136     }
    137
    138     /***
    139      * Adds a namespace with prefix to this fault.
    140      *
    141      * @param prefix the prefix
    142      * @param ns     the namespace.
    143      */
    144     public void addNamespace(String prefix, String ns)
    145     {
    146         namespaces.put(prefix, ns);
    147     }
    148
    149     /***
    150      * Prints this throwable and its backtrace to the specified print stream.
    151      *
    152      * @param s <code>PrintStream</code> to use for output
    153      */
    154     public void printStackTrace(PrintStream s)
    155     {
    156         if (this.cause == null || this.cause == this)
    157         {
    158             super.printStackTrace(s);
    159         }
    160         else
    161         {
    162             s.println(this);
    163             this.cause.printStackTrace(s);
    164         }
    165     }
    166
    167     /***
    168      * Prints this throwable and its backtrace to the specified print writer.
    169      *
    170      * @param w <code>PrintWriter</code> to use for output
    171      */
    172     public void printStackTrace(PrintWriter w)
    173     {
    174         if (this.cause == null || this.cause == this)
    175         {
    176             super.printStackTrace(w);
    177         }
    178         else
    179         {
    180             w.println(this);
    181             this.cause.printStackTrace(w);
    182         }
    183     }
    184
    185     /***
    186      * Returns the cause of this throwable or <code>null</code> if the  cause is nonexistent or unknown.
    187      *
    188      * @return the nested cause.
    189      */
    190     public Throwable getCause()
    191     {
    192         return (this.cause == this ? null : this.cause);
    193     }
    194
    195     /***
    196      * Returns the detail node. If no detail node has been set, an empty <code>&lt;detail&gt;</code> is created.
    197      *
    198      * @return the detail node.
    199      */
    200     public Element getDetail()
    201     {
    202         if (detail == null)
    203         {
    204             detail = new Element("detail");
    205         }
    206         return detail;
    207     }
    208
    209     /***
    210      * Sets a details <code>Node</code> on this fault.
    211      *
    212      * @param details the detail node.
    213      */
    214     public void setDetail(Element details)
    215     {
    216         detail = details;
    217     }
    218
    219     /***
    220      * Returns the fault code of this fault.
    221      *
    222      * @return the fault code.
    223      */
    224     public String getFaultCode()
    225     {
    226         return faultCode;
    227     }
    228
    229     /***
    230      * Sets the fault code of this fault.
    231      *
    232      * @param faultCode the fault code.
    233      */
    234     public void setFaultCode(String faultCode)
    235     {
    236         this.faultCode = faultCode;
    237     }
    238
    239     /***
    240      * Returns the detail message string of this fault.
    241      *
    242      * @return the detail message string of this <code>XfireFault</code> (which may be <code>null</code>)
    243      */
    244     public String getMessage()
    245     {
    246         return message;
    247     }
    248
    249     /***
    250      * @param message The message to set.
    251      */
    252     public void setMessage(String message)
    253     {
    254         this.message = message;
    255     }
    256
    257     /***
    258      * User defined namespaces which will be written out on the resultant SOAP Fault (for use easy with SubCodes and
    259      * Detail) elements.
    260      *
    261      * @return
    262      */
    263     public Map getNamespaces()
    264     {
    265         return namespaces;
    266     }
    267
    268     public String getReason()
    269     {
    270         return getMessage();
    271     }
    272
    273     /***
    274      * Returns the fault actor.
    275      *
    276      * @return the fault actor.
    277      */
    278     public String getRole()
    279     {
    280         return role;
    281     }
    282
    283     /***
    284      * Sets the fault actor.
    285      *
    286      * @param actor the actor.
    287      */
    288     public void setRole(String actor)
    289     {
    290         this.role = actor;
    291     }
    292
    293     /***
    294      * Returns the SubCode for the Fault Code.
    295      *
    296      * @return The SubCode element as detailed by the SOAP 1.2 spec.
    297      */
    298     public String getSubCode()
    299     {
    300         return subCode;
    301     }
    302
    303     /***
    304      * Sets the SubCode for the Fault Code.
    305      *
    306      * @param subCode The SubCode element as detailed by the SOAP 1.2 spec.
    307      */
    308     public void setSubCode(String subCode)
    309     {
    310         this.subCode = subCode;
    311     }
    312
    313     /***
    314      * Indicates whether this fault has a detail message.
    315      *
    316      * @return <code>true</code> if this fault has a detail message; <code>false</code> otherwise.
    317      */
    318     public boolean hasDetails()
    319     {
    320         return detail == null ? false : true;
    321     }
    322 }
    323