scolebourne 2003/08/24 02:47:19
Modified: collections/src/test/org/apache/commons/collections
TestMapUtils.java
collections/src/java/org/apache/commons/collections
MapUtils.java
Log:
Improve debugPrint() and verbosePrint()
bug 20740, from Arun Mammen Thomas
Revision Changes Path
1.7 +166 -2
jakarta-commons/collections/src/test/org/apache/commons/collections/TestMapUtils.java
Index: TestMapUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/TestMapUtils.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- TestMapUtils.java 20 Aug 2003 21:03:16 -0000 1.6
+++ TestMapUtils.java 24 Aug 2003 09:47:19 -0000 1.7
@@ -66,6 +66,7 @@
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
+import java.util.TreeMap;
import junit.framework.Test;
@@ -331,5 +332,168 @@
} catch (final ClassCastException e) {
fail("No Casting should be occurring!");
}
+ }
+
+ public void testDebugAndVerbosePrintNullMap() {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintStream outPrint = new PrintStream(out);
+
+ final String LABEL = "Print Map";
+ outPrint.println(LABEL + " = " + String.valueOf((Object) null));
+ final String EXPECTED_OUT = out.toString();
+
+ out.reset();
+
+ MapUtils.debugPrint(outPrint, LABEL, null);
+ assertEquals(EXPECTED_OUT, out.toString());
+
+ out.reset();
+
+ MapUtils.verbosePrint(outPrint, LABEL, null);
+ assertEquals(EXPECTED_OUT, out.toString());
+ }
+
+ public void testVerbosePrintNullLabel() {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintStream outPrint = new PrintStream(out);
+
+ final String INDENT = " ";
+
+ final Map map = new TreeMap(); // treeMap guarantees order across JDKs for
test
+ map.put( new Integer(2) , "B" );
+ map.put( new Integer(3) , "C" );
+
+ outPrint.println("{");
+ outPrint.println(INDENT + "2 = B");
+ outPrint.println(INDENT + "3 = C");
+ outPrint.println("}");
+ final String EXPECTED_OUT = out.toString();
+ out.reset();
+
+ MapUtils.verbosePrint(outPrint, null, map);
+ assertEquals(EXPECTED_OUT, out.toString());
+ }
+
+ public void testDebugPrintNullLabel() {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintStream outPrint = new PrintStream(out);
+
+ final String INDENT = " ";
+
+ final Map map = new TreeMap(); // treeMap guarantees order across JDKs for
test
+ map.put( new Integer(2) , "B" );
+ map.put( new Integer(3) , "C" );
+
+ outPrint.println("{");
+ outPrint.println(INDENT + "2 = B " + String.class.getName());
+ outPrint.println(INDENT + "3 = C " + String.class.getName());
+ outPrint.println("} " + TreeMap.class.getName());
+ final String EXPECTED_OUT = out.toString();
+ out.reset();
+
+ MapUtils.debugPrint(outPrint, null, map);
+ assertEquals(EXPECTED_OUT, out.toString());
+ }
+
+ public void testVerbosePrintNullLabelAndMap() {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintStream outPrint = new PrintStream(out);
+
+ MapUtils.verbosePrint(outPrint, null, null);
+ assertEquals("", out.toString());
+ }
+
+ public void testDebugPrintNullLabelAndMap() {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintStream outPrint = new PrintStream(out);
+
+ MapUtils.debugPrint(outPrint, null, null);
+ assertEquals("", out.toString());
+ }
+
+ public void testVerbosePrintNullStream() {
+ try {
+ MapUtils.verbosePrint(null, "Map", new HashMap());
+ fail();
+ } catch (NullPointerException ex) {
+ }
+ }
+
+ public void testDebugPrintNullStream() {
+ try {
+ MapUtils.debugPrint(null, "Map", new HashMap());
+ fail();
+ } catch (NullPointerException ex) {
+ }
+ }
+
+ public void testVerbosePrint() {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintStream outPrint = new PrintStream(out);
+
+ final String LABEL = "Print Map";
+ final String INDENT = " ";
+
+ outPrint.println(LABEL + " = ");
+ outPrint.println("{");
+ outPrint.println(INDENT + "0 = A");
+ outPrint.println(INDENT + "1 = ");
+ outPrint.println(INDENT + "{");
+ outPrint.println(INDENT + INDENT + "2 = B");
+ outPrint.println(INDENT + INDENT + "3 = C");
+ outPrint.println(INDENT + "}");
+ outPrint.println(INDENT + "7 = this Map");
+ outPrint.println("}");
+
+ final String EXPECTED_OUT = out.toString();
+
+ out.reset();
+
+ final Map inner = new TreeMap(); // treeMap guarantees order across JDKs
for test
+ inner.put( new Integer(2) , "B" );
+ inner.put( new Integer(3) , "C" );
+
+ final Map outer = new TreeMap();
+ outer.put( new Integer(1) , inner );
+ outer.put( new Integer(0) , "A");
+ outer.put( new Integer(7) , outer);
+
+ MapUtils.verbosePrint(outPrint, "Print Map", outer);
+ assertEquals(EXPECTED_OUT, out.toString());
+ }
+
+ public void testDebugPrint() {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintStream outPrint = new PrintStream(out);
+
+ final String LABEL = "Print Map";
+ final String INDENT = " ";
+
+ outPrint.println(LABEL + " = ");
+ outPrint.println("{");
+ outPrint.println(INDENT + "0 = A " + String.class.getName());
+ outPrint.println(INDENT + "1 = ");
+ outPrint.println(INDENT + "{");
+ outPrint.println(INDENT + INDENT + "2 = B " + String.class.getName());
+ outPrint.println(INDENT + INDENT + "3 = C " + String.class.getName());
+ outPrint.println(INDENT + "} " + TreeMap.class.getName());
+ outPrint.println(INDENT + "7 = this Map");
+ outPrint.println("} " + TreeMap.class.getName());
+
+ final String EXPECTED_OUT = out.toString();
+
+ out.reset();
+
+ final Map inner = new TreeMap(); // treeMap guarantees order across JDKs
for test
+ inner.put( new Integer(2) , "B" );
+ inner.put( new Integer(3) , "C" );
+
+ final Map outer = new TreeMap();
+ outer.put( new Integer(1) , inner );
+ outer.put( new Integer(0) , "A");
+ outer.put( new Integer(7) , outer);
+
+ MapUtils.debugPrint(outPrint, "Print Map", outer);
+ assertEquals(EXPECTED_OUT, out.toString());
}
}
1.27 +73 -41
jakarta-commons/collections/src/java/org/apache/commons/collections/MapUtils.java
Index: MapUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/MapUtils.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- MapUtils.java 20 Aug 2003 21:03:16 -0000 1.26
+++ MapUtils.java 24 Aug 2003 09:47:19 -0000 1.27
@@ -116,6 +116,7 @@
* @author Arun Mammen Thomas
* @author Janek Bogucki
* @author Max Rydahl Andersen
+ * @author Arun Mammen Thomas
*/
public class MapUtils {
@@ -130,7 +131,9 @@
*/
public static final SortedMap EMPTY_SORTED_MAP =
Collections.unmodifiableSortedMap(new TreeMap());
- private static int debugIndent = 0;
+ private static int indentDepth = 0; // must be synchronized
+
+ private static final String INDENT_STRING = " ";
/**
* <code>MapUtils</code> should not normally be instantiated.
@@ -677,36 +680,48 @@
//-------------------------------------------------------------------------
/**
- * Prints the given map with nice line breaks.
+ * Prints the given map with nice line breaks.
+ * <p>
+ * This method prints a nicely formatted String decribing the Map.
+ * Each map entry will be printed with key and value.
+ * When the value is a Map, recursive behaviour occurs.
*
- * @param out the stream to print to
- * @param label the label to be applied to the output generated. This
- * may well be the key associated with this map within a
- * surrounding map in which this is nested.
- * @param map the map to print
+ * @param out the stream to print to, must not be null
+ * @param label the label to be applied to the output generated. This
+ * may well be the key associated with this map within a
+ * surrounding map in which this is nested.
+ * @param map the map to print, may be null
+ * @throws NullPointerException if the stream is null
*/
public static synchronized void verbosePrint(
final PrintStream out,
final Object label,
final Map map) {
+ indentDepth = 0;
verbosePrintInternal(out, label, map, false);
}
/**
- * Prints the given map with nice line breaks.
+ * Prints the given map with nice line breaks.
+ * <p>
+ * This method prints a nicely formatted String decribing the Map.
+ * Each map entry will be printed with key, value and value classname.
+ * When the value is a Map, recursive behaviour occurs.
*
- * @param out the stream to print to
- * @param label the label to be applied to the output generated. This
- * may well be the key associated with this map within a
- * surrounding map in which this is nested.
- * @param map the map to print
+ * @param out the stream to print to, must not be null
+ * @param label the label to be applied to the output generated. This
+ * may well be the key associated with this map within a
+ * surrounding map in which this is nested.
+ * @param map the map to print, may be null
+ * @throws NullPointerException if the stream is null
*/
public static synchronized void debugPrint(
final PrintStream out,
final Object label,
final Map map) {
+ indentDepth = 0;
verbosePrintInternal(out, label, map, true);
}
@@ -718,9 +733,9 @@
*
* @param out the stream to indent
*/
- protected static void debugPrintIndent(PrintStream out) {
- for (int i = 0; i < debugIndent; i++) {
- out.print(" ");
+ protected static void printIndent(PrintStream out) {
+ for (int i = 0; i < indentDepth; i++) {
+ out.print(INDENT_STRING);
}
}
@@ -737,53 +752,70 @@
* Implementation providing functionality for [EMAIL PROTECTED] #debugPrint}
and for
* [EMAIL PROTECTED] #verbosePrint}. This prints the given map with nice line
breaks.
* If the debug flag is true, it additionally prints the type of the object
- * value. .
+ * value.
*
* @param out the stream to print to
* @param label the label to be applied to the output generated. This
- * may well be the key associated with this map within a
- * surrounding map in which this is nested.
- * @param map the map to print
+ * may well be the key associated with this map within a
+ * surrounding map in which this is nested.
+ * @param map the map to print, may be null
* @param debug flag indicating whether type names should be output.
*/
- private static void verbosePrintInternal(
+ private static void verbosePrintInternal( // externally synchronized
final PrintStream out,
final Object label,
final Map map,
final boolean debug) {
- debugPrintIndent(out);
- out.println(label + " = ");
+ printIndent(out);
+
+ if (label != null) {
+ if (map == null) {
+ // Guard against null map.
+ out.println(label + " = null");
+ return;
+ } else {
+ out.println(label + " = ");
+ }
+ }
+ if (map == null) {
+ return;
+ }
- debugPrintIndent(out);
+ printIndent(out);
out.println("{");
- ++debugIndent;
+ indentDepth++;
- for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
- Map.Entry entry = (Map.Entry) iter.next();
+ for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
+ Map.Entry entry = (Map.Entry) it.next();
Object childKey = entry.getKey();
Object childValue = entry.getValue();
if (childValue instanceof Map) {
- verbosePrintInternal(out, childKey, (Map) childValue, false);
+ if (childValue == map) {
+ printIndent(out);
+ out.println(childKey + " = this Map"); // should have stack
really...
+ } else {
+ verbosePrintInternal(out, childKey, (Map) childValue, debug);
+ }
} else {
- debugPrintIndent(out);
-
- if (debug) {
- String typeName =
- (childValue != null)
- ? childValue.getClass().getName()
- : null;
+ printIndent(out);
+ if (debug && childValue != null) {
out.println(
- childKey + " = " + childValue + " class: " + typeName);
+ childKey
+ + " = "
+ + childValue
+ + " "
+ + childValue.getClass().getName()
+ );
} else {
out.println(childKey + " = " + childValue);
}
}
}
- --debugIndent;
- debugPrintIndent(out);
- out.println("}");
+ indentDepth--;
+ printIndent(out);
+ out.println(debug ? "} " + map.getClass().getName() : "}");
}
// Misc
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]