001    /* ========================================================================
002     * JCommon : a free general purpose class library for the Java(tm) platform
003     * ========================================================================
004     *
005     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006     * 
007     * Project Info:  http://www.jfree.org/jcommon/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it 
010     * under the terms of the GNU Lesser General Public License as published by 
011     * the Free Software Foundation; either version 2.1 of the License, or 
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but 
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022     * USA.  
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025     * in the United States and other countries.]
026     * 
027     * -----------------------
028     * StackableException.java
029     * -----------------------
030     * (C)opyright 2002-2004, by Thomas Morgner and Contributors.
031     *
032     * Original Author:  Thomas Morgner;
033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
034     *
035     * $Id: StackableException.java,v 1.3 2005/11/14 10:56:55 mungady Exp $
036     *
037     * Changes
038     * -------
039     * 06-Dec-2002 : Initial version
040     * 10-Dec-2002 : Fixed issues reported by Checkstyle (DG);
041     * 29-Apr-2003 : Distilled from the JFreeReport project and moved into JCommon
042     *
043     */
044    
045    package org.jfree.util;
046    
047    import java.io.PrintStream;
048    import java.io.PrintWriter;
049    
050    /**
051     * A baseclass for exceptions, which could have parent exceptions. These parent exceptions
052     * are raised in a subclass and are now wrapped into a subclass of this Exception.
053     * <p>
054     * The parents are printed when this exception is printed. This class exists mainly for
055     * debugging reasons, as with them it is easier to detect the root cause of an error.
056     *
057     * <!-- In a perfect world there would be no need for such a class :)-->
058     *
059     * @author Thomas Morgner
060     */
061    public abstract class StackableException extends Exception {
062    
063        /** The parent exception. */
064        private Exception parent;
065    
066        /**
067         * Creates a StackableRuntimeException with no message and no parent.
068         */
069        public StackableException() {
070            super();
071        }
072    
073        /**
074         * Creates an exception.
075         *
076         * @param message  the exception message.
077         * @param ex  the parent exception.
078         */
079        public StackableException(final String message, final Exception ex) {
080            super(message);
081            this.parent = ex;
082        }
083    
084        /**
085         * Creates an exception.
086         *
087         * @param message  the exception message.
088         */
089        public StackableException(final String message) {
090            super(message);
091        }
092    
093        /**
094         * Returns the parent exception (possibly null).
095         *
096         * @return the parent exception.
097         */
098        public Exception getParent() {
099            return this.parent;
100        }
101    
102        /**
103         * Prints the stack trace to the specified stream.
104         *
105         * @param stream  the output stream.
106         */
107        public void printStackTrace(final PrintStream stream) {
108            super.printStackTrace(stream);
109            if (getParent() != null) {
110                stream.println("ParentException: ");
111                getParent().printStackTrace(stream);
112            }
113        }
114    
115        /**
116         * Prints the stack trace to the specified writer.
117         *
118         * @param writer  the writer.
119         */
120        public void printStackTrace(final PrintWriter writer) {
121            super.printStackTrace(writer);
122            if (getParent() != null) {
123                writer.println("ParentException: ");
124                getParent().printStackTrace(writer);
125            }
126        }
127    
128        /**
129         * Prints this <code>Throwable</code> and its backtrace to the
130         * standard error stream. This method prints a stack trace for this
131         * <code>Throwable</code> object on the error output stream that is
132         * the value of the field <code>System.err</code>. The first line of
133         * output contains the result of the {@link #toString()} method for
134         * this object. Remaining lines represent data previously recorded by
135         * the method {@link #fillInStackTrace()}. The format of this
136         * information depends on the implementation, but the following
137         * example may be regarded as typical:
138         * <blockquote><pre>
139         * java.lang.NullPointerException
140         *         at MyClass.mash(MyClass.java:9)
141         *         at MyClass.crunch(MyClass.java:6)
142         *         at MyClass.main(MyClass.java:3)
143         * </pre></blockquote>
144         * This example was produced by running the program:
145         * <blockquote><pre>
146         *
147         * class MyClass {
148         *
149         *     public static void main(String[] argv) {
150         *         crunch(null);
151         *     }
152         *     static void crunch(int[] a) {
153         *         mash(a);
154         *     }
155         *
156         *     static void mash(int[] b) {
157         *         System.out.println(b[0]);
158         *     }
159         * }
160         * </pre></blockquote>
161         *
162         * @see     System#err
163         */
164        public void printStackTrace() {
165            synchronized (System.err) {
166                printStackTrace(System.err);
167            }
168        }
169    }