001    package com.mockrunner.base;
002    
003    import java.io.PrintWriter;
004    import java.io.StringWriter;
005    
006    /**
007     * If Mockrunner catches an exception inside application code,
008     * it rethrows it as an instance of this class.
009     */
010    public class NestedApplicationException extends RuntimeException
011    {
012        private Throwable nested;
013        
014        public NestedApplicationException(String message, Throwable nested)
015        {
016            super(message);
017            this.nested = nested;
018        }
019        
020        public NestedApplicationException(Throwable nested)
021        {
022            this.nested = nested;
023        }
024        
025        /**
026         * Returns the nested exception 
027         * (which may also be a <code>NestedApplicationException</code>)
028         * @return the nested exception
029         */
030        public Throwable getNested()
031        {
032            return nested;
033        }
034        
035        /**
036         * Returns the root cause, i.e. the first exception that is
037         * not an instance of <code>NestedApplicationException</code>.
038         * @return the root exception
039         */
040        public Throwable getRootCause()
041        {
042            if(nested == null) return null;
043            if(!(nested instanceof NestedApplicationException)) return nested;
044            return ((NestedApplicationException)nested).getRootCause();
045        }
046        
047        public String getMessage()
048        {
049            StringWriter writer = new StringWriter();
050            PrintWriter printWriter = new PrintWriter(writer);
051            String message = super.getMessage();
052            if(null != message)
053            {
054                printWriter.println(super.getMessage());
055            }
056            else
057            {
058                printWriter.println();
059            }
060            Throwable cause = getRootCause();
061            if(null != cause)
062            {
063                printWriter.print("Cause: ");
064                cause.printStackTrace(printWriter);
065            }
066            writer.flush();
067            return writer.toString();
068        }
069    }