001 /*
002 * Copyright 2001-2004 The Apache Software Foundation.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package javax.xml.soap;
017
018 /**
019 * An exception that signals that a SOAP exception has
020 * occurred. A <CODE>SOAPException</CODE> object may contain a
021 * <CODE>String</CODE> that gives the reason for the exception, an
022 * embedded <CODE>Throwable</CODE> object, or both. This class
023 * provides methods for retrieving reason messages and for
024 * retrieving the embedded <CODE>Throwable</CODE> object.</P>
025 *
026 * <P>Typical reasons for throwing a <CODE>SOAPException</CODE>
027 * object are problems such as difficulty setting a header, not
028 * being able to send a message, and not being able to get a
029 * connection with the provider. Reasons for embedding a <CODE>
030 * Throwable</CODE> object include problems such as input/output
031 * errors or a parsing problem, such as an error in parsing a
032 * header.
033 */
034 public class SOAPException extends Exception {
035
036 /**
037 * Constructs a <CODE>SOAPException</CODE> object with no
038 * reason or embedded <CODE>Throwable</CODE> object.
039 */
040 public SOAPException() {
041 cause = null;
042 }
043
044 /**
045 * Constructs a <CODE>SOAPException</CODE> object with the
046 * given <CODE>String</CODE> as the reason for the exception
047 * being thrown.
048 * @param reason a description of what caused
049 * the exception
050 */
051 public SOAPException(String reason) {
052
053 super(reason);
054
055 cause = null;
056 }
057
058 /**
059 * Constructs a <CODE>SOAPException</CODE> object with the
060 * given <CODE>String</CODE> as the reason for the exception
061 * being thrown and the given <CODE>Throwable</CODE> object as
062 * an embedded exception.
063 * @param reason a description of what caused
064 * the exception
065 * @param cause a <CODE>Throwable</CODE> object
066 * that is to be embedded in this <CODE>SOAPException</CODE>
067 * object
068 */
069 public SOAPException(String reason, Throwable cause) {
070
071 super(reason);
072
073 initCause(cause);
074 }
075
076 /**
077 * Constructs a <CODE>SOAPException</CODE> object
078 * initialized with the given <CODE>Throwable</CODE>
079 * object.
080 * @param cause a <CODE>Throwable</CODE> object
081 * that is to be embedded in this <CODE>SOAPException</CODE>
082 * object
083 */
084 public SOAPException(Throwable cause) {
085
086 super(cause.toString());
087
088 initCause(cause);
089 }
090
091 /**
092 * Returns the detail message for this <CODE>
093 * SOAPException</CODE> object.
094 *
095 * <P>If there is an embedded <CODE>Throwable</CODE> object,
096 * and if the <CODE>SOAPException</CODE> object has no detail
097 * message of its own, this method will return the detail
098 * message from the embedded <CODE>Throwable</CODE>
099 * object.</P>
100 * @return the error or warning message for this <CODE>
101 * SOAPException</CODE> or, if it has none, the message of
102 * the embedded <CODE>Throwable</CODE> object, if there is
103 * one
104 */
105 public String getMessage() {
106
107 String s = super.getMessage();
108
109 if ((s == null) && (cause != null)) {
110 return cause.getMessage();
111 } else {
112 return s;
113 }
114 }
115
116 /**
117 * Returns the <CODE>Throwable</CODE> object embedded in
118 * this <CODE>SOAPException</CODE> if there is one. Otherwise,
119 * this method returns <CODE>null</CODE>.
120 * @return the embedded <CODE>Throwable</CODE> object or <CODE>
121 * null</CODE> if there is none
122 */
123 public Throwable getCause() {
124 return cause;
125 }
126
127 /**
128 * Initializes the <CODE>cause</CODE> field of this <CODE>
129 * SOAPException</CODE> object with the given <CODE>
130 * Throwable</CODE> object.
131 *
132 * <P>This method can be called at most once. It is generally
133 * called from within the constructor or immediately after the
134 * constructor has returned a new <CODE>SOAPException</CODE>
135 * object. If this <CODE>SOAPException</CODE> object was
136 * created with the constructor {@link #SOAPException(java.lang.Throwable) SOAPException(java.lang.Throwable)}
137 * or {@link #SOAPException(java.lang.String, java.lang.Throwable) SOAPException(java.lang.String, java.lang.Throwable)}, meaning
138 * that its <CODE>cause</CODE> field already has a value, this
139 * method cannot be called even once.
140 *
141 * @param cause the <CODE>Throwable</CODE>
142 * object that caused this <CODE>SOAPException</CODE> object
143 * to be thrown. The value of this parameter is saved for
144 * later retrieval by the <A href=
145 * "../../../javax/xml/soap/SOAPException.html#getCause()">
146 * <CODE>getCause()</CODE></A> method. A <TT>null</TT> value
147 * is permitted and indicates that the cause is nonexistent
148 * or unknown.
149 * @return a reference to this <CODE>SOAPException</CODE>
150 * instance
151 * @throws java.lang.IllegalArgumentException if
152 * <CODE>cause</CODE> is this <CODE>Throwable</CODE> object.
153 * (A <CODE>Throwable</CODE> object cannot be its own
154 * cause.)
155 * @throws java.lang.IllegalStateException if this <CODE>
156 * SOAPException</CODE> object was created with {@link #SOAPException(java.lang.Throwable) SOAPException(java.lang.Throwable)}
157 * or {@link #SOAPException(java.lang.String, java.lang.Throwable) SOAPException(java.lang.String, java.lang.Throwable)}, or this
158 * method has already been called on this <CODE>
159 * SOAPException</CODE> object
160 */
161 public synchronized Throwable initCause(Throwable cause) {
162
163 if (this.cause != null) {
164 throw new IllegalStateException("Can't override cause");
165 }
166
167 if (cause == this) {
168 throw new IllegalArgumentException("Self-causation not permitted");
169 } else {
170 this.cause = cause;
171
172 return this;
173 }
174 }
175
176 private Throwable cause;
177 }