Language Basics Java

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2002 - 2007 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
//package flex.messaging.util;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
/**
 * @exclude
 */
public class ExceptionUtil {
  /**
   * List of no-arg methods that are known to return a wrapped throwable.
   **/
  public static String[] unwrapMethods = { "getRootCause",
      "getTargetException", "getTargetError", "getException",
      "getCausedByException", "getLinkedException" };
  public static Throwable wrappedException(Throwable t) {
    // Handle these statically since they are core to Java
    return (t instanceof InvocationTargetException) ? ((InvocationTargetException) t)
        .getTargetException() : getRootCauseWithReflection(t);
  }
  /**
   * Get to the base exception (if any).
   */
  public static Throwable baseException(Throwable t) {
    Throwable wrapped = wrappedException(t);
    return wrapped != null ? baseException(wrapped) : t;
  }
  /**
   * Return the stack trace in a String.
   */
  public static String toString(Throwable t) {
    StringWriter strWrt = new StringWriter();
    t.printStackTrace(new PrintWriter(strWrt));
    return strWrt.toString();
  }
  /**
   * Return the stack trace up to the first line that starts with prefix.
   * 
   * 


   * Example: ExceptionUtil.getStackTraceUpTo(exception, "jrunx.");
   * 


   */
  public static String getStackTraceUpTo(Throwable t, String prefix) {
    StringTokenizer tokens = new StringTokenizer(toString(t), "\n\r");
    StringBuffer trace = new StringBuffer();
    boolean done = false;
    String lookingFor = "at " + prefix;
    while (!done && tokens.hasMoreElements()) {
      String token = tokens.nextToken();
      if (token.indexOf(lookingFor) == -1)
        trace.append(token);
      else
        done = true;
      trace.append("\n");
    }
    return trace.toString();
  }
  /**
   * return the top n lines of this stack trace.
   * 
   * 


   * Example: ExceptionUtil.getStackTraceLines(exception, 10);
   * 


   */
  public static String getStackTraceLines(Throwable t, int numLines) {
    StringTokenizer tokens = new StringTokenizer(toString(t), "\n\r");
    StringBuffer trace = new StringBuffer();
    for (int i = 0; i < numLines; i++) {
      String token = tokens.nextToken();
      trace.append(token);
      trace.append("\n");
    }
    return trace.toString();
  }
  /**
   * Return the "nth" method call from the stack trace of "t", where 0 is the
   * top.
   */
  public static String getCallAt(Throwable t, int nth) {
    StringTokenizer tokens = new StringTokenizer(toString(t), "\n\r");
    try {
      // Skip the first line - the exception message
      for (int i = 0; i <= nth; ++i)
        tokens.nextToken();
      // get the method name from the next token
      String token = tokens.nextToken();
      int index1 = token.indexOf(' ');
      int index2 = token.indexOf('(');
      StringBuffer call = new StringBuffer();
      call.append(token.substring(index1 < 0 ? 0 : index1 + 1,
          index2 < 0 ? call.length() : index2));
      int index3 = token.indexOf(':', index2 < 0 ? 0 : index2);
      if (index3 >= 0) {
        int index4 = token.indexOf(')', index3);
        call.append(token.substring(index3, index4 < 0 ? token.length()
            : index4));
      }
      return call.toString();
    } catch (NoSuchElementException e) {
    }
    return "unknown";
  }
  /**
   * Utility method for converting an exception into a string. This method
   * unwinds all wrapped exceptions
   * 
   * @param t
   *            The throwable exception
   * @return The printable exception
   */
  public static String exceptionToString(Throwable t) {
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);
    // print out the exception stack.
    printExceptionStack(t, out, 0);
    return sw.toString();
  }
  /**
   * Utility method for converting an exception and all chained root causes
   * into a string. Unlike exceptionToString(Throwable) which
   * prints the chain from most nested root cause down to the top-level
   * exception, this method prints from the top-level exception down to the
   * most nested root cause.
   * 
   * @param t
   *            The throwable exception.
   * @return The printable exception.
   */
  public static String exceptionFollowedByRootCausesToString(Throwable t) {
    StringBuffer output = new StringBuffer();
    Throwable root = t;
    while (root != null) {
      output.append((root == t) ? ((root instanceof Exception) ? "  Exception: "
          : "  Error: ")
          : "  Root cause: ");
      output.append(ExceptionUtil.toString(root));
      // Do not recurse if the root cause has already been printed; this
      // will have happened if the root cause has
      // been assigned to the current Throwable via initCause() or as a
      // constructor argument.
      Throwable cause = root.getCause();
      root = ExceptionUtil.wrappedException(root);
      if (cause == root)
        break;
    }
    return output.toString();
  }
  /**
   * Recursively prints out a stack of wrapped exceptions.
   */
  protected static void printExceptionStack(Throwable th, PrintWriter out,
      int depth) {
    // only print the stack depth if the depth is greater than 0
    boolean printStackDepth = depth > 0;
    Throwable wrappedException = ExceptionUtil.wrappedException(th);
    if (wrappedException != null) {
      printStackDepth = true;
      printExceptionStack(wrappedException, out, depth + 1);
    }
    if (printStackDepth) {
      out.write("[" + depth + "]");
    }
    th.printStackTrace(out);
  }
  private static Throwable getRootCauseWithReflection(Throwable t) {
    for (int i = 0; i < unwrapMethods.length; i++) {
      Method m = null;
      try {
        m = t.getClass().getMethod(unwrapMethods[i], (Class[]) null);
        return (Throwable) m.invoke(t, (Object[]) null);
      } catch (Exception nsme) {
        // ignore
      }
    }
    return null;
  }
}