View Javadoc

1   /*
2    $Id: CompilerConfiguration.java,v 1.15 2006/06/06 14:33:47 blackdrag 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 org.codehaus.groovy.control.io.NullWriter;
50  import org.codehaus.groovy.control.messages.WarningMessage;
51  
52  import java.io.File;
53  import java.io.PrintWriter;
54  import java.util.LinkedList;
55  import java.util.List;
56  import java.util.Properties;
57  import java.util.StringTokenizer;
58  
59  
60  /***
61   * Compilation control flags and coordination stuff.
62   *
63   * @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
64   * @author <a href="mailto:blackdrag@gmx.org">Jochen Theodorou</a>
65   * @version $Id: CompilerConfiguration.java,v 1.15 2006/06/06 14:33:47 blackdrag Exp $
66   */
67  
68  public class CompilerConfiguration {
69      public static final CompilerConfiguration DEFAULT = new CompilerConfiguration();
70  
71      /*** Whether to use the JSR parser or not if no property is explicitly stated */
72      protected static final boolean DEFAULT_JSR_FLAG = true;
73  
74      private static boolean jsrGroovy;
75  
76      /***
77       * See WarningMessage for levels
78       */
79      private int warningLevel;
80      /***
81       * Encoding for source files
82       */
83      private String sourceEncoding;
84      /***
85       * A PrintWriter for communicating with the user
86       */
87      private PrintWriter output;
88      /***
89       * Directory into which to write classes
90       */
91      private File targetDirectory;
92      /***
93       * Classpath for use during compilation
94       */
95      private LinkedList classpath;
96      /***
97       * If true, the compiler should produce action information
98       */
99      private boolean verbose;
100     /***
101      * If true, debugging code should be activated
102      */
103     private boolean debug;
104     /***
105      * The number of non-fatal errors to allow before bailing
106      */
107     private int tolerance;
108     /***
109      * Base class name for scripts (must derive from Script)
110      */
111     private String scriptBaseClass;
112     /***
113      * should we use the New JSR Groovy parser or stay with the static one
114      */
115     private boolean useNewGroovy = getDefaultJsrFlag();
116 
117     private ParserPluginFactory pluginFactory;
118 
119     /***
120      * extension used to find a groovy file
121      */
122     private String defaultScriptExtension = ".groovy";
123     
124     /***
125      * if set to true recompilation is enabled
126      */
127     private boolean recompileGroovySource;
128     
129     /***
130      * sets the minimum of time after a script can be recompiled.
131      */
132     private int minimumRecompilationIntervall;
133 
134     /***
135      * Sets the Flags to defaults.
136      */
137     public CompilerConfiguration() {
138         //
139         // Set in safe defaults
140 
141         setWarningLevel(WarningMessage.LIKELY_ERRORS);
142         setSourceEncoding("US-ASCII");
143         setOutput(null);
144         setTargetDirectory((File) null);
145         setClasspath("");
146         setVerbose(false);
147         setDebug(false);
148         setTolerance(10);
149         setScriptBaseClass(null);
150         setRecompileGroovySource(false);
151         setMinimumRecompilationIntervall(100);
152 
153 
154         //
155         // Try for better defaults, ignore errors.
156 
157         try {
158             setSourceEncoding(System.getProperty("file.encoding", "US-ASCII"));
159         }
160         catch (Exception e) {
161         }
162         try {
163             setOutput(new PrintWriter(System.err));
164         }
165         catch (Exception e) {
166         }
167         /*try {
168             setClasspath(System.getProperty("java.class.path"));
169         }
170         catch (Exception e) {
171         }*/
172 
173         try {
174             String target = System.getProperty("groovy.target.directory");
175             if (target != null) {
176                 setTargetDirectory(target);
177             }
178         }
179         catch (Exception e) {
180         }
181     }
182 
183 
184     /***
185      * Sets the Flags to the specified configuration, with defaults
186      * for those not supplied.
187      */
188 
189     public CompilerConfiguration(Properties configuration) throws ConfigurationException {
190         this();
191 
192         String text = null;
193         int numeric = 0;
194 
195 
196         //
197         // Warning level
198 
199         numeric = getWarningLevel();
200         try {
201             text = configuration.getProperty("groovy.warnings", "likely errors");
202             numeric = Integer.parseInt(text);
203         }
204         catch (NumberFormatException e) {
205             if (text.equals("none")) {
206                 numeric = WarningMessage.NONE;
207             }
208             else if (text.startsWith("likely")) {
209                 numeric = WarningMessage.LIKELY_ERRORS;
210             }
211             else if (text.startsWith("possible")) {
212                 numeric = WarningMessage.POSSIBLE_ERRORS;
213             }
214             else if (text.startsWith("paranoia")) {
215                 numeric = WarningMessage.PARANOIA;
216             }
217             else {
218                 throw new ConfigurationException("unrecogized groovy.warnings: " + text);
219             }
220         }
221 
222         setWarningLevel(numeric);
223 
224 
225         //
226         // Source file encoding
227 
228         text = configuration.getProperty("groovy.source.encoding");
229         if (text != null) {
230             setSourceEncoding(text);
231         }
232 
233 
234         //
235         // Target directory for classes
236 
237         text = configuration.getProperty("groovy.target.directory");
238         if (text != null) {
239             setTargetDirectory(text);
240         }
241 
242 
243         //
244         // Classpath
245 
246         text = configuration.getProperty("groovy.classpath");
247         if (text != null) {
248             setClasspath(text);
249         }
250 
251 
252         //
253         // Verbosity
254 
255         text = configuration.getProperty("groovy.output.verbose");
256         if (text != null && text.equals("true")) {
257             setVerbose(true);
258         }
259 
260 
261         //
262         // Debugging
263 
264         text = configuration.getProperty("groovy.output.debug");
265         if (text != null && text.equals("true")) {
266             setDebug(true);
267         }
268 
269 
270         //
271         // Tolerance
272 
273         numeric = 10;
274 
275         try {
276             text = configuration.getProperty("groovy.errors.tolerance", "10");
277             numeric = Integer.parseInt(text);
278         }
279         catch (NumberFormatException e) {
280             throw new ConfigurationException(e);
281         }
282 
283         setTolerance(numeric);
284 
285 
286         //
287         // Script Base Class
288 
289         text = configuration.getProperty("groovy.script.base");
290         setScriptBaseClass(text);
291 
292         text = configuration.getProperty("groovy.jsr");
293         if (text != null) {
294             setUseNewGroovy(text.equalsIgnoreCase("true"));
295         }
296         
297         
298         //
299         // recompilation options
300         //
301         text = configuration.getProperty("groovy.recompile");
302         if (text != null) {
303             setRecompileGroovySource(text.equalsIgnoreCase("true"));
304         }
305         
306         numeric = 100;
307         try {
308             text = configuration.getProperty("groovy.recompile.minimumIntervall", ""+numeric);
309             numeric = Integer.parseInt(text);
310         }
311         catch (NumberFormatException e) {
312             throw new ConfigurationException(e);
313         }
314         setMinimumRecompilationIntervall(numeric);
315         
316         
317     }
318 
319 
320     /***
321      * Gets the currently configured warning level.  See WarningMessage
322      * for level details.
323      */
324     public int getWarningLevel() {
325         return this.warningLevel;
326     }
327 
328 
329     /***
330      * Sets the warning level.  See WarningMessage for level details.
331      */
332     public void setWarningLevel(int level) {
333         if (level < WarningMessage.NONE || level > WarningMessage.PARANOIA) {
334             this.warningLevel = WarningMessage.LIKELY_ERRORS;
335         }
336         else {
337             this.warningLevel = level;
338         }
339     }
340 
341 
342     /***
343      * Gets the currently configured source file encoding.
344      */
345     public String getSourceEncoding() {
346         return this.sourceEncoding;
347     }
348 
349 
350     /***
351      * Sets the encoding to be used when reading source files.
352      */
353     public void setSourceEncoding(String encoding) {
354         this.sourceEncoding = encoding;
355     }
356 
357 
358     /***
359      * Gets the currently configured output writer.
360      */
361     public PrintWriter getOutput() {
362         return this.output;
363     }
364 
365 
366     /***
367      * Sets the output writer.
368      */
369     public void setOutput(PrintWriter output) {
370         if (this.output == null) {
371             this.output = new PrintWriter(NullWriter.DEFAULT);
372         }
373         else {
374             this.output = output;
375         }
376     }
377 
378 
379     /***
380      * Gets the target directory for writing classes.
381      */
382     public File getTargetDirectory() {
383         return this.targetDirectory;
384     }
385 
386 
387     /***
388      * Sets the target directory.
389      */
390     public void setTargetDirectory(String directory) {
391         if (directory != null && directory.length() > 0) {
392             this.targetDirectory = new File(directory);
393         }
394         else {
395             this.targetDirectory = null;
396         }
397     }
398 
399 
400     /***
401      * Sets the target directory.
402      */
403     public void setTargetDirectory(File directory) {
404         this.targetDirectory = directory;
405     }
406 
407 
408     /***
409      * Gets the classpath.
410      */
411     public List getClasspath() {
412         return this.classpath;
413     }
414 
415 
416     /***
417      * Sets the classpath.
418      */
419     public void setClasspath(String classpath) {
420         this.classpath = new LinkedList();
421 
422         StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator);
423         while (tokenizer.hasMoreTokens()) {
424             this.classpath.add(tokenizer.nextToken());
425         }
426     }
427 
428 
429     /***
430      * Returns true if verbose operation has been requested.
431      */
432     public boolean getVerbose() {
433         return this.verbose;
434     }
435 
436 
437     /***
438      * Turns verbose operation on or off.
439      */
440     public void setVerbose(boolean verbose) {
441         this.verbose = verbose;
442     }
443 
444 
445     /***
446      * Returns true if debugging operation has been requested.
447      */
448     public boolean getDebug() {
449         return this.debug;
450     }
451 
452 
453     /***
454      * Turns debugging operation on or off.
455      */
456     public void setDebug(boolean debug) {
457         this.debug = debug;
458     }
459 
460 
461     /***
462      * Returns the requested error tolerance.
463      */
464     public int getTolerance() {
465         return this.tolerance;
466     }
467 
468 
469     /***
470      * Sets the error tolerance, which is the number of
471      * non-fatal errors (per unit) that should be tolerated before
472      * compilation is aborted.
473      */
474     public void setTolerance(int tolerance) {
475         this.tolerance = tolerance;
476     }
477 
478 
479     /***
480      * Gets the name of the base class for scripts.  It must be a subclass
481      * of Script.
482      */
483     public String getScriptBaseClass() {
484         return this.scriptBaseClass;
485     }
486 
487 
488     /***
489      * Sets the name of the base class for scripts.  It must be a subclass
490      * of Script.
491      */
492     public void setScriptBaseClass(String scriptBaseClass) {
493         this.scriptBaseClass = scriptBaseClass;
494     }
495 
496     /***
497      * Returns true if the new groovy (JSR) parser is enabled
498      */
499     public boolean isUseNewGroovy() {
500         return useNewGroovy;
501     }
502 
503     public void setUseNewGroovy(boolean useNewGroovy) {
504         this.useNewGroovy = useNewGroovy;
505     }
506 
507     public ParserPluginFactory getPluginFactory() {
508         if (pluginFactory == null) {
509             pluginFactory = ParserPluginFactory.newInstance(isUseNewGroovy());
510         }
511         return pluginFactory;
512     }
513 
514     public void setPluginFactory(ParserPluginFactory pluginFactory) {
515         this.pluginFactory = pluginFactory;
516     }
517 
518     /***
519      * Returns true if we are the JSR compatible Groovy language
520      */
521     public static boolean isJsrGroovy() {
522         return jsrGroovy;
523     }
524 
525     /***
526      * Should only be called by the JSR parser
527      */
528     public static void setJsrGroovy(boolean value) {
529         jsrGroovy = value;
530     }
531 
532     protected static boolean getDefaultJsrFlag() {
533         // TODO a temporary hack while we have 2 parsers
534         String property = null;
535         try {
536              property = System.getProperty("groovy.jsr");
537         }
538         catch (Throwable e) {
539             // ignore security warnings
540         }
541         if (property != null) {
542             return "true".equalsIgnoreCase(property);
543         }
544         return DEFAULT_JSR_FLAG;
545     }
546 
547 
548     public String getDefaultScriptExtension() {
549         return defaultScriptExtension;
550     }
551 
552 
553     public void setDefaultScriptExtension(String defaultScriptExtension) {
554         this.defaultScriptExtension = defaultScriptExtension;
555     }
556     
557     public void setRecompileGroovySource(boolean recompile) {
558         recompileGroovySource = recompile;
559     }
560     
561     public boolean getRecompileGroovySource(){
562         return recompileGroovySource;
563     }
564     
565     public void setMinimumRecompilationIntervall(int time) {
566         minimumRecompilationIntervall = Math.max(0,time);
567     }
568     
569     public int getMinimumRecompilationIntervall() {
570         return minimumRecompilationIntervall;
571     }
572 
573 }