package org.eclipse.jdt.internal.core.util; | |
/* | |
* (c) Copyright IBM Corp. 2000, 2001. | |
* All Rights Reserved. | |
*/ | |
import java.io.*; | |
/** | |
* A dumper knows how to dump objects in a human-readable representation to a PrintWriter. | |
* Objects which implement IDumpable know how to dump themselves to a Dumper, otherwise | |
* the dumper just uses toString() on the object. | |
* Example: | |
* <pre> | |
* Dumper dumper = new Dumper(System.out); | |
* dumper.dump(myObject); | |
* dumper.flush(); | |
* </pre> | |
* | |
* @see IDumpable | |
* @see PrintWriter | |
*/ | |
public class Dumper { | |
int fTabLevel = 0; | |
PrintWriter fWriter; | |
/** | |
* Creates a dumper which sends output to System.out. | |
*/ | |
public Dumper() { | |
this(System.out); | |
} | |
/** | |
* Creates a dumper which sends output to the given OutputStream. | |
*/ | |
public Dumper(OutputStream out) { | |
this(new PrintWriter(out)); | |
} | |
/** | |
* Creates a dumper which sends output to the given PrintWriter. | |
*/ | |
public Dumper(PrintWriter writer) { | |
fWriter = writer; | |
} | |
/** | |
* Returns the class name to use for the given object. | |
*/ | |
String classNameFor(Object val) { | |
String name = val.getClass().getName(); | |
int i = name.lastIndexOf('.'); | |
if (i != -1) { | |
name = name.substring(i+1); | |
} | |
return name; | |
} | |
/** | |
* Dumps the given array. | |
* Prints a maximum of maxPerLine items per line. | |
*/ | |
public void dump(int[] val, int maxPerLine) { | |
int len = val.length; | |
boolean oneLine = (len <= maxPerLine); | |
if (!oneLine) { | |
++fTabLevel; | |
} | |
fWriter.print("["/*nonNLS*/); | |
for (int i = 0; i < len; ++i) { | |
if (!oneLine) { | |
if ((i % maxPerLine) == 0) { | |
fWriter.println(); | |
tabIfNeeded(); | |
fWriter.print(i); | |
fWriter.print(": "/*nonNLS*/); | |
} | |
} | |
fWriter.print(val[i]); | |
if (i + 1 < len) { | |
fWriter.print(", "/*nonNLS*/); | |
} | |
} | |
if (oneLine) { | |
fWriter.print("]"/*nonNLS*/); | |
fWriter.println(); | |
} | |
else { | |
fWriter.println(); | |
--fTabLevel; | |
tabIfNeeded(); | |
fWriter.print("]"/*nonNLS*/); | |
fWriter.println(); | |
} | |
} | |
/** | |
* Dumps the given array. | |
*/ | |
public void dump(Object[] val) { | |
int len = val.length; | |
fWriter.print("["/*nonNLS*/); | |
if (len > 0) { | |
fWriter.println(); | |
++fTabLevel; | |
for (int i = 0; i < len; ++i) { | |
dump(val[i]); | |
} | |
--fTabLevel; | |
tabIfNeeded(); | |
} | |
fWriter.println("]"/*nonNLS*/); | |
} | |
/** | |
* Dumps the given array. | |
* Prints a maximum of maxPerLine items per line. | |
*/ | |
public void dump(String[] val, int maxPerLine) { | |
int len = val.length; | |
boolean oneLine = (len <= maxPerLine); | |
if (!oneLine) { | |
++fTabLevel; | |
} | |
fWriter.print("["/*nonNLS*/); | |
boolean newLine = !oneLine; | |
for (int i = 0; i < len; ++i) { | |
if (newLine) { | |
fWriter.println(); | |
tabIfNeeded(); | |
} | |
fWriter.print("\""/*nonNLS*/ + val[i] + "\""/*nonNLS*/); | |
if (i + 1 < len) { | |
fWriter.print(", "/*nonNLS*/); | |
} | |
newLine = (i != 0 && (i % maxPerLine) == 0); | |
} | |
fWriter.print("]"/*nonNLS*/); | |
if (oneLine || newLine) { | |
fWriter.println(); | |
} | |
if (!oneLine) { | |
--fTabLevel; | |
} | |
} | |
/** | |
* Dumps the given value. | |
*/ | |
public void dump(Object val) { | |
tabIfNeeded(); | |
if (val instanceof IDumpable) { | |
IDumpable dumpable = (IDumpable) val; | |
fWriter.println(classNameFor(val) + " {"/*nonNLS*/); | |
int originalLevel = fTabLevel; | |
++fTabLevel; | |
try { | |
dumpable.dump(this); | |
} | |
catch (Throwable t) { | |
fWriter.println("*ERR*"/*nonNLS*/); | |
} | |
fTabLevel = originalLevel; | |
tabIfNeeded(); | |
fWriter.println("}"/*nonNLS*/); | |
} | |
else { | |
fWriter.println(val); | |
} | |
} | |
/** | |
* Dumps the given value, with the given name as a prefix. | |
*/ | |
public void dump(String name, int[] val) { | |
dump(name, val, 10); | |
} | |
/** | |
* Dumps the given array, with the given name as a prefix. | |
* Prints a maximum of maxPerLine items per line. | |
*/ | |
public void dump(String name, int[] val, int maxPerLine) { | |
prefix(name); | |
dump(val, maxPerLine); | |
} | |
/** | |
* Dumps the given value, with the given name as a prefix. | |
*/ | |
public void dump(String name, Object[] val) { | |
prefix(name); | |
dump(val); | |
} | |
/** | |
* Dumps the given value, with the given name as a prefix. | |
*/ | |
public void dump(String name, String[] val) { | |
prefix(name); | |
dump(val, 5); | |
} | |
/** | |
* Dumps the given value, with the given name as a prefix. | |
*/ | |
public void dump(String name, int val) { | |
prefix(name); | |
fWriter.println(val); | |
} | |
/** | |
* Dumps the given value, with the given name as a prefix. | |
*/ | |
public void dump(String name, Object val) { | |
prefix(name); | |
fWriter.println(); | |
++fTabLevel; | |
dump(val); | |
--fTabLevel; | |
} | |
/** | |
* Dumps the given value, with the given name as a prefix. | |
*/ | |
public void dump(String name, String val) { | |
prefix(name); | |
fWriter.println(val == null ? "null"/*nonNLS*/ : "\""/*nonNLS*/ + val + "\""/*nonNLS*/); | |
} | |
/** | |
* Dumps the given value, with the given name as a prefix. | |
*/ | |
public void dump(String name, boolean val) { | |
prefix(name); | |
fWriter.println(val); | |
} | |
/** | |
* Dumps the given message, with the given name as a prefix. | |
*/ | |
public void dumpMessage(String name, String msg) { | |
prefix(name); | |
fWriter.println(msg); | |
} | |
/** | |
* Flushes the output writer. | |
*/ | |
public void flush() { | |
fWriter.flush(); | |
} | |
/** | |
* Returns the current tab level. | |
*/ | |
public int getTabLevel() { | |
return fTabLevel; | |
} | |
/** | |
* Returns the underlying PrintWriter. | |
*/ | |
public PrintWriter getWriter() { | |
return fWriter; | |
} | |
/** | |
* Increase the current tab level. | |
*/ | |
public void indent() { | |
++fTabLevel; | |
} | |
/** | |
* Decrease the current tab level. | |
*/ | |
public void outdent() { | |
if (--fTabLevel < 0) | |
fTabLevel = 0; | |
} | |
/** | |
* Outputs the given prefix, tabbing first if needed. | |
*/ | |
void prefix(String name) { | |
tabIfNeeded(); | |
fWriter.print(name); | |
fWriter.print(": "/*nonNLS*/); | |
} | |
/** | |
* Print an object directly, without a newline. | |
*/ | |
public void print(Object obj) { | |
fWriter.print(obj); | |
} | |
/** | |
* Print a newline directly. | |
*/ | |
public void println() { | |
fWriter.println(); | |
} | |
/** | |
* Print an object directly, with a newline. | |
*/ | |
public void println(Object obj) { | |
fWriter.println(obj); | |
} | |
/** | |
* Outputs tabs if needed. | |
*/ | |
void tabIfNeeded() { | |
for (int i = 0; i < fTabLevel; ++i) { | |
fWriter.print(" "/*nonNLS*/); | |
} | |
} | |
} |