package de.planetxml.tools; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.beans.Introspector; /** * Diese Klasse erzeugt eine Debugausgabe eines Objektes, Arrays, Liste oder * Map ähnlich der print_r oder var_dump Funktion in PHP. Es wird nicht * überprüft ob die Struktur rekursiv ist, stattdessen muss die maximale Tiefe * angegeben werden bis zu der verzweigt wird. * * Das Ausgabeformat orientiert sich an der * JavaScript Object Notation. * * @version $Revision$ * @author Jörn Horstmann , http://blog.planetxml.de/ */ public class DebugPrinter { private Object object; private int maxLevel; private HashSet visited; public DebugPrinter(Object o, int maxLevel) { this.object = o; this.maxLevel = maxLevel; this.visited = new HashSet(); } public DebugPrinter(Object o) { this(o, 3); } private static String escapeString(String str) { return escapeString(str, '"'); } private static String escapeString(String str, char quote) { // create a StringBuffer that is a bit bigger than str StringBuffer sb = new StringBuffer(str.length() + str.length() / 8 + 2); int len = str.length(); sb.append(quote); for (int i=0; i 2 && name.startsWith("is")) { property = name.substring(2); } else if (name.length() > 3 && name.startsWith("get")) { property = name.substring(3); } if (property != null) { property = Introspector.decapitalize(property); } } return property; } private void printProperties(Object o, PrintWriter pw, int level) { if (o == null) { pw.print("null"); } else if (o instanceof Boolean || o instanceof Byte || o instanceof Short || o instanceof Character || o instanceof Integer || o instanceof Long || o instanceof Float || o instanceof Double) { pw.print(o); } else if (o instanceof String) { pw.print(escapeString((String)o)); } else { if (level > maxLevel) { pw.print("..."); return; } else if (o.getClass().isArray()) { pw.println('['); int len = Array.getLength(o); for (int i=0; i 0 ? ", " : " "); printProperties(Array.get(o, i), pw, level+1); pw.println(); } indent(pw, level); pw.print(']'); } else if (o instanceof Collection) { pw.println('['); Collection col = (Collection)o; int c = 0; for (Iterator it=col.iterator(); it.hasNext(); ) { indent(pw, level+1); pw.print(c > 0 ? ", " : " "); printProperties(it.next(), pw, level+1); pw.println(); c++; } indent(pw, level); pw.print(']'); } else if (o instanceof Iterator) { pw.println('['); int c = 0; for (Iterator it=(Iterator)o; it.hasNext(); ) { indent(pw, level+1); pw.print(c > 0 ? ", " : " "); printProperties(it.next(), pw, level+1); pw.println(); c++; } indent(pw, level); pw.print(']'); } else if (o instanceof Enumeration) { pw.println('['); int c = 0; for (Enumeration e=(Enumeration)o; e.hasMoreElements(); ) { indent(pw, level+1); pw.print(c > 0 ? ", " : " "); printProperties(e.nextElement(), pw, level+1); pw.println(); c++; } indent(pw, level); pw.print(']'); } else if (o instanceof Map) { pw.println('{'); Map map = (Map)o; int c = 0; for (Iterator it=map.entrySet().iterator(); it.hasNext(); ) { Map.Entry me = (Map.Entry)it.next(); indent(pw, level+1); pw.print(c > 0 ? ", " : " "); pw.print(escapeString(me.getKey().toString())); pw.print(": "); printProperties(me.getValue(), pw, level+1); pw.println(); c++; } indent(pw, level); pw.print('}'); } else { Method[] m = o.getClass().getMethods(); int c = 0; pw.println('{'); for (int i=0; i 0 ? ", " : " "); pw.print(escapeString(property)); pw.print(": "); try { printProperties(m[i].invoke(o, null), pw, level+1); c++; } catch (Exception e) { } pw.println(); } } indent(pw, level); pw.print('}'); } } } }