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    package javax.xml.soap;
020    
021    /**
022     * An exception that signals that a SOAP exception has occurred. A <CODE>SOAPException</CODE> object
023     * may contain a <CODE>String</CODE> that gives the reason for the exception, an embedded
024     * <CODE>Throwable</CODE> object, or both. This class provides methods for retrieving reason
025     * messages and for retrieving the embedded <CODE>Throwable</CODE> object.</P>
026     * <p/>
027     * <P>Typical reasons for throwing a <CODE>SOAPException</CODE> object are problems such as
028     * difficulty setting a header, not being able to send a message, and not being able to get a
029     * connection with the provider. Reasons for embedding a <CODE> Throwable</CODE> object include
030     * problems such as input/output errors or a parsing problem, such as an error in parsing a header.
031     */
032    public class SOAPException extends Exception {
033    
034        private static final long serialVersionUID = 5083961510786058130L;
035    
036        /**
037         * Constructs a <CODE>SOAPException</CODE> object with no reason or embedded
038         * <CODE>Throwable</CODE> object.
039         */
040        public SOAPException() {
041            cause = null;
042        }
043    
044        /**
045         * Constructs a <CODE>SOAPException</CODE> object with the given <CODE>String</CODE> as the
046         * reason for the exception being thrown.
047         *
048         * @param reason a description of what caused the exception
049         */
050        public SOAPException(String reason) {
051    
052            super(reason);
053    
054            cause = null;
055        }
056    
057        /**
058         * Constructs a <CODE>SOAPException</CODE> object with the given <CODE>String</CODE> as the
059         * reason for the exception being thrown and the given <CODE>Throwable</CODE> object as an
060         * embedded exception.
061         *
062         * @param reason a description of what caused the exception
063         * @param cause  a <CODE>Throwable</CODE> object that is to be embedded in this
064         *               <CODE>SOAPException</CODE> object
065         */
066        public SOAPException(String reason, Throwable cause) {
067    
068            super(reason);
069    
070            initCause(cause);
071        }
072    
073        /**
074         * Constructs a <CODE>SOAPException</CODE> object initialized with the given
075         * <CODE>Throwable</CODE> object.
076         *
077         * @param cause a <CODE>Throwable</CODE> object that is to be embedded in this
078         *              <CODE>SOAPException</CODE> object
079         */
080        public SOAPException(Throwable cause) {
081    
082            super(cause.toString());
083    
084            initCause(cause);
085        }
086    
087        /**
088         * Returns the detail message for this <CODE> SOAPException</CODE> object.
089         * <p/>
090         * <P>If there is an embedded <CODE>Throwable</CODE> object, and if the
091         * <CODE>SOAPException</CODE> object has no detail message of its own, this method will return
092         * the detail message from the embedded <CODE>Throwable</CODE> object.</P>
093         *
094         * @return the error or warning message for this <CODE> SOAPException</CODE> or, if it has none,
095         *         the message of the embedded <CODE>Throwable</CODE> object, if there is one
096         */
097        public String getMessage() {
098    
099            String s = super.getMessage();
100    
101            if ((s == null) && (cause != null)) {
102                return cause.getMessage();
103            } else {
104                return s;
105            }
106        }
107    
108        /**
109         * Returns the <CODE>Throwable</CODE> object embedded in this <CODE>SOAPException</CODE> if
110         * there is one. Otherwise, this method returns <CODE>null</CODE>.
111         *
112         * @return the embedded <CODE>Throwable</CODE> object or <CODE> null</CODE> if there is none
113         */
114        public Throwable getCause() {
115            return cause;
116        }
117    
118        /**
119         * Initializes the <CODE>cause</CODE> field of this <CODE> SOAPException</CODE> object with the
120         * given <CODE> Throwable</CODE> object.
121         * <p/>
122         * <P>This method can be called at most once. It is generally called from within the constructor
123         * or immediately after the constructor has returned a new <CODE>SOAPException</CODE> object. If
124         * this <CODE>SOAPException</CODE> object was created with the constructor {@link
125         * #SOAPException(java.lang.Throwable) SOAPException(java.lang.Throwable)} or {@link
126         * #SOAPException(java.lang.String, java.lang.Throwable) SOAPException(java.lang.String,
127         * java.lang.Throwable)}, meaning that its <CODE>cause</CODE> field already has a value, this
128         * method cannot be called even once.
129         *
130         * @param cause the <CODE>Throwable</CODE> object that caused this <CODE>SOAPException</CODE>
131         *              object to be thrown. The value of this parameter is saved for later retrieval by
132         *              the <A href= "../../../javax/xml/soap/SOAPException.html#getCause()">
133         *              <CODE>getCause()</CODE></A> method. A <TT>null</TT> value is permitted and
134         *              indicates that the cause is nonexistent or unknown.
135         * @return a reference to this <CODE>SOAPException</CODE> instance
136         * @throws IllegalArgumentException
137         *          if <CODE>cause</CODE> is this <CODE>Throwable</CODE> object. (A
138         *          <CODE>Throwable</CODE> object cannot be its own cause.)
139         * @throws IllegalStateException
140         *          if this <CODE> SOAPException</CODE> object was created with {@link
141         *          #SOAPException(java.lang.Throwable) SOAPException(java.lang.Throwable)} or {@link
142         *          #SOAPException(java.lang.String, java.lang.Throwable) SOAPException(java.lang.String,
143         *          java.lang.Throwable)}, or this method has already been called on this <CODE>
144         *          SOAPException</CODE> object
145         */
146        public synchronized Throwable initCause(Throwable cause) {
147    
148            if (this.cause != null) {
149                throw new IllegalStateException("Can't override cause");
150            }
151    
152            if (cause == this) {
153                throw new IllegalArgumentException("Self-causation not permitted");
154            } else {
155                this.cause = cause;
156    
157                return this;
158            }
159        }
160    
161        private Throwable cause;
162    }