001    /*
002     $Id: ErrorReporter.java,v 1.6 2005/06/08 20:06:19 glaforge Exp $
003    
004     Copyright 2004 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005    
006     Redistribution and use of this software and associated documentation
007     ("Software"), with or without modification, are permitted provided
008     that the following conditions are met:
009    
010     1. Redistributions of source code must retain copyright
011        statements and notices.  Redistributions must also contain a
012        copy of this document.
013    
014     2. Redistributions in binary form must reproduce the
015        above copyright notice, this list of conditions and the
016        following disclaimer in the documentation and/or other
017        materials provided with the distribution.
018    
019     3. The name "groovy" must not be used to endorse or promote
020        products derived from this Software without prior written
021        permission of The Codehaus.  For written permission,
022        please contact info@codehaus.org.
023    
024     4. Products derived from this Software may not be called "groovy"
025        nor may "groovy" appear in their names without prior written
026        permission of The Codehaus. "groovy" is a registered
027        trademark of The Codehaus.
028    
029     5. Due credit should be given to The Codehaus -
030        http://groovy.codehaus.org/
031    
032     THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033     ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
036     THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043     OF THE POSSIBILITY OF SUCH DAMAGE.
044    
045     */
046    
047    
048    package org.codehaus.groovy.tools;
049    
050    import java.io.PrintStream;
051    import java.io.PrintWriter;
052    
053    import org.codehaus.groovy.GroovyExceptionInterface;
054    import org.codehaus.groovy.control.CompilationFailedException;
055    import groovy.lang.GroovyRuntimeException;
056    
057    
058    /**
059     *  Provides services for reporting compilation errors to the
060     *  user.  Primary entry point is <code>write()</code>.
061     *
062     *  @author <a href="mailto:cpoirier%20AT%20tapestry_os%20DOT%20org">Chris Poirier</a>
063     *  @version $Revision: 1.6 $
064     */
065    
066    public class ErrorReporter
067    {
068        private Throwable   base     = null;    // The exception on which to report
069        private boolean     debug    = false;   // If true, stack traces are always output
070    
071        private Object      output   = null;    // The stream/writer to which to output
072    
073    
074       /**
075        *  Configures a new Reporter.  Default mode is not to report a stack trace unless
076        *  the error was not of one of the supported types.
077        *
078        *  @param e  the exception on which to report
079        */
080    
081        public ErrorReporter( Throwable e )
082        {
083            this.base     = e;
084        }
085    
086    
087       /**
088        *  Configures a new Reporter.  
089        *
090        *  @param e      the exception on which to report
091        *  @param debug  if set, stack traces will be output for all reports
092        */
093    
094        public ErrorReporter( Throwable e, boolean debug )
095        {
096            this.base  = e;
097            this.debug = debug;
098        }
099    
100    
101       /**
102        *  Writes the error to the specified <code>PrintStream</code>.
103        */
104    
105        public void write( PrintStream stream )
106        {
107            this.output = stream;
108            dispatch( base, false );
109            stream.flush();
110        }
111    
112    
113       /**
114        *  Writes the error to the specified <code>PrintWriter</code>.
115        */
116    
117        public void write( PrintWriter writer )
118        {
119            this.output = writer;
120            dispatch( base, false );
121            writer.flush();
122        }
123    
124    
125       /**
126        *  Runs the report once all initialization is complete.
127        */
128    
129        protected void dispatch( Throwable object, boolean child )
130        {
131            if( object instanceof CompilationFailedException )
132            {
133                report( (CompilationFailedException)object, child );
134            }
135            else if( object instanceof GroovyExceptionInterface )
136            {
137                report( (GroovyExceptionInterface)object, child );
138            }
139            else if( object instanceof GroovyRuntimeException )
140            {
141                report( (GroovyRuntimeException)object, child );
142            }
143            else if( object instanceof Exception )
144            {
145                report( (Exception)object, child );
146            }
147            else
148            {
149                report( object, child );
150            }
151    
152        }
153    
154    
155    
156      //---------------------------------------------------------------------------
157      // REPORTING ROUTINES
158    
159    
160       /**
161        *  For CompilationFailedException.
162        */
163    
164        protected void report( CompilationFailedException e, boolean child )
165        {
166            println( e.toString() );
167            stacktrace( e, false );
168        }
169    
170    
171    
172       /**
173        *  For GroovyException.
174        */
175    
176        protected void report( GroovyExceptionInterface e, boolean child )
177        {
178            println( ((Exception)e).getMessage() );
179            stacktrace( (Exception)e, false );
180        }
181    
182    
183    
184       /**
185        *  For Exception.
186        */
187    
188        protected void report( Exception e, boolean child )
189        {
190            println( e.getMessage() );
191            stacktrace( e, false );
192        }
193    
194    
195    
196       /**
197        *  For everything else.
198        */
199    
200        protected void report( Throwable e, boolean child )
201        {
202            println( ">>> a serious error occurred: " + e.getMessage() );
203            stacktrace( e, true );
204        }
205    
206    
207    
208      //---------------------------------------------------------------------------
209      // GENERAL SUPPORT ROUTINES
210    
211    
212       /**
213        *  Prints a line to the underlying <code>PrintStream</code>
214        */
215    
216        protected void println( String line )
217        {
218            if( output instanceof PrintStream )
219            {
220                ((PrintStream)output).println( line );
221            }
222            else
223            {
224                ((PrintWriter)output).println( line );
225            }
226        }
227    
228        protected void println( StringBuffer line )
229        {
230            if( output instanceof PrintStream )
231            {
232                ((PrintStream)output).println( line );
233            }
234            else
235            {
236                ((PrintWriter)output).println( line );
237            }
238        }
239    
240    
241       /**
242        *  Displays an exception's stack trace, if <code>debug</code> or 
243        *  <code>always</code>.
244        */
245    
246        protected void stacktrace( Throwable e, boolean always )
247        {
248            if( debug || always )
249            {
250                println( ">>> stacktrace:" );
251                if( output instanceof PrintStream )
252                {
253                    e.printStackTrace( (PrintStream)output );
254                }
255                else
256                {
257                    e.printStackTrace( (PrintWriter)output );
258                }
259            }
260        }
261    
262    
263    
264    }