-added a method to this to get a JspMangler -added a boolean method which returns true if the compiler handles its own dependency checking -jspc doesnt do dependency work if this test returns true for its compiler -jspc uses the supplied mangler if it does need to do dependency checking -jspc should use package names too, but this aint tested yet -jspc caches the list of generated files and deletes any zero byte length ones after a build (failures) -jspc also assumes that a zero byte java file was an error when deciding when to compile files -jasperc gets jasper to return 9 on an error, catches and throws this as a buildException git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271843 13f79535-47bb-0310-9956-ffa450edef68master
@@ -58,13 +58,15 @@ import java.io.File; | |||
import java.util.Date; | |||
import java.util.Vector; | |||
import java.util.Enumeration; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.DirectoryScanner; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.taskdefs.MatchingTask; | |||
import org.apache.tools.ant.taskdefs.optional.jsp.compilers.CompilerAdapter; | |||
import org.apache.tools.ant.taskdefs.optional.jsp.compilers.CompilerAdapterFactory; | |||
import org.apache.tools.ant.taskdefs.optional.jsp.compilers.JspCompilerAdapter; | |||
import org.apache.tools.ant.taskdefs.optional.jsp.compilers.JspCompilerAdapterFactory; | |||
import org.apache.tools.ant.types.Path; | |||
import org.apache.tools.ant.types.FileSet; | |||
@@ -117,7 +119,7 @@ public class JspC extends MatchingTask | |||
private File destDir; | |||
private String packageName ; | |||
/** name of the compiler to use */ | |||
private String compiler="jasper"; | |||
private String compilerName="jasper"; | |||
/** | |||
* -ieplugin <clsid>Java Plugin classid for Internet Explorer | |||
@@ -126,6 +128,8 @@ public class JspC extends MatchingTask | |||
private boolean mapped ; | |||
private int verbose = 0; | |||
protected Vector compileList = new Vector(); | |||
Vector javaFiles=new Vector(); | |||
/** | |||
* flag to control action on execution trouble | |||
*/ | |||
@@ -349,7 +353,7 @@ public class JspC extends MatchingTask | |||
* set the compiler. optional: default=jasper | |||
*/ | |||
public void setCompiler(String compiler) { | |||
this.compiler=compiler; | |||
this.compilerName=compiler; | |||
} | |||
/** | |||
@@ -383,16 +387,21 @@ public class JspC extends MatchingTask | |||
location); | |||
} | |||
// calculate where the files will end up: | |||
File dest = null; | |||
if (packageName == null) { | |||
dest = destDir; | |||
} else { | |||
String path = destDir.getPath() + File.separatorChar + | |||
packageName.replace('.', File.separatorChar); | |||
dest = new File(path); | |||
File dest = getActualDestDir(); | |||
//bind to a compiler | |||
JspCompilerAdapter compiler = | |||
JspCompilerAdapterFactory.getCompiler(compilerName, this); | |||
// if the compiler does its own dependency stuff, we just call it right now | |||
if(compiler.implementsOwnDependencyChecking()) { | |||
doCompilation(compiler); | |||
return; | |||
} | |||
//the remainder of this method is only for compilers that need their dependency work done | |||
JspMangler mangler=compiler.createMangler(); | |||
// scan source directories and dest directory to build up both copy | |||
// lists and compile lists | |||
resetFileLists(); | |||
@@ -403,12 +412,10 @@ public class JspC extends MatchingTask | |||
throw new BuildException("srcdir \"" + srcDir.getPath() + | |||
"\" does not exist!", location); | |||
} | |||
DirectoryScanner ds = this.getDirectoryScanner(srcDir); | |||
String[] files = ds.getIncludedFiles(); | |||
filecount=files.length; | |||
scanDir(srcDir, dest, files); | |||
scanDir(srcDir, dest, mangler, files); | |||
} | |||
// compile the source files | |||
@@ -417,25 +424,12 @@ public class JspC extends MatchingTask | |||
if (compileList.size() > 0) { | |||
CompilerAdapter adapter = | |||
CompilerAdapterFactory.getCompiler(compiler, this); | |||
log("Compiling " + compileList.size() + | |||
" source file" | |||
+ (compileList.size() == 1 ? "" : "s") | |||
+ (destDir != null ? " to " + destDir : "")); | |||
// now we need to populate the compiler adapter | |||
adapter.setJspc( this ); | |||
+ dest); | |||
doCompilation(compiler); | |||
// finally, lets execute the compiler!! | |||
if (!adapter.execute()) { | |||
if (failOnError) { | |||
throw new BuildException(FAIL_MSG, location); | |||
} | |||
else { | |||
log(FAIL_MSG, Project.MSG_ERR); | |||
} | |||
} | |||
} | |||
else { | |||
if(filecount==0) { | |||
@@ -446,6 +440,42 @@ public class JspC extends MatchingTask | |||
} | |||
} | |||
} | |||
/** | |||
* calculate where the files will end up: | |||
* this is destDir or it id destDir + the package name | |||
*/ | |||
private File getActualDestDir() { | |||
File dest = null; | |||
if (packageName == null) { | |||
dest = destDir; | |||
} else { | |||
String path = destDir.getPath() + File.separatorChar + | |||
packageName.replace('.', File.separatorChar); | |||
dest = new File(path); | |||
} | |||
return dest; | |||
} | |||
/** | |||
* do the compile | |||
*/ | |||
private void doCompilation(JspCompilerAdapter compiler) | |||
throws BuildException { | |||
// now we need to populate the compiler adapter | |||
compiler.setJspc( this ); | |||
// finally, lets execute the compiler!! | |||
if (!compiler.execute()) { | |||
if (failOnError) { | |||
throw new BuildException(FAIL_MSG, location); | |||
} | |||
else { | |||
log(FAIL_MSG, Project.MSG_ERR); | |||
} | |||
} | |||
} | |||
/* ------------------------------------------------------------ */ | |||
/** | |||
* Clear the list of files to be compiled and copied.. | |||
@@ -453,54 +483,106 @@ public class JspC extends MatchingTask | |||
protected void resetFileLists() { | |||
compileList.removeAllElements(); | |||
} | |||
/* ------------------------------------------------------------ */ | |||
/** | |||
* Scans the directory looking for source files to be compiled. | |||
* The results are returned in the class variable compileList | |||
*/ | |||
protected void scanDir(File srcDir, File destDir, String files[]) { | |||
protected void scanDir(File srcDir, File dest, JspMangler mangler, String files[]) { | |||
long now = (new Date()).getTime(); | |||
for (int i = 0; i < files.length; i++) { | |||
String filename=files[i]; | |||
File srcFile = new File(srcDir, filename); | |||
File javaFile=mapToJavaFile(srcFile); | |||
File javaFile=mapToJavaFile(mangler,srcFile, srcDir, dest); | |||
if (srcFile.lastModified() > now) { | |||
log("Warning: file modified in the future: " +filename, | |||
Project.MSG_WARN); | |||
} | |||
boolean shouldCompile=false; | |||
shouldCompile=isCompileNeeded(srcFile, javaFile); | |||
if(shouldCompile) { | |||
compileList.addElement(srcFile.getAbsolutePath()); | |||
javaFiles.addElement(javaFile); | |||
} | |||
} | |||
} | |||
if (!javaFile.exists()) { | |||
shouldCompile=true; | |||
log("Compiling " + srcFile.getPath() + | |||
" because java file "+ javaFile.getPath() + " does not exist", | |||
Project.MSG_DEBUG); | |||
/** | |||
* test for compilation needed. true means yes, false means | |||
* our tests do not indicate this, but as the TLDs are | |||
* not used for dependency checking this is not guaranteed. | |||
* The current tests are | |||
* <ol> | |||
* <li>no dest file | |||
* <li>dest file out of date w.r.t source | |||
* <li>dest file zero bytes long | |||
* </ol> | |||
* @param srcFile JSP source file | |||
* @param javaFile JSP dest file | |||
* @return true if a compile is definately needed. | |||
* | |||
*/ | |||
private boolean isCompileNeeded(File srcFile, File javaFile) { | |||
boolean shouldCompile=false; | |||
if (!javaFile.exists()) { | |||
shouldCompile=true; | |||
log("Compiling " + srcFile.getPath() + | |||
" because java file "+ javaFile.getPath() + " does not exist", | |||
Project.MSG_VERBOSE); | |||
} else { | |||
if( srcFile.lastModified() > javaFile.lastModified()) { | |||
shouldCompile=true; | |||
log("Compiling " + srcFile.getPath() + | |||
" because it is out of date with respect to " + javaFile.getPath(), | |||
Project.MSG_VERBOSE); | |||
} else { | |||
if( srcFile.lastModified() > javaFile.lastModified()) { | |||
if( javaFile.length()==0) { | |||
shouldCompile=true; | |||
log("Compiling " + srcFile.getPath() + | |||
" because it is out of date with respect to " + javaFile.getPath(), | |||
Project.MSG_DEBUG); | |||
" because java file "+ javaFile.getPath() | |||
+ " is empty", | |||
Project.MSG_VERBOSE); | |||
} | |||
} | |||
if(shouldCompile) { | |||
compileList.addElement(srcFile.getAbsolutePath()); | |||
} | |||
} | |||
} | |||
return shouldCompile; | |||
} | |||
/** | |||
* get a filename from our jsp file | |||
* @todo support packages and subdirs | |||
*/ | |||
protected File mapToJavaFile(File srcFile) { | |||
protected File mapToJavaFile(JspMangler mangler, File srcFile, File srcDir, File dest) { | |||
if (!srcFile.getName().endsWith(".jsp")) { | |||
return null; | |||
} | |||
JspNameMangler mangler=new JspNameMangler(); | |||
return new File(destDir, mangler.mapJspToJavaName(srcFile)); | |||
String javaFileName=mangler.mapJspToJavaName(srcFile); | |||
// String srcFileDir=srcFile.getParent(); | |||
String packageNameIn=srcFile.getAbsolutePath(); | |||
return new File(dest, javaFileName); | |||
} | |||
/** | |||
* delete any java output files that are empty | |||
* this is to get around a little defect in jasper: when it | |||
* fails, it leaves incomplete files around. | |||
*/ | |||
public void deleteEmptyJavaFiles() { | |||
if(javaFiles!=null) { | |||
Enumeration enum = javaFiles.elements(); | |||
while (enum.hasMoreElements()) { | |||
File file = (File )enum.nextElement(); | |||
if(file.exists() && file.length()==0) { | |||
log("deleting empty output file "+file); | |||
file.delete(); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
@@ -530,5 +612,6 @@ public class JspC extends MatchingTask | |||
//end inner class | |||
} | |||
//end class | |||
} |
@@ -0,0 +1,81 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2002 The Apache Software Foundation. All rights | |||
* reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or without | |||
* modification, are permitted provided that the following conditions | |||
* are met: | |||
* | |||
* 1. Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* 2. Redistributions in binary form must reproduce the above copyright | |||
* notice, this list of conditions and the following disclaimer in | |||
* the documentation and/or other materials provided with the | |||
* distribution. | |||
* | |||
* 3. The end-user documentation included with the redistribution, if | |||
* any, must include the following acknowlegement: | |||
* "This product includes software developed by the | |||
* Apache Software Foundation (http://www.apache.org/)." | |||
* Alternately, this acknowlegement may appear in the software itself, | |||
* if and wherever such third-party acknowlegements normally appear. | |||
* | |||
* 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||
* Foundation" must not be used to endorse or promote products derived | |||
* from this software without prior written permission. For written | |||
* permission, please contact apache@apache.org. | |||
* | |||
* 5. Products derived from this software may not be called "Apache" | |||
* nor may "Apache" appear in their names without prior written | |||
* permission of the Apache Group. | |||
* | |||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
* SUCH DAMAGE. | |||
* ==================================================================== | |||
* | |||
* This software consists of voluntary contributions made by many | |||
* individuals on behalf of the Apache Software Foundation. For more | |||
* information on the Apache Software Foundation, please see | |||
* <http://www.apache.org/>. | |||
*/ | |||
package org.apache.tools.ant.taskdefs.optional.jsp; | |||
import java.io.File; | |||
/** | |||
* This is an interface to the Mangler service that jspc needs to map | |||
* JSP file names to java files. | |||
* Note the complete lack of correlation | |||
* with Jasper's mangler interface. | |||
*/ | |||
public interface JspMangler { | |||
/** | |||
* map from a jsp file to a java filename; does not do packages | |||
* | |||
* @param jspFile file | |||
* @return java filename | |||
*/ | |||
String mapJspToJavaName(File jspFile); | |||
/** | |||
* taking in the substring representing the path relative to the source dir | |||
* return a new string representing the destination path | |||
*/ | |||
String mapPath(String path); | |||
} |
@@ -57,13 +57,13 @@ import java.io.IOException; | |||
/** | |||
* this is a class derived from the Jasper code to map from a JSP filename | |||
* to a valid java classname | |||
* to a valid java classname. | |||
* | |||
* @author Steve Loughran | |||
* @author Danno Ferrin | |||
* @see org.apache.jasper.compiler.CommandLineCompiler; | |||
*/ | |||
public class JspNameMangler { | |||
public class JspNameMangler implements JspMangler { | |||
/** | |||
* this is the list of keywords which can not be used as classnames | |||
@@ -103,7 +103,7 @@ public class JspNameMangler { | |||
* @param jspFile jspFile file | |||
* @return exensionless potentially remapped name | |||
*/ | |||
public String mapJspToBaseName(File jspFile) { | |||
private String mapJspToBaseName(File jspFile) { | |||
String className; | |||
className = stripExtension(jspFile); | |||
@@ -184,5 +184,13 @@ public class JspNameMangler { | |||
return new String(result); | |||
} | |||
/** | |||
* taking in the substring representing the path relative to the source dir | |||
* return a new string representing the destination path | |||
* @todo | |||
*/ | |||
public String mapPath(String path) { | |||
return null; | |||
} | |||
} | |||
@@ -64,21 +64,22 @@ import java.util.Enumeration; | |||
import java.io.File; | |||
/** | |||
* This is the default implementation for the CompilerAdapter interface. | |||
* This is the default implementation for the JspCompilerAdapter interface. | |||
* This is currently very light on the ground since only one compiler type is | |||
* supported. | |||
* | |||
* @author Matthew Watson <a href="mailto:mattw@i3sp.com">mattw@i3sp.com</a> | |||
*/ | |||
public abstract class DefaultCompilerAdapter | |||
implements CompilerAdapter | |||
{ | |||
public abstract class DefaultJspCompilerAdapter | |||
implements JspCompilerAdapter { | |||
/* ------------------------------------------------------------ */ | |||
private static String lSep = System.getProperty("line.separator"); | |||
/* ------------------------------------------------------------ */ | |||
/** | |||
* Logs the compilation parameters, adds the files to compile and logs the | |||
* &qout;niceSourceList" | |||
* "niceSourceList" | |||
*/ | |||
protected void logAndAddFilesToCompile(JspC jspc, | |||
Vector compileList, | |||
@@ -103,11 +104,22 @@ public abstract class DefaultCompilerAdapter | |||
jspc.log(niceSourceList.toString(), Project.MSG_VERBOSE); | |||
} | |||
/** | |||
* our owner | |||
*/ | |||
protected JspC owner; | |||
/** | |||
* set the owner | |||
*/ | |||
public void setJspc( JspC owner ) { | |||
this.owner = owner; | |||
} | |||
/** get the owner | |||
* @return the owner; should never be null | |||
*/ | |||
public JspC getJspc() { | |||
return owner; | |||
} | |||
@@ -149,6 +161,15 @@ public abstract class DefaultCompilerAdapter | |||
cmd.createArgument().setValue(argument); | |||
cmd.createArgument().setFile(file); | |||
} | |||
} | |||
} | |||
/** | |||
* ask if compiler can sort out its own dependencies | |||
* @return true if the compiler wants to do its own | |||
* depends | |||
*/ | |||
public boolean implementsOwnDependencyChecking() { | |||
return false; | |||
} | |||
} | |||
@@ -59,6 +59,8 @@ import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.types.Commandline; | |||
import org.apache.tools.ant.types.Path; | |||
import org.apache.tools.ant.taskdefs.optional.jsp.JspC; | |||
import org.apache.tools.ant.taskdefs.optional.jsp.JspMangler; | |||
import org.apache.tools.ant.taskdefs.optional.jsp.JspNameMangler; | |||
import org.apache.tools.ant.taskdefs.Java; | |||
import java.io.File; | |||
@@ -71,7 +73,7 @@ import java.io.File; | |||
* @author steve loughran | |||
* @since ant1.5 | |||
*/ | |||
public class JasperC extends DefaultCompilerAdapter | |||
public class JasperC extends DefaultJspCompilerAdapter | |||
{ | |||
/** | |||
* our execute method | |||
@@ -113,6 +115,9 @@ public class JasperC extends DefaultCompilerAdapter | |||
ex, getJspc().getLocation()); | |||
} | |||
} | |||
finally { | |||
getJspc().deleteEmptyJavaFiles(); | |||
} | |||
} | |||
@@ -130,6 +135,8 @@ public class JasperC extends DefaultCompilerAdapter | |||
addArg(cmd,"-uriroot",jspc.getUriroot()); | |||
addArg(cmd,"-uribase",jspc.getUribase()); | |||
addArg(cmd,"-ieplugin",jspc.getIeplugin()); | |||
addArg(cmd,"-die9"); | |||
if (jspc.isMapped()){ | |||
addArg(cmd,"-mapped"); | |||
} | |||
@@ -140,4 +147,12 @@ public class JasperC extends DefaultCompilerAdapter | |||
logAndAddFilesToCompile(getJspc(), getJspc().getCompileList(), cmd); | |||
return cmd; | |||
} | |||
/** | |||
* @return an instance of the mangler this compiler uses | |||
*/ | |||
public JspMangler createMangler() { | |||
return new JspNameMangler(); | |||
} | |||
} |
@@ -1,7 +1,7 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2001 The Apache Software Foundation. All rights | |||
* Copyright (c) 2001-2002 The Apache Software Foundation. All rights | |||
* reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or without | |||
@@ -55,6 +55,7 @@ package org.apache.tools.ant.taskdefs.optional.jsp.compilers; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.taskdefs.optional.jsp.JspC; | |||
import org.apache.tools.ant.taskdefs.optional.jsp.JspMangler; | |||
/** | |||
* The interface that all jsp compiler adapters must adher to. | |||
@@ -70,7 +71,7 @@ import org.apache.tools.ant.taskdefs.optional.jsp.JspC; | |||
* @author Matthew Watson <a href="mailto:mattw@i3sp.com">mattw@i3sp.com</a> | |||
*/ | |||
public interface CompilerAdapter { | |||
public interface JspCompilerAdapter { | |||
/** | |||
* Sets the compiler attributes, which are stored in the Jspc task. | |||
@@ -83,4 +84,17 @@ public interface CompilerAdapter { | |||
* @return has the compilation been successful | |||
*/ | |||
boolean execute() throws BuildException; | |||
/** | |||
* @return an instance of the mangler this compiler uses | |||
*/ | |||
JspMangler createMangler(); | |||
/** | |||
* ask if compiler can sort out its own dependencies | |||
* @return true if the compiler wants to do its own | |||
* depends | |||
*/ | |||
boolean implementsOwnDependencyChecking(); | |||
} |
@@ -1,7 +1,7 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2001 The Apache Software Foundation. All rights | |||
* Copyright (c) 2001-2002 The Apache Software Foundation. All rights | |||
* reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or without | |||
@@ -63,10 +63,10 @@ import org.apache.tools.ant.Task; | |||
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a> | |||
* @author Matthew Watson <a href="mailto:mattw@i3sp.com">mattw@i3sp.com</a> | |||
*/ | |||
public class CompilerAdapterFactory { | |||
public class JspCompilerAdapterFactory { | |||
/** This is a singlton -- can't create instances!! */ | |||
private CompilerAdapterFactory() { | |||
/** This is a singleton -- can't create instances!! */ | |||
private JspCompilerAdapterFactory() { | |||
} | |||
/** | |||
@@ -85,7 +85,7 @@ public class CompilerAdapterFactory { | |||
* @throws BuildException if the compiler type could not be resolved into | |||
* a compiler adapter. | |||
*/ | |||
public static CompilerAdapter getCompiler( String compilerType, Task task ) | |||
public static JspCompilerAdapter getCompiler( String compilerType, Task task ) | |||
throws BuildException { | |||
/* If I've done things right, this should be the extent of the | |||
* conditional statements required. | |||
@@ -102,14 +102,14 @@ public class CompilerAdapterFactory { | |||
* | |||
* @param className The fully qualified classname to be created. | |||
* @throws BuildException This is the fit that is thrown if className | |||
* isn't an instance of CompilerAdapter. | |||
* isn't an instance of JspCompilerAdapter. | |||
*/ | |||
private static CompilerAdapter resolveClassName( String className ) | |||
private static JspCompilerAdapter resolveClassName( String className ) | |||
throws BuildException { | |||
try { | |||
Class c = Class.forName( className ); | |||
Object o = c.newInstance(); | |||
return (CompilerAdapter) o; | |||
return (JspCompilerAdapter) o; | |||
} catch ( ClassNotFoundException cnfe ) { | |||
throw new BuildException( className + " can\'t be found.", cnfe ); | |||
} catch ( ClassCastException cce ) { |