HHH-3918: Use standard JDK exception nesting

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@16604 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2009-05-20 04:39:00 +00:00
parent 97a0919521
commit 6eb4caf053
8 changed files with 20 additions and 1686 deletions

View File

@ -23,6 +23,8 @@
*/
package org.hibernate.test.cache.jbc2.functional;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
@ -42,7 +44,6 @@ import org.hibernate.cache.RegionFactory;
import org.hibernate.cache.jbc2.JBossCacheRegionFactory;
import org.hibernate.cache.jbc2.builder.SharedCacheInstanceManager;
import org.hibernate.cfg.Configuration;
import org.hibernate.exception.ExceptionUtils;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.test.cache.jbc2.functional.util.DualNodeConnectionProviderImpl;
@ -579,13 +580,21 @@ public class MVCCConcurrentWriteTest extends CacheTestCaseBase {
"[customerId=" + getCustomerId() +
" iterationsCompleted=" + getCompletedIterations() +
" completedAll=" + isSuccess() +
" causeOfFailure=" + (this.causeOfFailure != null ? ExceptionUtils.getStackTrace(causeOfFailure) : "") + "] ";
" causeOfFailure=" + (this.causeOfFailure != null ? getStackTrace(causeOfFailure) : "") + "] ";
}
}
public static String getStackTrace(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter( sw, true );
throwable.printStackTrace( pw );
return sw.getBuffer().toString();
}
/**
* sleep between 0 and THINK_TIME_MILLIS.
* @throws RuntimeException if sleep is interruped or TERMINATE_ALL_USERS flag was set to true i
* @throws RuntimeException if sleep is interrupted or TERMINATE_ALL_USERS flag was set to true i
n the meantime
*/
private void thinkRandomTime() {

View File

@ -24,8 +24,6 @@
*/
package org.hibernate;
import org.hibernate.exception.NestableRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,7 +32,7 @@ import org.slf4j.LoggerFactory;
*
* @author Gavin King
*/
public class AssertionFailure extends NestableRuntimeException {
public class AssertionFailure extends RuntimeException {
private static final Logger log = LoggerFactory.getLogger( AssertionFailure.class );

View File

@ -24,18 +24,17 @@
*/
package org.hibernate;
import org.hibernate.exception.NestableRuntimeException;
/**
* Any exception that occurs inside the persistence layer
* or JDBC driver. <tt>SQLException</tt>s are always wrapped
* by instances of <tt>JDBCException</tt>.
*
* The base {@link Throwable} type for Hibernate.
* <p/>
* Note that all {@link java.sql.SQLException SQLExceptions} will be wrapped in some form of
* {@link JDBCException}.
*
* @see JDBCException
*
* @author Gavin King
*/
public class HibernateException extends NestableRuntimeException {
public class HibernateException extends RuntimeException {
public HibernateException(Throwable root) {
super(root);

View File

@ -1,705 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.exception;
import org.hibernate.util.ArrayHelper;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
/**
* <p>Provides utilities for manipulating and examining
* <code>Throwable</code> objects.</p>
*
* @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
* @author Dmitri Plotnikov
* @author Stephen Colebourne
* @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
* @author Pete Gieser
* @version $Id: ExceptionUtils.java 4782 2004-11-21 00:11:27Z pgmjsd $
* @since 1.0
*/
public final class ExceptionUtils {
private static final String LINE_SEPARATOR = System.getProperty( "line.separator" );
/**
* <p>Used when printing stack frames to denote the start of a
* wrapped exception.</p>
* <p/>
* <p>Package private for accessibility by test suite.</p>
*/
static final String WRAPPED_MARKER = " [wrapped] ";
/**
* <p>The names of methods commonly used to access a wrapped exception.</p>
*/
private static final String[] CAUSE_METHOD_NAMES = {
"getCause",
"getNextException",
"getTargetException",
"getException",
"getSourceException",
"getRootCause",
"getCausedByException",
"getNested"
};
/**
* <p>The Method object for JDK1.4 getCause.</p>
*/
private static final Method THROWABLE_CAUSE_METHOD;
static {
Method getCauseMethod;
try {
getCauseMethod = Throwable.class.getMethod( "getCause", null );
}
catch ( Exception e ) {
getCauseMethod = null;
}
THROWABLE_CAUSE_METHOD = getCauseMethod;
}
private ExceptionUtils() {
}
//-----------------------------------------------------------------------
/**
* <p>Adds to the list of method names used in the search for <code>Throwable</code>
* objects.</p>
*
* @param methodName the methodName to add to the list, <code>null</code>
* and empty strings are ignored
* @since 2.0
*/
/*public static void addCauseMethodName(String methodName) {
if ( StringHelper.isNotEmpty(methodName) ) {
List list = new ArrayList( Arrays.asList(CAUSE_METHOD_NAMES );
list.add(methodName);
CAUSE_METHOD_NAMES = (String[]) list.toArray(new String[list.size()]);
}
}*/
/**
* <p>Introspects the <code>Throwable</code> to obtain the cause.</p>
* <p/>
* <p>The method searches for methods with specific names that return a
* <code>Throwable</code> object. This will pick up most wrapping exceptions,
* including those from JDK 1.4, and
* {@link org.apache.commons.lang.exception.NestableException NestableException}.
* The method names can be added to using {@link #addCauseMethodName(String)}.</p>
* <p/>
* <p>The default list searched for are:</p>
* <ul>
* <li><code>getCause()</code></li>
* <li><code>getNextException()</code></li>
* <li><code>getTargetException()</code></li>
* <li><code>getException()</code></li>
* <li><code>getSourceException()</code></li>
* <li><code>getRootCause()</code></li>
* <li><code>getCausedByException()</code></li>
* <li><code>getNested()</code></li>
* </ul>
* <p/>
* <p>In the absence of any such method, the object is inspected for a
* <code>detail</code> field assignable to a <code>Throwable</code>.</p>
* <p/>
* <p>If none of the above is found, returns <code>null</code>.</p>
*
* @param throwable the throwable to introspect for a cause, may be null
* @return the cause of the <code>Throwable</code>,
* <code>null</code> if none found or null throwable input
*/
public static Throwable getCause(Throwable throwable) {
return getCause( throwable, CAUSE_METHOD_NAMES );
}
/**
* <p>Introspects the <code>Throwable</code> to obtain the cause.</p>
* <p/>
* <ol>
* <li>Try known exception types.</li>
* <li>Try the supplied array of method names.</li>
* <li>Try the field 'detail'.</li>
* </ol>
* <p/>
* <p>A <code>null</code> set of method names means use the default set.
* A <code>null</code> in the set of method names will be ignored.</p>
*
* @param throwable the throwable to introspect for a cause, may be null
* @param methodNames the method names, null treated as default set
* @return the cause of the <code>Throwable</code>,
* <code>null</code> if none found or null throwable input
*/
public static Throwable getCause(Throwable throwable, String[] methodNames) {
if ( throwable == null ) {
return null;
}
Throwable cause = getCauseUsingWellKnownTypes( throwable );
if ( cause == null ) {
if ( methodNames == null ) {
methodNames = CAUSE_METHOD_NAMES;
}
for ( int i = 0; i < methodNames.length; i++ ) {
String methodName = methodNames[i];
if ( methodName != null ) {
cause = getCauseUsingMethodName( throwable, methodName );
if ( cause != null ) {
break;
}
}
}
if ( cause == null ) {
cause = getCauseUsingFieldName( throwable, "detail" );
}
}
return cause;
}
/**
* <p>Introspects the <code>Throwable</code> to obtain the root cause.</p>
* <p/>
* <p>This method walks through the exception chain to the last element,
* "root" of the tree, using {@link #getCause(Throwable)}, and
* returns that exception.</p>
*
* @param throwable the throwable to get the root cause for, may be null
* @return the root cause of the <code>Throwable</code>,
* <code>null</code> if none found or null throwable input
*/
public static Throwable getRootCause(Throwable throwable) {
Throwable cause = getCause( throwable );
if ( cause != null ) {
throwable = cause;
while ( ( throwable = getCause( throwable ) ) != null ) {
cause = throwable;
}
}
return cause;
}
/**
* <p>Finds a <code>Throwable</code> for known types.</p>
* <p/>
* <p>Uses <code>instanceof</code> checks to examine the exception,
* looking for well known types which could contain chained or
* wrapped exceptions.</p>
*
* @param throwable the exception to examine
* @return the wrapped exception, or <code>null</code> if not found
*/
private static Throwable getCauseUsingWellKnownTypes(Throwable throwable) {
if ( throwable instanceof Nestable ) {
return ( ( Nestable ) throwable ).getCause();
}
else if ( throwable instanceof SQLException ) {
return ( ( SQLException ) throwable ).getNextException();
}
else if ( throwable instanceof InvocationTargetException ) {
return ( ( InvocationTargetException ) throwable ).getTargetException();
}
else {
return null;
}
}
/**
* <p>Finds a <code>Throwable</code> by method name.</p>
*
* @param throwable the exception to examine
* @param methodName the name of the method to find and invoke
* @return the wrapped exception, or <code>null</code> if not found
*/
private static Throwable getCauseUsingMethodName(Throwable throwable, String methodName) {
Method method = null;
try {
method = throwable.getClass().getMethod( methodName, null );
}
catch ( NoSuchMethodException ignored ) {
}
catch ( SecurityException ignored ) {
}
if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) ) {
try {
return ( Throwable ) method.invoke( throwable, ArrayHelper.EMPTY_OBJECT_ARRAY );
}
catch ( IllegalAccessException ignored ) {
}
catch ( IllegalArgumentException ignored ) {
}
catch ( InvocationTargetException ignored ) {
}
}
return null;
}
/**
* <p>Finds a <code>Throwable</code> by field name.</p>
*
* @param throwable the exception to examine
* @param fieldName the name of the attribute to examine
* @return the wrapped exception, or <code>null</code> if not found
*/
private static Throwable getCauseUsingFieldName(Throwable throwable, String fieldName) {
Field field = null;
try {
field = throwable.getClass().getField( fieldName );
}
catch ( NoSuchFieldException ignored ) {
}
catch ( SecurityException ignored ) {
}
if ( field != null && Throwable.class.isAssignableFrom( field.getType() ) ) {
try {
return ( Throwable ) field.get( throwable );
}
catch ( IllegalAccessException ignored ) {
}
catch ( IllegalArgumentException ignored ) {
}
}
return null;
}
//-----------------------------------------------------------------------
/**
* <p>Checks if the Throwable class has a <code>getCause</code> method.</p>
* <p/>
* <p>This is true for JDK 1.4 and above.</p>
*
* @return true if Throwable is nestable
* @since 2.0
*/
public static boolean isThrowableNested() {
return ( THROWABLE_CAUSE_METHOD != null );
}
/**
* <p>Checks whether this <code>Throwable</code> class can store a cause.</p>
* <p/>
* <p>This method does <b>not</b> check whether it actually does store a cause.<p>
*
* @param throwable the <code>Throwable</code> to examine, may be null
* @return boolean <code>true</code> if nested otherwise <code>false</code>
* @since 2.0
*/
public static boolean isNestedThrowable(Throwable throwable) {
if ( throwable == null ) {
return false;
}
if ( throwable instanceof Nestable ) {
return true;
}
else if ( throwable instanceof SQLException ) {
return true;
}
else if ( throwable instanceof InvocationTargetException ) {
return true;
}
else if ( isThrowableNested() ) {
return true;
}
Class cls = throwable.getClass();
for ( int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++ ) {
try {
Method method = cls.getMethod( CAUSE_METHOD_NAMES[i], null );
if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) ) {
return true;
}
}
catch ( NoSuchMethodException ignored ) {
}
catch ( SecurityException ignored ) {
}
}
try {
Field field = cls.getField( "detail" );
if ( field != null ) {
return true;
}
}
catch ( NoSuchFieldException ignored ) {
}
catch ( SecurityException ignored ) {
}
return false;
}
//-----------------------------------------------------------------------
/**
* <p>Counts the number of <code>Throwable</code> objects in the
* exception chain.</p>
* <p/>
* <p>A throwable without cause will return <code>1</code>.
* A throwable with one cause will return <code>2</code> and so on.
* A <code>null</code> throwable will return <code>0</code>.</p>
*
* @param throwable the throwable to inspect, may be null
* @return the count of throwables, zero if null input
*/
public static int getThrowableCount(Throwable throwable) {
int count = 0;
while ( throwable != null ) {
count++;
throwable = ExceptionUtils.getCause( throwable );
}
return count;
}
/**
* <p>Returns the list of <code>Throwable</code> objects in the
* exception chain.</p>
* <p/>
* <p>A throwable without cause will return an array containing
* one element - the input throwable.
* A throwable with one cause will return an array containing
* two elements. - the input throwable and the cause throwable.
* A <code>null</code> throwable will return an array size zero.</p>
*
* @param throwable the throwable to inspect, may be null
* @return the array of throwables, never null
*/
public static Throwable[] getThrowables(Throwable throwable) {
List list = new ArrayList();
while ( throwable != null ) {
list.add( throwable );
throwable = ExceptionUtils.getCause( throwable );
}
return ( Throwable[] ) list.toArray( new Throwable[list.size()] );
}
//-----------------------------------------------------------------------
/**
* <p>Returns the (zero based) index of the first <code>Throwable</code>
* that matches the specified type in the exception chain.</p>
* <p/>
* <p>A <code>null</code> throwable returns <code>-1</code>.
* A <code>null</code> type returns <code>-1</code>.
* No match in the chain returns <code>-1</code>.</p>
*
* @param throwable the throwable to inspect, may be null
* @param type the type to search for
* @return the index into the throwable chain, -1 if no match or null input
*/
public static int indexOfThrowable(Throwable throwable, Class type) {
return indexOfThrowable( throwable, type, 0 );
}
/**
* <p>Returns the (zero based) index of the first <code>Throwable</code>
* that matches the specified type in the exception chain from
* a specified index.</p>
* <p/>
* <p>A <code>null</code> throwable returns <code>-1</code>.
* A <code>null</code> type returns <code>-1</code>.
* No match in the chain returns <code>-1</code>.
* A negative start index is treated as zero.
* A start index greater than the number of throwables returns <code>-1</code>.</p>
*
* @param throwable the throwable to inspect, may be null
* @param type the type to search for
* @param fromIndex the (zero based) index of the starting position,
* negative treated as zero, larger than chain size returns -1
* @return the index into the throwable chain, -1 if no match or null input
*/
public static int indexOfThrowable(Throwable throwable, Class type, int fromIndex) {
if ( throwable == null ) {
return -1;
}
if ( fromIndex < 0 ) {
fromIndex = 0;
}
Throwable[] throwables = ExceptionUtils.getThrowables( throwable );
if ( fromIndex >= throwables.length ) {
return -1;
}
for ( int i = fromIndex; i < throwables.length; i++ ) {
if ( throwables[i].getClass().equals( type ) ) {
return i;
}
}
return -1;
}
//-----------------------------------------------------------------------
/**
* <p>Prints a compact stack trace for the root cause of a throwable
* to <code>System.err</code>.</p>
* <p/>
* <p>The compact stack trace starts with the root cause and prints
* stack frames up to the place where it was caught and wrapped.
* Then it prints the wrapped exception and continues with stack frames
* until the wrapper exception is caught and wrapped again, etc.</p>
* <p/>
* <p>The method is equivalent to <code>printStackTrace</code> for throwables
* that don't have nested causes.</p>
*
* @param throwable the throwable to output
* @since 2.0
*/
public static void printRootCauseStackTrace(Throwable throwable) {
printRootCauseStackTrace( throwable, System.err );
}
/**
* <p>Prints a compact stack trace for the root cause of a throwable.</p>
* <p/>
* <p>The compact stack trace starts with the root cause and prints
* stack frames up to the place where it was caught and wrapped.
* Then it prints the wrapped exception and continues with stack frames
* until the wrapper exception is caught and wrapped again, etc.</p>
* <p/>
* <p>The method is equivalent to <code>printStackTrace</code> for throwables
* that don't have nested causes.</p>
*
* @param throwable the throwable to output, may be null
* @param stream the stream to output to, may not be null
* @throws IllegalArgumentException if the stream is <code>null</code>
* @since 2.0
*/
public static void printRootCauseStackTrace(Throwable throwable, PrintStream stream) {
if ( throwable == null ) {
return;
}
if ( stream == null ) {
throw new IllegalArgumentException( "The PrintStream must not be null" );
}
String trace[] = getRootCauseStackTrace( throwable );
for ( int i = 0; i < trace.length; i++ ) {
stream.println( trace[i] );
}
stream.flush();
}
/**
* <p>Prints a compact stack trace for the root cause of a throwable.</p>
* <p/>
* <p>The compact stack trace starts with the root cause and prints
* stack frames up to the place where it was caught and wrapped.
* Then it prints the wrapped exception and continues with stack frames
* until the wrapper exception is caught and wrapped again, etc.</p>
* <p/>
* <p>The method is equivalent to <code>printStackTrace</code> for throwables
* that don't have nested causes.</p>
*
* @param throwable the throwable to output, may be null
* @param writer the writer to output to, may not be null
* @throws IllegalArgumentException if the writer is <code>null</code>
* @since 2.0
*/
public static void printRootCauseStackTrace(Throwable throwable, PrintWriter writer) {
if ( throwable == null ) {
return;
}
if ( writer == null ) {
throw new IllegalArgumentException( "The PrintWriter must not be null" );
}
String trace[] = getRootCauseStackTrace( throwable );
for ( int i = 0; i < trace.length; i++ ) {
writer.println( trace[i] );
}
writer.flush();
}
//-----------------------------------------------------------------------
/**
* <p>Creates a compact stack trace for the root cause of the supplied
* <code>Throwable</code>.</p>
*
* @param throwable the throwable to examine, may be null
* @return an array of stack trace frames, never null
* @since 2.0
*/
public static String[] getRootCauseStackTrace(Throwable throwable) {
if ( throwable == null ) {
return ArrayHelper.EMPTY_STRING_ARRAY;
}
Throwable throwables[] = getThrowables( throwable );
int count = throwables.length;
ArrayList frames = new ArrayList();
List nextTrace = getStackFrameList( throwables[count - 1] );
for ( int i = count; --i >= 0; ) {
List trace = nextTrace;
if ( i != 0 ) {
nextTrace = getStackFrameList( throwables[i - 1] );
removeCommonFrames( trace, nextTrace );
}
if ( i == count - 1 ) {
frames.add( throwables[i].toString() );
}
else {
frames.add( WRAPPED_MARKER + throwables[i].toString() );
}
for ( int j = 0; j < trace.size(); j++ ) {
frames.add( trace.get( j ) );
}
}
return ( String[] ) frames.toArray( new String[0] );
}
/**
* <p>Removes common frames from the cause trace given the two stack traces.</p>
*
* @param causeFrames stack trace of a cause throwable
* @param wrapperFrames stack trace of a wrapper throwable
* @throws IllegalArgumentException if either argument is null
* @since 2.0
*/
public static void removeCommonFrames(List causeFrames, List wrapperFrames) {
if ( causeFrames == null || wrapperFrames == null ) {
throw new IllegalArgumentException( "The List must not be null" );
}
int causeFrameIndex = causeFrames.size() - 1;
int wrapperFrameIndex = wrapperFrames.size() - 1;
while ( causeFrameIndex >= 0 && wrapperFrameIndex >= 0 ) {
// Remove the frame from the cause trace if it is the same
// as in the wrapper trace
String causeFrame = ( String ) causeFrames.get( causeFrameIndex );
String wrapperFrame = ( String ) wrapperFrames.get( wrapperFrameIndex );
if ( causeFrame.equals( wrapperFrame ) ) {
causeFrames.remove( causeFrameIndex );
}
causeFrameIndex--;
wrapperFrameIndex--;
}
}
//-----------------------------------------------------------------------
/**
* <p>Gets the stack trace from a Throwable as a String.</p>
*
* @param throwable the <code>Throwable</code> to be examined
* @return the stack trace as generated by the exception's
* <code>printStackTrace(PrintWriter)</code> method
*/
public static String getStackTrace(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter( sw, true );
throwable.printStackTrace( pw );
return sw.getBuffer().toString();
}
/**
* <p>A way to get the entire nested stack-trace of an throwable.</p>
*
* @param throwable the <code>Throwable</code> to be examined
* @return the nested stack trace, with the root cause first
* @since 2.0
*/
public static String getFullStackTrace(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter( sw, true );
Throwable[] ts = getThrowables( throwable );
for ( int i = 0; i < ts.length; i++ ) {
ts[i].printStackTrace( pw );
if ( isNestedThrowable( ts[i] ) ) {
break;
}
}
return sw.getBuffer().toString();
}
//-----------------------------------------------------------------------
/**
* <p>Captures the stack trace associated with the specified
* <code>Throwable</code> object, decomposing it into a list of
* stack frames.</p>
*
* @param throwable the <code>Throwable</code> to exaamine, may be null
* @return an array of strings describing each stack frame, never null
*/
public static String[] getStackFrames(Throwable throwable) {
if ( throwable == null ) {
return ArrayHelper.EMPTY_STRING_ARRAY;
}
return getStackFrames( getStackTrace( throwable ) );
}
/**
* <p>Functionality shared between the
* <code>getStackFrames(Throwable)</code> methods of this and the
* {@link org.apache.commons.lang.exception.NestableDelegate}
* classes.</p>
*/
static String[] getStackFrames(String stackTrace) {
String linebreak = LINE_SEPARATOR;
StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
List list = new LinkedList();
while ( frames.hasMoreTokens() ) {
list.add( frames.nextToken() );
}
return ( String[] ) list.toArray( new String[list.size()] );
}
/**
* <p>Produces a <code>List</code> of stack frames - the message
* is not included.</p>
* <p/>
* <p>This works in most cases - it will only fail if the exception
* message contains a line that starts with:
* <code>&quot;&nbsp;&nbsp;&nbsp;at&quot;.</code></p>
*
* @param t is any throwable
* @return List of stack frames
*/
static List getStackFrameList(Throwable t) {
String stackTrace = getStackTrace( t );
String linebreak = LINE_SEPARATOR;
StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
List list = new LinkedList();
boolean traceStarted = false;
while ( frames.hasMoreTokens() ) {
String token = frames.nextToken();
// Determine if the line starts with <whitespace>at
int at = token.indexOf( "at" );
if ( at != -1 && token.substring( 0, at ).trim().length() == 0 ) {
traceStarted = true;
list.add( token );
}
else if ( traceStarted ) {
break;
}
}
return list;
}
}

View File

@ -1,174 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.exception;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* An interface to be implemented by {@link java.lang.Throwable}
* extensions which would like to be able to nest root exceptions
* inside themselves.
*
* @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
* @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
* @author Pete Gieser
* @version $Id: Nestable.java 4782 2004-11-21 00:11:27Z pgmjsd $
* @since 1.0
*/
public interface Nestable {
/**
* Returns the reference to the exception or error that caused the
* exception implementing the <code>Nestable</code> to be thrown.
*
* @return throwable that caused the original exception
*/
public Throwable getCause();
/**
* Returns the error message of this and any nested
* <code>Throwable</code>.
*
* @return the error message
*/
public String getMessage();
/**
* Returns the error message of the <code>Throwable</code> in the chain
* of <code>Throwable</code>s at the specified index, numbererd from 0.
*
* @param index the index of the <code>Throwable</code> in the chain of
* <code>Throwable</code>s
* @return the error message, or null if the <code>Throwable</code> at the
* specified index in the chain does not contain a message
* @throws IndexOutOfBoundsException if the <code>index</code> argument is
* negative or not less than the count of <code>Throwable</code>s in the
* chain
*/
public String getMessage(int index);
/**
* Returns the error message of this and any nested <code>Throwable</code>s
* in an array of Strings, one element for each message. Any
* <code>Throwable</code> not containing a message is represented in the
* array by a null. This has the effect of cause the length of the returned
* array to be equal to the result of the {@link #getThrowableCount()}
* operation.
*
* @return the error messages
*/
public String[] getMessages();
/**
* Returns the <code>Throwable</code> in the chain of
* <code>Throwable</code>s at the specified index, numbererd from 0.
*
* @param index the index, numbered from 0, of the <code>Throwable</code> in
* the chain of <code>Throwable</code>s
* @return the <code>Throwable</code>
* @throws IndexOutOfBoundsException if the <code>index</code> argument is
* negative or not less than the count of <code>Throwable</code>s in the
* chain
*/
public Throwable getThrowable(int index);
/**
* Returns the number of nested <code>Throwable</code>s represented by
* this <code>Nestable</code>, including this <code>Nestable</code>.
*
* @return the throwable count
*/
public int getThrowableCount();
/**
* Returns this <code>Nestable</code> and any nested <code>Throwable</code>s
* in an array of <code>Throwable</code>s, one element for each
* <code>Throwable</code>.
*
* @return the <code>Throwable</code>s
*/
public Throwable[] getThrowables();
/**
* Returns the index, numbered from 0, of the first occurrence of the
* specified type in the chain of <code>Throwable</code>s, or -1 if the
* specified type is not found in the chain.
*
* @param type <code>Class</code> to be found
* @return index of the first occurrence of the type in the chain, or -1 if
* the type is not found
*/
public int indexOfThrowable(Class type);
/**
* Returns the index, numbered from 0, of the first <code>Throwable</code>
* that matches the specified type in the chain of <code>Throwable</code>s
* with an index greater than or equal to the specified index, or -1 if
* the type is not found.
*
* @param type <code>Class</code> to be found
* @param fromIndex the index, numbered from 0, of the starting position in
* the chain to be searched
* @return index of the first occurrence of the type in the chain, or -1 if
* the type is not found
* @throws IndexOutOfBoundsException if the <code>fromIndex</code> argument
* is negative or not less than the count of <code>Throwable</code>s in the
* chain
*/
public int indexOfThrowable(Class type, int fromIndex);
/**
* Prints the stack trace of this exception to the specified print
* writer. Includes information from the exception, if any,
* which caused this exception.
*
* @param out <code>PrintWriter</code> to use for output.
*/
public void printStackTrace(PrintWriter out);
/**
* Prints the stack trace of this exception to the specified print
* stream. Includes inforamation from the exception, if any,
* which caused this exception.
*
* @param out <code>PrintStream</code> to use for output.
*/
public void printStackTrace(PrintStream out);
/**
* Prints the stack trace for this exception only--root cause not
* included--using the provided writer. Used by {@link
* org.apache.commons.lang.exception.NestableDelegate} to write
* individual stack traces to a buffer. The implementation of
* this method should call
* <code>super.printStackTrace(out);</code> in most cases.
*
* @param out The writer to use.
*/
public void printPartialStackTrace(PrintWriter out);
}

View File

@ -1,383 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.exception;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* <p>A shared implementation of the nestable exception functionality.</p>
* <p/>
* The code is shared between
* {@link org.apache.commons.lang.exception.NestableError NestableError},
* {@link org.apache.commons.lang.exception.NestableException NestableException} and
* {@link org.apache.commons.lang.exception.NestableRuntimeException NestableRuntimeException}.
* </p>
*
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
* @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
* @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
* @author Sean C. Sullivan
* @author Stephen Colebourne
* @version $Id: NestableDelegate.java 4782 2004-11-21 00:11:27Z pgmjsd $
* @since 1.0
*/
public class NestableDelegate implements Serializable {
/**
* Constructor error message.
*/
private static final String MUST_BE_THROWABLE =
"The Nestable implementation passed to the NestableDelegate(Nestable) "
+ "constructor must extend java.lang.Throwable";
/**
* Holds the reference to the exception or error that we're
* wrapping (which must be a {@link
* org.apache.commons.lang.exception.Nestable} implementation).
*/
private Throwable nestable = null;
/**
* Whether to print the stack trace top-down.
* This public flag may be set by calling code, typically in initialisation.
*
* @since 2.0
*/
private static boolean topDown = true;
/**
* Whether to trim the repeated stack trace.
* This public flag may be set by calling code, typically in initialisation.
*
* @since 2.0
*/
private static boolean trimStackFrames = true;
/**
* Constructs a new <code>NestableDelegate</code> instance to manage the
* specified <code>Nestable</code>.
*
* @param nestable the Nestable implementation (<i>must</i> extend
* {@link java.lang.Throwable})
* @since 2.0
*/
public NestableDelegate(Nestable nestable) {
if ( nestable instanceof Throwable ) {
this.nestable = ( Throwable ) nestable;
}
else {
throw new IllegalArgumentException( MUST_BE_THROWABLE );
}
}
/**
* Returns the error message of the <code>Throwable</code> in the chain
* of <code>Throwable</code>s at the specified index, numbererd from 0.
*
* @param index the index of the <code>Throwable</code> in the chain of
* <code>Throwable</code>s
* @return the error message, or null if the <code>Throwable</code> at the
* specified index in the chain does not contain a message
* @throws IndexOutOfBoundsException if the <code>index</code> argument is
* negative or not less than the count of <code>Throwable</code>s in the
* chain
* @since 2.0
*/
public String getMessage(int index) {
Throwable t = this.getThrowable( index );
if ( Nestable.class.isInstance( t ) ) {
return ( ( Nestable ) t ).getMessage( 0 );
}
else {
return t.getMessage();
}
}
/**
* Returns the full message contained by the <code>Nestable</code>
* and any nested <code>Throwable</code>s.
*
* @param baseMsg the base message to use when creating the full
* message. Should be generally be called via
* <code>nestableHelper.getMessage( super.getMessage() )</code>,
* where <code>super</code> is an instance of {@link
* java.lang.Throwable}.
* @return The concatenated message for this and all nested
* <code>Throwable</code>s
* @since 2.0
*/
public String getMessage(String baseMsg) {
StringBuffer msg = new StringBuffer();
if ( baseMsg != null ) {
msg.append( baseMsg );
}
Throwable nestedCause = ExceptionUtils.getCause( this.nestable );
if ( nestedCause != null ) {
String causeMsg = nestedCause.getMessage();
if ( causeMsg != null ) {
if ( baseMsg != null ) {
msg.append( ": " );
}
msg.append( causeMsg );
}
}
return ( msg.length() > 0 ? msg.toString() : null );
}
/**
* Returns the error message of this and any nested <code>Throwable</code>s
* in an array of Strings, one element for each message. Any
* <code>Throwable</code> not containing a message is represented in the
* array by a null. This has the effect of cause the length of the returned
* array to be equal to the result of the {@link #getThrowableCount()}
* operation.
*
* @return the error messages
* @since 2.0
*/
public String[] getMessages() {
Throwable[] throwables = this.getThrowables();
String[] msgs = new String[throwables.length];
for ( int i = 0; i < throwables.length; i++ ) {
msgs[i] = Nestable.class.isInstance( throwables[i] ) ?
( ( Nestable ) throwables[i] ).getMessage( 0 ) :
throwables[i].getMessage();
}
return msgs;
}
/**
* Returns the <code>Throwable</code> in the chain of
* <code>Throwable</code>s at the specified index, numbererd from 0.
*
* @param index the index, numbered from 0, of the <code>Throwable</code> in
* the chain of <code>Throwable</code>s
* @return the <code>Throwable</code>
* @throws IndexOutOfBoundsException if the <code>index</code> argument is
* negative or not less than the count of <code>Throwable</code>s in the
* chain
* @since 2.0
*/
public Throwable getThrowable(int index) {
if ( index == 0 ) {
return this.nestable;
}
Throwable[] throwables = this.getThrowables();
return throwables[index];
}
/**
* Returns the number of <code>Throwable</code>s contained in the
* <code>Nestable</code> contained by this delegate.
*
* @return the throwable count
* @since 2.0
*/
public int getThrowableCount() {
return ExceptionUtils.getThrowableCount( this.nestable );
}
/**
* Returns this delegate's <code>Nestable</code> and any nested
* <code>Throwable</code>s in an array of <code>Throwable</code>s, one
* element for each <code>Throwable</code>.
*
* @return the <code>Throwable</code>s
* @since 2.0
*/
public Throwable[] getThrowables() {
return ExceptionUtils.getThrowables( this.nestable );
}
/**
* Returns the index, numbered from 0, of the first <code>Throwable</code>
* that matches the specified type in the chain of <code>Throwable</code>s
* held in this delegate's <code>Nestable</code> with an index greater than
* or equal to the specified index, or -1 if the type is not found.
*
* @param type <code>Class</code> to be found
* @param fromIndex the index, numbered from 0, of the starting position in
* the chain to be searched
* @return index of the first occurrence of the type in the chain, or -1 if
* the type is not found
* @throws IndexOutOfBoundsException if the <code>fromIndex</code> argument
* is negative or not less than the count of <code>Throwable</code>s in the
* chain
* @since 2.0
*/
public int indexOfThrowable(Class type, int fromIndex) {
if ( fromIndex < 0 ) {
throw new IndexOutOfBoundsException( "The start index was out of bounds: " + fromIndex );
}
Throwable[] throwables = ExceptionUtils.getThrowables( this.nestable );
if ( fromIndex >= throwables.length ) {
throw new IndexOutOfBoundsException( "The start index was out of bounds: "
+ fromIndex + " >= " + throwables.length );
}
for ( int i = fromIndex; i < throwables.length; i++ ) {
if ( throwables[i].getClass().equals( type ) ) {
return i;
}
}
return -1;
}
/**
* Prints the stack trace of this exception the the standar error
* stream.
*/
public void printStackTrace() {
printStackTrace( System.err );
}
/**
* Prints the stack trace of this exception to the specified
* stream.
*
* @param out <code>PrintStream</code> to use for output.
* @see #printStackTrace(PrintWriter)
*/
public void printStackTrace(PrintStream out) {
synchronized ( out ) {
PrintWriter pw = new PrintWriter( out, false );
printStackTrace( pw );
// Flush the PrintWriter before it's GC'ed.
pw.flush();
}
}
/**
* Prints the stack trace of this exception to the specified
* writer. If the Throwable class has a <code>getCause</code>
* method (i.e. running on jre1.4 or higher), this method just
* uses Throwable's printStackTrace() method. Otherwise, generates
* the stack-trace, by taking into account the 'topDown' and
* 'trimStackFrames' parameters. The topDown and trimStackFrames
* are set to 'true' by default (produces jre1.4-like stack trace).
*
* @param out <code>PrintWriter</code> to use for output.
*/
public void printStackTrace(PrintWriter out) {
Throwable throwable = this.nestable;
// if running on jre1.4 or higher, use default printStackTrace
if ( ExceptionUtils.isThrowableNested() ) {
if ( throwable instanceof Nestable ) {
( ( Nestable ) throwable ).printPartialStackTrace( out );
}
else {
throwable.printStackTrace( out );
}
return;
}
// generating the nested stack trace
List stacks = new ArrayList();
while ( throwable != null ) {
String[] st = getStackFrames( throwable );
stacks.add( st );
throwable = ExceptionUtils.getCause( throwable );
}
// If NOT topDown, reverse the stack
String separatorLine = "Caused by: ";
if ( !topDown ) {
separatorLine = "Rethrown as: ";
Collections.reverse( stacks );
}
// Remove the repeated lines in the stack
if ( trimStackFrames ) trimStackFrames( stacks );
synchronized ( out ) {
for ( Iterator iter = stacks.iterator(); iter.hasNext(); ) {
String[] st = ( String[] ) iter.next();
for ( int i = 0, len = st.length; i < len; i++ ) {
out.println( st[i] );
}
if ( iter.hasNext() ) out.print( separatorLine );
}
}
}
/**
* Captures the stack trace associated with the specified
* <code>Throwable</code> object, decomposing it into a list of
* stack frames.
*
* @param t The <code>Throwable</code>.
* @return An array of strings describing each stack frame.
* @since 2.0
*/
protected String[] getStackFrames(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter( sw, true );
// Avoid infinite loop between decompose() and printStackTrace().
if ( t instanceof Nestable ) {
( ( Nestable ) t ).printPartialStackTrace( pw );
}
else {
t.printStackTrace( pw );
}
return ExceptionUtils.getStackFrames( sw.getBuffer().toString() );
}
/**
* Trims the stack frames. The first set is left untouched. The rest
* of the frames are truncated from the bottom by comparing with
* one just on top.
*
* @param stacks The list containing String[] elements
* @since 2.0
*/
protected void trimStackFrames(List stacks) {
for ( int size = stacks.size(), i = size - 1; i > 0; i-- ) {
String[] curr = ( String[] ) stacks.get( i );
String[] next = ( String[] ) stacks.get( i - 1 );
List currList = new ArrayList( Arrays.asList( curr ) );
List nextList = new ArrayList( Arrays.asList( next ) );
ExceptionUtils.removeCommonFrames( currList, nextList );
int trimmed = curr.length - currList.size();
if ( trimmed > 0 ) {
currList.add( "\t... " + trimmed + " more" );
stacks.set( i,
currList.toArray( new String[currList.size()] ) );
}
}
}
}

View File

@ -1,225 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.exception;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* The base class of all exceptions which can contain other exceptions.
* <p/>
* It is intended to ease the debugging by carrying on the information
* about the exception which was caught and provoked throwing the
* current exception. Catching and rethrowing may occur multiple
* times, and provided that all exceptions except the first one
* are descendands of <code>NestedException</code>, when the
* exception is finally printed out using any of the <code>
* printStackTrace()</code> methods, the stacktrace will contain
* the information about all exceptions thrown and caught on
* the way.
* <p> Running the following program
* <p><blockquote><pre>
* 1 import org.apache.commons.lang.exception.NestableException;
* 2
* 3 public class Test {
* 4 public static void main( String[] args ) {
* 5 try {
* 6 a();
* 7 } catch(Exception e) {
* 8 e.printStackTrace();
* 9 }
* 10 }
* 11
* 12 public static void a() throws Exception {
* 13 try {
* 14 b();
* 15 } catch(Exception e) {
* 16 throw new NestableException("foo", e);
* 17 }
* 18 }
* 19
* 20 public static void b() throws Exception {
* 21 try {
* 22 c();
* 23 } catch(Exception e) {
* 24 throw new NestableException("bar", e);
* 25 }
* 26 }
* 27
* 28 public static void c() throws Exception {
* 29 throw new Exception("baz");
* 30 }
* 31 }
* </pre></blockquote>
* <p>Yields the following stacktrace:
* <p><blockquote><pre>
* org.apache.commons.lang.exception.NestableException: foo
* at Test.a(Test.java:16)
* at Test.main(Test.java:6)
* Caused by: org.apache.commons.lang.exception.NestableException: bar
* at Test.b(Test.java:24)
* at Test.a(Test.java:14)
* ... 1 more
* Caused by: java.lang.Exception: baz
* at Test.c(Test.java:29)
* at Test.b(Test.java:22)
* ... 2 more
* </pre></blockquote><br>
*
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
* @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
* @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
* @version $Id: NestableException.java 4782 2004-11-21 00:11:27Z pgmjsd $
* @since 1.0
*/
public class NestableException extends Exception implements Nestable {
/**
* The helper instance which contains much of the code which we
* delegate to.
*/
protected NestableDelegate delegate = new NestableDelegate( this );
/**
* Holds the reference to the exception or error that caused
* this exception to be thrown.
*/
private Throwable cause = null;
/**
* Constructs a new <code>NestableException</code> without specified
* detail message.
*/
public NestableException() {
super();
}
/**
* Constructs a new <code>NestableException</code> with specified
* detail message.
*
* @param msg The error message.
*/
public NestableException(String msg) {
super( msg );
}
/**
* Constructs a new <code>NestableException</code> with specified
* nested <code>Throwable</code>.
*
* @param cause the exception or error that caused this exception to be
* thrown
*/
public NestableException(Throwable cause) {
super();
this.cause = cause;
}
/**
* Constructs a new <code>NestableException</code> with specified
* detail message and nested <code>Throwable</code>.
*
* @param msg the error message
* @param cause the exception or error that caused this exception to be
* thrown
*/
public NestableException(String msg, Throwable cause) {
super( msg );
this.cause = cause;
}
public Throwable getCause() {
return cause;
}
/**
* Returns the detail message string of this throwable. If it was
* created with a null message, returns the following:
* ( cause==null ? null : cause.toString() ).
*/
public String getMessage() {
if ( super.getMessage() != null ) {
return super.getMessage();
}
else if ( cause != null ) {
return cause.toString();
}
else {
return null;
}
}
public String getMessage(int index) {
if ( index == 0 ) {
return super.getMessage();
}
else {
return delegate.getMessage( index );
}
}
public String[] getMessages() {
return delegate.getMessages();
}
public Throwable getThrowable(int index) {
return delegate.getThrowable( index );
}
public int getThrowableCount() {
return delegate.getThrowableCount();
}
public Throwable[] getThrowables() {
return delegate.getThrowables();
}
public int indexOfThrowable(Class type) {
return delegate.indexOfThrowable( type, 0 );
}
public int indexOfThrowable(Class type, int fromIndex) {
return delegate.indexOfThrowable( type, fromIndex );
}
public void printStackTrace() {
delegate.printStackTrace();
}
public void printStackTrace(PrintStream out) {
delegate.printStackTrace( out );
}
public void printStackTrace(PrintWriter out) {
delegate.printStackTrace( out );
}
public final void printPartialStackTrace(PrintWriter out) {
super.printStackTrace( out );
}
}

View File

@ -1,185 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.exception;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.ObjectOutputStream;
import java.io.IOException;
import antlr.RecognitionException;
/**
* The base class of all runtime exceptions which can contain other
* exceptions.
*
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
* @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
* @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
* @version $Id: NestableRuntimeException.java 8137 2005-09-09 15:21:10Z epbernard $
* @see org.apache.commons.lang.exception.NestableException
* @since 1.0
*/
public class NestableRuntimeException extends RuntimeException implements Nestable {
/**
* The helper instance which contains much of the code which we
* delegate to.
*/
protected NestableDelegate delegate = new NestableDelegate( this );
/**
* Holds the reference to the exception or error that caused
* this exception to be thrown.
*/
private Throwable cause = null;
/**
* Constructs a new <code>NestableRuntimeException</code> without specified
* detail message.
*/
public NestableRuntimeException() {
super();
}
/**
* Constructs a new <code>NestableRuntimeException</code> with specified
* detail message.
*
* @param msg the error message
*/
public NestableRuntimeException(String msg) {
super( msg );
}
/**
* Constructs a new <code>NestableRuntimeException</code> with specified
* nested <code>Throwable</code>.
*
* @param cause the exception or error that caused this exception to be
* thrown
*/
public NestableRuntimeException(Throwable cause) {
super();
this.cause = cause;
}
/**
* Constructs a new <code>NestableRuntimeException</code> with specified
* detail message and nested <code>Throwable</code>.
*
* @param msg the error message
* @param cause the exception or error that caused this exception to be
* thrown
*/
public NestableRuntimeException(String msg, Throwable cause) {
super( msg );
this.cause = cause;
}
public Throwable getCause() {
return cause;
}
/**
* Returns the detail message string of this throwable. If it was
* created with a null message, returns the following:
* ( cause==null ? null : cause.toString( ).
*/
public String getMessage() {
if ( super.getMessage() != null ) {
return super.getMessage();
}
else if ( cause != null ) {
return cause.toString();
}
else {
return null;
}
}
public String getMessage(int index) {
if ( index == 0 ) {
return super.getMessage();
}
else {
return delegate.getMessage( index );
}
}
public String[] getMessages() {
return delegate.getMessages();
}
public Throwable getThrowable(int index) {
return delegate.getThrowable( index );
}
public int getThrowableCount() {
return delegate.getThrowableCount();
}
public Throwable[] getThrowables() {
return delegate.getThrowables();
}
public int indexOfThrowable(Class type) {
return delegate.indexOfThrowable( type, 0 );
}
public int indexOfThrowable(Class type, int fromIndex) {
return delegate.indexOfThrowable( type, fromIndex );
}
public void printStackTrace() {
delegate.printStackTrace();
}
public void printStackTrace(PrintStream out) {
delegate.printStackTrace( out );
}
public void printStackTrace(PrintWriter out) {
delegate.printStackTrace( out );
}
public final void printPartialStackTrace(PrintWriter out) {
super.printStackTrace( out );
}
private void writeObject(ObjectOutputStream oos) throws IOException {
Throwable tempCause = cause;
//don't propagate RecognitionException, might be not serializable
if ( cause instanceof RecognitionException ) {
cause = null;
}
oos.defaultWriteObject();
cause = tempCause;
}
}