KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > xml > xmlc > taskdef > Xmlc


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site (http://www.enhydra.org/).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  * @author simon.tuffs@lutris.com
21  * @author christos@dynamic.net.au
22  * @author kevin@bluedog.com.au
23  * @author ericb@interactiveportal.com
24  * @author Christian Cryder [christianc@granitepeaks.com]
25  * @author Stephen Peterson [stephen_peterson@agilent.com]
26  * @author Jacob Kjome [hoju@visi.com]
27  * @author David Li [taweili@yahoo.com]
28  * @author Stefan Armbruster [sarmbruster@web.de]
29  *
30  * $Id: Xmlc.java,v 1.5 2005/01/26 08:28:45 jkjome Exp $
31  */

32 package org.enhydra.xml.xmlc.taskdef;
33
34 import java.io.File JavaDoc;
35 import java.lang.reflect.InvocationTargetException JavaDoc;
36 import java.lang.reflect.Method JavaDoc;
37 import java.util.ArrayList JavaDoc;
38
39 import org.apache.tools.ant.BuildException;
40 import org.apache.tools.ant.DirectoryScanner;
41 import org.apache.tools.ant.Project;
42 import org.apache.tools.ant.types.Commandline;
43 import org.apache.tools.ant.types.EnumeratedAttribute;
44
45
46 /**
47  * ANT task to invoke the XMLC compiler to generate Java code.
48  *
49  * <p>Implements an Ant taskdef to perform XMLC compilations. Please refer
50  * to the <a HREF="http://ant.apache.org/">Ant website</a>
51  * for more information. XMLCTask extends MatchingTask which means that
52  * it has the ability to include or exclude files based on pattern matching.
53  * The supported tags are as follows:</p>
54  *
55  * <table border="1" cellspacing="3" cellpadding="3" width="100%">
56  * <tr>
57  * <th>tag</th>
58  * <th>required</th>
59  * <th>default value</th>
60  * <th>description</th>
61  * </tr>
62  * <tr>
63  * <td>srcdir</td>
64  * <td>yes</td>
65  * <td>&nbsp;</td>
66  * <td>The source directory root</td>
67  * </tr>
68  * <tr>
69  * <td>sourceout</td>
70  * <td>no</td>
71  * <td>value of srcdir</td>
72  * <td>The destination directory into which the generated source *ML.java files are
73  * written, if keep=&quot;yes&quot;. If sourceout is not specified it is set to the value
74  * of the srcdir. This will put the *ML.java files in the same location as the .*ml files.
75  * </td>
76  * </tr>
77  * <tr>
78  * <td>destdir</td>
79  * <td>no</td>
80  * <td>&nbsp;</td>
81  * <td>The destination directory root. Only really useful if you want XMLC to
82  * do the compilation, so we can check dependencies.
83  * </td>
84  * </tr>
85  * <tr>
86  * <td>packagedir</td>
87  * <td>no</td>
88  * <td>relative path from srcdir</td>
89  * <td>Package prefix for generated classes, expressed as a directory path (relative to srcdir). Eg... my/package.
90  * If not specified, the relative path from srcdir becomes the package.
91  * </td>
92  * </tr>
93  * <tr>
94  * <td>packagename</td>
95  * <td>no</td>
96  * <td>blank package</td>
97  * <td>Package prefix for generated classes, while preserving any source file directory paths.
98  * For example, given &lt;xmlc srcdir=&quot;foo/resources&quot; sourceout=&quot;foo/source&quot; packagename=&quot;a.b&quot; /&gt;, packagename=&quot;a.b&quot;,
99  * markup file located at &quot;foo/resources/c/d/Foo.ml&quot; will be generated to &quot;foo/source/a/b/c/d/FooML.java&quot; and will start with a &quot;package a.b.c.d;&quot; statement.
100  * </td>
101  * </tr>
102  * <tr>
103  * <td>markup</td>
104  * <td>no</td>
105  * <td>HTML</td>
106  * <td>The kind of markup language being processed. Choices currently include
107  * HTML, WML, XHTML, CHTML and VoiceXML. The generated class is suffixed with
108  * this value</td>
109  * </tr>
110  * <tr>
111  * <td>verbose</td>
112  * <td>no</td>
113  * <td>no</td>
114  * <td>Displays the XMLC command and all of the arguments</td>
115  * </tr>
116  * <tr>
117  * <td>compile</td>
118  * <td>no</td>
119  * <td>no</td>
120  * <td>Have XMLC compile the resulting java files? Note: The default is to not
121  * invoke the Java compiler through XMLC, since this is really slow. Any
122  * java files created are better handled by the ANT <javac> rule.
123  * </td>
124  * </tr>
125  * <tr>
126  * <td>force</td>
127  * <td>no</td>
128  * <td>no</td>
129  * <td>Force XMLC to always re-process the ML code whether it has changed or not</td>
130  * </tr>
131  * <tr>
132  * <td>keep</td>
133  * <td>no</td>
134  * <td>yes</td>
135  * <td>Keep the Java files generated by XMLC? To not keep them, you must allow XMLC to
136  * compile them first. However, since this is slower, the default is to keep them
137  * and let ANT compile the files using a seperate task.
138  * </td>
139  * </tr>
140  * <tr>
141  * <td>performExec</td>
142  * <td>no</td>
143  * <td>no</td>
144  * <td>XMLC is invoked by performing a Runtime.exec()<br><i>(kept for historical reasons by the author)</i></td>
145  * </tr>
146  * <tr>
147  * <td>options</td>
148  * <td>no</td>
149  * <td>&nbsp;</td>
150  * <td>File name of XMLC options or a glob style pattern.</td>
151  * </tr>
152  * <tr>
153  * <td>&lt;arg&gt;</td>
154  * <td>no</td>
155  * <td>&nbsp;</td>
156  * <td>Nested element representing additional command line arguments to be passed to XMLC. See the XMLC documentation
157  * for all the possible commands. Note: these are applied after the other XMLC arguments derived from the options listed above.
158  * <p>For example, to specify an URL mapping to XMLC:
159  * <code>
160  * <pre>
161  * &lt;xmlc source="." includes="*.html"&gt;
162  * &lt;arg value="-urlmapping" /&gt;
163  * &lt;arg value="Edit.html" /&gt;
164  * &lt;arg value="To.po" /&gt;
165  * &lt;/xmlc&gt;
166  * </pre>
167  * </code>
168  * <b>Caution:</b> Do not be tempted to surround the URL's with single-quotes, as is common
169  * when calling XMLC from a shell command line, for example
170  * <pre>
171  * &lt;xmlc source="." includes="*.html"&gt;
172  * &lt;arg line="-urlmapping 'Edit.html' 'To.po'" /&gt;
173  * &lt;/xmlc&gt;
174  * </pre>
175  * The single-quotes will be taken as part of the URL to replace, and this is probably not what
176  * you intend
177  * </td>
178  * </tr>
179  *
180  * </table>
181  * <p>
182  *
183  * @author simon.tuffs@lutris.com
184  * @author christos@dynamic.net.au
185  * @author kevin@bluedog.com.au
186  * @author ericb@interactiveportal.com
187  * @author Christian Cryder [christianc@granitepeaks.com]
188  * @author Stephen Peterson [stephen_peterson@agilent.com]
189  * @author Jacob Kjome [hoju@visi.com]
190  * @author David Li [taweili@yahoo.com]
191  * @author Stefan Armbruster [sarmbruster@web.de]
192  * @version %I%, %G%
193  * @since 2.2
194  */

195 public class Xmlc extends org.apache.tools.ant.taskdefs.MatchingTask {
196
197     protected static String JavaDoc logHdr = " [xmlc] ";
198     protected File JavaDoc srcDir, destDir, srcOutDir;
199     protected String JavaDoc classPath, packageDir, packageName, srcDirName, srcOutDirName;
200     protected String JavaDoc options = null;
201     protected String JavaDoc xmlcArgs = null;
202     protected String JavaDoc performExec = null;
203     protected boolean verbose, forceBuild, compile;
204     protected boolean keep = true;
205     protected int logLevel = Project.MSG_VERBOSE;
206     protected int upToDate = 0;
207     // The following string is used as a suffix to the class name when generating
208
// code. This will vary, for HTML it defaults to "HTML", but other choices such
209
// as "XML", "WML" etc would be appropriate. This is set with the markup option.
210
protected String JavaDoc ML = "HTML";
211     protected Commandline cmdl = new Commandline();
212
213     /**
214      * Set the source directory containing the HTML files.
215      *
216      * @param srcdirname The name of the directory containing the HTML files
217      */

218     public void setSrcdir(String JavaDoc srcdirname) {
219         srcDirName = srcdirname;
220         srcDir = getProject().resolveFile(srcDirName);
221     }
222
223     /**
224      * Set the destination directory into which the generated classes are
225      * written.
226      *
227      * @param destDirName The destination directory into which the generated classes are written.
228      */

229     public void setDestdir(String JavaDoc destDirName) {
230         destDir = getProject().resolveFile(destDirName);
231     }
232
233     /**
234      * Allow general XMLC options to be passed through unchanged. Appended to the
235      * options lists.
236      *
237      * @param args The XMLC options to be passed through.
238      * @deprecated Use &lt;arg&gt; tags for now, this will eventually be removed.
239      */

240     public void setArgs(String JavaDoc args) {
241         this.xmlcArgs = args;
242         getProject().log(logHdr+"DEPRECATED, The 'args' attribute. Use <arg> tags instead.", Project.MSG_WARN);
243     }
244
245     /**
246      * Set the classpath for the XMLC compiler.
247      *
248      * @param classpath The classpath for XMLC to use.
249      * @deprecated Use nested <arg> elements or "args" option instead.
250      */

251     public void setClasspath(String JavaDoc classpath) {
252         this.classPath = classpath;
253         getProject().log(logHdr+"DEPRECATED, The 'classpath' attribute. Use <arg> tags instead.", Project.MSG_WARN);
254     }
255
256     /**
257      * Set the destination directory into which the generated source .java files are
258      * written, if -keep is used.
259      *
260      * @param sourceout The destination directory into which the generated sources are written.
261      *
262      * Note: Currently -keep is used by default since the .java files are best
263      * compiled by the built-in Ant javac command as a separate rule.
264      */

265     public void setSourceout(String JavaDoc sourceout) {
266         this.srcOutDirName = sourceout;
267         this.srcOutDir = getProject().resolveFile(sourceout);
268     }
269
270     /**
271      * Force XMLC to always re-process the ML code (or not)
272      *
273      * @param force whether to force re-processing of markup or not
274      */

275     public void setForce(BooleanAttribute force) {
276         this.forceBuild = force.booleanValue();
277     }
278
279     /**
280      * Run XMLC in verbose mode (-verbose flag)
281      *
282      * @param verbose Set "true" for -verbose, anything else (e.g. "false") for
283      * quiet mode.
284      */

285     public void setVerbose(BooleanAttribute verbose) {
286         this.verbose = verbose.booleanValue();
287         // Set the project log level to INFO if the "verbose" argument is used in the Ant invocation
288
// of this taskdef.
289
if (this.verbose) {
290             logLevel = Project.MSG_INFO;
291         } else {
292             logLevel = Project.MSG_VERBOSE;
293         }
294     }
295
296     /**
297      * Set whether or not to keep the generated Java file.
298      *
299      * @param keep Set to "true" or "false"
300      */

301     public void setKeep(BooleanAttribute keep) {
302         this.keep = keep.booleanValue();
303     }
304
305     /**
306      * Set whether or not to have XMLC compile the generated Java file.
307      *
308      * @param compile Set to "true" or "false"
309      */

310     public void setCompile(BooleanAttribute compile) {
311         this.compile = compile.booleanValue();
312     }
313
314     /**
315      * Set to a specific options file to add parameters to the XMLC command. Or,
316      * use a glob style pattern to base the options file name off the name of each
317      * source file to be processed (e.g. *.xmlc).
318      *
319      * @param options Set to file name or glob pattern
320      */

321     public void setOptions(String JavaDoc options) {
322         this.options = options;
323     }
324
325     /**
326      * Set the Package prefix for generated classes. Expressed as a directory path.
327      *
328      * <p>Note: packagedir is used to set the package name of the generated class, <b>and</b>
329      * to specify the directory where the file will be generated (relative to sourceout).
330      * As such, any directory prefix on a source file is stripped before the packagedir
331      * is applied. This means that all files from the source tree will end up in the
332      * same directory, which may not be what you intend, if you are using Xmlc to
333      * process files in a directory hierarchy.</p>
334      *
335      * @param packagedir Expressed as a directory path, either '/' or '\' are accepted.
336      * @see #setPackagename(String)
337      */

338     public void setPackagedir(String JavaDoc packagedir) {
339         packageDir = packagedir;
340     }
341
342     /**
343      * Set the package prefix for generated classes, while preserving any source
344      * file directory paths. This is useful if you want to take source (markup
345      * language) files from one tree, but generate the Java code into another
346      * tree, preserving relative paths.
347      * <p>
348      * For example, suppose that you have .html files under a directory called
349      * "foo/resources", and you want to generate Java code under "foo/source",
350      * but have the package name be "a.b". The following Xmlc taskdef will
351      * achieve this:
352      * <p>
353      * &lt;xmlc srcdir=&quot;foo/resources&quot; sourceout=&quot;foo/source&quot; packagename=&quot;a.b&quot; /&gt;
354      * <p>
355      * A markup file located at "foo/resources/c/d/Foo.ml" will be generated to
356      * "foo/source/a/b/c/d/FooML.java" and will start with a "package a.b.c.d"
357      * statement.
358      *
359      * @param packagename Expressed as a package path, [package].[package]
360      * @see #setPackagedir(String)
361      */

362     public void setPackagename(String JavaDoc packagename) {
363         this.packageName = packagename;
364     }
365
366     /**
367      * The kind of markup language being processed. Choices currently include
368      * HTML, WML, XHTML, CHTML and VoiceXML. The generated class is suffixed with
369      * this value.
370      *
371      * @param markup The type of markup language (controls only the file-name suffix,
372      * the actual markup is controlled through the XMLC -dom option which is accessible
373      * through the "args" option or &lt;arg&gt; tag.
374      */

375     public void setMarkup(String JavaDoc markup) {
376         this.ML = markup;
377     }
378
379     /**
380      * Set whether or not to invoke XMLC by using Runtime.exec() to
381      * create a seperate JVM. This capability was originally written to get
382      * around a problem with name-space clashes between packages. Set this
383      * to the command to execute.
384      *
385      * @param performExec Set to "true" or "false"
386      */

387     public void setPerformexec(String JavaDoc performExec) {
388         this.performExec = performExec;
389     }
390
391     /**
392      * Check if the given target file is newer than all of the files
393      * @param traget the file to be checked
394      * @param files the files
395      */

396     private boolean isNewerThanFiles(File JavaDoc target, File JavaDoc[] files) {
397         boolean newer = true;
398         for (int i = 0 ; i < files.length ; i++) {
399             if (files[i].lastModified() > target.lastModified()) {
400                 newer = false;
401                 getProject().log(logHdr+" " + files[i].getPath() + " is newer then " + target.getPath(), logLevel);
402                 break;
403             }
404         }
405         return newer;
406     }
407
408     /**
409      * Required by ant framework - implements execute() in Task.
410      * Called by the project to let the task do its work.
411      *
412      * @exception BuildException All exceptions are thrown as BuildException.
413      *
414      * Note: most of the logic here was cloned from the Javac command. Unfortunately
415      * this was the only way to 'reuse' it.
416      */

417     public void execute() throws org.apache.tools.ant.BuildException {
418         getProject().log(logHdr+"Xmlc srcdir=" + srcDir, logLevel);
419         getProject().log(logHdr+" destdir=" + destDir, logLevel);
420         getProject().log(logHdr+" sourceout=" + srcOutDir, logLevel);
421         getProject().log(logHdr+" packagedir=" + packageDir, logLevel);
422         getProject().log(logHdr+" packagename=" + packageName, logLevel);
423         // first off, make sure that we've got a srcdir
424

425         if (srcDir == null) {
426             throw new BuildException("srcdir attribute must be set!");
427         }
428         if (!srcDir.exists()) {
429             throw new BuildException("srcdir does not exist!");
430         }
431         if (!compile && !keep) {
432             throw new BuildException("If you do not keep the source, you must have XMLC compile them!");
433         }
434
435         XmlcUtils xmlcUtils = XmlcUtils.create();
436
437         // scan source and dest dirs to build up both copy lists and
438
// compile lists
439
DirectoryScanner ds = this.getDirectoryScanner(srcDir);
440         String JavaDoc[] files = ds.getIncludedFiles();
441
442         getProject().log(logHdr+"XMLC processing " + files.length + " files: ", logLevel);
443         for (int i=0; i<files.length; i++) {
444             String JavaDoc file = files[i];
445             try {
446                 String JavaDoc fileName = xmlcUtils.buildFullBaseFileName(packageName, packageDir, file);
447
448                 String JavaDoc className = xmlcUtils.buildClassName(fileName, ML);
449                 String JavaDoc javaName = className.replace('.', '/');
450
451                 // If srcOutDir is not specified, set it to srcDir. This will put the
452
// ML.java files in the same location as the .ml files, which is
453
// desirable.
454
if (srcOutDir == null) {
455                     srcOutDir = srcDir;
456                     srcOutDirName = srcDirName;
457                 }
458
459                 File JavaDoc mlFile = new File JavaDoc(srcDir, file);
460                 //csc File javaFile = new File(srcOutDir, fileName + ML + ".java");
461
File JavaDoc javaFile = new File JavaDoc(srcOutDir, javaName + ".java"); //csc
462
File JavaDoc classFile = new File JavaDoc((destDir != null) ? destDir : srcOutDir, fileName + ".class");
463
464                 java.util.ArrayList JavaDoc args = new java.util.ArrayList JavaDoc();
465
466                 // Quick test: if the .java file is newer than the .ml file, don't need
467
// to run XMLC. This is a rats-nest of logic, but hard to simplify.
468
File JavaDoc target = null;
469
470                 // The 'options' arg must precede the name of the file to be compiled
471
// Should really have -compile and -nokeep options since -nocompile
472
// and -keep are the default.
473

474                 // sam, 2003-01-26
475
// add recursive search
476
ArrayList JavaDoc al = new ArrayList JavaDoc();
477                 File JavaDoc f = javaFile;
478                 while ((f = f.getParentFile()) != null) {
479                     al.add(f);
480                 }
481                 f = mlFile;
482                 while ((f = f.getParentFile()) != null) {
483                     al.add(f);
484                 }
485                 File JavaDoc[] possibleOptionFilesDirs = new File JavaDoc[al.size()];
486                 for (int ii=0; ii<al.size(); ii++) {
487                     possibleOptionFilesDirs[al.size() - ii - 1] = (File JavaDoc)al.get(ii);
488                     getProject().log("possibleOptionFilesDirs :" + possibleOptionFilesDirs[al.size() - ii - 1].getAbsolutePath(), logLevel);
489                 }
490                 //File[] possibleOptionFilesDirs = { javaFile.getParentFile(), mlFile.getParentFile()};
491
// END sam, 2003-01-26
492

493                 String JavaDoc[] possibleOptionFileNames = { fileName, options};
494                 String JavaDoc[] foundOptionsFiles =
495                     xmlcUtils.getOptionFiles(possibleOptionFilesDirs, possibleOptionFileNames);
496
497                 File JavaDoc[] foundOptions = new File JavaDoc[foundOptionsFiles.length];
498                 for (int j = 0 ; j < foundOptions.length ; j++) {
499                     foundOptions[j] = new File JavaDoc(foundOptionsFiles[j]);
500                 }
501
502                 /*
503                  * Since we can't update the last modified time of the
504                  * ML, an option checkfile is created along with the
505                  * XMLC output files and this files is checked against
506                  * the option files.
507                  */

508                 File JavaDoc optionCheck = null;
509                 if (keep) {
510                     optionCheck = new File JavaDoc(javaFile.getPath() + ".optionCheck");
511                 } else {
512                     optionCheck = new File JavaDoc(classFile.getPath() + ".optionCheck");
513                 }
514
515                 getProject().log(logHdr+" option check to created " + optionCheck.getPath(), logLevel);
516                 if (keep) {
517                     if (!javaFile.exists()) {
518                         target = javaFile;
519                         // If we are going to keep the generated file but don't have one, then better create it
520
getProject().log(logHdr+" " + javaFile + " does not exist, invoking XMLC", logLevel);
521                     } else if (compile) {
522                         target = classFile;
523                         // If we are going to keep the generated file and compile it, then we have two dependencies to verify
524
if (mlFile.lastModified() <= classFile.lastModified() && mlFile.lastModified() <= javaFile.lastModified()) {
525                             if (optionCheck.exists() && isNewerThanFiles(optionCheck, foundOptions)) {
526                                 if (!forceBuild) {
527                                     getProject().log(logHdr+" " + classFile.getName() + " and " + javaFile.getName() + " are newer than " + mlFile.getName(), logLevel);
528                                     upToDate++;
529                                     continue;
530                                 }
531                             } else {
532                                 getProject().log(logHdr+" " + "One of the option files are newer than " + mlFile.getName() + " invoking XMLC" , logLevel);
533                             }
534                         } else {
535                             getProject().log(logHdr+" " + classFile.getName() + " or " + javaFile.getName() + " is older than " + mlFile.getName() + " invoking XMLC", logLevel);
536                         }
537                     } else {
538                         // If we are going to keep the generated file but not compile it, then we only care if the java
539
// file is out of date. We'll let someone else check if the class file is out of date.
540
target = javaFile;
541                         if (mlFile.lastModified() <= javaFile.lastModified()) {
542                             if (optionCheck.exists() && isNewerThanFiles(optionCheck, foundOptions)) {
543                                 if (!forceBuild) {
544                                     getProject().log(logHdr+" " + javaFile.getName() + " is newer than " + mlFile.getName(), logLevel);
545                                     upToDate++;
546                                     continue;
547                                 }
548                             } else {
549                                 getProject().log(logHdr+" " + "One of the option files are newer than " + mlFile.getName() + " invoking XMLC" , logLevel);
550                             }
551                         } else {
552                             getProject().log(logHdr+" " + javaFile.getName() + " is older than " + mlFile.getName() + " invoking XMLC", logLevel);
553                             target = javaFile;
554                         }
555                     }
556                 } else {
557                     // Not "keep" so target must be classFile.
558
target = classFile;
559                     if (mlFile.lastModified() <= classFile.lastModified()) {
560                         if (optionCheck.exists() && isNewerThanFiles(optionCheck, foundOptions)) {
561                             if (!forceBuild) {
562                                 // If we are not going to keep the generated file then we must compile it
563
getProject().log(logHdr+" " + classFile.getName() + " is newer than " + mlFile.getName(), logLevel);
564                                 upToDate++;
565                                 continue;
566                             }
567                         } else {
568                             getProject().log(logHdr+" " + "One of the option files are newer than " + mlFile.getName() + " invoking XMLC" , logLevel);
569                         }
570                     } else {
571                         getProject().log(logHdr+" " + classFile.getName() + " is older than " + mlFile.getName() + " invoking XMLC", logLevel);
572                     }
573                 }
574
575                 getProject().log(logHdr+" " + mlFile.getName() + " --> " + target.getName(), logLevel);
576                 if (classPath != null) {
577                     args.add("-classpath");
578                     args.add(classPath);
579                 }
580                 // Don't do the Java compilation here, it's much faster to do it with
581
// the Javac task which invokes the Javac compiler without forking a
582
// new process.
583
if (!compile) args.add("-nocompile");
584                 if (keep) args.add("-keep");
585                 if (verbose) args.add("-verbose");
586
587                 args.add("-class");
588                 args.add(className);
589
590                 args.add("-sourceout");
591                 args.add(srcOutDir.toString());
592
593                 if (xmlcArgs != null) {
594                     // We have to tokenize the arguments. Assumpions: URL's will not contain
595
// whitespace, and if they did, they should use %20 or &space entities.
596
//
597
java.util.StringTokenizer JavaDoc tok = new java.util.StringTokenizer JavaDoc(xmlcArgs, " ");
598                     while (tok.hasMoreElements()) {
599                         args.add(tok.nextToken());
600                     }
601                 }
602
603                 String JavaDoc[] additionalArgs = cmdl.getArguments();
604                 for (int idx=0; idx < additionalArgs.length; idx++) {
605                     args.add(additionalArgs[idx]);
606                 }
607
608                 // Option files to be added right before the ML file
609
if (foundOptionsFiles.length > 0) {
610                     for (int optionsIdx = 0; optionsIdx < foundOptionsFiles.length; optionsIdx++) {
611                         args.add(foundOptionsFiles[optionsIdx]);
612                         getProject().log(logHdr+" Using options file " + foundOptionsFiles[optionsIdx], logLevel);
613                     }
614                 } else {
615                     getProject().log(logHdr+"No options file could not be located for " + file +
616                         " in paths " + javaFile.getParentFile() + ", " +
617                         mlFile.getParentFile(), Project.MSG_WARN);
618                 }
619                 // *** WARNING DO NOT SEPARATE THE FOLLOWING CODE FROM THE BLOCK ABOVE! ***
620
args.add(new File JavaDoc(srcDir, file).getAbsolutePath());
621
622                 getProject().log(logHdr+"args==" + args, logLevel);
623
624                 getProject().log(logHdr+"Invoke XMLC on " + mlFile.getPath(), Project.MSG_INFO);
625                 if (performExec != null) {
626                     args.add(0, performExec);
627                     String JavaDoc [] _args = (String JavaDoc[])args.toArray(new String JavaDoc[args.size()]);
628                     Runtime JavaDoc runtime = Runtime.getRuntime();
629                     Process JavaDoc process = runtime.exec(_args);
630                     int status = process.waitFor();
631                     if (status != 0) {
632                         throw new BuildException("exit status of exec = "+status + toString(_args));
633                     }
634                 } else {
635                     String JavaDoc [] _args = (String JavaDoc[])args.toArray(new String JavaDoc[args.size()]);
636
637                     // Execute XMLC directly. This requires that enhydra.jar, or an equivalent
638
// path containing the needed DOM code is on the CLASSPATH of ANT.
639
String JavaDoc xmlcClassName = "org.enhydra.xml.xmlc.commands.xmlc.XMLC";
640
641                     Method JavaDoc m = null;
642                     Class JavaDoc c = null;
643                     try {
644                         c = Class.forName(xmlcClassName, true, getClass().getClassLoader());
645                         m = c.getMethod("main", new Class JavaDoc[] { String JavaDoc[].class});
646                     } catch (Exception JavaDoc e) {
647                         // Reflection errors. Class or method does not exist!
648
e.printStackTrace();
649                         throw new BuildException(e);
650                     }
651
652                     if (m != null) {
653                         m.invoke(null,new Object JavaDoc[] { _args});
654                     }
655                 }
656
657                 /*
658                  * Create the option file
659                  */

660                 if (optionCheck.exists()) {
661                     optionCheck.delete();
662                 }
663                 optionCheck.createNewFile();
664             } catch (InvocationTargetException JavaDoc ite) {
665                 ite.printStackTrace();
666                 throw new BuildException(ite);
667             } catch (Exception JavaDoc x) {
668                 x.printStackTrace();
669                 throw new BuildException(x);
670             }
671         }
672
673         if (upToDate > 0) {
674             getProject().log(logHdr+"XMLC " + upToDate + " files were up-to-date, consider using force=\"true\"", logLevel);
675         }
676     }
677
678     /**
679      * Simple utility to concatenate an array of Strings into one single
680      * String.
681      *
682      * @param args The array of Strings
683      * @return The resulting String
684      */

685     static private String JavaDoc toString(String JavaDoc[] args) {
686         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
687         for (int i=0; i<args.length; i++) buffer.append(args[i]).append(" ");
688         return buffer.toString();
689     }
690
691     /**
692      * Set nested arguments to the XMLC command to be executed.
693      *
694      */

695     public Commandline.Argument createArg() {
696         return cmdl.createArgument();
697     }
698
699     public static class BooleanAttribute extends EnumeratedAttribute {
700         public String JavaDoc[] getValues() {
701             return new String JavaDoc[] {"yes", "no", "on", "off", "true", "false"};
702         }
703
704         public boolean booleanValue() {
705             return (this.getValue().equals("yes") || this.getValue().equals("on") || this.getValue().equals("true"));
706         }
707     }
708
709 }
710
Popular Tags