source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 17.7 KB
Line 
1/*
2 * Copyright 2001-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.apache.tools.ant.taskdefs.optional.jsp;
19
20import java.io.File;
21import java.util.Date;
22import java.util.Enumeration;
23import java.util.Vector;
24import org.apache.tools.ant.BuildException;
25import org.apache.tools.ant.DirectoryScanner;
26import org.apache.tools.ant.Project;
27import org.apache.tools.ant.taskdefs.MatchingTask;
28import org.apache.tools.ant.taskdefs.optional.jsp.compilers.JspCompilerAdapter;
29import org.apache.tools.ant.taskdefs.optional.jsp.compilers.JspCompilerAdapterFactory;
30import org.apache.tools.ant.types.Path;
31import org.apache.tools.ant.types.Reference;
32
33/**
34 * Runs a JSP compiler.
35 *
36 * <p> This task takes the given jsp files and compiles them into java
37 * files. It is then up to the user to compile the java files into classes.
38 *
39 * <p> The task requires the srcdir and destdir attributes to be
40 * set. This Task is a MatchingTask, so the files to be compiled can be
41 * specified using includes/excludes attributes or nested include/exclude
42 * elements. Optional attributes are verbose (set the verbosity level passed
43 * to jasper), package (name of the destination package for generated java
44 * classes and classpath (the classpath to use when running the jsp
45 * compiler).
46 * <p> This task supports the nested elements classpath (A Path) and
47 * classpathref (A Reference) which can be used in preference to the
48 * attribute classpath, if the jsp compiler is not already in the ant
49 * classpath.
50 *
51 * <p><h4>Usage</h4>
52 * <pre>
53 * &lt;jspc srcdir="${basedir}/src/war"
54 * destdir="${basedir}/gensrc"
55 * package="com.i3sp.jsp"
56 * verbose="9"&gt;
57 * &lt;include name="**\/*.jsp" /&gt;
58 * &lt;/jspc&gt;
59 * </pre>
60 *
61 * @since 1.5
62 */
63public class JspC extends MatchingTask {
64 private Path classpath;
65 private Path compilerClasspath;
66 private Path src;
67 private File destDir;
68 private String packageName ;
69 /** name of the compiler to use */
70 private String compilerName = "jasper";
71
72 /**
73 * -ieplugin &lt;clsid&gt; Java Plugin classid for Internet Explorer
74 */
75 private String iepluginid ;
76 private boolean mapped ;
77 private int verbose = 0;
78 protected Vector compileList = new Vector();
79 Vector javaFiles = new Vector();
80
81 /**
82 * flag to control action on execution trouble
83 */
84 protected boolean failOnError = true;
85
86 /**
87 * -uriroot &lt;dir&gt; The root directory that uri files should be resolved
88 * against,
89 */
90 private File uriroot;
91
92 /**
93 * -webinc &lt;file&gt; Creates partial servlet mappings for the -webapp option
94 */
95 private File webinc;
96
97 /**
98 * -webxml &lt;file&gt; Creates a complete web.xml when using the -webapp option.
99 */
100
101 private File webxml;
102
103 /**
104 * web apps
105 */
106 protected WebAppParameter webApp;
107
108
109
110 private static final String FAIL_MSG
111 = "Compile failed, messages should have been provided.";
112
113 /**
114 * Set the path for source JSP files.
115 */
116 public void setSrcDir(Path srcDir) {
117 if (src == null) {
118 src = srcDir;
119 } else {
120 src.append(srcDir);
121 }
122 }
123 public Path getSrcDir() {
124 return src;
125 }
126
127 /**
128 * Set the destination directory into which the JSP source
129 * files should be compiled.
130 */
131 public void setDestdir(File destDir) {
132 this.destDir = destDir;
133 }
134 public File getDestdir() {
135 return destDir;
136 }
137
138 /**
139 * Set the name of the package the compiled jsp files should be in.
140 */
141 public void setPackage(String pkg) {
142 this.packageName = pkg;
143 }
144
145 public String getPackage() {
146 return packageName;
147 }
148
149 /**
150 * Set the verbose level of the compiler
151 */
152 public void setVerbose(int i) {
153 verbose = i;
154 }
155 public int getVerbose() {
156 return verbose;
157 }
158
159 /**
160 * Whether or not the build should halt if compilation fails.
161 * Defaults to <code>true</code>.
162 */
163 public void setFailonerror(boolean fail) {
164 failOnError = fail;
165 }
166 /**
167 * Gets the failonerror flag.
168 */
169 public boolean getFailonerror() {
170 return failOnError;
171 }
172
173 public String getIeplugin() {
174 return iepluginid;
175 }
176 /**
177 * Java Plugin CLASSID for Internet Explorer
178 */
179 public void setIeplugin(String iepluginid) {
180 this.iepluginid = iepluginid;
181 }
182
183 /**
184 * If true, generate separate write() calls for each HTML line
185 * in the JSP.
186 * @return mapping status
187 */
188 public boolean isMapped() {
189 return mapped;
190 }
191
192 /**
193 * If true, generate separate write() calls for each HTML line
194 * in the JSP.
195 */
196 public void setMapped(boolean mapped) {
197 this.mapped = mapped;
198 }
199
200 /**
201 * The URI context of relative URI references in the JSP pages.
202 * If it does not exist then it is derived from the location
203 * of the file relative to the declared or derived value of uriroot.
204 *
205 * @param uribase The new Uribase value
206 */
207 public void setUribase(File uribase) {
208 log("Uribase is currently an unused parameter", Project.MSG_WARN);
209 }
210
211 public File getUribase() {
212 return uriroot;
213 }
214
215 /**
216 * The root directory that uri files should be resolved
217 * against. (Default is the directory jspc is invoked from)
218 *
219 * @param uriroot The new Uribase value
220 */
221 public void setUriroot(File uriroot) {
222 this.uriroot = uriroot;
223 }
224
225 public File getUriroot() {
226 return uriroot;
227 }
228
229
230 /**
231 * Set the classpath to be used for this compilation.
232 */
233 public void setClasspath(Path cp) {
234 if (classpath == null) {
235 classpath = cp;
236 } else {
237 classpath.append(cp);
238 }
239 }
240
241 /**
242 * Adds a path to the classpath.
243 */
244 public Path createClasspath() {
245 if (classpath == null) {
246 classpath = new Path(getProject());
247 }
248 return classpath.createPath();
249 }
250
251 /**
252 * Adds a reference to a classpath defined elsewhere
253 */
254 public void setClasspathRef(Reference r) {
255 createClasspath().setRefid(r);
256 }
257 public Path getClasspath() {
258 return classpath;
259 }
260
261 /**
262 * Set the classpath to be used to find this compiler adapter
263 */
264 public void setCompilerclasspath(Path cp) {
265 if (compilerClasspath == null) {
266 compilerClasspath = cp;
267 } else {
268 compilerClasspath.append(cp);
269 }
270 }
271
272 /**
273 * get the classpath used to find the compiler adapter
274 */
275 public Path getCompilerclasspath() {
276 return compilerClasspath;
277 }
278
279 /**
280 * Support nested compiler classpath, used to locate compiler adapter
281 */
282 public Path createCompilerclasspath() {
283 if (compilerClasspath == null) {
284 compilerClasspath = new Path(getProject());
285 }
286 return compilerClasspath.createPath();
287 }
288
289 /**
290 * Filename for web.xml.
291 *
292 * @param webxml The new Webxml value
293 */
294 public void setWebxml(File webxml) {
295 this.webxml = webxml;
296 }
297
298 /**
299 * Filename for web.xml.
300 * @return The filename for web.xml.
301 */
302 public File getWebxml() {
303 return this.webxml;
304 }
305
306 /**
307 * output filename for the fraction of web.xml that lists
308 * servlets.
309 * @param webinc The new Webinc value
310 */
311 public void setWebinc(File webinc) {
312 this.webinc = webinc;
313 }
314
315 public File getWebinc() {
316 return this.webinc;
317 }
318
319 /**
320 * Adds a single webapp.
321 *
322 * @param webappParam add a web app parameter
323 */
324 public void addWebApp(WebAppParameter webappParam)
325 throws BuildException {
326 //demand create vector of filesets
327 if (webApp == null) {
328 webApp = webappParam;
329 } else {
330 throw new BuildException("Only one webapp can be specified");
331 }
332 }
333
334 public WebAppParameter getWebApp() {
335 return webApp;
336 }
337
338 /**
339 * Class name of a JSP compiler adapter.
340 */
341 public void setCompiler(String compiler) {
342 this.compilerName = compiler;
343 }
344
345 /**
346 * get the list of files to compile
347 */
348 public Vector getCompileList() {
349 return compileList;
350 }
351
352 /**
353 * execute by building up a list of files that
354 * have changed and hand them off to a jsp compiler
355 */
356 public void execute()
357 throws BuildException {
358
359 // make sure that we've got a destdir
360 if (destDir == null) {
361 throw new BuildException("destdir attribute must be set!",
362 getLocation());
363 }
364
365 if (!destDir.isDirectory()) {
366 throw new BuildException("destination directory \"" + destDir
367 + "\" does not exist or is not a directory", getLocation());
368 }
369
370 File dest = getActualDestDir();
371
372 //bind to a compiler
373 JspCompilerAdapter compiler =
374 JspCompilerAdapterFactory.getCompiler(compilerName, this,
375 getProject().createClassLoader(compilerClasspath));
376
377 //if we are a webapp, hand off to the compiler, which had better handle it
378 if (webApp != null) {
379 doCompilation(compiler);
380 return;
381 }
382
383 // make sure that we've got a srcdir
384 if (src == null) {
385 throw new BuildException("srcdir attribute must be set!",
386 getLocation());
387 }
388 String [] list = src.list();
389 if (list.length == 0) {
390 throw new BuildException("srcdir attribute must be set!",
391 getLocation());
392 }
393
394
395 // if the compiler does its own dependency stuff, we just call it right now
396 if (compiler.implementsOwnDependencyChecking()) {
397 doCompilation(compiler);
398 return;
399 }
400
401 //the remainder of this method is only for compilers that need their dependency work done
402 JspMangler mangler = compiler.createMangler();
403
404 // scan source directories and dest directory to build up both copy
405 // lists and compile lists
406 resetFileLists();
407 int filecount = 0;
408 for (int i = 0; i < list.length; i++) {
409 File srcDir = getProject().resolveFile(list[i]);
410 if (!srcDir.exists()) {
411 throw new BuildException("srcdir \"" + srcDir.getPath()
412 + "\" does not exist!", getLocation());
413 }
414 DirectoryScanner ds = this.getDirectoryScanner(srcDir);
415 String[] files = ds.getIncludedFiles();
416 filecount = files.length;
417 scanDir(srcDir, dest, mangler, files);
418 }
419
420 // compile the source files
421
422 log("compiling " + compileList.size() + " files", Project.MSG_VERBOSE);
423
424 if (compileList.size() > 0) {
425
426 log("Compiling " + compileList.size() + " source file"
427 + (compileList.size() == 1 ? "" : "s")
428 + " to "
429 + dest);
430 doCompilation(compiler);
431
432 } else {
433 if (filecount == 0) {
434 log("there were no files to compile", Project.MSG_INFO);
435 } else {
436 log("all files are up to date", Project.MSG_VERBOSE);
437 }
438 }
439 }
440
441 /**
442 * calculate where the files will end up:
443 * this is destDir or it id destDir + the package name
444 */
445 private File getActualDestDir() {
446 File dest = null;
447 if (packageName == null) {
448 dest = destDir;
449 } else {
450 String path = destDir.getPath() + File.separatorChar
451 + packageName.replace('.', File.separatorChar);
452 dest = new File(path);
453 }
454 return dest;
455 }
456
457 /**
458 * do the compile
459 */
460 private void doCompilation(JspCompilerAdapter compiler)
461 throws BuildException {
462 // now we need to populate the compiler adapter
463 compiler.setJspc(this);
464
465 // finally, lets execute the compiler!!
466 if (!compiler.execute()) {
467 if (failOnError) {
468 throw new BuildException(FAIL_MSG, getLocation());
469 } else {
470 log(FAIL_MSG, Project.MSG_ERR);
471 }
472 }
473 }
474
475 /**
476 * Clear the list of files to be compiled and copied..
477 */
478 protected void resetFileLists() {
479 compileList.removeAllElements();
480 }
481
482 /**
483 * Scans the directory looking for source files to be compiled.
484 * The results are returned in the class variable compileList
485 */
486 protected void scanDir(File srcDir, File dest, JspMangler mangler, String files[]) {
487
488 long now = (new Date()).getTime();
489
490 for (int i = 0; i < files.length; i++) {
491 String filename = files[i];
492 File srcFile = new File(srcDir, filename);
493 File javaFile = mapToJavaFile(mangler, srcFile, srcDir, dest);
494 if (javaFile == null) {
495 continue;
496 }
497
498 if (srcFile.lastModified() > now) {
499 log("Warning: file modified in the future: " + filename,
500 Project.MSG_WARN);
501 }
502 boolean shouldCompile = false;
503 shouldCompile = isCompileNeeded(srcFile, javaFile);
504 if (shouldCompile) {
505 compileList.addElement(srcFile.getAbsolutePath());
506 javaFiles.addElement(javaFile);
507 }
508 }
509 }
510
511 /**
512 * Test whether or not compilation is needed. A return value of
513 * <code>true<code> means yes, <code>false</code> means
514 * our tests do not indicate this, but as the TLDs are
515 * not used for dependency checking this is not guaranteed.
516 * The current tests are
517 * <ol>
518 * <li>no dest file
519 * <li>dest file out of date w.r.t source
520 * <li>dest file zero bytes long
521 * </ol>
522 * @param srcFile JSP source file
523 * @param javaFile JSP dest file
524 * @return true if a compile is definately needed.
525 *
526 */
527 private boolean isCompileNeeded(File srcFile, File javaFile) {
528 boolean shouldCompile = false;
529 if (!javaFile.exists()) {
530 shouldCompile = true;
531 log("Compiling " + srcFile.getPath()
532 + " because java file " + javaFile.getPath()
533 + " does not exist", Project.MSG_VERBOSE);
534 } else {
535 if (srcFile.lastModified() > javaFile.lastModified()) {
536 shouldCompile = true;
537 log("Compiling " + srcFile.getPath()
538 + " because it is out of date with respect to "
539 + javaFile.getPath(),
540 Project.MSG_VERBOSE);
541 } else {
542 if (javaFile.length() == 0) {
543 shouldCompile = true;
544 log("Compiling " + srcFile.getPath()
545 + " because java file " + javaFile.getPath()
546 + " is empty", Project.MSG_VERBOSE);
547 }
548 }
549 }
550 return shouldCompile;
551 }
552
553
554 /**
555 * get a filename from our jsp file
556 * @todo support packages and subdirs
557 */
558 protected File mapToJavaFile(JspMangler mangler, File srcFile, File srcDir, File dest) {
559 if (!srcFile.getName().endsWith(".jsp")) {
560 return null;
561 }
562 String javaFileName = mangler.mapJspToJavaName(srcFile);
563// String srcFileDir=srcFile.getParent();
564 return new File(dest, javaFileName);
565 }
566
567 /**
568 * delete any java output files that are empty
569 * this is to get around a little defect in jasper: when it
570 * fails, it leaves incomplete files around.
571 */
572 public void deleteEmptyJavaFiles() {
573 if (javaFiles != null) {
574 Enumeration e = javaFiles.elements();
575 while (e.hasMoreElements()) {
576 File file = (File) e.nextElement();
577 if (file.exists() && file.length() == 0) {
578 log("deleting empty output file " + file);
579 file.delete();
580 }
581 }
582 }
583 }
584
585 /**
586 * static inner class used as a parameter element
587 */
588 public static class WebAppParameter {
589
590 /**
591 * the sole option
592 */
593 private File directory;
594
595 /**
596 * query current directory
597 */
598
599 public File getDirectory() {
600 return directory;
601 }
602
603 /**
604 * set directory; alternate syntax
605 */
606 public void setBaseDir(File directory) {
607 this.directory = directory;
608 }
609 //end inner class
610 }
611
612
613//end class
614}
Note: See TracBrowser for help on using the repository browser.