KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > PolyglotAntTask


1 import java.io.File JavaDoc;
2 import java.util.*;
3
4 import org.apache.tools.ant.BuildException;
5 import org.apache.tools.ant.DirectoryScanner;
6 import org.apache.tools.ant.Project;
7 import org.apache.tools.ant.taskdefs.MatchingTask;
8 import org.apache.tools.ant.types.Commandline;
9 import org.apache.tools.ant.types.Path;
10 import org.apache.tools.ant.types.Reference;
11 import org.apache.tools.ant.util.GlobPatternMapper;
12 import org.apache.tools.ant.util.SourceFileScanner;
13
14 import polyglot.main.Main.TerminationException;
15
16 /**
17  * An ANT <code>Task</code> to facilitate the building of
18  * of code written in language extensions within the ANT framework. This task
19  * can be used similarly way to the <code>JavaC</code> task.
20  *
21  * <p> This class can
22  * optionally be subclassed by extensions (to provide compilation for
23  * a particular language). In that case, subclasses should override the
24  * init method to set the source file extension
25  * ({@link PolyglotAntTask#srcExt srcExt}) and extension name
26  * or class ({@link PolyglotAntTask#extensionName extensionName} or
27  * {@link PolyglotAntTask#extensionClass extensionClass}) appropriately, and
28  * override the setter methods for these fields to prevent the user from modifying
29  * these fields.
30  *
31  * <b>This class has not been fully tested.</b>
32  *
33  * @see org.apache.tools.ant.Task
34  */

35 public class PolyglotAntTask extends MatchingTask {
36     /**
37      * Name of the extension, like the <code>-ext</code> command line option.
38      */

39     protected String JavaDoc extensionName;
40     /**
41      * Class of the extension, like the <code>-extclass</code> command line
42      * option.
43      */

44     protected Class JavaDoc extensionClass;
45     /**
46      * Destination directory, like the <code>-d</code> command line option.
47      */

48     protected File JavaDoc destDir;
49     /**
50      * The path for source compilation.
51      */

52     protected Path src;
53     
54     /**
55      * Bootclasspath, like the <code>-bootclasspath</code> command line option.
56      */

57     protected Path bootclasspath;
58     /**
59      * The file extension for sourcefiles, like the <code>-sx</code>
60      * command line option.
61      */

62     protected String JavaDoc srcExt;
63     /**
64      * The file extensions for output files, like the <code>-ox</code>
65      * command line option.
66      */

67     protected String JavaDoc outputExt;
68     /**
69      * A file containing additional command line options to parse, like
70      * the <code>@&lt;file$gt;</code> command line option.
71      */

72     protected File JavaDoc optionsFile;
73     
74     /**
75      * The post compiler to invoke, like the <code>-post</code>
76      * command line option.
77      */

78     protected String JavaDoc post;
79     /**
80      * Indiciates if the Polyglot compiler should produce serialized type
81      * information in the output files, like the <code>-noserial</code>
82      * command line option.
83      */

84     protected boolean noSerial;
85     /**
86      * Indiciates if the Polyglot compiler should delete the output files
87      * after compilation, like the <code>-nooutput</code> command line option.
88      */

89     protected boolean noOutput;
90     /**
91      * Indiciates if the Polyglot compiler should use fully qualified
92      * class names, like the <code>-fqcn</code>
93      * command line option.
94      */

95     protected boolean fqcn;
96     /**
97      * Indiciates if the Polyglot compiler should use only compile to the
98      * output files, like the <code>-c</code>
99      * command line option.
100      */

101     protected boolean onlyToJava;
102     
103     /**
104      * A <code>List</code> of {@link org.apache.tools.ant.types.Commandline.Arguments
105      * Commandline.Arguments}, to allow the user to specify command line
106      * options that we do not deal with explicitly.
107      */

108     protected List additionalArgs;
109     
110     /**
111      * The classpath to be used for compilation, like the <code>-classpath</code>
112      * command line option.
113      */

114     protected Path compileClasspath;
115     /**
116      * The path for finding source files, like the <code>-sourcepath</code>
117      * command line option.
118      */

119     protected Path compileSourcepath;
120
121     public PolyglotAntTask() { }
122     
123     public void init() {
124         super.init();
125         extensionName = null;
126         extensionClass = null;
127         destDir = null;
128         src = null;
129         bootclasspath = null;
130         srcExt = "java";
131         outputExt = "java";
132         optionsFile = null;
133         post = null;
134         noSerial = false;
135         noOutput = false;
136         fqcn = false;
137         onlyToJava = false;
138         additionalArgs = null;
139         compileClasspath = null;
140         compileSourcepath = null;
141     }
142     
143     public void execute() throws BuildException {
144         dumpDetails();
145         checkParameters();
146         // scan source directories and dest directory to build up
147
File JavaDoc[] compileFiles = getCompileFiles();
148         
149         if (compileFiles.length == 0) {
150             // nothing to do. no files to compile
151
log("No files to compile",
152                 Project.MSG_INFO);
153             return;
154         }
155         
156         // build up the argument list
157
String JavaDoc[] args = constructArgList(compileFiles);
158         
159         log("Invoking polyglot with the following arguments: " +
160             "(enclosing single quotes are not part of the arguments):",
161             Project.MSG_VERBOSE);
162         for (int i = 0; i < args.length; i++) {
163             log(" '" + args[i] + "'", Project.MSG_VERBOSE);
164         }
165         // invoke the polyglot compiler.
166
compile(args);
167     }
168     
169     protected File JavaDoc[] getCompileFiles() {
170         File JavaDoc[] compileFiles = new File JavaDoc[0];
171         String JavaDoc[] srcList = src.list();
172         for (int i = 0; i < srcList.length; i++) {
173             File JavaDoc srcDir = getProject().resolveFile(srcList[i]);
174             if (!srcDir.exists()) {
175                 throw new BuildException("srcdir \""
176                                          + srcDir.getPath()
177                                          + "\" does not exist!", getLocation());
178             }
179
180             DirectoryScanner ds = this.getDirectoryScanner(srcDir);
181             String JavaDoc[] files = ds.getIncludedFiles();
182
183             compileFiles = scanDir(compileFiles, srcDir, destDir != null ? destDir : srcDir, files);
184         }
185         return compileFiles;
186     }
187     
188     /**
189      * Scans the directory looking for source files to be compiled.
190      * The results are returned in the class variable compileList
191      */

192     protected File JavaDoc[] scanDir(File JavaDoc[] compileFiles, File JavaDoc srcDir, File JavaDoc destDir, String JavaDoc[] files) {
193         GlobPatternMapper m = new GlobPatternMapper();
194         m.setFrom("*." + srcExt);
195         m.setTo("*." + destFileExt());
196         SourceFileScanner sfs = new SourceFileScanner(this);
197         File JavaDoc[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
198
199         if (newFiles.length > 0) {
200             File JavaDoc[] newCompileList = new File JavaDoc[compileFiles.length +
201                 newFiles.length];
202             System.arraycopy(compileFiles, 0, newCompileList, 0,
203                 compileFiles.length);
204             System.arraycopy(newFiles, 0, newCompileList,
205                 compileFiles.length, newFiles.length);
206             compileFiles = newCompileList;
207         }
208         return compileFiles;
209     }
210
211     /**
212      * The file extension of the destination files. Used by the global pattern
213      * matcher to determine which files need to be compiled.
214      */

215     protected String JavaDoc destFileExt() {
216         return onlyToJava ? outputExt : "class";
217     }
218     
219     /**
220      * Check to make sure the paramters are consistent with invoking the
221      * Polyglot compiler.
222      * @throws BuildException if the parameters are inconsistent.
223      */

224     protected void checkParameters() throws BuildException {
225         // at most one of extenstionClass and extensionName is set.
226
if (extensionClass != null && extensionName != null) {
227             throw new BuildException("At most one of extclass and " +
228                                      "extname can be set.", getLocation());
229         }
230         
231         if (src == null) {
232             throw new BuildException("srcdir attribute must be set!",
233                                      getLocation());
234         }
235         if (src.size() == 0) {
236             throw new BuildException("srcdir attribute must be set!",
237                                      getLocation());
238         }
239
240         if (destDir != null && !destDir.isDirectory()) {
241             throw new BuildException("destination directory \""
242                                      + destDir
243                                      + "\" does not exist "
244                                      + "or is not a directory", getLocation());
245         }
246     }
247
248     /**
249      * Construct the argument list that will be given to the Polyglot
250      * compiler.
251      * @param files the files to compile
252      */

253     protected String JavaDoc[] constructArgList(File JavaDoc[] files) {
254         List argList = new ArrayList();
255         
256         // set up command line args
257
if (optionsFile != null) {
258             argList.add("@" + optionsFile.getPath());
259         }
260         if (extensionName != null) {
261             argList.add("-ext");
262             argList.add(extensionName);
263         }
264         if (extensionClass != null) {
265             argList.add("-extclass");
266             argList.add(extensionClass.getName());
267         }
268         if (noSerial) {
269             argList.add("-noserial");
270         }
271         if (noOutput) {
272             argList.add("-nooutput");
273         }
274         if (fqcn) {
275             argList.add("-fqcn");
276         }
277         if (onlyToJava) {
278             argList.add("-c");
279         }
280         if (post != null) {
281             argList.add("-post");
282             argList.add(post);
283         }
284         if (srcExt != null) {
285             argList.add("-sx");
286             argList.add(srcExt);
287         }
288         if (outputExt != null) {
289             argList.add("-ox");
290             argList.add(outputExt);
291         }
292         if (destDir != null) {
293             argList.add("-d");
294             argList.add(destDir.getPath());
295         }
296         if (compileSourcepath != null) {
297             argList.add("-sourcepath");
298             argList.add(compileSourcepath.toString());
299         }
300         else if (src != null) {
301             argList.add("-sourcepath");
302             argList.add(src.toString());
303         }
304         if (bootclasspath != null) {
305             argList.add("-bootclasspath");
306             argList.add(bootclasspath.toString());
307         }
308         if (compileClasspath != null) {
309             argList.add("-classpath");
310             argList.add(compileClasspath.toString());
311         }
312         if (additionalArgs != null) {
313             for (Iterator i = additionalArgs.iterator(); i.hasNext(); ) {
314                 Commandline.Argument arg = (Commandline.Argument)i.next();
315                 String JavaDoc[] parts = arg.getParts();
316                 for (int j = 0; j < parts.length; j++) {
317                     argList.add(parts[j]);
318                 }
319             }
320         }
321         
322         // add the files to compile.
323
int argListSize = argList.size();
324         String JavaDoc[] args = new String JavaDoc[argListSize + files.length];
325         argList.toArray(args);
326         
327         for (int i = 0; i < files.length; ++i) {
328             args[argListSize + i] = files[i].getPath();
329         }
330         
331         return args;
332     }
333     
334     /**
335      * Invoke the Polyglot compiler, with the given command line arguments.
336      */

337     protected void compile(String JavaDoc[] args) {
338         try {
339             new polyglot.main.Main().start(args);
340         }
341         catch (TerminationException e) {
342             throw new BuildException(e.getMessage(), e);
343         }
344     }
345      
346     /**
347      * Dump the settings of the parameters, for debugging purposes.
348      */

349     protected void dumpDetails() {
350         log("extensionName = " + extensionName, Project.MSG_DEBUG);
351         log("extensionClass = " + extensionClass, Project.MSG_DEBUG);
352         log("destdir = " + destDir, Project.MSG_DEBUG);
353         log("src = " + src, Project.MSG_DEBUG);
354         log("bootclasspath = " + bootclasspath, Project.MSG_DEBUG);
355         log("srcExt = " + srcExt, Project.MSG_DEBUG);
356         log("outputExt = " + outputExt, Project.MSG_DEBUG);
357         log("optionsFile = " + optionsFile, Project.MSG_DEBUG);
358         log("post = " + post, Project.MSG_DEBUG);
359         log("noSerial = " + noSerial, Project.MSG_DEBUG);
360         log("noOutput = " + noOutput, Project.MSG_DEBUG);
361         log("fqcn = " + fqcn, Project.MSG_DEBUG);
362         log("onlyToJava = " + onlyToJava, Project.MSG_DEBUG);
363         log("additionalArgs = ", Project.MSG_DEBUG);
364         if (additionalArgs != null) {
365             for (Iterator i = additionalArgs.iterator(); i.hasNext(); ) {
366                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
367                 Commandline.Argument arg = (Commandline.Argument)i.next();
368                 String JavaDoc[] parts = arg.getParts();
369                 sb.append(" '");
370                 for (int j = 0; j < parts.length; j++) {
371                     sb.append(parts[j]);
372                 }
373                 sb.append("'");
374                 log(sb.toString(), Project.MSG_DEBUG);
375             }
376         }
377         log("compileClasspath = " + compileClasspath, Project.MSG_DEBUG);
378         log("compileSourcepath = " + compileSourcepath, Project.MSG_DEBUG);
379         log("fileset = " + Arrays.asList(this.getCompileFiles()), Project.MSG_DEBUG);
380
381     }
382     /**
383      * Adds a command-line argument.
384      */

385     public Commandline.Argument createArg() {
386         Commandline.Argument argument = new Commandline.Argument();
387         if (additionalArgs == null) {
388             additionalArgs = new LinkedList();
389         }
390         additionalArgs.add(argument);
391         return argument;
392     }
393
394     public void setExtname(String JavaDoc extensionName) {
395         this.extensionName = extensionName;
396     }
397
398     public void setExtclass(Class JavaDoc extensionClass) {
399         this.extensionClass = extensionClass;
400     }
401
402     public void setDestdir(File JavaDoc destdir) {
403         this.destDir = destdir;
404     }
405
406     public Path createSrc() {
407         if (src == null) {
408             src = new Path(getProject());
409         }
410         return src.createPath();
411     }
412     public void setSrcdir(Path srcDir) {
413         if (src == null) {
414             src = srcDir;
415         } else {
416             src.append(srcDir);
417         }
418     }
419
420     public void setBootclasspath(Path bootclasspath) {
421         if (this.bootclasspath == null) {
422             this.bootclasspath = bootclasspath;
423         } else {
424             this.bootclasspath.append(bootclasspath);
425         }
426     }
427     
428     public Path createBootclasspath() {
429         if (bootclasspath == null) {
430             bootclasspath = new Path(getProject());
431         }
432         return bootclasspath.createPath();
433     }
434     
435     /**
436      * Adds a reference to a classpath defined elsewhere.
437      */

438     public void setBootClasspathRef(Reference r) {
439         createBootclasspath().setRefid(r);
440     }
441
442     public void setSx(String JavaDoc srcExt) {
443         this.srcExt = srcExt;
444     }
445
446     public void setOx(String JavaDoc outExt) {
447         this.outputExt = outExt;
448     }
449     public void setOptions(File JavaDoc optionsFile) {
450         this.optionsFile = optionsFile;
451     }
452
453     public void setPost(String JavaDoc post) {
454         this.post = post;
455     }
456
457     public void setNoserial(boolean noSerial) {
458         this.noSerial = noSerial;
459     }
460
461     public void setNooutput(boolean noOutput) {
462         this.noOutput = noOutput;
463     }
464
465     public void setFqcn(boolean fqcn) {
466         this.fqcn = fqcn;
467     }
468
469     public void setOnlytojava(boolean onlyToJava) {
470         this.onlyToJava = onlyToJava;
471     }
472     
473     public void setClasspath(Path classpath) {
474         if (compileClasspath == null) {
475             compileClasspath = classpath;
476         } else {
477             compileClasspath.append(classpath) ;
478         }
479     }
480
481     /**
482      * Adds a path to the classpath.
483      */

484     public Path createClasspath() {
485         if (compileClasspath == null) {
486             compileClasspath = new Path(getProject());
487         }
488         return compileClasspath.createPath();
489     }
490
491     /**
492      * Adds a reference to a classpath defined elsewhere.
493      */

494     public void setClasspathRef(Reference r) {
495         createClasspath().setRefid(r);
496     }
497
498     /**
499      * Set the sourcepath to be used for this compilation.
500      */

501     public void setSourcepath(Path sourcepath) {
502         if (compileSourcepath == null) {
503             compileSourcepath = sourcepath;
504         } else {
505             compileSourcepath.append(sourcepath);
506         }
507     }
508
509     /** Gets the sourcepath to be used for this compilation. */
510     public Path getSourcepath() {
511         return compileSourcepath;
512     }
513
514     /**
515      * Adds a path to sourcepath.
516      */

517     public Path createSourcepath() {
518         if (compileSourcepath == null) {
519             compileSourcepath = new Path(getProject());
520         }
521         return compileSourcepath.createPath();
522     }
523
524     /**
525      * Adds a reference to a source path defined elsewhere.
526      */

527     public void setSourcepathRef(Reference r) {
528         createSourcepath().setRefid(r);
529     }
530
531 }
532
Popular Tags