1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
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
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
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
211
212 text = configuration.getProperty("groovy.source.encoding");
213 if (text != null) {
214 setSourceEncoding(text);
215 }
216
217
218
219
220
221 text = configuration.getProperty("groovy.target.directory");
222 if (text != null) {
223 setTargetDirectory(text);
224 }
225
226
227
228
229
230 text = configuration.getProperty("groovy.classpath");
231 if (text != null) {
232 setClasspath(text);
233 }
234
235
236
237
238
239 text = configuration.getProperty("groovy.output.verbose");
240 if (text != null && text.equals("true")) {
241 setVerbose(true);
242 }
243
244
245
246
247
248 text = configuration.getProperty("groovy.output.debug");
249 if (text != null && text.equals("true")) {
250 setDebug(true);
251 }
252
253
254
255
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
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
515 String property = null;
516 try {
517 property = System.getProperty("groovy.jsr");
518 }
519 catch (Throwable e) {
520
521 }
522 if (property != null) {
523 return "true".equalsIgnoreCase(property);
524 }
525 return DEFAULT_JSR_FLAG;
526 }
527
528 }
529
530
531
532