KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > groovy > control > ProcessingUnit


1 /*
2  $Id: ProcessingUnit.java,v 1.3 2004/12/15 00:19:52 zohar Exp $
3
4  Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5
6  Redistribution and use of this software and associated documentation
7  ("Software"), with or without modification, are permitted provided
8  that the following conditions are met:
9
10  1. Redistributions of source code must retain copyright
11     statements and notices. Redistributions must also contain a
12     copy of this document.
13
14  2. Redistributions in binary form must reproduce the
15     above copyright notice, this list of conditions and the
16     following disclaimer in the documentation and/or other
17     materials provided with the distribution.
18
19  3. The name "groovy" must not be used to endorse or promote
20     products derived from this Software without prior written
21     permission of The Codehaus. For written permission,
22     please contact info@codehaus.org.
23
24  4. Products derived from this Software may not be called "groovy"
25     nor may "groovy" appear in their names without prior written
26     permission of The Codehaus. "groovy" is a registered
27     trademark of The Codehaus.
28
29  5. Due credit should be given to The Codehaus -
30     http://groovy.codehaus.org/
31
32  THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
36  THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43  OF THE POSSIBILITY OF SUCH DAMAGE.
44
45  */

46
47 package org.codehaus.groovy.control;
48
49 import java.io.PrintWriter JavaDoc;
50 import java.util.Iterator JavaDoc;
51 import java.util.LinkedList JavaDoc;
52 import java.util.List JavaDoc;
53
54 import org.codehaus.groovy.control.messages.ExceptionMessage;
55 import org.codehaus.groovy.control.messages.Message;
56 import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
57 import org.codehaus.groovy.control.messages.WarningMessage;
58 import org.codehaus.groovy.syntax.SyntaxException;
59
60
61 /**
62  * A base class for data structures that can collect messages and errors
63  * during processing.
64  *
65  * @author <a HREF="mailto:cpoirier@dreaming.org">Chris Poirier</a>
66  *
67  * @version $Id: ProcessingUnit.java,v 1.3 2004/12/15 00:19:52 zohar Exp $
68  */

69
70 public abstract class ProcessingUnit
71 {
72
73   //---------------------------------------------------------------------------
74
// CONSTRUCTION AND SUCH
75

76     protected LinkedList JavaDoc warnings; // WarningMessages collected during processing
77
protected LinkedList JavaDoc errors; // ErrorMessages collected during processing
78
protected boolean fatal; // Set on the first fatal error
79

80     protected int phase; // The current phase
81
protected boolean phaseComplete; // Set true if phase is finished
82

83     protected CompilerConfiguration configuration; // Configuration and other settings that control processing
84
protected int warningLevel; // Warnings will be filtered on this level
85
protected PrintWriter JavaDoc output; // A place to send warning output
86
protected int tolerance; // The number of non-fatal errors to allow before fail()
87

88     protected ClassLoader JavaDoc classLoader; // The ClassLoader to use during processing
89

90
91
92    /**
93     * Initialize the ProcessingUnit to the empty state.
94     */

95
96     public ProcessingUnit( CompilerConfiguration configuration, ClassLoader JavaDoc classLoader )
97     {
98         this.warnings = null;
99         this.errors = null;
100         this.fatal = false;
101
102         this.phase = Phases.INITIALIZATION;
103         this.classLoader = (classLoader == null ? new CompilerClassLoader() : classLoader);
104
105         configure( (configuration == null ? new CompilerConfiguration() : configuration) );
106     }
107
108
109
110    /**
111     * Reconfigures the ProcessingUnit.
112     */

113
114     public void configure( CompilerConfiguration configuration )
115     {
116         this.configuration = configuration;
117         this.warningLevel = configuration.getWarningLevel();
118         this.output = configuration.getOutput();
119         this.tolerance = configuration.getTolerance();
120     }
121
122
123
124    /**
125     * Returns the class loader in use by this ProcessingUnit.
126     */

127
128     public ClassLoader JavaDoc getClassLoader()
129     {
130         return classLoader;
131     }
132
133
134
135    /**
136     * Sets the class loader for use by this ProcessingUnit.
137     */

138
139     public void setClassLoader( ClassLoader JavaDoc loader )
140     {
141         this.classLoader = loader;
142     }
143
144
145
146    /**
147     * Returns the current phase.
148     */

149
150     public int getPhase()
151     {
152         return this.phase;
153     }
154
155
156
157    /**
158     * Returns the description for the current phase.
159     */

160
161     public String JavaDoc getPhaseDescription()
162     {
163         return Phases.getDescription( this.phase );
164     }
165
166
167
168    /**
169     * Returns the list of warnings, or null if there are none.
170     */

171
172     public List JavaDoc getWarnings()
173     {
174         return this.warnings;
175     }
176
177
178
179    /**
180     * Returns the list of errors, or null if there are none.
181     */

182
183     public List JavaDoc getErrors()
184     {
185         return this.errors;
186     }
187
188
189
190    /**
191     * Returns the number of warnings.
192     */

193
194     public int getWarningCount()
195     {
196         return ((this.warnings == null) ? 0 : this.warnings.size());
197     }
198
199
200
201    /**
202     * Returns the number of errors.
203     */

204
205     public int getErrorCount()
206     {
207         return ((this.errors == null) ? 0 : this.errors.size());
208     }
209
210
211
212    /**
213     * Returns the specified warning message, or null.
214     */

215
216     public WarningMessage getWarning( int index )
217     {
218         if( index < getWarningCount() )
219         {
220             return (WarningMessage)this.warnings.get(index);
221         }
222
223         return null;
224     }
225
226
227
228    /**
229     * Returns the specified error message, or null.
230     */

231
232     public Message getError( int index )
233     {
234         if( index < getErrorCount() )
235         {
236             return (Message)this.errors.get(index);
237         }
238
239         return null;
240     }
241
242
243
244    /**
245     * Convenience routine to return the specified error's
246     * underlying SyntaxException, or null if it isn't one.
247     */

248
249     public SyntaxException getSyntaxError( int index )
250     {
251         SyntaxException exception = null;
252
253         Message message = getError( index );
254         if( message != null && message instanceof SyntaxErrorMessage )
255         {
256             exception = ((SyntaxErrorMessage)message).getCause();
257         }
258
259         return exception;
260     }
261
262
263
264    /**
265     * Convenience routine to return the specified error's
266     * underlying Exception, or null if it isn't one.
267     */

268
269     public Exception JavaDoc getException( int index )
270     {
271         Exception JavaDoc exception = null;
272
273         Message message = getError( index );
274         if( message != null )
275         {
276             if( message instanceof ExceptionMessage )
277             {
278                 exception = ((ExceptionMessage)message).getCause();
279             }
280             else if( message instanceof SyntaxErrorMessage )
281             {
282                 exception = ((SyntaxErrorMessage)message).getCause();
283             }
284         }
285
286         return exception;
287     }
288
289
290
291
292   //---------------------------------------------------------------------------
293
// MESSAGES
294

295
296    /**
297     * Adds a WarningMessage to the message set.
298     */

299
300     public void addWarning( WarningMessage message )
301     {
302         if( message.isRelevant(this.warningLevel) )
303         {
304             if( this.warnings == null )
305             {
306                 this.warnings = new LinkedList JavaDoc();
307             }
308
309             this.warnings.add( message );
310         }
311     }
312
313
314
315    /**
316     * Adds a non-fatal error to the message set.
317     */

318
319     public void addError( Message message ) throws CompilationFailedException
320     {
321         if( this.errors == null )
322         {
323             this.errors = new LinkedList JavaDoc();
324         }
325
326         this.errors.add( message );
327
328         if( this.errors.size() >= this.tolerance )
329         {
330             fail();
331         }
332     }
333
334
335
336    /**
337     * Adds an optionally-fatal error to the message set. Throws
338     * the unit as a PhaseFailedException, if the error is fatal.
339     */

340
341     public void addError( Message message, boolean fatal ) throws CompilationFailedException
342     {
343         if( fatal )
344         {
345             addFatalError( message );
346         }
347         else
348         {
349             addError( message );
350         }
351     }
352
353
354
355    /**
356     * Adds a fatal exception to the message set and throws
357     * the unit as a PhaseFailedException.
358     */

359
360     public void addFatalError( Message message ) throws CompilationFailedException
361     {
362         addError( message );
363         fail();
364     }
365
366
367
368
369   //---------------------------------------------------------------------------
370
// PROCESSING
371

372
373    /**
374     * Returns true if there are any errors pending.
375     */

376
377     public boolean hasErrors()
378     {
379         return this.errors != null;
380     }
381
382
383
384    /**
385     * Marks the current phase complete and processes any
386     * errors.
387     */

388
389     public void completePhase() throws CompilationFailedException
390     {
391         //
392
// First up, display and clear any pending warnings.
393

394         if( this.warnings != null )
395         {
396             Janitor janitor = new Janitor();
397
398             try
399             {
400                 Iterator JavaDoc iterator = this.warnings.iterator();
401                 while( iterator.hasNext() )
402                 {
403                     WarningMessage warning = (WarningMessage)iterator.next();
404                     warning.write( output, this, janitor );
405                 }
406
407                 this.warnings = null;
408             }
409             finally
410             {
411                 janitor.cleanup();
412             }
413         }
414
415         //
416
// Then either fail() or update the phase and return
417

418         if( this.hasErrors() )
419         {
420             fail();
421         }
422         else
423         {
424             phaseComplete = true;
425         }
426     }
427
428
429
430    /**
431     * A synonym for <code>gotoPhase( phase + 1 )</code>.
432     */

433
434     public void nextPhase() throws CompilationFailedException
435     {
436         gotoPhase( this.phase + 1 );
437     }
438
439
440
441    /**
442     * Wraps up any pending operations for the current phase
443     * and switches to the next phase.
444     */

445
446     public void gotoPhase( int phase ) throws CompilationFailedException
447     {
448         if( !this.phaseComplete )
449         {
450             completePhase();
451         }
452
453         this.phase = phase;
454         this.phaseComplete = false;
455     }
456
457
458
459    /**
460     * Causes the current phase to fail by throwing a
461     * CompilationFailedException.
462     */

463
464     protected void fail() throws CompilationFailedException
465     {
466         throw new CompilationFailedException( phase, this );
467     }
468
469
470
471   //---------------------------------------------------------------------------
472
// OUTPUT
473

474
475    /**
476     * Writes error messages to the specified PrintWriter.
477     */

478
479     public void write( PrintWriter JavaDoc writer, Janitor janitor )
480     {
481         if( this.warnings != null )
482         {
483             Iterator JavaDoc iterator = this.warnings.iterator();
484             while( iterator.hasNext() )
485             {
486                 WarningMessage warning = (WarningMessage)iterator.next();
487                 warning.write( writer, this, janitor );
488             }
489
490             this.warnings = null;
491         }
492
493         if( this.errors != null )
494         {
495             Iterator JavaDoc iterator = this.errors.iterator();
496             while( iterator.hasNext() )
497             {
498                 Message message = (Message)iterator.next();
499                 message.write( writer, this, janitor );
500             }
501
502             //why? this nukes the errors once a getString call is made
503
//this.errors = null;
504
}
505     }
506
507
508 }
509
510
511
512
513
Popular Tags