1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18// $Id: DatatypeConfigurationException.java 569987 2007-08-27 04:08:46Z mrglavas $
19
20package javax.xml.datatype;
21
22import java.io.IOException;
23import java.io.ObjectInputStream;
24import java.io.PrintStream;
25import java.io.PrintWriter;
26import java.lang.reflect.Method;
27
28/**
29 * <p>Indicates a serious configuration error.</p>
30 *
31 * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
32 * @version $Revision: 569987 $, $Date: 2007-08-26 21:08:46 -0700 (Sun, 26 Aug 2007) $
33 * @since 1.5
34 */
35
36public class DatatypeConfigurationException extends Exception {
37
38    /** Stream Unique Identifier. */
39    private static final long serialVersionUID = -1699373159027047238L;
40
41    /** This field is required to store the cause on JDK 1.3 and below. */
42    private Throwable causeOnJDK13OrBelow;
43
44    /** Indicates whether this class is being used in a JDK 1.4 context. */
45    private transient boolean isJDK14OrAbove = false;
46
47    /**
48     * <p>Create a new <code>DatatypeConfigurationException</code> with
49     * no specified detail message and cause.</p>
50     */
51
52    public DatatypeConfigurationException() {
53    }
54
55    /**
56     * <p>Create a new <code>DatatypeConfigurationException</code> with
57     * the specified detail message.</p>
58     *
59     * @param message The detail message.
60     */
61
62    public DatatypeConfigurationException(String message) {
63        super(message);
64    }
65
66    /**
67     * <p>Create a new <code>DatatypeConfigurationException</code> with
68     * the specified detail message and cause.</p>
69     *
70     * @param message The detail message.
71     * @param cause The cause.  A <code>null</code> value is permitted, and indicates that the cause is nonexistent or unknown.
72     */
73
74    public DatatypeConfigurationException(String message, Throwable cause) {
75        super(message);
76        initCauseByReflection(cause);
77    }
78
79    /**
80     * <p>Create a new <code>DatatypeConfigurationException</code> with
81     * the specified cause.</p>
82     *
83     * @param cause The cause.  A <code>null</code> value is permitted, and indicates that the cause is nonexistent or unknown.
84     */
85
86    public DatatypeConfigurationException(Throwable cause) {
87        super(cause == null ? null : cause.toString());
88        initCauseByReflection(cause);
89    }
90
91    /**
92     * Print the the trace of methods from where the error
93     * originated.  This will trace all nested exception
94     * objects, as well as this object.
95     */
96    public void printStackTrace() {
97        if (!isJDK14OrAbove && causeOnJDK13OrBelow != null) {
98            printStackTrace0(new PrintWriter(System.err, true));
99        }
100        else {
101            super.printStackTrace();
102        }
103    }
104
105    /**
106     * Print the the trace of methods from where the error
107     * originated.  This will trace all nested exception
108     * objects, as well as this object.
109     * @param s The stream where the dump will be sent to.
110     */
111    public void printStackTrace(PrintStream s) {
112        if (!isJDK14OrAbove && causeOnJDK13OrBelow != null) {
113            printStackTrace0(new PrintWriter(s));
114        }
115        else {
116            super.printStackTrace(s);
117        }
118    }
119
120    /**
121     * Print the the trace of methods from where the error
122     * originated.  This will trace all nested exception
123     * objects, as well as this object.
124     * @param s The writer where the dump will be sent to.
125     */
126    public void printStackTrace(PrintWriter s) {
127        if (!isJDK14OrAbove && causeOnJDK13OrBelow != null) {
128            printStackTrace0(s);
129        }
130        else {
131            super.printStackTrace(s);
132        }
133    }
134
135    private void printStackTrace0(PrintWriter s) {
136        causeOnJDK13OrBelow.printStackTrace(s);
137        s.println("------------------------------------------");
138        super.printStackTrace(s);
139    }
140
141    private void initCauseByReflection(Throwable cause) {
142        causeOnJDK13OrBelow = cause;
143        try {
144            Method m = this.getClass().getMethod("initCause", new Class[] {Throwable.class});
145            m.invoke(this, new Object[] {cause});
146            isJDK14OrAbove = true;
147        }
148        // Ignore exception
149        catch (Exception e) {}
150    }
151
152    private void readObject(ObjectInputStream in)
153        throws IOException, ClassNotFoundException {
154        in.defaultReadObject();
155        try {
156            Method m1 = this.getClass().getMethod("getCause", new Class[] {});
157            Throwable cause = (Throwable) m1.invoke(this, new Object[] {});
158            if (causeOnJDK13OrBelow == null) {
159                causeOnJDK13OrBelow = cause;
160            }
161            else if (cause == null) {
162                Method m2 = this.getClass().getMethod("initCause", new Class[] {Throwable.class});
163                m2.invoke(this, new Object[] {causeOnJDK13OrBelow});
164            }
165            isJDK14OrAbove = true;
166        }
167        // Ignore exception
168        catch (Exception e) {}
169    }
170}
171