Back

package com.futureshocked.debug;

import java.lang.reflect.*;

/** StaticDebugger will print out all the information about an <tt>Object</tt>
 *   passed into it, including private fields with the help of reflection.
 * <br><br>
 *  It can use recursion to call itself on any objects that are members of the
 *    first object passed in, etc etc.
 */
public class StaticDebugger {
  /**
   * The default maximum recursion depth for printing.
   */
  public static final int defaultMaxDepth = 1;

  /**
   * Prints the members of an object, with default recursion depth.
   *
   * @param o <tt>Object</tt> to print out.
   */
  public static void printDebugInformation(Object o) {
    StaticDebugger.printDebugInformation(o, StaticDebugger.defaultMaxDepth);
  }

  /**
   * Prints the members of an object, with user specified max recursion depth.
   *
   * @param o <tt>Object</tt> to print out.
   * @param maxDepth Maximum recursive depth to descend.
   */
  public static void printDebugInformation(Object o, int maxDepth) {
    StaticDebugger.printDebugInformation(o, maxDepth, 0);
    System.out.println();
  }

  /**
   * Private recurisve method that does the actual displaying of the
   *   <tt>Object</tt>.
   * @param o <tt>Object</tt> to print out.
   * @param maxDepth Maximum depth to descend.
   * @param currentDepth The current recursive depth.
   */
  private static void printDebugInformation(Object o, int maxDepth,
      int currentDepth) {
    if ((o == null) || (currentDepth++ > maxDepth))
      return;
    if (currentDepth == 1)
      System.out.println("------------------------");

    String smallIndent = Indenter.indent(currentDepth - 1);
    String bigIndent = Indenter.indent(currentDepth);

    Class c = o.getClass();
    System.out.println(c.getSimpleName() + "@" +
        Integer.toHexString(o.hashCode()) + " {");

    Field[] fields = c.getDeclaredFields();

    try {
      for (int x = 0; x < fields.length; x++) {
        Field field = fields[x];
        field.setAccessible(true);
        Class type = field.getType();

        System.out.print(bigIndent + type.getSimpleName()  + " " +
            field.getName() + " = ");

        // this probably could have just been a check for type Object, and if
        //   not an Object (ie: it's a primitive) just use
        //   field.toGenericString()...
        if (type.equals(Boolean.TYPE))
          System.out.println(field.getBoolean(o));
        else if (type.equals(Byte.TYPE))
          System.out.println(field.getByte(o));
        else if (type.equals(Character.TYPE))
          System.out.println(field.getChar(o));
        else if (type.equals(Short.TYPE))
          System.out.println(field.getShort(o));
        else if (type.equals(Integer.TYPE))
          System.out.println(field.getInt(o));
        else if (type.equals(Long.TYPE))
          System.out.println(field.getLong(o));
        else if (type.equals(Float.TYPE))
          System.out.println(field.getFloat(o));
        else if (type.equals(Double.TYPE))
          System.out.println(field.getDouble(o));
        else {
          Object fieldObj = field.get(o);
          if (fieldObj == null)
            System.out.println("null");
          else {
            // Don't recursively print the sun classes, nor go too deep
            if ((currentDepth >= maxDepth) ||
                (type.getName().startsWith("java")) ||
                (type.getName().startsWith("sun.")))
              System.out.println(
                  StringUtil.getShortClassName(fieldObj.toString()));
            else
              StaticDebugger.printDebugInformation(fieldObj, maxDepth,
                  currentDepth);
          }
        }
      }
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    }

    System.out.println(smallIndent + "}");
  }

}

Top