KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > NetRexxC


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs.optional;
19
20 import java.io.BufferedReader JavaDoc;
21 import java.io.File JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.PrintWriter JavaDoc;
24 import java.io.StringReader JavaDoc;
25 import java.io.StringWriter JavaDoc;
26 import java.util.Enumeration JavaDoc;
27 import java.util.Hashtable JavaDoc;
28 import java.util.Properties JavaDoc;
29 import java.util.StringTokenizer JavaDoc;
30 import java.util.Vector JavaDoc;
31 import netrexx.lang.Rexx;
32 import org.apache.tools.ant.BuildException;
33 import org.apache.tools.ant.DirectoryScanner;
34 import org.apache.tools.ant.Project;
35 import org.apache.tools.ant.taskdefs.MatchingTask;
36 import org.apache.tools.ant.types.EnumeratedAttribute;
37 import org.apache.tools.ant.util.FileUtils;
38
39 /**
40  * Compiles NetRexx source files.
41  * This task can take the following
42  * arguments:
43  * <ul>
44  * <li>binary</li>
45  * <li>classpath</li>
46  * <li>comments</li>
47  * <li>compile</li>
48  * <li>console</li>
49  * <li>crossref</li>
50  * <li>decimal</li>
51  * <li>destdir</li>
52  * <li>diag</li>
53  * <li>explicit</li>
54  * <li>format</li>
55  * <li>keep</li>
56  * <li>logo</li>
57  * <li>replace</li>
58  * <li>savelog</li>
59  * <li>srcdir</li>
60  * <li>sourcedir</li>
61  * <li>strictargs</li>
62  * <li>strictassign</li>
63  * <li>strictcase</li>
64  * <li>strictimport</li>
65  * <li>symbols</li>
66  * <li>time</li>
67  * <li>trace</li>
68  * <li>utf8</li>
69  * <li>verbose</li>
70  * <li>suppressMethodArgumentNotUsed</li>
71  * <li>suppressPrivatePropertyNotUsed</li>
72  * <li>suppressVariableNotUsed</li>
73  * <li>suppressExceptionNotSignalled</li>
74  * <li>suppressDeprecation</li>
75  * </ul>
76  * Of these arguments, the <b>srcdir</b> argument is required.
77  *
78  * <p>When this task executes, it will recursively scan the srcdir
79  * looking for NetRexx source files to compile. This task makes its
80  * compile decision based on timestamp.
81  * <p>Before files are compiled they and any other file in the
82  * srcdir will be copied to the destdir allowing support files to be
83  * located properly in the classpath. The reason for copying the source files
84  * before the compile is that NetRexxC has only two destinations for classfiles:
85  * <ol>
86  * <li>The current directory, and,</li>
87  * <li>The directory the source is in (see sourcedir option)
88  * </ol>
89  *
90  */

91 public class NetRexxC extends MatchingTask {
92
93     // variables to hold arguments
94
private boolean binary;
95     private String JavaDoc classpath;
96     private boolean comments;
97     private boolean compact = true; // should be the default, as it integrates better in ant.
98
private boolean compile = true;
99     private boolean console;
100     private boolean crossref;
101     private boolean decimal = true;
102     private File JavaDoc destDir;
103     private boolean diag;
104     private boolean explicit;
105     private boolean format;
106     private boolean keep;
107     private boolean logo = true;
108     private boolean replace;
109     private boolean savelog;
110     private File JavaDoc srcDir;
111     private boolean sourcedir = true; // ?? Should this be the default for ant?
112
private boolean strictargs;
113     private boolean strictassign;
114     private boolean strictcase;
115     private boolean strictimport;
116     private boolean strictprops;
117     private boolean strictsignal;
118     private boolean symbols;
119     private boolean time;
120     private String JavaDoc trace = "trace2";
121     private boolean utf8;
122     private String JavaDoc verbose = "verbose3";
123     private boolean suppressMethodArgumentNotUsed = false;
124     private boolean suppressPrivatePropertyNotUsed = false;
125     private boolean suppressVariableNotUsed = false;
126     private boolean suppressExceptionNotSignalled = false;
127     private boolean suppressDeprecation = false;
128
129     // constants for the messages to suppress by flags and their corresponding properties
130
static final String JavaDoc MSG_METHOD_ARGUMENT_NOT_USED
131         = "Warning: Method argument is not used";
132     static final String JavaDoc MSG_PRIVATE_PROPERTY_NOT_USED
133         = "Warning: Private property is defined but not used";
134     static final String JavaDoc MSG_VARIABLE_NOT_USED
135         = "Warning: Variable is set but not used";
136     static final String JavaDoc MSG_EXCEPTION_NOT_SIGNALLED
137         = "is in SIGNALS list but is not signalled within the method";
138     static final String JavaDoc MSG_DEPRECATION = "has been deprecated";
139
140     // other implementation variables
141
private Vector JavaDoc compileList = new Vector JavaDoc();
142     private Hashtable JavaDoc filecopyList = new Hashtable JavaDoc();
143
144     /**
145      * Set whether literals are treated as binary, rather than NetRexx types.
146      * @param binary a <code>boolean</code> value.
147      */

148     public void setBinary(boolean binary) {
149         this.binary = binary;
150     }
151
152
153     /**
154      * Set the classpath used for NetRexx compilation.
155      * @param classpath the classpath to use.
156      */

157     public void setClasspath(String JavaDoc classpath) {
158         this.classpath = classpath;
159     }
160
161
162     /**
163      * Set whether comments are passed through to the generated java source.
164      * Valid true values are "on" or "true". Anything else sets the flag to
165      * false. The default value is false
166      * @param comments a <code>boolean</code> value.
167      */

168     public void setComments(boolean comments) {
169         this.comments = comments;
170     }
171
172
173     /**
174      * Set whether error messages come out in compact or verbose format. Valid
175      * true values are "on" or "true". Anything else sets the flag to false.
176      * The default value is false
177      * @param compact a <code>boolean</code> value.
178      */

179     public void setCompact(boolean compact) {
180         this.compact = compact;
181     }
182
183
184     /**
185      * Set whether the NetRexx compiler should compile the generated java code
186      * Valid true values are "on" or "true". Anything else sets the flag to
187      * false. The default value is true. Setting this flag to false, will
188      * automatically set the keep flag to true.
189      * @param compile a <code>boolean</code> value.
190      */

191     public void setCompile(boolean compile) {
192         this.compile = compile;
193         if (!this.compile && !this.keep) {
194             this.keep = true;
195         }
196     }
197
198
199     /**
200      * Set whether or not messages should be displayed on the 'console' Valid
201      * true values are "on" or "true". Anything else sets the flag to false.
202      * The default value is true.
203      * @param console a <code>boolean</code> value.
204      */

205     public void setConsole(boolean console) {
206         this.console = console;
207     }
208
209
210     /**
211      * Whether variable cross references are generated.
212      * @param crossref a <code>boolean</code> value.
213      */

214     public void setCrossref(boolean crossref) {
215         this.crossref = crossref;
216     }
217
218
219     /**
220      * Set whether decimal arithmetic should be used for the netrexx code.
221      * Binary arithmetic is used when this flag is turned off. Valid true
222      * values are "on" or "true". Anything else sets the flag to false. The
223      * default value is true.
224      * @param decimal a <code>boolean</code> value.
225      */

226     public void setDecimal(boolean decimal) {
227         this.decimal = decimal;
228     }
229
230
231     /**
232      * Set the destination directory into which the NetRexx source files
233      * should be copied and then compiled.
234      * @param destDirName the destination directory.
235      */

236     public void setDestDir(File JavaDoc destDirName) {
237         destDir = destDirName;
238     }
239
240
241     /**
242      * Whether diagnostic information about the compile is generated
243      * @param diag a <code>boolean</code> value.
244      */

245     public void setDiag(boolean diag) {
246         this.diag = diag;
247     }
248
249
250     /**
251      * Sets whether variables must be declared explicitly before use. Valid
252      * true values are "on" or "true". Anything else sets the flag to false.
253      * The default value is false.
254      * @param explicit a <code>boolean</code> value.
255      */

256     public void setExplicit(boolean explicit) {
257         this.explicit = explicit;
258     }
259
260
261     /**
262      * Whether the generated java code is formatted nicely or left to match
263      * NetRexx line numbers for call stack debugging.
264      * @param format a <code>boolean</code> value.
265      */

266     public void setFormat(boolean format) {
267         this.format = format;
268     }
269
270
271     /**
272      * Whether the generated java code is produced Valid true values are "on"
273      * or "true". Anything else sets the flag to false. The default value is
274      * false.
275      * @param java a <code>boolean</code> value.
276      */

277     public void setJava(boolean java) {
278         log("The attribute java is currently unused.", Project.MSG_WARN);
279     }
280
281
282     /**
283      * Sets whether the generated java source file should be kept after
284      * compilation. The generated files will have an extension of .java.keep,
285      * <b>not</b> .java Valid true values are "on" or "true". Anything else
286      * sets the flag to false. The default value is false.
287      * @param keep a <code>boolean</code> value.
288      */

289     public void setKeep(boolean keep) {
290         this.keep = keep;
291     }
292
293
294     /**
295      * Whether the compiler text logo is displayed when compiling.
296      * @param logo a <code>boolean</code> value.
297      */

298     public void setLogo(boolean logo) {
299         this.logo = logo;
300     }
301
302
303     /**
304      * Whether the generated .java file should be replaced when compiling
305      * Valid true values are "on" or "true". Anything else sets the flag to
306      * false. The default value is false.
307      * @param replace a <code>boolean</code> value.
308      */

309     public void setReplace(boolean replace) {
310         this.replace = replace;
311     }
312
313
314     /**
315      * Sets whether the compiler messages will be written to NetRexxC.log as
316      * well as to the console Valid true values are "on" or "true". Anything
317      * else sets the flag to false. The default value is false.
318      * @param savelog a <code>boolean</code> value.
319      */

320     public void setSavelog(boolean savelog) {
321         this.savelog = savelog;
322     }
323
324
325     /**
326      * Tells the NetRexx compiler to store the class files in the same
327      * directory as the source files. The alternative is the working directory
328      * Valid true values are "on" or "true". Anything else sets the flag to
329      * false. The default value is true.
330      * @param sourcedir a <code>boolean</code> value.
331      */

332     public void setSourcedir(boolean sourcedir) {
333         this.sourcedir = sourcedir;
334     }
335
336
337     /**
338      * Set the source dir to find the source Java files.
339      * @param srcDirName the source directory.
340      */

341     public void setSrcDir(File JavaDoc srcDirName) {
342         srcDir = srcDirName;
343     }
344
345
346     /**
347      * Tells the NetRexx compiler that method calls always need parentheses,
348      * even if no arguments are needed, e.g. <code>aStringVar.getBytes</code>
349      * vs. <code>aStringVar.getBytes()</code> Valid true values are "on" or
350      * "true". Anything else sets the flag to false. The default value is
351      * false.
352      * @param strictargs a <code>boolean</code> value.
353      */

354     public void setStrictargs(boolean strictargs) {
355         this.strictargs = strictargs;
356     }
357
358
359     /**
360      * Tells the NetRexx compile that assignments must match exactly on type.
361      * @param strictassign a <code>boolean</code> value.
362      */

363     public void setStrictassign(boolean strictassign) {
364         this.strictassign = strictassign;
365     }
366
367
368     /**
369      * Specifies whether the NetRexx compiler should be case sensitive or not.
370      * @param strictcase a <code>boolean</code> value.
371      */

372     public void setStrictcase(boolean strictcase) {
373         this.strictcase = strictcase;
374     }
375
376
377     /**
378      * Sets whether classes need to be imported explicitly using an <code>import</code>
379      * statement. By default the NetRexx compiler will import certain packages
380      * automatically Valid true values are "on" or "true". Anything else sets
381      * the flag to false. The default value is false.
382      * @param strictimport a <code>boolean</code> value.
383      */

384     public void setStrictimport(boolean strictimport) {
385         this.strictimport = strictimport;
386     }
387
388
389     /**
390      * Sets whether local properties need to be qualified explicitly using
391      * <code>this</code> Valid true values are "on" or "true". Anything else
392      * sets the flag to false. The default value is false.
393      * @param strictprops a <code>boolean</code> value.
394      */

395     public void setStrictprops(boolean strictprops) {
396         this.strictprops = strictprops;
397     }
398
399
400     /**
401      * Whether the compiler should force catching of exceptions by explicitly
402      * named types.
403      * @param strictsignal a <code>boolean</code> value.
404      */

405     public void setStrictsignal(boolean strictsignal) {
406         this.strictsignal = strictsignal;
407     }
408
409
410     /**
411      * Sets whether debug symbols should be generated into the class file
412      * Valid true values are "on" or "true". Anything else sets the flag to
413      * false. The default value is false.
414      * @param symbols a <code>boolean</code> value.
415      */

416     public void setSymbols(boolean symbols) {
417         this.symbols = symbols;
418     }
419
420
421     /**
422      * Asks the NetRexx compiler to print compilation times to the console
423      * Valid true values are "on" or "true". Anything else sets the flag to
424      * false. The default value is false.
425      * @param time a <code>boolean</code> value.
426      */

427     public void setTime(boolean time) {
428         this.time = time;
429     }
430
431     /**
432      * Turns on or off tracing and directs the resultant trace output Valid
433      * values are: "trace", "trace1", "trace2" and "notrace". "trace" and
434      * "trace2".
435      * @param trace the value to set.
436      */

437     public void setTrace(TraceAttr trace) {
438         this.trace = trace.getValue();
439     }
440
441     /**
442      * Turns on or off tracing and directs the resultant trace output Valid
443      * values are: "trace", "trace1", "trace2" and "notrace". "trace" and
444      * "trace2".
445      * @param trace the value to set.
446      */

447     public void setTrace(String JavaDoc trace) {
448         TraceAttr t = new TraceAttr();
449
450         t.setValue(trace);
451         setTrace(t);
452     }
453
454
455     /**
456      * Tells the NetRexx compiler that the source is in UTF8 Valid true values
457      * are "on" or "true". Anything else sets the flag to false. The default
458      * value is false.
459      * @param utf8 a <code>boolean</code> value.
460      */

461     public void setUtf8(boolean utf8) {
462         this.utf8 = utf8;
463     }
464
465
466     /**
467      * Whether lots of warnings and error messages should be generated
468      * @param verbose the value to set - verbose&lt;level&gt; or noverbose.
469      */

470     public void setVerbose(VerboseAttr verbose) {
471         this.verbose = verbose.getValue();
472     }
473
474
475     /**
476      * Whether lots of warnings and error messages should be generated
477      * @param verbose the value to set - verbose&lt;level&gt; or noverbose.
478      */

479     public void setVerbose(String JavaDoc verbose) {
480         VerboseAttr v = new VerboseAttr();
481
482         v.setValue(verbose);
483         setVerbose(v);
484     }
485
486     /**
487      * Whether the task should suppress the "Method argument is not used" in
488      * strictargs-Mode, which can not be suppressed by the compiler itself.
489      * The warning is logged as verbose message, though.
490      * @param suppressMethodArgumentNotUsed a <code>boolean</code> value.
491      */

492     public void setSuppressMethodArgumentNotUsed(boolean suppressMethodArgumentNotUsed) {
493         this.suppressMethodArgumentNotUsed = suppressMethodArgumentNotUsed;
494     }
495
496
497     /**
498      * Whether the task should suppress the "Private property is defined but
499      * not used" in strictargs-Mode, which can be quite annoying while
500      * developing. The warning is logged as verbose message, though.
501      * @param suppressPrivatePropertyNotUsed a <code>boolean</code> value.
502      */

503     public void setSuppressPrivatePropertyNotUsed(boolean suppressPrivatePropertyNotUsed) {
504         this.suppressPrivatePropertyNotUsed = suppressPrivatePropertyNotUsed;
505     }
506
507
508     /**
509      * Whether the task should suppress the "Variable is set but not used" in
510      * strictargs-Mode. Be careful with this one! The warning is logged as
511      * verbose message, though.
512      * @param suppressVariableNotUsed a <code>boolean</code> value.
513      */

514     public void setSuppressVariableNotUsed(boolean suppressVariableNotUsed) {
515         this.suppressVariableNotUsed = suppressVariableNotUsed;
516     }
517
518
519     /**
520      * Whether the task should suppress the "FooException is in SIGNALS list
521      * but is not signalled within the method", which is sometimes rather
522      * useless. The warning is logged as verbose message, though.
523      * @param suppressExceptionNotSignalled a <code>boolean</code> value.
524      */

525     public void setSuppressExceptionNotSignalled(boolean suppressExceptionNotSignalled) {
526         this.suppressExceptionNotSignalled = suppressExceptionNotSignalled;
527     }
528
529
530     /**
531      * Tells whether we should filter out any deprecation-messages
532      * of the compiler out.
533      * @param suppressDeprecation a <code>boolean</code> value.
534      */

535     public void setSuppressDeprecation(boolean suppressDeprecation) {
536         this.suppressDeprecation = suppressDeprecation;
537     }
538
539
540     /**
541      * init-Method sets defaults from Properties. That way, when ant is called
542      * with arguments like -Dant.netrexxc.verbose=verbose5 one can easily take
543      * control of all netrexxc-tasks.
544      */

545     public void init() {
546         String JavaDoc p;
547
548         if ((p = getProject().getProperty("ant.netrexxc.binary")) != null) {
549             this.binary = Project.toBoolean(p);
550         }
551         // classpath makes no sense
552
if ((p = getProject().getProperty("ant.netrexxc.comments")) != null) {
553             this.comments = Project.toBoolean(p);
554         }
555         if ((p = getProject().getProperty("ant.netrexxc.compact")) != null) {
556             this.compact = Project.toBoolean(p);
557         }
558         if ((p = getProject().getProperty("ant.netrexxc.compile")) != null) {
559             this.compile = Project.toBoolean(p);
560         }
561         if ((p = getProject().getProperty("ant.netrexxc.console")) != null) {
562             this.console = Project.toBoolean(p);
563         }
564         if ((p = getProject().getProperty("ant.netrexxc.crossref")) != null) {
565             this.crossref = Project.toBoolean(p);
566         }
567         if ((p = getProject().getProperty("ant.netrexxc.decimal")) != null) {
568             this.decimal = Project.toBoolean(p);
569             // destDir
570
}
571         if ((p = getProject().getProperty("ant.netrexxc.diag")) != null) {
572             this.diag = Project.toBoolean(p);
573         }
574         if ((p = getProject().getProperty("ant.netrexxc.explicit")) != null) {
575             this.explicit = Project.toBoolean(p);
576         }
577         if ((p = getProject().getProperty("ant.netrexxc.format")) != null) {
578             this.format = Project.toBoolean(p);
579         }
580         if ((p = getProject().getProperty("ant.netrexxc.keep")) != null) {
581             this.keep = Project.toBoolean(p);
582         }
583         if ((p = getProject().getProperty("ant.netrexxc.logo")) != null) {
584             this.logo = Project.toBoolean(p);
585         }
586         if ((p = getProject().getProperty("ant.netrexxc.replace")) != null) {
587             this.replace = Project.toBoolean(p);
588         }
589         if ((p = getProject().getProperty("ant.netrexxc.savelog")) != null) {
590             this.savelog = Project.toBoolean(p);
591             // srcDir
592
}
593         if ((p = getProject().getProperty("ant.netrexxc.sourcedir")) != null) {
594             this.sourcedir = Project.toBoolean(p);
595         }
596         if ((p = getProject().getProperty("ant.netrexxc.strictargs")) != null) {
597             this.strictargs = Project.toBoolean(p);
598         }
599         if ((p = getProject().getProperty("ant.netrexxc.strictassign")) != null) {
600             this.strictassign = Project.toBoolean(p);
601         }
602         if ((p = getProject().getProperty("ant.netrexxc.strictcase")) != null) {
603             this.strictcase = Project.toBoolean(p);
604         }
605         if ((p = getProject().getProperty("ant.netrexxc.strictimport")) != null) {
606             this.strictimport = Project.toBoolean(p);
607         }
608         if ((p = getProject().getProperty("ant.netrexxc.strictprops")) != null) {
609             this.strictprops = Project.toBoolean(p);
610         }
611         if ((p = getProject().getProperty("ant.netrexxc.strictsignal")) != null) {
612             this.strictsignal = Project.toBoolean(p);
613         }
614         if ((p = getProject().getProperty("ant.netrexxc.symbols")) != null) {
615             this.symbols = Project.toBoolean(p);
616         }
617         if ((p = getProject().getProperty("ant.netrexxc.time")) != null) {
618             this.time = Project.toBoolean(p);
619         }
620         if ((p = getProject().getProperty("ant.netrexxc.trace")) != null) {
621             setTrace(p);
622         }
623         if ((p = getProject().getProperty("ant.netrexxc.utf8")) != null) {
624             this.utf8 = Project.toBoolean(p);
625         }
626         if ((p = getProject().getProperty("ant.netrexxc.verbose")) != null) {
627             setVerbose(p);
628         }
629         if ((p = getProject().getProperty("ant.netrexxc.suppressMethodArgumentNotUsed")) != null) {
630             this.suppressMethodArgumentNotUsed = Project.toBoolean(p);
631         }
632         if ((p = getProject().getProperty("ant.netrexxc.suppressPrivatePropertyNotUsed")) != null) {
633             this.suppressPrivatePropertyNotUsed = Project.toBoolean(p);
634         }
635         if ((p = getProject().getProperty("ant.netrexxc.suppressVariableNotUsed")) != null) {
636             this.suppressVariableNotUsed = Project.toBoolean(p);
637         }
638         if ((p = getProject().getProperty("ant.netrexxc.suppressExceptionNotSignalled")) != null) {
639             this.suppressExceptionNotSignalled = Project.toBoolean(p);
640         }
641         if ((p = getProject().getProperty("ant.netrexxc.suppressDeprecation")) != null) {
642             this.suppressDeprecation = Project.toBoolean(p);
643         }
644     }
645
646
647     /**
648      * Executes the task - performs the actual compiler call.
649      * @throws BuildException on error.
650      */

651     public void execute() throws BuildException {
652
653         // first off, make sure that we've got a srcdir and destdir
654
if (srcDir == null || destDir == null) {
655             throw new BuildException("srcDir and destDir attributes must be set!");
656         }
657
658         // scan source and dest dirs to build up both copy lists and
659
// compile lists
660
// scanDir(srcDir, destDir);
661
DirectoryScanner ds = getDirectoryScanner(srcDir);
662
663         String JavaDoc[] files = ds.getIncludedFiles();
664
665         scanDir(srcDir, destDir, files);
666
667         // copy the source and support files
668
copyFilesToDestination();
669
670         // compile the source files
671
if (compileList.size() > 0) {
672             log("Compiling " + compileList.size() + " source file"
673                  + (compileList.size() == 1 ? "" : "s")
674                  + " to " + destDir);
675             doNetRexxCompile();
676         }
677     }
678
679
680     /**
681      * Scans the directory looking for source files to be compiled and support
682      * files to be copied.
683      */

684     private void scanDir(File JavaDoc srcDir, File JavaDoc destDir, String JavaDoc[] files) {
685         for (int i = 0; i < files.length; i++) {
686             File JavaDoc srcFile = new File JavaDoc(srcDir, files[i]);
687             File JavaDoc destFile = new File JavaDoc(destDir, files[i]);
688             String JavaDoc filename = files[i];
689             // if it's a non source file, copy it if a later date than the
690
// dest
691
// if it's a source file, see if the destination class file
692
// needs to be recreated via compilation
693
if (filename.toLowerCase().endsWith(".nrx")) {
694                 File JavaDoc classFile =
695                     new File JavaDoc(destDir,
696                     filename.substring(0, filename.lastIndexOf('.')) + ".class");
697
698                 if (!compile || srcFile.lastModified() > classFile.lastModified()) {
699                     filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
700                     compileList.addElement(destFile.getAbsolutePath());
701                 }
702             } else {
703                 if (srcFile.lastModified() > destFile.lastModified()) {
704                     filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
705                 }
706             }
707         }
708     }
709
710
711     /** Copy eligible files from the srcDir to destDir */
712     private void copyFilesToDestination() {
713         if (filecopyList.size() > 0) {
714             log("Copying " + filecopyList.size() + " file"
715                  + (filecopyList.size() == 1 ? "" : "s")
716                  + " to " + destDir.getAbsolutePath());
717
718             Enumeration JavaDoc e = filecopyList.keys();
719
720             while (e.hasMoreElements()) {
721                 String JavaDoc fromFile = (String JavaDoc) e.nextElement();
722                 String JavaDoc toFile = (String JavaDoc) filecopyList.get(fromFile);
723
724                 try {
725                     FileUtils.getFileUtils().copyFile(fromFile, toFile);
726                 } catch (IOException JavaDoc ioe) {
727                     String JavaDoc msg = "Failed to copy " + fromFile + " to " + toFile
728                          + " due to " + ioe.getMessage();
729
730                     throw new BuildException(msg, ioe);
731                 }
732             }
733         }
734     }
735
736
737     /** Performs a compile using the NetRexx 1.1.x compiler */
738     private void doNetRexxCompile() throws BuildException {
739         log("Using NetRexx compiler", Project.MSG_VERBOSE);
740
741         String JavaDoc classpath = getCompileClasspath();
742         StringBuffer JavaDoc compileOptions = new StringBuffer JavaDoc();
743
744         // create an array of strings for input to the compiler: one array
745
// comes from the compile options, the other from the compileList
746
String JavaDoc[] compileOptionsArray = getCompileOptionsAsArray();
747         String JavaDoc[] fileListArray = new String JavaDoc[compileList.size()];
748         Enumeration JavaDoc e = compileList.elements();
749         int j = 0;
750
751         while (e.hasMoreElements()) {
752             fileListArray[j] = (String JavaDoc) e.nextElement();
753             j++;
754         }
755         // create a single array of arguments for the compiler
756
String JavaDoc[] compileArgs = new String JavaDoc[compileOptionsArray.length + fileListArray.length];
757
758         for (int i = 0; i < compileOptionsArray.length; i++) {
759             compileArgs[i] = compileOptionsArray[i];
760         }
761         for (int i = 0; i < fileListArray.length; i++) {
762             compileArgs[i + compileOptionsArray.length] = fileListArray[i];
763         }
764
765         // print nice output about what we are doing for the log
766
compileOptions.append("Compilation args: ");
767         for (int i = 0; i < compileOptionsArray.length; i++) {
768             compileOptions.append(compileOptionsArray[i]);
769             compileOptions.append(" ");
770         }
771         log(compileOptions.toString(), Project.MSG_VERBOSE);
772
773         String JavaDoc eol = System.getProperty("line.separator");
774         StringBuffer JavaDoc niceSourceList = new StringBuffer JavaDoc("Files to be compiled:" + eol);
775
776         for (int i = 0; i < compileList.size(); i++) {
777             niceSourceList.append(" ");
778             niceSourceList.append(compileList.elementAt(i).toString());
779             niceSourceList.append(eol);
780         }
781
782         log(niceSourceList.toString(), Project.MSG_VERBOSE);
783
784         // need to set java.class.path property and restore it later
785
// since the NetRexx compiler has no option for the classpath
786
String JavaDoc currentClassPath = System.getProperty("java.class.path");
787         Properties JavaDoc currentProperties = System.getProperties();
788
789         currentProperties.put("java.class.path", classpath);
790
791         try {
792             StringWriter JavaDoc out = new StringWriter JavaDoc();
793             int rc =
794                 COM.ibm.netrexx.process.NetRexxC.main(new Rexx(compileArgs), new PrintWriter JavaDoc(out));
795             String JavaDoc sdir = srcDir.getAbsolutePath();
796             String JavaDoc ddir = destDir.getAbsolutePath();
797             boolean doReplace = !(sdir.equals(ddir));
798             int dlen = ddir.length();
799             String JavaDoc l;
800             BufferedReader JavaDoc in = new BufferedReader JavaDoc(new StringReader JavaDoc(out.toString()));
801
802             log("replacing destdir '" + ddir + "' through sourcedir '"
803                 + sdir + "'", Project.MSG_VERBOSE);
804             while ((l = in.readLine()) != null) {
805                 int idx;
806
807                 while (doReplace && ((idx = l.indexOf(ddir)) != -1)) {
808                     // path is mentioned in the message
809
l = (new StringBuffer JavaDoc(l)).replace(idx, idx + dlen, sdir).toString();
810                 }
811                 // verbose level logging for suppressed messages
812
if (suppressMethodArgumentNotUsed
813                     && l.indexOf(MSG_METHOD_ARGUMENT_NOT_USED) != -1) {
814                     log(l, Project.MSG_VERBOSE);
815                 } else if (suppressPrivatePropertyNotUsed
816                     && l.indexOf(MSG_PRIVATE_PROPERTY_NOT_USED) != -1) {
817                     log(l, Project.MSG_VERBOSE);
818                 } else if (suppressVariableNotUsed
819                     && l.indexOf(MSG_VARIABLE_NOT_USED) != -1) {
820                     log(l, Project.MSG_VERBOSE);
821                 } else if (suppressExceptionNotSignalled
822                     && l.indexOf(MSG_EXCEPTION_NOT_SIGNALLED) != -1) {
823                     log(l, Project.MSG_VERBOSE);
824                 } else if (suppressDeprecation
825                     && l.indexOf(MSG_DEPRECATION) != -1) {
826                     log(l, Project.MSG_VERBOSE);
827                 } else if (l.indexOf("Error:") != -1) {
828                     // error level logging for compiler errors
829
log(l, Project.MSG_ERR);
830                 } else if (l.indexOf("Warning:") != -1) {
831                     // warning for all warning messages
832
log(l, Project.MSG_WARN);
833                 } else {
834                     log(l, Project.MSG_INFO); // info level for the rest.
835
}
836             }
837             if (rc > 1) {
838                 throw new BuildException("Compile failed, messages should "
839                     + "have been provided.");
840             }
841         } catch (IOException JavaDoc ioe) {
842             throw new BuildException("Unexpected IOException while "
843                 + "playing with Strings", ioe);
844         } finally {
845             // need to reset java.class.path property
846
// since the NetRexx compiler has no option for the classpath
847
currentProperties = System.getProperties();
848             currentProperties.put("java.class.path", currentClassPath);
849         }
850
851     }
852
853
854     /** Builds the compilation classpath. */
855     private String JavaDoc getCompileClasspath() {
856         StringBuffer JavaDoc classpath = new StringBuffer JavaDoc();
857
858         // add dest dir to classpath so that previously compiled and
859
// untouched classes are on classpath
860
classpath.append(destDir.getAbsolutePath());
861
862         // add our classpath to the mix
863
if (this.classpath != null) {
864             addExistingToClasspath(classpath, this.classpath);
865         }
866
867         // add the system classpath
868
// addExistingToClasspath(classpath,System.getProperty("java.class.path"));
869
return classpath.toString();
870     }
871
872
873     /** This */
874     private String JavaDoc[] getCompileOptionsAsArray() {
875         Vector JavaDoc options = new Vector JavaDoc();
876
877         options.addElement(binary ? "-binary" : "-nobinary");
878         options.addElement(comments ? "-comments" : "-nocomments");
879         options.addElement(compile ? "-compile" : "-nocompile");
880         options.addElement(compact ? "-compact" : "-nocompact");
881         options.addElement(console ? "-console" : "-noconsole");
882         options.addElement(crossref ? "-crossref" : "-nocrossref");
883         options.addElement(decimal ? "-decimal" : "-nodecimal");
884         options.addElement(diag ? "-diag" : "-nodiag");
885         options.addElement(explicit ? "-explicit" : "-noexplicit");
886         options.addElement(format ? "-format" : "-noformat");
887         options.addElement(keep ? "-keep" : "-nokeep");
888         options.addElement(logo ? "-logo" : "-nologo");
889         options.addElement(replace ? "-replace" : "-noreplace");
890         options.addElement(savelog ? "-savelog" : "-nosavelog");
891         options.addElement(sourcedir ? "-sourcedir" : "-nosourcedir");
892         options.addElement(strictargs ? "-strictargs" : "-nostrictargs");
893         options.addElement(strictassign ? "-strictassign" : "-nostrictassign");
894         options.addElement(strictcase ? "-strictcase" : "-nostrictcase");
895         options.addElement(strictimport ? "-strictimport" : "-nostrictimport");
896         options.addElement(strictprops ? "-strictprops" : "-nostrictprops");
897         options.addElement(strictsignal ? "-strictsignal" : "-nostrictsignal");
898         options.addElement(symbols ? "-symbols" : "-nosymbols");
899         options.addElement(time ? "-time" : "-notime");
900         options.addElement("-" + trace);
901         options.addElement(utf8 ? "-utf8" : "-noutf8");
902         options.addElement("-" + verbose);
903
904         String JavaDoc[] results = new String JavaDoc[options.size()];
905
906         options.copyInto(results);
907         return results;
908     }
909
910
911     /**
912      * Takes a classpath-like string, and adds each element of this string to
913      * a new classpath, if the components exist. Components that don't exist,
914      * aren't added. We do this, because jikes issues warnings for
915      * non-existant files/dirs in his classpath, and these warnings are pretty
916      * annoying.
917      *
918      * @param target - target classpath
919      * @param source - source classpath to get file objects.
920      */

921     private void addExistingToClasspath(StringBuffer JavaDoc target, String JavaDoc source) {
922         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(source,
923             System.getProperty("path.separator"), false);
924
925         while (tok.hasMoreTokens()) {
926             File JavaDoc f = getProject().resolveFile(tok.nextToken());
927
928             if (f.exists()) {
929                 target.append(File.pathSeparator);
930                 target.append(f.getAbsolutePath());
931             } else {
932                 log("Dropping from classpath: "
933                     + f.getAbsolutePath(), Project.MSG_VERBOSE);
934             }
935         }
936
937     }
938
939
940     /**
941      * Enumerated class corresponding to the trace attribute.
942      */

943     public static class TraceAttr extends EnumeratedAttribute {
944         /** {@inheritDoc}. */
945         public String JavaDoc[] getValues() {
946             return new String JavaDoc[]{"trace", "trace1", "trace2", "notrace"};
947         }
948     }
949
950     /**
951      * Enumerated class corresponding to the verbose attribute.
952      */

953     public static class VerboseAttr extends EnumeratedAttribute {
954         /** {@inheritDoc}. */
955         public String JavaDoc[] getValues() {
956             return new String JavaDoc[]{"verbose", "verbose0", "verbose1",
957                 "verbose2", "verbose3", "verbose4",
958                 "verbose5", "noverbose"};
959         }
960     }
961 }
962
963
Popular Tags