FileDocCategorySizeDatePackage
NestableDelegate.javaAPI DocHibernate 3.2.514358Sat Nov 20 17:11:28 GMT 2004org.hibernate.exception

NestableDelegate

public class NestableDelegate extends Object implements Serializable

A shared implementation of the nestable exception functionality.

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}.

author
Rafal Krzewski
author
Daniel Rall
author
Kasper Nielsen
author
Steven Caswell
author
Sean C. Sullivan
author
Stephen Colebourne
version
$Id: NestableDelegate.java 4782 2004-11-21 00:11:27Z pgmjsd $
since
1.0

Fields Summary
private static final String
MUST_BE_THROWABLE
Constructor error message.
private Throwable
nestable
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 static boolean
topDown
Whether to print the stack trace top-down. This public flag may be set by calling code, typically in initialisation.
private static boolean
trimStackFrames
Whether to trim the repeated stack trace. This public flag may be set by calling code, typically in initialisation.
Constructors Summary
public NestableDelegate(Nestable nestable)
Constructs a new NestableDelegate instance to manage the specified Nestable.

param
nestable the Nestable implementation (must extend {@link java.lang.Throwable})
since
2.0


	                                     	 
	   
		if ( nestable instanceof Throwable ) {
			this.nestable = ( Throwable ) nestable;
		}
		else {
			throw new IllegalArgumentException( MUST_BE_THROWABLE );
		}
	
Methods Summary
public java.lang.StringgetMessage(int index)
Returns the error message of the Throwable in the chain of Throwables at the specified index, numbererd from 0.

param
index the index of the Throwable in the chain of Throwables
return
the error message, or null if the Throwable at the specified index in the chain does not contain a message
throws
IndexOutOfBoundsException if the index argument is negative or not less than the count of Throwables in the chain
since
2.0

		Throwable t = this.getThrowable( index );
		if ( Nestable.class.isInstance( t ) ) {
			return ( ( Nestable ) t ).getMessage( 0 );
		}
		else {
			return t.getMessage();
		}
	
public java.lang.StringgetMessage(java.lang.String baseMsg)
Returns the full message contained by the Nestable and any nested Throwables.

param
baseMsg the base message to use when creating the full message. Should be generally be called via nestableHelper.getMessage( super.getMessage() ), where super is an instance of {@link java.lang.Throwable}.
return
The concatenated message for this and all nested Throwables
since
2.0

		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 );
	
public java.lang.String[]getMessages()
Returns the error message of this and any nested Throwables in an array of Strings, one element for each message. Any Throwable 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

		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;
	
protected java.lang.String[]getStackFrames(java.lang.Throwable t)
Captures the stack trace associated with the specified Throwable object, decomposing it into a list of stack frames.

param
t The Throwable.
return
An array of strings describing each stack frame.
since
2.0

		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() );
	
public java.lang.ThrowablegetThrowable(int index)
Returns the Throwable in the chain of Throwables at the specified index, numbererd from 0.

param
index the index, numbered from 0, of the Throwable in the chain of Throwables
return
the Throwable
throws
IndexOutOfBoundsException if the index argument is negative or not less than the count of Throwables in the chain
since
2.0

		if ( index == 0 ) {
			return this.nestable;
		}
		Throwable[] throwables = this.getThrowables();
		return throwables[index];
	
public intgetThrowableCount()
Returns the number of Throwables contained in the Nestable contained by this delegate.

return
the throwable count
since
2.0

		return ExceptionUtils.getThrowableCount( this.nestable );
	
public java.lang.Throwable[]getThrowables()
Returns this delegate's Nestable and any nested Throwables in an array of Throwables, one element for each Throwable.

return
the Throwables
since
2.0

		return ExceptionUtils.getThrowables( this.nestable );
	
public intindexOfThrowable(java.lang.Class type, int fromIndex)
Returns the index, numbered from 0, of the first Throwable that matches the specified type in the chain of Throwables held in this delegate's Nestable with an index greater than or equal to the specified index, or -1 if the type is not found.

param
type Class 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 fromIndex argument is negative or not less than the count of Throwables in the chain
since
2.0

		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;
	
public voidprintStackTrace(java.io.PrintStream out)
Prints the stack trace of this exception to the specified stream.

param
out PrintStream to use for output.
see
#printStackTrace(PrintWriter)

		synchronized ( out ) {
			PrintWriter pw = new PrintWriter( out, false );
			printStackTrace( pw );
			// Flush the PrintWriter before it's GC'ed.
			pw.flush();
		}
	
public voidprintStackTrace(java.io.PrintWriter out)
Prints the stack trace of this exception to the specified writer. If the Throwable class has a getCause 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 PrintWriter to use for output.

		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 );
			}
		}
	
public voidprintStackTrace()
Prints the stack trace of this exception the the standar error stream.

		printStackTrace( System.err );
	
protected voidtrimStackFrames(java.util.List stacks)
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

		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()] ) );
			}
		}