commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From scolebou...@apache.org
Subject cvs commit: jakarta-commons/collections/src/java/org/apache/commons/collections MapUtils.java
Date Wed, 17 Sep 2003 19:59:45 GMT
scolebourne    2003/09/17 12:59:45

  Modified:    collections/src/test/org/apache/commons/collections
                        TestMapUtils.java
               collections/src/java/org/apache/commons/collections
                        MapUtils.java
  Log:
  Fix Map debug output for recursion
  bug 23041, from Janek Bogucki/Arun Mammen Thomas
  
  Revision  Changes    Path
  1.13      +172 -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.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- TestMapUtils.java	14 Sep 2003 03:30:23 -0000	1.12
  +++ TestMapUtils.java	17 Sep 2003 19:59:45 -0000	1.13
  @@ -81,6 +81,7 @@
    * @author Stephen Colebourne
    * @author Arun Mammen Thomas
    * @author Max Rydahl Andersen
  + * @author Janek Bogucki
    */
   public class TestMapUtils extends BulkTest {
   
  @@ -355,10 +356,12 @@
           final Map map = new TreeMap();  // treeMap guarantees order across JDKs for test
           map.put( new Integer(2) , "B" );
           map.put( new Integer(3) , "C" );
  +        map.put( new Integer(4) , null );
       
           outPrint.println("{");
           outPrint.println(INDENT + "2 = B " + String.class.getName());
           outPrint.println(INDENT + "3 = C " + String.class.getName());
  +        outPrint.println(INDENT + "4 = null");
           outPrint.println("} " + TreeMap.class.getName());
           final String EXPECTED_OUT = out.toString();
           out.reset();
  @@ -426,6 +429,25 @@
           assertEquals(EXPECTED_OUT, out.toString());
       }
   
  +    public void testVerbosePrintNullKey() {
  +        final ByteArrayOutputStream out = new ByteArrayOutputStream();
  +        final PrintStream outPrint = new PrintStream(out);
  +
  +        final String INDENT = "    ";
  +
  +        final Map map = new HashMap();
  +        map.put( null , "A" );
  +    
  +        outPrint.println("{");
  +        outPrint.println(INDENT + "null = A");
  +        outPrint.println("}");
  +        final String EXPECTED_OUT = out.toString();
  +        out.reset();
  +        
  +        MapUtils.verbosePrint(outPrint, null, map);
  +        assertEquals(EXPECTED_OUT, out.toString());
  +    }
  +
       public void testDebugPrintNullKeyToMap1() {
           final ByteArrayOutputStream out = new ByteArrayOutputStream();
           final PrintStream outPrint = new PrintStream(out);
  @@ -445,6 +467,25 @@
           assertEquals(EXPECTED_OUT, out.toString());
       }
   
  +    public void testVerbosePrintNullKeyToMap1() {
  +        final ByteArrayOutputStream out = new ByteArrayOutputStream();
  +        final PrintStream outPrint = new PrintStream(out);
  +
  +        final String INDENT = "    ";
  +
  +        final Map map = new HashMap();
  +        map.put( null , map );
  +    
  +        outPrint.println("{");
  +        outPrint.println(INDENT + "null = (this Map)");
  +        outPrint.println("}");
  +        final String EXPECTED_OUT = out.toString();
  +        out.reset();
  +        
  +        MapUtils.verbosePrint(outPrint, null, map);
  +        assertEquals(EXPECTED_OUT, out.toString());
  +    }    
  +
       public void testDebugPrintNullKeyToMap2() {
           final ByteArrayOutputStream out = new ByteArrayOutputStream();
           final PrintStream outPrint = new PrintStream(out);
  @@ -469,6 +510,30 @@
           assertEquals(EXPECTED_OUT, out.toString());
       }
   
  +    public void testVerbosePrintNullKeyToMap2() {
  +        final ByteArrayOutputStream out = new ByteArrayOutputStream();
  +        final PrintStream outPrint = new PrintStream(out);
  +
  +        final String INDENT = "    ";
  +
  +        final Map map = new HashMap();
  +        final Map map2= new HashMap();
  +        map.put( null , map2 );
  +        map2.put( "2", "B" );
  +    
  +        outPrint.println("{");
  +        outPrint.println(INDENT + "null = ");
  +        outPrint.println(INDENT + "{");
  +        outPrint.println(INDENT + INDENT + "2 = B");
  +        outPrint.println(INDENT + "}");
  +        outPrint.println("}");
  +        final String EXPECTED_OUT = out.toString();
  +        out.reset();
  +        
  +        MapUtils.verbosePrint(outPrint, null, map);
  +        assertEquals(EXPECTED_OUT, out.toString());
  +    }    
  +
       public void testVerbosePrint() {
           final ByteArrayOutputStream out = new ByteArrayOutputStream();
           final PrintStream outPrint = new PrintStream(out);
  @@ -538,4 +603,109 @@
           MapUtils.debugPrint(outPrint, "Print Map", outer);
           assertEquals(EXPECTED_OUT, out.toString());
       }
  +
  +    public void testVerbosePrintSelfReference() {
  +        final ByteArrayOutputStream out = new ByteArrayOutputStream();
  +        final PrintStream outPrint = new PrintStream(out);
  +
  +        final String LABEL = "Print Map";
  +        final String INDENT = "    ";
  +        
  +
  +        final Map grandfather = new TreeMap();// treeMap guarantees order across JDKs for
test
  +        final Map father = new TreeMap();
  +        final Map son    = new TreeMap();
  +        
  +        grandfather.put( new Integer(0), "A" );
  +        grandfather.put( new Integer(1), father );
  +        
  +        father.put( new Integer(2), "B" );
  +        father.put( new Integer(3), grandfather);
  +        father.put( new Integer(4), son);
  +        
  +        son.put( new Integer(5), "C");
  +        son.put( new Integer(6), grandfather);
  +        son.put( new Integer(7), father);
  +        
  +        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 = (ancestor[0] Map)");
  +        outPrint.println(INDENT + INDENT + "4 = ");
  +        outPrint.println(INDENT + INDENT + "{");
  +        outPrint.println(INDENT + INDENT + INDENT + "5 = C");
  +        outPrint.println(INDENT + INDENT + INDENT + "6 = (ancestor[1] Map)");
  +        outPrint.println(INDENT + INDENT + INDENT + "7 = (ancestor[0] Map)");
  +        outPrint.println(INDENT + INDENT + "}");
  +        outPrint.println(INDENT + "}");
  +        outPrint.println("}");
  +
  +        final String EXPECTED_OUT = out.toString();
  +
  +        out.reset();
  +        MapUtils.verbosePrint(outPrint, "Print Map", grandfather);
  +
  +        System.out.println(EXPECTED_OUT);
  +        System.out.println(EXPECTED_OUT.length());
  +        System.out.println(out.toString());
  +        System.out.println(out.toString().length());
  +
  +        assertEquals(EXPECTED_OUT, out.toString());
  +    }
  +    
  +    public void testDebugPrintSelfReference() {
  +        final ByteArrayOutputStream out = new ByteArrayOutputStream();
  +        final PrintStream outPrint = new PrintStream(out);
  +    
  +        final String LABEL = "Print Map";
  +        final String INDENT = "    ";
  +        
  +    
  +        final Map grandfather = new TreeMap();// treeMap guarantees order across JDKs for
test
  +        final Map father = new TreeMap();
  +        final Map son    = new TreeMap();
  +        
  +        grandfather.put( new Integer(0), "A" );
  +        grandfather.put( new Integer(1), father );
  +        
  +        father.put( new Integer(2), "B" );
  +        father.put( new Integer(3), grandfather);
  +        father.put( new Integer(4), son);
  +        
  +        son.put( new Integer(5), "C");
  +        son.put( new Integer(6), grandfather);
  +        son.put( new Integer(7), father);
  +        
  +        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 = (ancestor[0] Map) " + TreeMap.class.getName());
  +        outPrint.println(INDENT + INDENT + "4 = ");
  +        outPrint.println(INDENT + INDENT + "{");
  +        outPrint.println(INDENT + INDENT + INDENT + "5 = C " + String.class.getName());
  +        outPrint.println(INDENT + INDENT + INDENT + "6 = (ancestor[1] Map) " + TreeMap.class.getName());
  +        outPrint.println(INDENT + INDENT + INDENT + "7 = (ancestor[0] Map) " + TreeMap.class.getName());
  +        outPrint.println(INDENT + INDENT + "} " + TreeMap.class.getName());
  +        outPrint.println(INDENT + "} " + TreeMap.class.getName());
  +        outPrint.println("} " + TreeMap.class.getName());
  +    
  +        final String EXPECTED_OUT = out.toString();
  +    
  +        out.reset();
  +        MapUtils.debugPrint(outPrint, "Print Map", grandfather);
  +    
  +        System.out.println(EXPECTED_OUT);
  +        System.out.println(EXPECTED_OUT.length());
  +        System.out.println(out.toString());
  +        System.out.println(out.toString().length());
  +    
  +        assertEquals(EXPECTED_OUT, out.toString());
  +    }
  +    
   }
  
  
  
  1.34      +47 -16    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.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- MapUtils.java	9 Sep 2003 21:05:51 -0000	1.33
  +++ MapUtils.java	17 Sep 2003 19:59:45 -0000	1.34
  @@ -641,7 +641,7 @@
        * @param map  the map to convert to a Properties object, may not be null
        * @return the properties object
        */
  -    public static Properties toProperties(Map map) {
  +    public static Properties toProperties(final Map map) {
           Properties answer = new Properties();
           if (map != null) {
               for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
  @@ -661,7 +661,7 @@
        * @return the hashmap containing the data
        * @throws NullPointerException if the bundle is null
        */
  -    public static Map toMap(ResourceBundle resourceBundle) {
  +    public static Map toMap(final ResourceBundle resourceBundle) {
           Enumeration enum = resourceBundle.getKeys();
           Map map = new HashMap();
   
  @@ -698,7 +698,7 @@
           final Map map) {
   
           indentDepth = 0;
  -        verbosePrintInternal(out, label, map, false);
  +        verbosePrintInternal(out, label, map, new ArrayStack(), false);
       }
   
       /**
  @@ -722,7 +722,7 @@
           final Map map) {
   
           indentDepth = 0;
  -        verbosePrintInternal(out, label, map, true);
  +        verbosePrintInternal(out, label, map, new ArrayStack(), true);
       }
   
       // Implementation methods
  @@ -733,7 +733,7 @@
        *
        * @param out  the stream to indent
        */
  -    protected static void printIndent(PrintStream out) {
  +    protected static void printIndent(final PrintStream out) {
           for (int i = 0; i < indentDepth; i++) {
               out.print(INDENT_STRING);
           }
  @@ -744,7 +744,7 @@
        *
        * @param ex  the exception to log
        */
  -    protected static void logInfo(Exception ex) {
  +    protected static void logInfo(final Exception ex) {
           System.out.println("INFO: Exception: " + ex);
       }
   
  @@ -752,14 +752,23 @@
        * Implementation providing functionality for {@link #debugPrint} and for 
        * {@link #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.  If the contents of a map include the map itself, then the text 
  +     * <em>(this Map)</em> is printed out.  If the contents include a 
  +     * parent container of the map, the the text <em>(ancestor[i] Map)</em>
is 
  +     * printed, where i actually indicates the number of levels which must be 
  +     * traversed in the sequential list of ancesters (e.g. father, grandfather, 
  +     * great-grandfather, etc).  
        *
        * @param out  the stream to print to
  -     * @param label  The label to be used, may be <code>null</code>.
  +     * @param label  the label to be used, may be <code>null</code>.
        *  If <code>null</code>, the label is not output.
        *  It typically represents the name of the property in a bean or similar.
  -     * @param map  The map to print, may be <code>null</code>.
  -     *  If <code>null</code>, the text 'null' is output.
  +     * @param map  the map to print, may be <code>null</code>.
  +     *  If <code>null</code>, the text 'null' is output
  +     * @param lineage  a stack consisting of any maps in which the previous 
  +     *  argument is contained. This is checked to avoid infinite recursion when
  +     *  printing the output
  +     *                   
        * @param debug flag indicating whether type names should be output.
        * @throws NullPointerException if the stream is <code>null</code>
        */
  @@ -767,8 +776,9 @@
           final PrintStream out,
           final Object label,
           final Map map,
  +        final ArrayStack lineage,
           final boolean debug) {
  -
  +        
           printIndent(out);
   
           if (map == null) {
  @@ -786,19 +796,38 @@
   
           printIndent(out);
           out.println("{");
  +
           indentDepth++;
  +        lineage.push(map);
   
           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 && childValue != map) {
  -                verbosePrintInternal(out, (childKey == null ? "null" : childKey), (Map)
childValue, debug);
  +            if (childValue instanceof Map && !lineage.contains(childValue)) {
  +                verbosePrintInternal(
  +                    out,
  +                    (childKey == null ? "null" : childKey),
  +                    (Map) childValue,
  +                    lineage,
  +                    debug);
               } else {
                   printIndent(out);
                   out.print(childKey);
                   out.print(" = ");
  -                out.print(childValue == map ? "(this Map)" : childValue);
  +                
  +                final int lineageIndex = lineage.indexOf(childValue);
  +                if (lineageIndex == -1) {
  +                    out.print(childValue);
  +                } else if (lineage.size() - 1 == lineageIndex) {
  +                    out.print("(this Map)");    
  +                } else {
  +                    out.print(
  +                        "(ancestor["
  +                            + (lineage.size() - 1 - lineageIndex - 1)
  +                            + "] Map)");
  +                }
  +                
                   if (debug && childValue != null) {
                       out.print(' ');
                       out.println(childValue.getClass().getName());
  @@ -808,7 +837,9 @@
               }
           }
           
  +        lineage.pop();
           indentDepth--;
  +
           printIndent(out);
           out.println(debug ? "} " + map.getClass().getName() : "}");
       }
  
  
  

Mime
View raw message