commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject cvs commit: jakarta-commons-sandbox/lang/src/test/org/apache/commons/lang/exception NestableDelegateTestCase.java NestableExceptionTestCase.java NestableRuntimeExceptionTestCase.java
Date Wed, 17 Jul 2002 05:04:48 GMT
bayard      2002/07/16 22:04:47

  Modified:    lang/src/java/org/apache/commons/lang/exception
                        Nestable.java NestableDelegate.java
                        NestableException.java
                        NestableRuntimeException.java
               lang/src/test/org/apache/commons/lang/exception
                        NestableDelegateTestCase.java
                        NestableExceptionTestCase.java
                        NestableRuntimeExceptionTestCase.java
  Log:
  Applied rewrite patch to exception package's api.
  
  Submitted by: Steven Caswell <steven@caswell.name>
  
  Revision  Changes    Path
  1.4       +78 -20    jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/Nestable.java
  
  Index: Nestable.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/Nestable.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Nestable.java	5 Jul 2002 16:38:36 -0000	1.3
  +++ Nestable.java	17 Jul 2002 05:04:47 -0000	1.4
  @@ -75,40 +75,98 @@
       public Throwable getCause();
   
       /**
  -     * Returns the error message of this <code>Nestable</code>
  +     * Returns the number of nested <code>Throwable</code>s represented by
  +     * this <code>Nestable</code>, including this <code>Nestable</code>.
  +     */
  +    public int getLength();
  +    
  +    /**
  +     * Returns the error message of this and any nested
  +     * <code>Throwable</code>.
        *
        * @return The error message.
        */
  -    public String getFirstMessage();
  +    public String getMessage();
   
       /**
  -     * Returns the error message of the last <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested
  -     * <code>Throwable</code> or if the last nested <code>Throwable</code> was
  -     * created without a message specified.
  +     * Returns the error message of the <code>Throwable</code> in the chain
  +     * of <code>Throwable</code>s at the specified index, numbererd from 0.
  +     * If <code>index</code> is negative, the effect is the same as if it
  +     * were 0. If <code>index</code> is greater than or equal to the length
  +     * of the chain, the message of the last <code>Throwable</code> in the
  +     * chain is returned.
        *
  -     * @return The error message.
  +     * @param index the index of the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s
  +     * @return the error message
        */
  -    public String getLastMessage();
  -    
  +    public String getMessage(int index);
  +
       /**
  -     * Returns the error message of this and any nested
  -     * <code>Throwable</code>.
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
        *
  -     * @return The error message.
  +     * @return the error messages
        */
  -    public String getMessage();
  +    public String[] getMessages();
   
       /**
  -     * Returns the error message of the next <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested 
  -     * <code>Throwable</code> or if the next nested <code>Throwable</code> was
  -     * created without a message specified.
  +     * Returns the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s at the specified index, numbererd from 0. If
  +     * <code>index</code> is negative, the effect is the same as if it
  +     * were 0. If <code>index</code> is greater than or equal to the length
  +     * of the chain, the last <code>Throwable</code> in the chain is returned.
        *
  -     * @return The error message.
  +     * @param index the index of the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s
  +     * @return the <code>Throwable</code>
        */
  -    public String getNextMessage();
  +    public Throwable getThrowable(int index);
   
  +    /**
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
  +     *
  +     * @return the <code>Throwable</code>s
  +     */
  +    public Throwable[] getThrowables();
  +
  +    /**
  +     * Returns the index, numbered from 0, of the first occurrence of the
  +     * specified type in the chain of <code>Throwable</code>s, or -1 if the
  +     * specified type is not found in the chain. If <code>pos</code> is
  +     * negative, the effect is the same as if it were 0. If <code>pos</code>
  +     * is greater than or equal to the length of the chain, the effect is the
  +     * same as if it were the index of the last element in the chain.
  +     *
  +     * @param type <code>Class</code> to be found
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
  +     */
  +    public int indexOfThrowable(Class type);
  +
  +    /**
  +     * Returns the index, numbered from 0, of the first <code>Throwable</code>
  +     * that matches the specified type in the chain of <code>Throwable</code>s
  +     * with an index greater than or equal to the specified position, or -1 if
  +     * the type is not found. If <code>pos</code> is negative, the effect is the
  +     * same as if it were 0. If <code>pos</code> is greater than or equal to the
  +     * length of the chain, the effect is the same as if it were the index of
  +     * the last element in the chain.
  +     *
  +     * @param type <code>Class</code> to be found
  +     * @param pos index, numbered from 0, of the starting position in the chain
  +     * to be searched
  +     * 
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
  +     */
  +    public int indexOfThrowable(int pos, Class type);
  +    
       /**
        * Prints the stack trace of this exception to the specified print
        * writer.  Includes inforamation from the exception--if
  
  
  
  1.4       +84 -23    jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableDelegate.java
  
  Index: NestableDelegate.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableDelegate.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- NestableDelegate.java	5 Jul 2002 16:38:36 -0000	1.3
  +++ NestableDelegate.java	17 Jul 2002 05:04:47 -0000	1.4
  @@ -88,7 +88,7 @@
        * @param cause The Nestable implementation to get a stack trace for
        * (<i>must</i> extend {@link java.lang.Throwable}).
        */
  -    public NestableDelegate(Nestable cause)
  +    NestableDelegate(Nestable cause) // package
       {
           if (cause instanceof Throwable)
           {
  @@ -101,32 +101,34 @@
       }
   
       /**
  -     * Returns the last message in the chain of <code>Throwable</code>s
  -     * specified when this delegate was created.
  +     * Returns the number of <code>Throwable</code>s contained in the
  +     * <code>Nestable</code> contained by this delegate.
        */
  -    public String getLastMessage()
  +    int getLength() // package
       {
  +        // Count the number of throwables
  +        int count = 1;
           String msg = null;
           if(this.cause.getCause() == null)
           {
  -            return null;
  +            return count;
           }
           Throwable t = this.cause.getCause();
           while(t != null)
           {
  +            ++count;
               if(Nestable.class.isInstance(t))
               {
                   t = ((Nestable) t).getCause();
               }
               else
               {
  -                msg = t.getMessage();
                   t = null;
               }
           }
  -        return msg;
  +        return count;
       }
  -
  +    
       /**
        * @param baseMsg The base message to use when creating the full
        * message.  Should be generally be called via
  @@ -136,7 +138,7 @@
        * @return The concatenated message for this and all nested
        * exceptions.
        */
  -    public String getMessage(String baseMsg)
  +    String getMessage(String baseMsg) // package
       {
           StringBuffer msg = new StringBuffer();
           if (baseMsg != null)
  @@ -161,28 +163,87 @@
           return (msg.length() > 0 ? msg.toString() : null);
       }
   
  -    /**
  -     * Returns the next message in the chain of <code>Throwable</code>s
  -     * specified when this delegate was created.
  -     */
  -    public String getNextMessage()
  +    String getMessage(int index)
       {
  -        if(this.cause == null)
  +        Throwable t = this.getThrowable(index);
  +        if(Nestable.class.isInstance(t))
           {
  -            return null;
  +            return ((Nestable) t).getMessage(0);
           }
  -        if(this.cause.getCause() == null) 
  +        else
           {
  -            return null;
  +            return t.getMessage();
           }
  -        if(Nestable.class.isInstance(this.cause.getCause()))
  +    }
  +    
  +    Throwable getThrowable(int index)
  +    {
  +        Throwable[] throwables = this.getThrowables();
  +        if(index < 0)
           {
  -            return ((Nestable) this.cause.getCause()).getFirstMessage();
  +            index = 0;
           }
  -        else
  +        if(index == 0)
  +        {
  +            return (Throwable) this.cause;
  +        }
  +        if(index >= throwables.length)
  +        {
  +            index = throwables.length - 1;
  +        }
  +        return throwables[index];
  +    }
  +    
  +    Throwable[] getThrowables() // package
  +    {
  +        int count = this.getLength();
  +        // Allocate an array to hold the messages
  +        Throwable[] throwables = new Throwable[count];
  +        count = 0;
  +        if(cause != null)
  +        {
  +            throwables[count++] = (Throwable) this.cause;
  +            Throwable t = this.cause.getCause();
  +            while(t != null)
  +            {
  +                throwables[count++] = t;
  +                if(Nestable.class.isInstance(t))
  +                {
  +                    t = ((Nestable) t).getCause();
  +                }
  +                else
  +                {
  +                    t = null;
  +                }
  +            }
  +        }
  +        return throwables;
  +    }
  +
  +    String[] getMessages() // package
  +    {
  +        Throwable throwables[] = this.getThrowables();
  +        String[] msgs = new String[throwables.length];
  +        for(int i = 0; i < throwables.length; i++)
           {
  -            return this.cause.getCause().getMessage();
  +            msgs[i] = (Nestable.class.isInstance(throwables[i]) ? ((Nestable) throwables[i]).getMessage(0) : throwables[i].getMessage());
  +        }
  +        return msgs;
  +    }
  +
  +    int indexOfThrowable(int pos, Class type) // package
  +    {
  +        pos = (pos < 0) ? 0 : pos;
  +        Throwable throwables[] = this.getThrowables();
  +        pos = (pos >= throwables.length) ? throwables.length - 1 : pos;
  +        for(int i = pos; i < throwables.length; i++)
  +        {
  +            if(throwables[i].getClass().equals(type))
  +            {
  +                return i;
  +            }
           }
  +        return -1;
       }
       
       /**
  
  
  
  1.4       +70 -26    jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableException.java
  
  Index: NestableException.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableException.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- NestableException.java	5 Jul 2002 16:38:36 -0000	1.3
  +++ NestableException.java	17 Jul 2002 05:04:47 -0000	1.4
  @@ -197,26 +197,12 @@
       }
   
       /**
  -     * Returns the error message of this <code>Nestable</code>
  -     *
  -     * @return The error message.
  -     */
  -    public String getFirstMessage()
  -    {
  -        return super.getMessage();
  -    }
  -    
  -    /**
  -     * Returns the error message of the last <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested
  -     * <code>Throwable</code> or if the last nested <code>Throwable</code> was
  -     * created without a message specified.
  -     *
  -     * @return The error message.
  +     * Returns the number of nested <code>Throwable</code>s represented by
  +     * this <code>Nestable</code>, including this <code>Nestable</code>.
        */
  -    public String getLastMessage()
  +    public int getLength()
       {
  -        return delegate.getLastMessage();
  +        return delegate.getLength();
       }
       
       /**
  @@ -247,16 +233,74 @@
       }
   
       /**
  -     * Returns the error message of the next <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested
  -     * <code>Throwable</code> or if the next nested <code>Throwable</code> was
  -     * created without a message specified.
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
  +     */
  +    public String[] getMessages()
  +    {
  +        return delegate.getMessages();
  +    }
  +    
  +    public Throwable getThrowable(int index)
  +    {
  +        return delegate.getThrowable(index);
  +    }
  +    
  +    public Throwable[] getThrowables()
  +    {
  +        return delegate.getThrowables();
  +    }
  +    
  +    public String getMessage(int index)
  +    {
  +        if(index == 0)
  +        {
  +            return super.getMessage();
  +        }
  +        else
  +        {
  +            return delegate.getMessage(index);
  +        }
  +    }
  +    
  +    /**
  +     * Returns the index, numbered from 0, of the first occurrence of the
  +     * specified type in the chain of <code>Throwable</code>s, or -1 if the
  +     * specified type is not found in the chain. If <code>pos</code> is
  +     * negative, the effect is the same as if it were 0. If <code>pos</code>
  +     * is greater than or equal to the length of the chain, the effect is the
  +     * same as if it were the index of the last element in the chain.
  +     *
  +     * @param type <code>Class</code> to be found
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
  +     */
  +    public int indexOfThrowable(Class type)
  +    {
  +        return delegate.indexOfThrowable(0, type);
  +    }
  +
  +    /**
  +     * Returns the index, numbered from 0, of the first <code>Throwable</code>
  +     * that matches the specified type in the chain of <code>Throwable</code>s
  +     * with an index greater than or equal to the specified position, or -1 if
  +     * the type is not found. If <code>pos</code> is negative, the effect is the
  +     * same as if it were 0. If <code>pos</code> is greater than or equal to the
  +     * length of the chain, the effect is the same as if it were the index of
  +     * the last element in the chain.
        *
  -     * @return The error message.
  +     * @param type <code>Class</code> to be found
  +     * @param pos index, numbered from 0, of the starting position in the chain
  +     * to be searched
  +     * 
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
        */
  -    public String getNextMessage()
  +    public int indexOfThrowable(int pos, Class type)
       {
  -        return delegate.getNextMessage();
  +        return delegate.indexOfThrowable(pos, type);
       }
       
       /**
  
  
  
  1.4       +70 -26    jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableRuntimeException.java
  
  Index: NestableRuntimeException.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/lang/src/java/org/apache/commons/lang/exception/NestableRuntimeException.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- NestableRuntimeException.java	5 Jul 2002 16:38:36 -0000	1.3
  +++ NestableRuntimeException.java	17 Jul 2002 05:04:47 -0000	1.4
  @@ -144,26 +144,12 @@
       }
   
       /**
  -     * Returns the error message of this <code>Nestable</code>
  -     *
  -     * @return The error message.
  -     */
  -    public String getFirstMessage()
  -    {
  -        return super.getMessage();
  -    }
  -    
  -    /**
  -     * Returns the error message of the last <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested
  -     * <code>Throwable</code> or if the last nested <code>Throwable</code> was
  -     * created without a message specified.
  -     *
  -     * @return The error message.
  +     * Returns the number of nested <code>Throwable</code>s represented by
  +     * this <code>Nestable</code>, including this <code>Nestable</code>.
        */
  -    public String getLastMessage()
  +    public int getLength()
       {
  -        return delegate.getLastMessage();
  +        return delegate.getLength();
       }
       
       /**
  @@ -194,16 +180,74 @@
       }
   
       /**
  -     * Returns the error message of the next <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested
  -     * <code>Throwable</code> or if the next nested <code>Throwable</code> was
  -     * created without a message specified.
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
  +     */
  +    public String[] getMessages()
  +    {
  +        return delegate.getMessages();
  +    }
  +    
  +    public Throwable getThrowable(int index)
  +    {
  +        return delegate.getThrowable(index);
  +    }
  +    
  +    public Throwable[] getThrowables()
  +    {
  +        return delegate.getThrowables();
  +    }
  +    
  +    public String getMessage(int index)
  +    {
  +        if(index == 0)
  +        {
  +            return super.getMessage();
  +        }
  +        else
  +        {
  +            return delegate.getMessage(index);
  +        }
  +    }
  +    
  +    /**
  +     * Returns the index, numbered from 0, of the first occurrence of the
  +     * specified type in the chain of <code>Throwable</code>s, or -1 if the
  +     * specified type is not found in the chain. If <code>pos</code> is
  +     * negative, the effect is the same as if it were 0. If <code>pos</code>
  +     * is greater than or equal to the length of the chain, the effect is the
  +     * same as if it were the index of the last element in the chain.
  +     *
  +     * @param type <code>Class</code> to be found
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
  +     */
  +    public int indexOfThrowable(Class type)
  +    {
  +        return delegate.indexOfThrowable(0, type);
  +    }
  +
  +    /**
  +     * Returns the index, numbered from 0, of the first <code>Throwable</code>
  +     * that matches the specified type in the chain of <code>Throwable</code>s
  +     * with an index greater than or equal to the specified position, or -1 if
  +     * the type is not found. If <code>pos</code> is negative, the effect is the
  +     * same as if it were 0. If <code>pos</code> is greater than or equal to the
  +     * length of the chain, the effect is the same as if it were the index of
  +     * the last element in the chain.
        *
  -     * @return The error message.
  +     * @param type <code>Class</code> to be found
  +     * @param pos index, numbered from 0, of the starting position in the chain
  +     * to be searched
  +     * 
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
        */
  -    public String getNextMessage()
  +    public int indexOfThrowable(int pos, Class type)
       {
  -        return delegate.getNextMessage();
  +        return delegate.indexOfThrowable(pos, type);
       }
       
       /**
  
  
  
  1.6       +783 -84   jakarta-commons-sandbox/lang/src/test/org/apache/commons/lang/exception/NestableDelegateTestCase.java
  
  Index: NestableDelegateTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/lang/src/test/org/apache/commons/lang/exception/NestableDelegateTestCase.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- NestableDelegateTestCase.java	5 Jul 2002 16:38:36 -0000	1.5
  +++ NestableDelegateTestCase.java	17 Jul 2002 05:04:47 -0000	1.6
  @@ -153,6 +153,296 @@
               nd2.getMessage("base").equals("base: " + ne2.getCause().getMessage()));
       }
   
  +    public void testNestableDelegateGetLength()
  +    {
  +        Nestable n = null;
  +        NestableDelegate d = null;
  +        
  +        n = new NestableDelegateTester1();
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetLength(d, 1);
  +        
  +        n = new NestableDelegateTester1("level 1");
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetLength(d, 1);
  +        
  +        n = new NestableDelegateTester1(new Exception());
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetLength(d, 2);
  +        
  +        n = new NestableDelegateTester1(new Exception("level 2"));
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetLength(d, 2);
  +        
  +        n = new NestableDelegateTester1("level 1", new NestableDelegateTester2("level 2", new NestableDelegateTester1(new NestableDelegateTester2("level 4", new Exception("level 5")))));
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetLength(d, 5);
  +    }
  +
  +    private void doNestableDelegateGetLength(NestableDelegate d, int len)
  +    {
  +        // Compare the lengths
  +        assertEquals("delegate length", len, d.getLength());
  +    }
  +    
  +    public void testNestableDelegateGetMessages()
  +    {
  +        Nestable n = null;
  +        NestableDelegate d = null;
  +        String msgs[] = null;
  +        
  +        msgs = new String[1];
  +        n = new NestableDelegateTester1();
  +        d = new NestableDelegate(n);        
  +        doNestableDelegateGetMessages(d, msgs);
  +        
  +        msgs = new String[1];
  +        msgs[0] = "level 1";
  +        n = new NestableDelegateTester1(msgs[0]);
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetMessages(d, msgs);
  +
  +        msgs = new String[2];
  +        n = new NestableDelegateTester1(new Exception());
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetMessages(d, msgs);
  +
  +        msgs = new String[2];
  +        msgs[0] = null;
  +        msgs[1] = "level 2";
  +        n = new NestableDelegateTester1(new Exception(msgs[1]));
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetMessages(d, msgs);
  + 
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetMessages(d, msgs);
  +    }
  +
  +    private void doNestableDelegateGetMessages(NestableDelegate d, String[] nMsgs)
  +    {
  +        // Compare the messages
  +        String[] dMsgs = d.getMessages();
  +        assertEquals("messages length", nMsgs.length, dMsgs.length);
  +        for(int i = 0; i < nMsgs.length; i++)
  +        {
  +            assertEquals("message " + i, nMsgs[i], dMsgs[i]);
  +        }
  +    }
  +
  +    public void testNestableDelegateGetMessageN()
  +    {
  +        Nestable n = null;
  +        NestableDelegate d = null;
  +        String[] msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
  +        d = new NestableDelegate(n);
  +        for(int i = 0; i < msgs.length; i++)
  +        {
  +            assertEquals("message " + i, msgs[i], d.getMessage(i));
  +        }
  +        assertEquals("message -1", msgs[0], d.getMessage(-1));
  +        assertEquals("message -1", msgs[msgs.length - 1], d.getMessage(msgs.length + 100));
  +    }
  +
  +    public void testNestableDelegateGetThrowable()
  +    {
  +        Nestable n = null;
  +        NestableDelegate d = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[2];
  +        msgs[0] = null;
  +        msgs[1] = "level 2";
  +        throwables = new Class[2];
  +        throwables[0] = NestableDelegateTester1.class;
  +        throwables[1] = Exception.class;
  +        n = new NestableDelegateTester1(new Exception(msgs[1]));
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetThrowable(d, throwables, msgs);
  + 
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableDelegateTester1.class;
  +        throwables[1] = NestableDelegateTester2.class;
  +        throwables[2] = NestableDelegateTester1.class;
  +        throwables[3] = NestableDelegateTester2.class;
  +        throwables[4] = Exception.class;        
  +        n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetThrowable(d, throwables, msgs);
  +    }
  +
  +    private void doNestableDelegateGetThrowable(NestableDelegate d, Class[] classes, String[] msgs)
  +    {
  +        Throwable t = null;
  +        String msg = null;
  +        
  +        for(int i = 0; i < classes.length; i++)
  +        {
  +            t = d.getThrowable(i);
  +            assertEquals("throwable class", classes[i], t.getClass());
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("throwable message", msgs[i], msg);
  +        }
  +        t = d.getThrowable(-1);
  +        assertEquals("throwable(-1)", classes[0], t.getClass());
  +        if(Nestable.class.isInstance(t))
  +        {
  +            msg = ((Nestable) t).getMessage(0);
  +        }
  +        else
  +        {
  +            msg = t.getMessage();
  +        }
  +        assertEquals("throwable message", msgs[0], msg);
  +        t = d.getThrowable(999);
  +        assertEquals("throwable(999)", classes[classes.length - 1], t.getClass());
  +        if(Nestable.class.isInstance(t))
  +        {
  +            msg = ((Nestable) t).getMessage(0);
  +        }
  +        else
  +        {
  +            msg = t.getMessage();
  +        }
  +        assertEquals("throwable message", msgs[msgs.length - 1], msg);
  +    }
  +
  +    public void testNestableDelegateGetThrowables()
  +    {
  +        Nestable n = null;
  +        NestableDelegate d = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[2];
  +        msgs[0] = null;
  +        msgs[1] = "level 2";
  +        throwables = new Class[2];
  +        throwables[0] = NestableDelegateTester1.class;
  +        throwables[1] = Exception.class;
  +        n = new NestableDelegateTester1(new Exception(msgs[1]));
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetThrowables(d, throwables, msgs);
  + 
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableDelegateTester1.class;
  +        throwables[1] = NestableDelegateTester2.class;
  +        throwables[2] = NestableDelegateTester1.class;
  +        throwables[3] = NestableDelegateTester2.class;
  +        throwables[4] = Exception.class;        
  +        n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
  +        d = new NestableDelegate(n);
  +        doNestableDelegateGetThrowables(d, throwables, msgs);
  +    }
  +    
  +    private void doNestableDelegateGetThrowables(NestableDelegate d, Class[] classes, String[] msgs)
  +    {
  +        Throwable[] throwables = null;
  +        String msg = null;
  +
  +        throwables = d.getThrowables();
  +        assertEquals("throwables length", classes.length, throwables.length);
  +        for(int i = 0; i < classes.length; i++)
  +        {
  +            assertEquals("throwable class", classes[i], throwables[i].getClass());
  +            Throwable t = throwables[i];
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("throwable message", msgs[i], msg);
  +        }
  +    }
  +
  +    public void testIndexOfThrowable()
  +    {
  +        Nestable n = null;
  +        NestableDelegate d = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableDelegateTester1.class;
  +        throwables[1] = NestableDelegateTester2.class;
  +        throwables[2] = NestableDelegateTester1.class;
  +        throwables[3] = NestableDelegateTester2.class;
  +        throwables[4] = Exception.class;
  +        int[] indexes = {0, 1, 0, 1, 4};
  +        n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
  +        d = new NestableDelegate(n);
  +        for(int i = 0; i < throwables.length; i++)
  +        {
  +            doNestableDelegateIndexOfThrowable(d, throwables[i], 0, indexes[i], msgs[indexes[i]]);
  +        }
  +        doNestableDelegateIndexOfThrowable(d, NestableDelegateTester2.class, 2, 3, msgs[3]);
  +        doNestableDelegateIndexOfThrowable(d, NestableDelegateTester1.class, 1, 2, msgs[2]);
  +        doNestableDelegateIndexOfThrowable(d, java.util.Date.class, 0, -1, null);
  +    }
  +
  +    private void doNestableDelegateIndexOfThrowable(NestableDelegate d, Class type, int pos, int expectedIndex, String expectedMsg)
  +    {
  +        Throwable t = null;
  +        
  +        int index = d.indexOfThrowable(pos, type);
  +        assertEquals("index of throwable " + type.getName(), expectedIndex, index);
  +        t = d.getThrowable(index);
  +        if(expectedMsg != null)
  +        {
  +            String msg = null;
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("message of indexed throwable", expectedMsg, msg);
  +        }
  +    }
  +    
       public void testNestableDelegetePrintStackTrace()
       {
           int lineSepLen = lineSeparator.length();
  @@ -192,74 +482,107 @@
       }
   }
   
  -class ThrowableNestable extends Throwable implements Nestable
  +class NestableDelegateTester1 extends Exception implements Nestable
   {
  +    private Throwable cause = null;
  +
  +    public NestableDelegateTester1()
  +    {
  +        super();
  +    }
  +
  +    public NestableDelegateTester1(String reason, Throwable cause)
  +    {
  +        super(reason);
  +        this.cause = cause;
  +    }
  +    
  +    public NestableDelegateTester1(String reason)
  +    {
  +        super(reason);
  +    }
  +    
  +    public NestableDelegateTester1(Throwable cause)
  +    {
  +        super();
  +        this.cause = cause;
  +    }
       
       /**
  -     * Returns the error message of this and any nested
  -     * <code>Throwable</code>.
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
        *
  -     * @return The error message.
  +     * @return the <code>Throwable</code>s
        */
  -    public String getMessage()
  +    public Throwable[] getThrowables()
       {
  -        return "ThrowableNestable exception";
  +        return new Throwable[0];
       }
       
       /**
  -     * Returns the reference to the exception or error that caused the
  -     * exception implementing the <code>Nestable</code> to be thrown.
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
  +     *
  +     * @return the error messages
        */
  -    public Throwable getCause()
  +    public String[] getMessages()
       {
  -        return new Exception("ThrowableNestable cause");
  +        return new String[0];
       }
  -
  +    
       /**
  -     * Returns the error message of this <code>Nestable</code>
  +     * Returns the index, numbered from 0, of the first occurrence of the
  +     * specified type in the chain of <code>Throwable</code>s, or -1 if the
  +     * specified type is not found in the chain. If <code>pos</code> is
  +     * negative, the effect is the same as if it were 0. If <code>pos</code>
  +     * is greater than or equal to the length of the chain, the effect is the
  +     * same as if it were the index of the last element in the chain.
        *
  -     * @return The error message.
  +     * @param type <code>Class</code> to be found
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
        */
  -    public String getFirstMessage()
  +    public int indexOfThrowable(Class type)
       {
  -        return "ThrowableNestable first message";
  +        return -1;
       }
       
       /**
  -     * Returns the error message of the last <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested
  -     * <code>Throwable</code> or if the last nested <code>Throwable</code> was
  -     * created without a message specified.
  +     * Returns the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s at the specified index, numbererd from 0. If
  +     * <code>index</code> is negative, the effect is the same as if it
  +     * were 0. If <code>index</code> is greater than or equal to the length
  +     * of the chain, the last <code>Throwable</code> in the chain is returned.
        *
  -     * @return The error message.
  +     * @param index the index of the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s
  +     * @return the <code>Throwable</code>
        */
  -    public String getLastMessage()
  +    public Throwable getThrowable(int index)
       {
  -        return "ThrowableNestable last message";
  +        return null;
       }
       
       /**
  -     * Returns the error message of the next <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested 
  -     * <code>Throwable</code> or if the next nested <code>Throwable</code> was
  -     * created without a message specified.
  -     *
  -     * @return The error message.
  +     * Returns the number of nested <code>Throwable</code>s represented by
  +     * this <code>Nestable</code>, including this <code>Nestable</code>.
        */
  -    public String getNextMessage()
  +    public int getLength()
       {
  -        return "ThrowableNestable next message";
  +        return 1;
       }
  -
  +    
       /**
  -     * Prints the stack trace of this exception to the specified print
  -     * writer.  Includes inforamation from the exception--if
  -     * any--which caused this exception.
  -     *
  -     * @param out <code>PrintWriter</code> to use for output.
  +     * Returns the reference to the exception or error that caused the
  +     * exception implementing the <code>Nestable</code> to be thrown.
        */
  -    public void printStackTrace(PrintWriter out)
  +    public Throwable getCause()
       {
  +        return cause;
       }
       
       /**
  @@ -276,25 +599,145 @@
       {
       }
       
  +    /**
  +     * Returns the error message of the <code>Throwable</code> in the chain
  +     * of <code>Throwable</code>s at the specified index, numbererd from 0.
  +     * If <code>index</code> is negative, the effect is the same as if it
  +     * were 0. If <code>index</code> is greater than or equal to the length
  +     * of the chain, the message of the last <code>Throwable</code> in the
  +     * chain is returned.
  +     *
  +     * @param index the index of the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s
  +     * @return the error message
  +     */
  +    public String getMessage(int index)
  +    {
  +        if(index == 0)
  +        {
  +            return super.getMessage();
  +        }
  +        else
  +        {
  +            return "";
  +        }
  +    }
  +    
  +    /**
  +     * Returns the index, numbered from 0, of the first <code>Throwable</code>
  +     * that matches the specified type in the chain of <code>Throwable</code>s
  +     * with an index greater than or equal to the specified position, or -1 if
  +     * the type is not found. If <code>pos</code> is negative, the effect is the
  +     * same as if it were 0. If <code>pos</code> is greater than or equal to the
  +     * length of the chain, the effect is the same as if it were the index of
  +     * the last element in the chain.
  +     *
  +     * @param type <code>Class</code> to be found
  +     * @param pos index, numbered from 0, of the starting position in the chain
  +     * to be searched
  +     *
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
  +     */
  +    public int indexOfThrowable(int pos, Class type)
  +    {
  +        return -1;
  +    }
  +    
   }
   
  -class ThrowableNestedNestable extends Throwable implements Nestable
  +class NestableDelegateTester2 extends Throwable implements Nestable
   {
       private Throwable cause = null;
  +
  +    public NestableDelegateTester2()
  +    {
  +        super();
  +    }
       
  -    public ThrowableNestedNestable(Throwable cause)
  +    public NestableDelegateTester2(String reason, Throwable cause)
  +    {
  +        super(reason);
  +        this.cause = cause;
  +    }
  +    
  +    public NestableDelegateTester2(String reason)
  +    {
  +        super(reason);
  +    }
  +    
  +    public NestableDelegateTester2(Throwable cause)
       {
  +        super();
           this.cause = cause;
       }
  +    
       /**
  -     * Returns the error message of this and any nested
  -     * <code>Throwable</code>.
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
        *
  -     * @return The error message.
  +     * @return the <code>Throwable</code>s
        */
  -    public String getMessage()
  +    public Throwable[] getThrowables()
       {
  -        return "ThrowableNestedNestable exception (" + cause.getMessage() + ")";
  +        return new Throwable[0];
  +    }
  +    
  +    /**
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
  +     *
  +     * @return the error messages
  +     */
  +    public String[] getMessages()
  +    {
  +        return new String[0];
  +    }
  +    
  +    /**
  +     * Returns the index, numbered from 0, of the first occurrence of the
  +     * specified type in the chain of <code>Throwable</code>s, or -1 if the
  +     * specified type is not found in the chain. If <code>pos</code> is
  +     * negative, the effect is the same as if it were 0. If <code>pos</code>
  +     * is greater than or equal to the length of the chain, the effect is the
  +     * same as if it were the index of the last element in the chain.
  +     *
  +     * @param type <code>Class</code> to be found
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
  +     */
  +    public int indexOfThrowable(Class type)
  +    {
  +        return -1;
  +    }
  +    
  +    /**
  +     * Returns the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s at the specified index, numbererd from 0. If
  +     * <code>index</code> is negative, the effect is the same as if it
  +     * were 0. If <code>index</code> is greater than or equal to the length
  +     * of the chain, the last <code>Throwable</code> in the chain is returned.
  +     *
  +     * @param index the index of the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s
  +     * @return the <code>Throwable</code>
  +     */
  +    public Throwable getThrowable(int index)
  +    {
  +        return null;
  +    }
  +    
  +    /**
  +     * Returns the number of nested <code>Throwable</code>s represented by
  +     * this <code>Nestable</code>, including this <code>Nestable</code>.
  +     */
  +    public int getLength()
  +    {
  +        return 1;
       }
       
       /**
  @@ -307,39 +750,127 @@
       }
       
       /**
  -     * Returns the error message of this <code>Nestable</code>
  +     * Prints the stack trace for this exception only--root cause not
  +     * included--using the provided writer.  Used by {@link
  +     * org.apache.commons.lang.exception.NestableDelegate} to write
  +     * individual stack traces to a buffer.  The implementation of
  +     * this method should call
  +     * <code>super.printStackTrace(out);</code> in most cases.
        *
  -     * @return The error message.
  +     * @param out The writer to use.
        */
  -    public String getFirstMessage()
  +    public void printPartialStackTrace(PrintWriter out)
       {
  -        return "ThrowableNestedNestable first message";
       }
       
       /**
  -     * Returns the error message of the last <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested
  -     * <code>Throwable</code> or if the last nested <code>Throwable</code> was
  -     * created without a message specified.
  +     * Returns the error message of the <code>Throwable</code> in the chain
  +     * of <code>Throwable</code>s at the specified index, numbererd from 0.
  +     * If <code>index</code> is negative, the effect is the same as if it
  +     * were 0. If <code>index</code> is greater than or equal to the length
  +     * of the chain, the message of the last <code>Throwable</code> in the
  +     * chain is returned.
  +     *
  +     * @param index the index of the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s
  +     * @return the error message
  +     */
  +    public String getMessage(int index)
  +    {
  +        if(index == 0)
  +        {
  +            return super.getMessage();
  +        }
  +        else
  +        {
  +            return "";
  +        }
  +    }
  +    
  +    /**
  +     * Returns the index, numbered from 0, of the first <code>Throwable</code>
  +     * that matches the specified type in the chain of <code>Throwable</code>s
  +     * with an index greater than or equal to the specified position, or -1 if
  +     * the type is not found. If <code>pos</code> is negative, the effect is the
  +     * same as if it were 0. If <code>pos</code> is greater than or equal to the
  +     * length of the chain, the effect is the same as if it were the index of
  +     * the last element in the chain.
  +     *
  +     * @param type <code>Class</code> to be found
  +     * @param pos index, numbered from 0, of the starting position in the chain
  +     * to be searched
        *
  -     * @return The error message.
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
  +     */
  +    public int indexOfThrowable(int pos, Class type)
  +    {
  +        return -1;
  +    }
  +    
  +}
  +
  +class ThrowableNestable extends Throwable implements Nestable
  +{
  +    private Throwable cause = new Exception("ThrowableNestable cause");
  +
  +    /**
  +     * Returns the number of nested <code>Throwable</code>s represented by
  +     * this <code>Nestable</code>, including this <code>Nestable</code>.
        */
  -    public String getLastMessage()
  +    public int getLength()
       {
  -        return "ThrowableNestedNestable last message";
  +        return 1;
       }
       
       /**
  -     * Returns the error message of the next <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested 
  -     * <code>Throwable</code> or if the next nested <code>Throwable</code> was
  -     * created without a message specified.
  +     * Returns the error message of this and any nested
  +     * <code>Throwable</code>.
        *
        * @return The error message.
        */
  -    public String getNextMessage()
  +    public String getMessage()
       {
  -        return "ThrowableNestedNestable next message";
  +        return "ThrowableNestable exception";
  +    }
  +
  +    /**
  +     * Returns the error message of the <code>Throwable</code> in the chain
  +     * of <code>Throwable</code>s at the specified index, numbererd from 0.
  +     * If <code>index</code> is negative, the effect is the same as if it
  +     * were 0. If <code>index</code> is greater than or equal to the length
  +     * of the chain, the message of the last <code>Throwable</code> in the
  +     * chain is returned.
  +     *
  +     * @param index the index of the <code>Throwable</code> in the chain of
  +     * <code>Throwable</code>s
  +     * @return the error message
  +     */
  +    public String getMessage(int index)
  +    {
  +        return getMessage();
  +    }
  +
  +    /**
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
  +     */
  +    public String[] getMessages()
  +    {
  +        String msgs[] = new String[1];
  +        msgs[0] = getMessage();
  +        return msgs;
  +    }
  +    
  +    /**
  +     * Returns the reference to the exception or error that caused the
  +     * exception implementing the <code>Nestable</code> to be thrown.
  +     */
  +    public Throwable getCause()
  +    {
  +        return cause;
       }
   
       /**
  @@ -351,7 +882,6 @@
        */
       public void printStackTrace(PrintWriter out)
       {
  -        out.println("ThrowableNestedNestable stack trace place-holder");
       }
       
       /**
  @@ -366,13 +896,60 @@
        */
       public void printPartialStackTrace(PrintWriter out)
       {
  -        out.println("ThrowableNestedNestable partial stack trace place-holder");
  +    }
  +    
  +    public Throwable getThrowable(int index)
  +    {
  +        return cause;
  +    }
  +    
  +    public Throwable[] getThrowables()
  +    {
  +        Throwable throwables[] = new Throwable[1];
  +        throwables[0] = cause;
  +        return throwables;
  +    }
  +    
  +    public int indexOfThrowable(Class type)
  +    {
  +        if(Exception.class.isInstance(type))
  +        {
  +            return 0;
  +        }
  +        return -1;
  +    }
  +    
  +    /**
  +     * Returns the index of the first <code>Throwable</code> that matches the
  +     * specified type with an index greater than or equal to the specified
  +     * position, or -1 if the type is not found.
  +     *
  +     * @param type <code>Class</code> to be found
  +     * @param pos
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
  +     */
  +    public int indexOfThrowable(int pos, Class type)
  +    {
  +        return indexOfThrowable(type);
       }
       
   }
   
  -class NonThrowableNestable implements Nestable
  +class ThrowableNestedNestable extends Throwable implements Nestable
   {
  +    private Throwable cause = null;
  +    
  +    public ThrowableNestedNestable(Throwable cause)
  +    {
  +        this.cause = cause;
  +    }
  +    
  +    public int getLength()
  +    {
  +        return 1;
  +    }
  +    
       /**
        * Returns the error message of this and any nested
        * <code>Throwable</code>.
  @@ -381,7 +958,25 @@
        */
       public String getMessage()
       {
  -        return "non-throwable";
  +        return "ThrowableNestedNestable exception (" + cause.getMessage() + ")";
  +    }
  +
  +    public String getMessage(int index)
  +    {
  +        return "ThrowableNestedNestable exception (" + cause.getMessage() + ")";
  +    }
  +    
  +    /**
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
  +     */
  +    public String[] getMessages()
  +    {
  +        String[] msgs = new String[1];
  +        msgs[0] = "ThrowableNestedNestable exception (" + cause.getMessage() + ")";
  +        return msgs;
       }
       
       /**
  @@ -390,45 +985,119 @@
        */
       public Throwable getCause()
       {
  -        return null;
  +        return cause;
  +    }
  +    
  +    /**
  +     * Prints the stack trace of this exception to the specified print
  +     * writer.  Includes inforamation from the exception--if
  +     * any--which caused this exception.
  +     *
  +     * @param out <code>PrintWriter</code> to use for output.
  +     */
  +    public void printStackTrace(PrintWriter out)
  +    {
  +        out.println("ThrowableNestedNestable stack trace place-holder");
       }
       
       /**
  -     * Returns the error message of this <code>Nestable</code>
  +     * Prints the stack trace for this exception only--root cause not
  +     * included--using the provided writer.  Used by {@link
  +     * org.apache.commons.lang.exception.NestableDelegate} to write
  +     * individual stack traces to a buffer.  The implementation of
  +     * this method should call
  +     * <code>super.printStackTrace(out);</code> in most cases.
        *
  -     * @return The error message.
  +     * @param out The writer to use.
        */
  -    public String getFirstMessage()
  +    public void printPartialStackTrace(PrintWriter out)
       {
  -        return "non-throwable first message";
  +        out.println("ThrowableNestedNestable partial stack trace place-holder");
  +    }
  +    
  +    public Throwable getThrowable(int index)
  +    {
  +        return cause;
  +    }
  +    
  +    public Throwable[] getThrowables()
  +    {
  +        Throwable throwables[] = new Throwable[1];
  +        throwables[0] = cause;
  +        return throwables;
  +    }
  +    
  +    public int indexOfThrowable(Class type)
  +    {
  +        if(Exception.class.isInstance(type))
  +        {
  +            return 0;
  +        }
  +        return -1;
       }
       
       /**
  -     * Returns the error message of the last <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested
  -     * <code>Throwable</code> or if the last nested <code>Throwable</code> was
  -     * created without a message specified.
  +     * Returns the index of the first <code>Throwable</code> that matches the
  +     * specified type with an index greater than or equal to the specified
  +     * position, or -1 if the type is not found.
        *
  -     * @return The error message.
  +     * @param type <code>Class</code> to be found
  +     * @param pos
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
        */
  -    public String getLastMessage()
  +    public int indexOfThrowable(int pos, Class type)
  +    {
  +        return indexOfThrowable(type);
  +    }
  +    
  +}
  +
  +class NonThrowableNestable implements Nestable
  +{
  +    public int getLength()
       {
  -        return "non-throwable last message";
  +        return 1;
       }
       
       /**
  -     * Returns the error message of the next <code>Throwable</code> in the
  -     * nestable chain. Returns <code>null</code> if there is no nested 
  -     * <code>Throwable</code> or if the next nested <code>Throwable</code> was
  -     * created without a message specified.
  +     * Returns the error message of this and any nested
  +     * <code>Throwable</code>.
        *
        * @return The error message.
        */
  -    public String getNextMessage()
  +    public String getMessage()
       {
  -        return "non-throwable next message";
  +        return "non-throwable";
       }
   
  +    public String getMessage(int index)
  +    {
  +        return "non-throwable";
  +    }
  +    
  +    /**
  +     * Returns the error message of this and any nested <code>Throwable</code>s
  +     * in an array of Strings, one element for each message. Any
  +     * <code>Throwable</code> specified without a message is represented in
  +     * the array by a null.
  +     */
  +    public String[] getMessages()
  +    {
  +        String[] msgs = new String[1];
  +        msgs[0] = "non-throwable";
  +        return msgs;
  +    }
  +    
  +    /**
  +     * Returns the reference to the exception or error that caused the
  +     * exception implementing the <code>Nestable</code> to be thrown.
  +     */
  +    public Throwable getCause()
  +    {
  +        return null;
  +    }
  +    
       /**
        * Prints the stack trace of this exception to the specified print
        * writer.  Includes inforamation from the exception--if
  @@ -452,6 +1121,36 @@
        */
       public void printPartialStackTrace(PrintWriter out)
       {
  +    }
  +    
  +    public Throwable getThrowable(int index)
  +    {
  +        return null;
  +    }
  +    
  +    public Throwable[] getThrowables()
  +    {
  +        return new Throwable[0];
  +    }
  +    
  +    public int indexOfThrowable(Class type)
  +    {
  +        return -1;
  +    }
  +    
  +    /**
  +     * Returns the index of the first <code>Throwable</code> that matches the
  +     * specified type with an index greater than or equal to the specified
  +     * position, or -1 if the type is not found.
  +     *
  +     * @param type <code>Class</code> to be found
  +     * @param pos
  +     * @return index of the first occurrence of the type in the chain, or -1 if
  +     * the type is not found
  +     */
  +    public int indexOfThrowable(int pos, Class type)
  +    {
  +        return -1;
       }
       
   }
  
  
  
  1.4       +380 -93   jakarta-commons-sandbox/lang/src/test/org/apache/commons/lang/exception/NestableExceptionTestCase.java
  
  Index: NestableExceptionTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/lang/src/test/org/apache/commons/lang/exception/NestableExceptionTestCase.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- NestableExceptionTestCase.java	5 Jul 2002 16:38:36 -0000	1.3
  +++ NestableExceptionTestCase.java	17 Jul 2002 05:04:47 -0000	1.4
  @@ -68,10 +68,6 @@
    */
   public class NestableExceptionTestCase extends junit.framework.TestCase
   {
  -    private Nestable[] nestables = new Nestable[9];
  -    private String[] firstMessage = new String[nestables.length];
  -    private String[] nextMessage = new String[nestables.length];
  -    private String[] lastMessage = new String[nestables.length];
       
       /**
        * Construct a new instance of NestableExceptionTestCase with the specified name
  @@ -86,50 +82,6 @@
        */
       public void setUp()
       {
  -        nestables[0] = new NestableException("one level");
  -        firstMessage[0] = "one level";
  -        nextMessage[0] = "null";
  -        lastMessage[0] = "null";
  -
  -        nestables[1] = new NestableException(new Exception("two levels"));
  -        firstMessage[1] = "null";
  -        nextMessage[1] = "two levels";
  -        lastMessage[1] = "two levels";
  -
  -        nestables[2] = new NestableException(new NestableException(new Exception("three levels")));
  -        firstMessage[2] = "null";
  -        nextMessage[2] = "null";
  -        lastMessage[2] = "three levels";
  -
  -        nestables[3] = new NestableException("top level", new NestableException(new Exception("three levels")));
  -        firstMessage[3] = "top level";
  -        nextMessage[3] = "null";
  -        lastMessage[3] = "three levels";
  -
  -        nestables[4] = new NestableException("top level", new NestableException("next level", new Exception("three levels")));
  -        firstMessage[4] = "top level";
  -        nextMessage[4] = "next level";
  -        lastMessage[4] = "three levels";
  -
  -        nestables[5] = new NestableException("top level", new NestableException("next level", new Exception()));
  -        firstMessage[5] = "top level";
  -        nextMessage[5] = "next level";
  -        lastMessage[5] = "null";
  -
  -        nestables[6] = new NestableException("top level", new NestableException());
  -        firstMessage[6] = "top level";
  -        nextMessage[6] = "null";
  -        lastMessage[6] = "null";
  -
  -        nestables[7] = new NestableException(new NestableException("next level", new Exception()));
  -        firstMessage[7] = "null";
  -        nextMessage[7] = "next level";
  -        lastMessage[7] = "null";
  -
  -        nestables[8] = new NestableException(new NestableException(new Exception()));
  -        firstMessage[8] = "null";
  -        nextMessage[8] = "null";
  -        lastMessage[8] = "null";
       }
       
       public static Test suite()
  @@ -147,70 +99,88 @@
       /**
        * Test the implementation
        */
  -    public void testGetFirstMessage()
  +    public void testGetCause()
       {
  -        for(int i = 0; i < nestables.length; i++)
  -        {
  -            assertEquals("nestables " + i + " first message", firstMessage[i], ((nestables[i].getFirstMessage() == null) ? "null" : nestables[i].getFirstMessage()));
  -        }
  -    }
  -    
  -    public void testGetNextMessage()
  -    {
  -        for(int i = 0; i < nestables.length; i++)
  -        {
  -            assertEquals("nestables " + i + " next message", nextMessage[i], ((nestables[i].getNextMessage() == null) ? "null" : nestables[i].getNextMessage()));
  -        }
  +        NestableException ne1 = new NestableException();
  +        assertNull("nestable exception() cause is null", ne1.getCause()); 
  +        
  +        NestableException ne2 = new NestableException("ne2");
  +        assertNull("nestable exception(\"ne2\") cause is null", ne2.getCause());
  +        
  +        NestableException ne3 = new NestableException(new Exception("ne3 exception"));
  +        assertNotNull("nestable exception(new Exception(\"ne3 exception\") cause is not null",
  +            ne3.getCause()); 
  +        assertTrue("nestable exception(new Exception(\"ne3 exception\") cause message == ne3 exception",
  +            ne3.getCause().getMessage().equals("ne3 exception")); 
  +        
  +        NestableException ne4 = new NestableException("ne4", new Exception("ne4 exception"));
  +        assertNotNull("nestable exception(\"ne4\", new Exception(\"ne4 exception\") cause is not null", 
  +            ne4.getCause()); 
  +        
  +        NestableException ne5 = new NestableException("ne5", null);
  +        assertNull("nestable exception(\"ne5\", null) cause is null", 
  +            ne5.getCause()); 
  +        
  +        NestableException ne6 = new NestableException(null, new Exception("ne6 exception"));
  +        assertNotNull("nestable exception(null, new Exception(\"ne6 exception\") cause is not null", 
  +            ne6.getCause()); 
       }
  -    
  -    public void testGetLastMessage()
  +
  +    public void testGetLength()
       {
  -        for(int i = 0; i < nestables.length; i++)
  -        {
  -            assertEquals("nestables " + i + " last message", lastMessage[i], ((nestables[i].getLastMessage() == null) ? "null" : nestables[i].getLastMessage()));
  -        }
  +        NestableException ne1 = new NestableException();
  +        assertEquals("ne1 length", 1, ne1.getLength());
  +
  +        NestableException ne2 = new NestableException("ne2");
  +        assertEquals("ne2 length", 1, ne2.getLength());
  +        
  +        NestableException ne3 = new NestableException(new Exception("ne3 exception"));
  +        assertEquals("ne3 length", 2, ne3.getLength());
  +        
  +        NestableException ne4 = new NestableException("ne4", new Exception("ne4 exception"));
  +        assertEquals("ne4 length", 2, ne4.getLength());
  +        
  +        NestableException ne5 = new NestableException("ne5", null);
  +        assertEquals("ne 5 length", 1, ne5.getLength());
  +        
  +        NestableException ne6 = new NestableException(null, new Exception("ne6 exception"));
  +        assertEquals("ne 6 length", 2, ne6.getLength());
  +        
  +        NestableException ne7 = new NestableException("ne7o", new NestableException("ne7i", new Exception("ne7 exception")));
  +        assertEquals("ne 7 length", 3, ne7.getLength());
  +
  +        NestableException ne8 = new NestableException("level 1", new NestableException("level 2", new NestableException(new NestableException("level 4", new Exception("level 5")))));
  +        assertEquals("ne 8 length", 5, ne8.getLength());
       }
       
  -    public void testNestableException()
  +    public void testGetMessage()
       {
           NestableException ne1 = new NestableException();
  -        assertNull("nestable exception() cause is null", ne1.getCause()); 
           assertNull("nestable exception() message is null", ne1.getMessage()); 
   
           NestableException ne2 = new NestableException("ne2");
  -        assertNull("nestable exception(\"ne2\") cause is null", ne2.getCause());
           assertNotNull("nestable exception(\"ne2\") message is not null", ne2.getMessage());
           assertTrue("nestable exception(\"ne2\") message == ne2", ne2.getMessage().equals("ne2"));
  -
  +        
           NestableException ne3 = new NestableException(new Exception("ne3 exception"));
  -        assertNotNull("nestable exception(new Exception(\"ne3 exception\") cause is not null",
  -            ne3.getCause()); 
  -        assertTrue("nestable exception(new Exception(\"ne3 exception\") cause message == ne3 exception",
  -            ne3.getCause().getMessage().equals("ne3 exception")); 
           assertNotNull("nestable exception(new Exception(\"ne3 exception\") message is not null",
               ne3.getMessage()); 
           assertTrue("nestable exception(new Exception(\"ne3 exception\") message == cause message",
               ne3.getMessage().equals(ne3.getCause().getMessage())); 
           
           NestableException ne4 = new NestableException("ne4", new Exception("ne4 exception"));
  -        assertNotNull("nestable exception(\"ne4\", new Exception(\"ne4 exception\") cause is not null", 
  -            ne4.getCause()); 
           assertNotNull("nestable exception(\"ne4\", new Exception(\"ne4 exception\") message is not null", 
               ne4.getMessage()); 
           assertTrue("nestable exception(\"ne4\", new Exception(\"ne4 exception\") message == ne4: ne4 exception", 
               ne4.getMessage().equals("ne4: ne4 exception")); 
  -
  +        
           NestableException ne5 = new NestableException("ne5", null);
  -        assertNull("nestable exception(\"ne5\", null) cause is null", 
  -            ne5.getCause()); 
           assertNotNull("nestable exception(\"ne5\", new Exception(\"ne5 exception\") message is not null", 
               ne5.getMessage()); 
           assertTrue("nestable exception(\"ne5\", null) message == ne5", 
               ne5.getMessage().equals("ne5")); 
           
           NestableException ne6 = new NestableException(null, new Exception("ne6 exception"));
  -        assertNotNull("nestable exception(null, new Exception(\"ne6 exception\") cause is not null", 
  -            ne6.getCause()); 
           assertTrue("nestable exception(null, new Exception(\"ne6 exception\") cause == ne6 exception", 
               ne6.getMessage().equals("ne6 exception")); 
           
  @@ -218,17 +188,271 @@
           assertTrue("nextable exception(\"ne7o\", new NestableException(\"ne7i\", new Exception(\"ne7 exception\"))) message is ne7o: ne7i: ne7 exception",
               ne7.getMessage().equals("ne7o: ne7i: ne7 exception"));
   
  -        NestableException ne8 = new NestableException("ne8", new Exception("ne8 exception"));
  -        ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
  -        PrintStream ps1 = new PrintStream(baos1);
  -        PrintWriter pw1 = new PrintWriter(ps1, true);
  -        ne8.printStackTrace(ps1);
  -        String stack1 = baos1.toString();
  -        assertTrue("stack trace startsWith == java.lang.Exception: ne8 exception",
  -            stack1.startsWith("java.lang.Exception: ne8 exception")); 
  -        assertTrue("stack trace indexOf org.apache.commons.lang.exception.NestableException: ne8: ne8 exception > -1",
  -            stack1.indexOf("org.apache.commons.lang.exception.NestableException: ne8: ne8 exception") > -1); 
  +    }
  +
  +    public void testGetMessageN()
  +    {
  +        String[] msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        NestableException ne = new NestableException(msgs[0], new NestableException(msgs[1], new NestableException(new NestableException(msgs[3], new Exception(msgs[4])))));
  +        for(int i = 0; i < msgs.length; i++)
  +        {
  +            assertEquals("message " + i, msgs[i], ne.getMessage(i));
  +        }
  +        assertEquals("message -1", msgs[0], ne.getMessage(-1));
  +        assertEquals("message 999", msgs[4], ne.getMessage(999));
  +    }
  +    
  +    public void testGetMessages()
  +    {
  +        String[] msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        NestableException ne = new NestableException(msgs[0], new NestableException(msgs[1], new NestableException(new NestableException(msgs[3], new Exception(msgs[4])))));
  +        String[] nMsgs = ne.getMessages();
  +        assertEquals("messages length", msgs.length, nMsgs.length);
  +        for(int i = 0; i < nMsgs.length; i++)
  +        {
  +            assertEquals("message " + i, msgs[i], nMsgs[i]);
  +        }
  +    }
  +
  +    public void testGetThrowable()
  +    {
  +        Nestable n = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[2];
  +        msgs[0] = null;
  +        msgs[1] = "level 2";
  +        throwables = new Class[2];
  +        throwables[0] = NestableExceptionTester1.class;
  +        throwables[1] = Exception.class;
  +        n = new NestableExceptionTester1(new Exception(msgs[1]));
  +        doNestableExceptionGetThrowable(n, throwables, msgs);
  + 
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableExceptionTester1.class;
  +        throwables[1] = NestableExceptionTester2.class;
  +        throwables[2] = NestableExceptionTester1.class;
  +        throwables[3] = NestableExceptionTester2.class;
  +        throwables[4] = Exception.class;        
  +        n = new NestableExceptionTester1(msgs[0], new NestableExceptionTester2(msgs[1], new NestableExceptionTester1(new NestableExceptionTester2(msgs[3], new Exception(msgs[4])))));
  +        doNestableExceptionGetThrowable(n, throwables, msgs);
  +    }
  +    
  +    private void doNestableExceptionGetThrowable(Nestable n, Class[] classes, String[] msgs)
  +    {
  +        Throwable t = null;
  +        String msg = null;
   
  +        for(int i = 0; i < classes.length; i++)
  +        {
  +            t = n.getThrowable(i);
  +            assertEquals("throwable class", classes[i], t.getClass());
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("throwable message", msgs[i], msg);
  +        }
  +        t = n.getThrowable(-1);
  +        assertEquals("throwable(-1)", classes[0], t.getClass());
  +        if(Nestable.class.isInstance(t))
  +        {
  +            msg = ((Nestable) t).getMessage(0);
  +        }
  +        else
  +        {
  +            msg = t.getMessage();
  +        }
  +        assertEquals("throwable message", msgs[0], msg);
  +        t = n.getThrowable(999);
  +        assertEquals("throwable(999)", classes[classes.length - 1], t.getClass());
  +        if(Nestable.class.isInstance(t))
  +        {
  +            msg = ((Nestable) t).getMessage(0);
  +        }
  +        else
  +        {
  +            msg = t.getMessage();
  +        }
  +        assertEquals("throwable message", msgs[msgs.length - 1], msg);
  +    }
  +    
  +    public void testGetThrowables()
  +    {
  +        Nestable n = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[2];
  +        msgs[0] = null;
  +        msgs[1] = "level 2";
  +        throwables = new Class[2];
  +        throwables[0] = NestableExceptionTester1.class;
  +        throwables[1] = Exception.class;
  +        n = new NestableExceptionTester1(new Exception(msgs[1]));
  +        doNestableExceptionGetThrowables(n, throwables, msgs);
  + 
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableExceptionTester1.class;
  +        throwables[1] = NestableExceptionTester2.class;
  +        throwables[2] = NestableExceptionTester1.class;
  +        throwables[3] = NestableExceptionTester2.class;
  +        throwables[4] = Exception.class;        
  +        n = new NestableExceptionTester1(msgs[0], new NestableExceptionTester2(msgs[1], new NestableExceptionTester1(new NestableExceptionTester2(msgs[3], new Exception(msgs[4])))));
  +        doNestableExceptionGetThrowables(n, throwables, msgs);
  +    }
  +    
  +    private void doNestableExceptionGetThrowables(Nestable n, Class[] classes, String[] msgs)
  +    {
  +        String msg = null;
  +
  +        Throwable throwables[] = n.getThrowables();
  +        assertEquals("throwables length", classes.length, throwables.length);
  +        for(int i = 0; i < classes.length; i++)
  +        {
  +            assertEquals("throwable class", classes[i], throwables[i].getClass());
  +            Throwable t = throwables[i];
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("throwable message", msgs[i], msg);
  +        }
  +    }
  +    
  +    public void testIndexOfThrowable()
  +    {
  +        Nestable n = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableExceptionTester1.class;
  +        throwables[1] = NestableExceptionTester2.class;
  +        throwables[2] = NestableExceptionTester1.class;
  +        throwables[3] = NestableExceptionTester2.class;
  +        throwables[4] = Exception.class;
  +        int[] indexes = {0, 1, 0, 1, 4};
  +        n = new NestableExceptionTester1(msgs[0], new NestableExceptionTester2(msgs[1], new NestableExceptionTester1(new NestableExceptionTester2(msgs[3], new Exception(msgs[4])))));
  +        for(int i = 0; i < throwables.length; i++)
  +        {
  +            doNestableExceptionIndexOfThrowable(n, throwables[i], indexes[i], msgs[indexes[i]]);
  +        }
  +        doNestableExceptionIndexOfThrowable(n, java.util.Date.class, -1, null);
  +    }
  +    
  +    private void doNestableExceptionIndexOfThrowable(Nestable n, Class type, int expectedIndex, String expectedMsg)
  +    {
  +        Throwable t = null;
  +        
  +        int index = n.indexOfThrowable(type);
  +        assertEquals("index of throwable " + type.getName(), expectedIndex, index);
  +        t = n.getThrowable(index);
  +        if(expectedMsg != null)
  +        {
  +            String msg = null;
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("message of indexed throwable", expectedMsg, msg);
  +        }
  +    }
  +    
  +    public void testIndexOfThrowableN()
  +    {
  +        Nestable n = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableExceptionTester1.class;
  +        throwables[1] = NestableExceptionTester2.class;
  +        throwables[2] = NestableExceptionTester1.class;
  +        throwables[3] = NestableExceptionTester2.class;
  +        throwables[4] = Exception.class;
  +        int[] indexes = {0, 1, 0, 1, 4};
  +        n = new NestableExceptionTester1(msgs[0], new NestableExceptionTester2(msgs[1], new NestableExceptionTester1(new NestableExceptionTester2(msgs[3], new Exception(msgs[4])))));
  +        for(int i = 0; i < throwables.length; i++)
  +        {
  +            doNestableExceptionIndexOfThrowableN(n, throwables[i], 0, indexes[i], msgs[indexes[i]]);
  +        }
  +        doNestableExceptionIndexOfThrowableN(n, NestableExceptionTester2.class, 2, 3, msgs[3]);
  +        doNestableExceptionIndexOfThrowableN(n, NestableExceptionTester1.class, 1, 2, msgs[2]);
  +        doNestableExceptionIndexOfThrowableN(n, java.util.Date.class, 0, -1, null);
  +    }
  +
  +    private void doNestableExceptionIndexOfThrowableN(Nestable n, Class type, int pos, int expectedIndex, String expectedMsg)
  +    {
  +        Throwable t = null;
  +        
  +        int index = n.indexOfThrowable(pos, type);
  +        assertEquals("index of throwable " + type.getName(), expectedIndex, index);
  +        t = n.getThrowable(index);
  +        if(expectedMsg != null)
  +        {
  +            String msg = null;
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("message of indexed throwable", expectedMsg, msg);
  +        }
  +    }
  +    
  +    public void testPrintPartialStackTrace()
  +    {
           NestableException ne9 = new NestableException("ne9", new Exception("ne9 exception"));
           ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
           PrintStream ps2 = new PrintStream(baos2);
  @@ -240,9 +464,72 @@
           assertEquals("stack trace indexOf rethrown == -1",
               stack2.indexOf("rethrown"), -1);
       }
  +    
  +    public void testPrintStackTrace()
  +    {
  +        NestableException ne8 = new NestableException("ne8", new Exception("ne8 exception"));
  +        ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
  +        PrintStream ps1 = new PrintStream(baos1);
  +        PrintWriter pw1 = new PrintWriter(ps1, true);
  +        ne8.printStackTrace(ps1);
  +        String stack1 = baos1.toString();
  +        assertTrue("stack trace startsWith == java.lang.Exception: ne8 exception",
  +            stack1.startsWith("java.lang.Exception: ne8 exception")); 
  +        assertTrue("stack trace indexOf org.apache.commons.lang.exception.NestableException: ne8: ne8 exception > -1",
  +            stack1.indexOf("org.apache.commons.lang.exception.NestableException: ne8: ne8 exception") > -1); 
  +    }
   
       public static void main(String args[])
       {
           TestRunner.run(suite());
       }
   }
  +
  +class NestableExceptionTester1 extends NestableException
  +{
  +    public NestableExceptionTester1()
  +    {
  +        super();
  +    }
  +
  +    public NestableExceptionTester1(String reason, Throwable cause)
  +    {
  +        super(reason, cause);
  +    }
  +    
  +    public NestableExceptionTester1(String reason)
  +    {
  +        super(reason);
  +    }
  +    
  +    public NestableExceptionTester1(Throwable cause)
  +    {
  +        super(cause);
  +    }
  +    
  +}
  +
  +class NestableExceptionTester2 extends NestableException
  +{
  +    public NestableExceptionTester2()
  +    {
  +        super();
  +    }
  +    
  +    public NestableExceptionTester2(String reason, Throwable cause)
  +    {
  +        super(reason, cause);
  +    }
  +    
  +    public NestableExceptionTester2(String reason)
  +    {
  +        super(reason);
  +    }
  +    
  +    public NestableExceptionTester2(Throwable cause)
  +    {
  +        super(cause);
  +    }
  +    
  +}
  +
  
  
  
  1.4       +369 -85   jakarta-commons-sandbox/lang/src/test/org/apache/commons/lang/exception/NestableRuntimeExceptionTestCase.java
  
  Index: NestableRuntimeExceptionTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/lang/src/test/org/apache/commons/lang/exception/NestableRuntimeExceptionTestCase.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- NestableRuntimeExceptionTestCase.java	5 Jul 2002 16:38:36 -0000	1.3
  +++ NestableRuntimeExceptionTestCase.java	17 Jul 2002 05:04:47 -0000	1.4
  @@ -68,11 +68,6 @@
    */
   public class NestableRuntimeExceptionTestCase extends junit.framework.TestCase
   {
  -    private Nestable[] nestables = new Nestable[9];
  -    private String[] firstMessage = new String[nestables.length];
  -    private String[] nextMessage = new String[nestables.length];
  -    private String[] lastMessage = new String[nestables.length];
  -    
       /**
        * Construct a new instance of NestableRuntimeExceptionTestCase with the specified name
        */
  @@ -86,50 +81,6 @@
        */
       public void setUp()
       {
  -        nestables[0] = new NestableRuntimeException("one level");
  -        firstMessage[0] = "one level";
  -        nextMessage[0] = "null";
  -        lastMessage[0] = "null";
  -
  -        nestables[1] = new NestableRuntimeException(new Exception("two levels"));
  -        firstMessage[1] = "null";
  -        nextMessage[1] = "two levels";
  -        lastMessage[1] = "two levels";
  -
  -        nestables[2] = new NestableRuntimeException(new NestableRuntimeException(new Exception("three levels")));
  -        firstMessage[2] = "null";
  -        nextMessage[2] = "null";
  -        lastMessage[2] = "three levels";
  -
  -        nestables[3] = new NestableRuntimeException("top level", new NestableRuntimeException(new Exception("three levels")));
  -        firstMessage[3] = "top level";
  -        nextMessage[3] = "null";
  -        lastMessage[3] = "three levels";
  -
  -        nestables[4] = new NestableRuntimeException("top level", new NestableRuntimeException("next level", new Exception("three levels")));
  -        firstMessage[4] = "top level";
  -        nextMessage[4] = "next level";
  -        lastMessage[4] = "three levels";
  -
  -        nestables[5] = new NestableRuntimeException("top level", new NestableRuntimeException("next level", new Exception()));
  -        firstMessage[5] = "top level";
  -        nextMessage[5] = "next level";
  -        lastMessage[5] = "null";
  -
  -        nestables[6] = new NestableRuntimeException("top level", new NestableRuntimeException());
  -        firstMessage[6] = "top level";
  -        nextMessage[6] = "null";
  -        lastMessage[6] = "null";
  -
  -        nestables[7] = new NestableRuntimeException(new NestableRuntimeException("next level", new Exception()));
  -        firstMessage[7] = "null";
  -        nextMessage[7] = "next level";
  -        lastMessage[7] = "null";
  -
  -        nestables[8] = new NestableRuntimeException(new NestableRuntimeException(new Exception()));
  -        firstMessage[8] = "null";
  -        nextMessage[8] = "null";
  -        lastMessage[8] = "null";
       }
       
       public static Test suite()
  @@ -147,77 +98,359 @@
       /**
        * Test the implementation
        */
  -    public void testGetFirstMessage()
  -    {
  -        for(int i = 0; i < nestables.length; i++)
  -        {
  -            assertEquals("nestables " + i + " first message", firstMessage[i], ((nestables[i].getFirstMessage() == null) ? "null" : nestables[i].getFirstMessage()));
  -        }
  -    }
  -    
  -    public void testGetNextMessage()
  +    public void testGetCause()
       {
  -        for(int i = 0; i < nestables.length; i++)
  -        {
  -            assertEquals("nestables " + i + " next message", nextMessage[i], ((nestables[i].getNextMessage() == null) ? "null" : nestables[i].getNextMessage()));
  -        }
  +        NestableRuntimeException ne1 = new NestableRuntimeException();
  +        assertNull("nestable runtime exception() cause is null", ne1.getCause()); 
  +        
  +        NestableRuntimeException ne2 = new NestableRuntimeException("ne2");
  +        assertNull("nestable runtime exception(\"ne2\") cause is null", ne2.getCause());
  +
  +        NestableRuntimeException ne3 = new NestableRuntimeException(new Exception("ne3 exception"));
  +        assertNotNull("nestable runtime exception(new Exception(\"ne3 exception\") cause is not null",
  +            ne3.getCause()); 
  +        assertTrue("nestable runtime exception(new Exception(\"ne3 exception\") cause message == ne3 exception",
  +            ne3.getCause().getMessage().equals("ne3 exception")); 
  +
  +        NestableRuntimeException ne4 = new NestableRuntimeException("ne4", new Exception("ne4 exception"));
  +        assertNotNull("nestable runtime exception(\"ne4\", new Exception(\"ne4 exception\") cause is not null", 
  +            ne4.getCause()); 
  +
  +        NestableRuntimeException ne5 = new NestableRuntimeException("ne5", null);
  +        assertNull("nestable runtime exception(\"ne5\", null) cause is null", 
  +            ne5.getCause());
  +
  +        NestableRuntimeException ne6 = new NestableRuntimeException(null, new Exception("ne6 exception"));
  +        assertNotNull("nestable runtime exception(null, new Exception(\"ne6 exception\") cause is not null", 
  +            ne6.getCause()); 
       }
       
  -    public void testGetLastMessage()
  +    public void testGetLength()
       {
  -        for(int i = 0; i < nestables.length; i++)
  -        {
  -            assertEquals("nestables " + i + " last message", lastMessage[i], ((nestables[i].getLastMessage() == null) ? "null" : nestables[i].getLastMessage()));
  -        }
  +        NestableRuntimeException ne1 = new NestableRuntimeException();
  +        assertEquals("ne1 length", 1, ne1.getLength());
  +
  +        NestableRuntimeException ne2 = new NestableRuntimeException("ne2");
  +        assertEquals("ne2 length", 1, ne2.getLength());
  +        
  +        NestableRuntimeException ne3 = new NestableRuntimeException(new Exception("ne3 exception"));
  +        assertEquals("ne3 length", 2, ne3.getLength());
  +        
  +        NestableRuntimeException ne4 = new NestableRuntimeException("ne4", new Exception("ne4 exception"));
  +        assertEquals("ne4 length", 2, ne4.getLength());
  +        
  +        NestableRuntimeException ne5 = new NestableRuntimeException("ne5", null);
  +        assertEquals("ne 5 length", 1, ne5.getLength());
  +        
  +        NestableRuntimeException ne6 = new NestableRuntimeException(null, new Exception("ne6 exception"));
  +        assertEquals("ne 6 length", 2, ne6.getLength());
  +        
  +        NestableRuntimeException ne7 = new NestableRuntimeException("ne7o", new NestableRuntimeException("ne7i", new Exception("ne7 exception")));
  +        assertEquals("ne 7 length", 3, ne7.getLength());
  +
  +        NestableRuntimeException ne8 = new NestableRuntimeException("level 1", new NestableRuntimeException("level 2", new NestableRuntimeException(new NestableRuntimeException("level 4", new Exception("level 5")))));
  +        assertEquals("ne 8 length", 5, ne8.getLength());
       }
       
  -    public void testNestableRuntimeException()
  +    public void testGetMessage()
       {
           NestableRuntimeException ne1 = new NestableRuntimeException();
  -        assertNull("nestable runtime exception() cause is null", ne1.getCause()); 
           assertNull("nestable runtime exception() message is null", ne1.getMessage()); 
  -
  +        
           NestableRuntimeException ne2 = new NestableRuntimeException("ne2");
  -        assertNull("nestable runtime exception(\"ne2\") cause is null", ne2.getCause());
           assertNotNull("nestable runtime exception(\"ne2\") message is not null", ne2.getMessage()); 
           assertTrue("nestable runtime exception(\"ne2\") message == ne2", ne2.getMessage().equals("ne2")); 
   
           NestableRuntimeException ne3 = new NestableRuntimeException(new Exception("ne3 exception"));
  -        assertNotNull("nestable runtime exception(new Exception(\"ne3 exception\") cause is not null",
  -            ne3.getCause()); 
  -        assertTrue("nestable runtime exception(new Exception(\"ne3 exception\") cause message == ne3 exception",
  -            ne3.getCause().getMessage().equals("ne3 exception")); 
           assertNotNull("nestable runtime exception(new Exception(\"ne3 exception\") message is not null",
               ne3.getMessage());
           assertTrue("nestable runtime exception(new Exception(\"ne3 exception\") message == cause message",
               ne3.getMessage().equals(ne3.getCause().getMessage())); 
  -        
  +
           NestableRuntimeException ne4 = new NestableRuntimeException("ne4", new Exception("ne4 exception"));
  -        assertNotNull("nestable runtime exception(\"ne4\", new Exception(\"ne4 exception\") cause is not null", 
  -            ne4.getCause()); 
           assertNotNull("nestable runtime exception(\"ne4\", new Exception(\"ne4 exception\") message is not null", 
               ne4.getMessage()); 
           assertTrue("nestable runtime exception(\"ne4\", new Exception(\"ne4 exception\") message == ne4: ne4 exception", 
               ne4.getMessage().equals("ne4: ne4 exception")); 
   
           NestableRuntimeException ne5 = new NestableRuntimeException("ne5", null);
  -        assertNull("nestable runtime exception(\"ne5\", null) cause is null", 
  -            ne5.getCause());
           assertNotNull("nestable runtime exception(\"ne5\", new Exception(\"ne5 exception\") message is not null", 
               ne5.getMessage()); 
           assertTrue("nestable runtime exception(\"ne5\", null) message == ne5", 
               ne5.getMessage().equals("ne5")); 
  -        
  +
           NestableRuntimeException ne6 = new NestableRuntimeException(null, new Exception("ne6 exception"));
  -        assertNotNull("nestable runtime exception(null, new Exception(\"ne6 exception\") cause is not null", 
  -            ne6.getCause()); 
           assertTrue("nestable runtime exception(null, new Exception(\"ne6 exception\") cause == ne6 exception", 
               ne6.getMessage().equals("ne6 exception")); 
  -        
  +
           NestableRuntimeException ne7 = new NestableRuntimeException("ne7o", new NestableRuntimeException("ne7i", new Exception("ne7 exception")));
           assertTrue("nextable exception(\"ne7o\", new NestableRuntimeException(\"ne7i\", new Exception(\"ne7 exception\"))) message is ne7o: ne7i: ne7 exception",
               ne7.getMessage().equals("ne7o: ne7i: ne7 exception")); 
  +    }
  +    
  +    public void testGetMessageN()
  +    {
  +        String[] msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        NestableRuntimeException ne = new NestableRuntimeException(msgs[0], new NestableRuntimeException(msgs[1], new NestableRuntimeException(new NestableRuntimeException(msgs[3], new Exception(msgs[4])))));
  +        for(int i = 0; i < msgs.length; i++)
  +        {
  +            assertEquals("message " + i, msgs[i], ne.getMessage(i));
  +        }
  +        assertEquals("message -1", msgs[0], ne.getMessage(-1));
  +        assertEquals("message 999", msgs[4], ne.getMessage(999));
  +    }
  +    
  +    public void testGetMessages()
  +    {
  +        String[] msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        NestableRuntimeException ne = new NestableRuntimeException(msgs[0], new NestableRuntimeException(msgs[1], new NestableRuntimeException(new NestableRuntimeException(msgs[3], new Exception(msgs[4])))));
  +        String[] nMsgs = ne.getMessages();
  +        assertEquals("messages length", msgs.length, nMsgs.length);
  +        for(int i = 0; i < nMsgs.length; i++)
  +        {
  +            assertEquals("message " + i, msgs[i], nMsgs[i]);
  +        }
  +    }
   
  +    public void testGetThrowable()
  +    {
  +        Nestable n = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[2];
  +        msgs[0] = null;
  +        msgs[1] = "level 2";
  +        throwables = new Class[2];
  +        throwables[0] = NestableRuntimeExceptionTester1.class;
  +        throwables[1] = Exception.class;
  +        n = new NestableRuntimeExceptionTester1(new Exception(msgs[1]));
  +        doNestableRuntimeExceptionGetThrowable(n, throwables, msgs);
  + 
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableRuntimeExceptionTester1.class;
  +        throwables[1] = NestableRuntimeExceptionTester2.class;
  +        throwables[2] = NestableRuntimeExceptionTester1.class;
  +        throwables[3] = NestableRuntimeExceptionTester2.class;
  +        throwables[4] = Exception.class;        
  +        n = new NestableRuntimeExceptionTester1(msgs[0], new NestableRuntimeExceptionTester2(msgs[1], new NestableRuntimeExceptionTester1(new NestableRuntimeExceptionTester2(msgs[3], new Exception(msgs[4])))));
  +        doNestableRuntimeExceptionGetThrowable(n, throwables, msgs);
  +    }
  +    
  +    private void doNestableRuntimeExceptionGetThrowable(Nestable n, Class[] classes, String[] msgs)
  +    {
  +        Throwable t = null;
  +        String msg = null;
  +
  +        for(int i = 0; i < classes.length; i++)
  +        {
  +            t = n.getThrowable(i);
  +            assertEquals("throwable class", classes[i], t.getClass());
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("throwable message", msgs[i], msg);
  +        }
  +        t = n.getThrowable(-1);
  +        assertEquals("throwable(-1)", classes[0], t.getClass());
  +        if(Nestable.class.isInstance(t))
  +        {
  +            msg = ((Nestable) t).getMessage(0);
  +        }
  +        else
  +        {
  +            msg = t.getMessage();
  +        }
  +        assertEquals("throwable message", msgs[0], msg);
  +        t = n.getThrowable(999);
  +        assertEquals("throwable(999)", classes[classes.length - 1], t.getClass());
  +        if(Nestable.class.isInstance(t))
  +        {
  +            msg = ((Nestable) t).getMessage(0);
  +        }
  +        else
  +        {
  +            msg = t.getMessage();
  +        }
  +        assertEquals("throwable message", msgs[msgs.length - 1], msg);
  +    }
  +    
  +    public void testGetThrowables()
  +    {
  +        Nestable n = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[2];
  +        msgs[0] = null;
  +        msgs[1] = "level 2";
  +        throwables = new Class[2];
  +        throwables[0] = NestableRuntimeExceptionTester1.class;
  +        throwables[1] = Exception.class;
  +        n = new NestableRuntimeExceptionTester1(new Exception(msgs[1]));
  +        doNestableRuntimeExceptionGetThrowables(n, throwables, msgs);
  + 
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableRuntimeExceptionTester1.class;
  +        throwables[1] = NestableRuntimeExceptionTester2.class;
  +        throwables[2] = NestableRuntimeExceptionTester1.class;
  +        throwables[3] = NestableRuntimeExceptionTester2.class;
  +        throwables[4] = Exception.class;        
  +        n = new NestableRuntimeExceptionTester1(msgs[0], new NestableRuntimeExceptionTester2(msgs[1], new NestableRuntimeExceptionTester1(new NestableRuntimeExceptionTester2(msgs[3], new Exception(msgs[4])))));
  +        doNestableRuntimeExceptionGetThrowables(n, throwables, msgs);
  +    }
  +    
  +    private void doNestableRuntimeExceptionGetThrowables(Nestable n, Class[] classes, String[] msgs)
  +    {
  +        String msg = null;
  +
  +        Throwable throwables[] = n.getThrowables();
  +        assertEquals("throwables length", classes.length, throwables.length);
  +        for(int i = 0; i < classes.length; i++)
  +        {
  +            assertEquals("throwable class", classes[i], throwables[i].getClass());
  +            Throwable t = throwables[i];
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("throwable message", msgs[i], msg);
  +        }
  +    }
  +    
  +    public void testIndexOfThrowable()
  +    {
  +        Nestable n = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableRuntimeExceptionTester1.class;
  +        throwables[1] = NestableRuntimeExceptionTester2.class;
  +        throwables[2] = NestableRuntimeExceptionTester1.class;
  +        throwables[3] = NestableRuntimeExceptionTester2.class;
  +        throwables[4] = Exception.class;
  +        int[] indexes = {0, 1, 0, 1, 4};
  +        n = new NestableRuntimeExceptionTester1(msgs[0], new NestableRuntimeExceptionTester2(msgs[1], new NestableRuntimeExceptionTester1(new NestableRuntimeExceptionTester2(msgs[3], new Exception(msgs[4])))));
  +        for(int i = 0; i < throwables.length; i++)
  +        {
  +            doNestableRuntimeExceptionIndexOfThrowable(n, throwables[i], indexes[i], msgs[indexes[i]]);
  +        }
  +        doNestableRuntimeExceptionIndexOfThrowable(n, java.util.Date.class, -1, null);
  +    }
  +    
  +    private void doNestableRuntimeExceptionIndexOfThrowable(Nestable n, Class type, int expectedIndex, String expectedMsg)
  +    {
  +        Throwable t = null;
  +        
  +        int index = n.indexOfThrowable(type);
  +        assertEquals("index of throwable " + type.getName(), expectedIndex, index);
  +        t = n.getThrowable(index);
  +        if(expectedMsg != null)
  +        {
  +            String msg = null;
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("message of indexed throwable", expectedMsg, msg);
  +        }
  +    }
  +    
  +    public void testIndexOfThrowableN()
  +    {
  +        Nestable n = null;
  +        String msgs[] = null;
  +        Class[] throwables = null;
  +        
  +        msgs = new String[5];
  +        msgs[0] = "level 1";
  +        msgs[1] = "level 2";
  +        msgs[2] = null;
  +        msgs[3] = "level 4";
  +        msgs[4] = "level 5";
  +        throwables = new Class[5];
  +        throwables[0] = NestableRuntimeExceptionTester1.class;
  +        throwables[1] = NestableRuntimeExceptionTester2.class;
  +        throwables[2] = NestableRuntimeExceptionTester1.class;
  +        throwables[3] = NestableRuntimeExceptionTester2.class;
  +        throwables[4] = Exception.class;
  +        int[] indexes = {0, 1, 0, 1, 4};
  +        n = new NestableRuntimeExceptionTester1(msgs[0], new NestableRuntimeExceptionTester2(msgs[1], new NestableRuntimeExceptionTester1(new NestableRuntimeExceptionTester2(msgs[3], new Exception(msgs[4])))));
  +        for(int i = 0; i < throwables.length; i++)
  +        {
  +            doNestableRuntimeExceptionIndexOfThrowableN(n, throwables[i], 0, indexes[i], msgs[indexes[i]]);
  +        }
  +        doNestableRuntimeExceptionIndexOfThrowableN(n, NestableRuntimeExceptionTester2.class, 2, 3, msgs[3]);
  +        doNestableRuntimeExceptionIndexOfThrowableN(n, NestableRuntimeExceptionTester1.class, 1, 2, msgs[2]);
  +        doNestableRuntimeExceptionIndexOfThrowableN(n, java.util.Date.class, 0, -1, null);
  +    }
  +
  +    private void doNestableRuntimeExceptionIndexOfThrowableN(Nestable n, Class type, int pos, int expectedIndex, String expectedMsg)
  +    {
  +        Throwable t = null;
  +        
  +        int index = n.indexOfThrowable(pos, type);
  +        assertEquals("index of throwable " + type.getName(), expectedIndex, index);
  +        t = n.getThrowable(index);
  +        if(expectedMsg != null)
  +        {
  +            String msg = null;
  +            if(Nestable.class.isInstance(t))
  +            {
  +                msg = ((Nestable) t).getMessage(0);
  +            }
  +            else
  +            {
  +                msg = t.getMessage();
  +            }
  +            assertEquals("message of indexed throwable", expectedMsg, msg);
  +        }
  +    }
  +    
  +    public void testPrintStackTrace()
  +    {
           NestableRuntimeException ne8 = new NestableRuntimeException("ne8", new Exception("ne8 exception"));
           ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
           PrintStream ps1 = new PrintStream(baos1);
  @@ -228,7 +461,10 @@
               stack1.startsWith("java.lang.Exception: ne8 exception")); 
           assertTrue("stack trace indexOf org.apache.commons.lang.exception.NestableRuntimeException: ne8: ne8 exception > -1",
               stack1.indexOf("org.apache.commons.lang.exception.NestableRuntimeException: ne8: ne8 exception") > -1); 
  +    }
   
  +    public void testPrintPartialStackTrace()
  +    {
           NestableRuntimeException ne9 = new NestableRuntimeException("ne9", new Exception("ne9 exception"));
           ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
           PrintStream ps2 = new PrintStream(baos2);
  @@ -245,4 +481,52 @@
       {
           TestRunner.run(suite());
       }
  +}
  +
  +class NestableRuntimeExceptionTester1 extends NestableRuntimeException
  +{
  +    public NestableRuntimeExceptionTester1()
  +    {
  +        super();
  +    }
  +
  +    public NestableRuntimeExceptionTester1(String reason, Throwable cause)
  +    {
  +        super(reason, cause);
  +    }
  +    
  +    public NestableRuntimeExceptionTester1(String reason)
  +    {
  +        super(reason);
  +    }
  +    
  +    public NestableRuntimeExceptionTester1(Throwable cause)
  +    {
  +        super(cause);
  +    }
  +    
  +}
  +
  +class NestableRuntimeExceptionTester2 extends NestableRuntimeException
  +{
  +    public NestableRuntimeExceptionTester2()
  +    {
  +        super();
  +    }
  +    
  +    public NestableRuntimeExceptionTester2(String reason, Throwable cause)
  +    {
  +        super(reason, cause);
  +    }
  +    
  +    public NestableRuntimeExceptionTester2(String reason)
  +    {
  +        super(reason);
  +    }
  +    
  +    public NestableRuntimeExceptionTester2(Throwable cause)
  +    {
  +        super(cause);
  +    }
  +    
   }
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message