001    /*
002     *  jDTAUS Core API
003     *  Copyright (c) 2005 Christian Schulte
004     *
005     *  Christian Schulte, Haldener Strasse 72, 58095 Hagen, Germany
006     *  <schulte2005@users.sourceforge.net> (+49 2331 3543887)
007     *
008     *  This library is free software; you can redistribute it and/or
009     *  modify it under the terms of the GNU Lesser General Public
010     *  License as published by the Free Software Foundation; either
011     *  version 2.1 of the License, or any later version.
012     *
013     *  This library is distributed in the hope that it will be useful,
014     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
015     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
016     *  Lesser General Public License for more details.
017     *
018     *  You should have received a copy of the GNU Lesser General Public
019     *  License along with this library; if not, write to the Free Software
020     *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
021     *
022     */
023    package org.jdtaus.core.lang;
024    
025    import java.util.EventObject;
026    
027    /**
028     * Event holding an exception.
029     *
030     * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
031     * @version $Id: ExceptionEvent.java 8044 2009-07-02 01:29:05Z schulte2005 $
032     *
033     * @see ExceptionEventSource
034     */
035    public class ExceptionEvent extends EventObject
036    {
037        //--Constants---------------------------------------------------------------
038    
039        /** Serial version UID for backwards compatibility with 1.4.x classes. */
040        private static final long serialVersionUID = 5909424199091260187L;
041    
042        //---------------------------------------------------------------Constants--
043        //--Constructors------------------------------------------------------------
044    
045        /**
046         * Creates a new {@code ExceptionEvent} instance taking an exception and
047         * a corresponding thread.
048         *
049         * @param source the source of the new event.
050         * @param thread the thread {@code throwable} occured in.
051         * @param throwable the exception which occured in {@code thread}.
052         *
053         * @throws NullPointerException if either {@code thread} or
054         * {@code throwable} is {@code null}.
055         */
056        public ExceptionEvent( final Object source, final Thread thread,
057                               final Throwable throwable )
058        {
059            super( source );
060    
061            if ( thread == null )
062            {
063                throw new NullPointerException( "thread" );
064            }
065            if ( throwable == null )
066            {
067                throw new NullPointerException( "throwable" );
068            }
069    
070            this.thread = thread;
071            this.throwable = throwable;
072        }
073    
074        //------------------------------------------------------------Constructors--
075        //--ExceptionEvent----------------------------------------------------------
076    
077        /** Thread {@code throwable} occured in. */
078        private transient Thread thread;
079    
080        /**
081         * Exception which occured in {@code thread}.
082         * @serial
083         */
084        private Throwable throwable;
085    
086        /**
087         * Getter for property {@code thread}.
088         *
089         * @return the thread of the event or {@code null}.
090         */
091        public Thread getThread()
092        {
093            return this.thread;
094        }
095    
096        /**
097         * Getter for property {@code exception}.
098         *
099         * @return the exception of the event.
100         */
101        public Throwable getException()
102        {
103            return this.throwable;
104        }
105    
106        /**
107         * Gets the root cause of the event's exception by traversing up the chained
108         * exception hierarchy.
109         *
110         * @return the root cause of the event's exception.
111         */
112        public final Throwable getRootCause()
113        {
114            Throwable current = this.getException();
115            Throwable root = current;
116    
117            while ( ( current = current.getCause() ) != null )
118            {
119                root = current;
120            }
121    
122            return root;
123        }
124    
125        /**
126         * Creates a string representing the properties of the instance.
127         *
128         * @return a string representing the properties of the instance.
129         */
130        private String internalString()
131        {
132            return new StringBuffer( 500 ).append( '{' ).
133                append( "thread=" ).append( this.thread ).
134                append( ", throwable=" ).append( this.throwable ).
135                append( '}' ).toString();
136    
137        }
138    
139        //----------------------------------------------------------ExceptionEvent--
140        //--Object------------------------------------------------------------------
141    
142        /**
143         * Returns a string representation of the object.
144         *
145         * @return a string representation of the object.
146         */
147        public String toString()
148        {
149            return super.toString() + this.internalString();
150        }
151    
152        //------------------------------------------------------------------Object--
153    }