View Javadoc

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