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