You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2010/05/19 13:39:00 UTC
svn commit: r946132 [2/2] - in /directory:
apacheds/trunk/avl-partition/src/test/java/org/apache/directory/server/core/partition/avl/
apacheds/trunk/core-annotations/src/main/java/org/apache/directory/server/core/factory/
apacheds/trunk/core-api/src/te...
Modified: directory/shared/trunk/ldap-convert/src/main/java/org/apache/directory/shared/converter/schema/SchemaParser.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap-convert/src/main/java/org/apache/directory/shared/converter/schema/SchemaParser.java?rev=946132&r1=946131&r2=946132&view=diff
==============================================================================
--- directory/shared/trunk/ldap-convert/src/main/java/org/apache/directory/shared/converter/schema/SchemaParser.java (original)
+++ directory/shared/trunk/ldap-convert/src/main/java/org/apache/directory/shared/converter/schema/SchemaParser.java Wed May 19 11:38:58 2010
@@ -30,30 +30,12 @@ import java.io.Writer;
import java.text.ParseException;
import java.util.List;
+import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.directory.shared.i18n.I18n;
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
import antlr.RecognitionException;
import antlr.TokenStreamException;
-/*
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.io.Writer;
-import java.text.ParseException;
-import java.util.List;
-
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
-*/
-
/**
* A reusable wrapper for antlr generated schema parsers.
Modified: directory/shared/trunk/ldap-schema-manager/src/test/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoaderTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap-schema-manager/src/test/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoaderTest.java?rev=946132&r1=946131&r2=946132&view=diff
==============================================================================
--- directory/shared/trunk/ldap-schema-manager/src/test/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoaderTest.java (original)
+++ directory/shared/trunk/ldap-schema-manager/src/test/java/org/apache/directory/shared/ldap/schema/loader/ldif/LdifSchemaLoaderTest.java Wed May 19 11:38:58 2010
@@ -32,7 +32,7 @@ import org.apache.directory.shared.ldap.
import org.apache.directory.shared.ldap.schema.ldif.extractor.impl.DefaultSchemaLdifExtractor;
import org.apache.directory.shared.ldap.schema.loader.ldif.LdifSchemaLoader;
import org.apache.directory.shared.ldap.schema.manager.impl.DefaultSchemaManager;
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
+import org.apache.directory.shared.ldap.util.LdapExceptionUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -87,7 +87,7 @@ public class LdifSchemaLoaderTest
if ( !loaded )
{
- fail( "Schema load failed : " + ExceptionUtils.printErrors( sm.getErrors() ) );
+ fail( "Schema load failed : " + LdapExceptionUtils.printErrors( sm.getErrors() ) );
}
assertTrue( sm.getRegistries().getAttributeTypeRegistry().contains( "cn" ) );
Modified: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/OpenLdapSchemaParser.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/OpenLdapSchemaParser.java?rev=946132&r1=946131&r2=946132&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/OpenLdapSchemaParser.java (original)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/schema/parsers/OpenLdapSchemaParser.java Wed May 19 11:38:58 2010
@@ -31,12 +31,12 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.schema.AttributeType;
import org.apache.directory.shared.ldap.schema.ObjectClass;
import org.apache.directory.shared.ldap.schema.SchemaObject;
import org.apache.directory.shared.ldap.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro;
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
import antlr.RecognitionException;
import antlr.TokenStreamException;
Copied: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapExceptionUtils.java (from r946084, directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/ExceptionUtils.java)
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapExceptionUtils.java?p2=directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapExceptionUtils.java&p1=directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/ExceptionUtils.java&r1=946084&r2=946132&rev=946132&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/ExceptionUtils.java (original)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/LdapExceptionUtils.java Wed May 19 11:38:58 2010
@@ -20,20 +20,7 @@
package org.apache.directory.shared.ldap.util;
-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.Arrays;
-import java.util.LinkedList;
import java.util.List;
-import java.util.StringTokenizer;
-
-import org.apache.directory.shared.i18n.I18n;
/**
@@ -45,935 +32,8 @@ import org.apache.directory.shared.i18n.
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
-public class ExceptionUtils
+public class LdapExceptionUtils
{
-
- /**
- * <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 String[] CAUSE_METHOD_NAMES =
- { "getCause", "getNextException", "getTargetException", "getException", "getSourceException", "getRootCause",
- "getCausedByException", "getNested", "getLinkedException", "getNestedException", "getLinkedCause",
- "getThrowable", };
-
- /**
- * <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", (Class[])null );
- }
- catch ( Exception e )
- {
- getCauseMethod = null;
- }
- THROWABLE_CAUSE_METHOD = getCauseMethod;
- }
-
-
- /**
- * <p>
- * Public constructor allows an instance of <code>ExceptionUtils</code> to
- * be created, although that is not normally necessary.
- * </p>
- */
- public ExceptionUtils()
- {
- }
-
-
- /**
- * <p>
- * Checks if a String is not empty ("") and not null.
- * </p>
- *
- * @param str
- * the String to check, may be null
- * @return <code>true</code> if the String is not empty and not null
- */
- private static boolean isNotEmpty( String str )
- {
- return ( str != null && str.length() > 0 );
- }
-
-
- // -----------------------------------------------------------------------
- /**
- * <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 ( isNotEmpty( methodName ) )
- {
- List<String> list = new ArrayList<String>( Arrays.asList( CAUSE_METHOD_NAMES ) );
- list.add( methodName );
- CAUSE_METHOD_NAMES = 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 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
- * @since 1.0
- */
- 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
- * @since 1.0
- */
- 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
- */
- // This will suppress PMD.EmptyCatchBlock warnings in this method
- @SuppressWarnings("PMD.EmptyCatchBlock")
- private static Throwable getCauseUsingMethodName( Throwable throwable, String methodName )
- {
- Method method = null;
- try
- {
- method = throwable.getClass().getMethod( methodName, (Class[])null );
- }
- catch ( NoSuchMethodException ignored )
- {
- }
- catch ( SecurityException ignored )
- {
- }
-
- if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) )
- {
- try
- {
- return ( Throwable ) method.invoke( throwable, ArrayUtils.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
- */
- // This will suppress PMD.EmptyCatchBlock warnings in this method
- @SuppressWarnings("PMD.EmptyCatchBlock")
- 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
- */
- // This will suppress PMD.EmptyCatchBlock warnings in this method
- @SuppressWarnings("PMD.EmptyCatchBlock")
- 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], (Class[])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<Throwable> list = new ArrayList<Throwable>();
-
- while ( throwable != null )
- {
- list.add( throwable );
- throwable = ExceptionUtils.getCause( throwable );
- }
-
- return 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( I18n.err( I18n.ERR_04356 ) );
- }
- 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 ArrayUtils.EMPTY_STRING_ARRAY;
- }
-
- Throwable throwables[] = getThrowables( throwable );
- int count = throwables.length;
- List<String> frames = new ArrayList<String>();
- List<String> nextTrace = getStackFrameList( throwables[count - 1] );
-
- for ( int i = count; --i >= 0; )
- {
- List<String> 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 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( I18n.err( I18n.ERR_04357 ) );
- }
- 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 examine, may be null
- * @return an array of strings describing each stack frame, never null
- */
- public static String[] getStackFrames( Throwable throwable )
- {
- if ( throwable == null )
- {
- return ArrayUtils.EMPTY_STRING_ARRAY;
- }
- return getStackFrames( getStackTrace( throwable ) );
- }
-
-
- /**
- * <p>
- * Functionality shared between the <code>getStackFrames(Throwable)</code>
- * methods of this and the
- */
- static String[] getStackFrames( String stackTrace )
- {
- String linebreak = SystemUtils.LINE_SEPARATOR;
- StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
- List<String> list = new LinkedList<String>();
-
- while ( frames.hasMoreTokens() )
- {
- list.add( frames.nextToken() );
- }
-
- return 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>" at".</code>
- * </p>
- *
- * @param t
- * is any throwable
- * @return List of stack frames
- */
- static List<String> getStackFrameList( Throwable t )
- {
- String stackTrace = getStackTrace( t );
- String linebreak = SystemUtils.LINE_SEPARATOR;
- StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
- List<String> list = new LinkedList<String>();
- 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;
- }
-
-
public static String printErrors( List<Throwable> errors )
{
StringBuilder sb = new StringBuilder();