diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetBaseMatchingTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetBaseMatchingTask.java new file mode 100644 index 000000000..e31d97a2e --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetBaseMatchingTask.java @@ -0,0 +1,213 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2003 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 + * . + */ + + +package org.apache.tools.ant.taskdefs.optional.dotnet; + +import org.apache.tools.ant.taskdefs.MatchingTask; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.DirectoryScanner; + +import java.io.File; +import java.util.Vector; +import java.util.Hashtable; +import java.util.Enumeration; + +/** + * refactoring of some stuff so that different things (like ILASM) + * can use shared code. + * @author steve loughran + */ +public class DotnetBaseMatchingTask extends MatchingTask { + /** + * output file. If not supplied this is derived from the source file + */ + protected File outputFile; + /** + * sets of file to compile + */ + protected Vector filesets = new Vector(); + /** + * source directory upon which the search pattern is applied + */ + protected File srcDir; + + /** + * Overridden because we need to be able to set the srcDir. + */ + public File getSrcDir() { + return this.srcDir; + } + + /** + * Set the source directory of the files to be compiled. + * + *@param srcDirName The new SrcDir value + */ + public void setSrcDir(File srcDirName) { + this.srcDir = srcDirName; + } + + /** + * Set the name of exe/library to create. + * + *@param file The new outputFile value + */ + public void setDestFile(File file) { + outputFile = file; + } + + /** + * add a new source directory to the compile + * @param src + */ + public void addSrc(FileSet src) { + filesets.add(src); + } + + /** + * get the destination file + * @return the dest file or null for not assigned + */ + public File getDestFile() { + return outputFile; + } + + /** + * create the list of files + * @param filesToBuild vector to add files to + * @param outputTimestamp timestamp to compare against + * @return number of files out of date + */ + protected int buildFileList(NetCommand command, Hashtable filesToBuild, long outputTimestamp) { + int filesOutOfDate=0; + boolean scanImplicitFileset=getSrcDir()!=null || filesets.size()==0; + if(scanImplicitFileset) { + //scan for an implicit fileset if there was a srcdir set + //or there was no srcDir set but the @ + if (getSrcDir() == null) { + //if there is no src dir here, set it + setSrcDir(getProject().resolveFile(".")); + } + log("working from source directory " + getSrcDir(), + Project.MSG_VERBOSE); + //get dependencies list. + DirectoryScanner scanner = getDirectoryScanner(getSrcDir()); + filesOutOfDate = command.scanOneFileset(scanner, + filesToBuild, outputTimestamp); + } + //get any included source directories + for (int i = 0; i < filesets.size(); i++) { + FileSet fs = (FileSet) filesets.elementAt(i); + filesOutOfDate+= command.scanOneFileset( + fs.getDirectoryScanner(getProject()), + filesToBuild, + outputTimestamp); + } + + return filesOutOfDate; + } + + /** + * add the list of files to a command + * @param filesToBuild vector of files + * @param command the command to append to + */ + protected void addFilesToCommand(Hashtable filesToBuild, NetCommand command) { + int count=filesToBuild.size(); + log("compiling " + count + " file" + ((count== 1) ? "" : "s")); + Enumeration files=filesToBuild.elements(); + while (files.hasMoreElements()) { + File file = (File) files.nextElement(); + command.addArgument(file.toString()); + } + } + + /** + * determine the timestamp of the output file + * @return a timestamp or 0 for no output file known/exists + */ + protected long getOutputFileTimestamp() { + long outputTimestamp; + if (getDestFile() != null && getDestFile().exists()) { + outputTimestamp = getDestFile().lastModified(); + } else { + outputTimestamp = 0; + } + return outputTimestamp; + } + + /** + * finish off the command by adding all dependent files, execute + * @param command + */ + protected void addFilesAndExecute(NetCommand command) { + long outputTimestamp = getOutputFileTimestamp(); + Hashtable filesToBuild =new Hashtable(); + int filesOutOfDate = buildFileList(command,filesToBuild, outputTimestamp); + + //add the files to the command + addFilesToCommand(filesToBuild, command); + + //now run the command of exe + settings + files + if (filesOutOfDate > 0) { + command.runCommand(); + } else { + log("output file is up to date",Project.MSG_VERBOSE); + } + } + + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java index ee9c750c3..c5236f9c6 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java @@ -108,7 +108,7 @@ import org.apache.tools.ant.types.EnumeratedAttribute; */ public abstract class DotnetCompile - extends MatchingTask { + extends DotnetBaseMatchingTask { /** * list of reference classes. (pretty much a classpath equivalent) @@ -130,11 +130,6 @@ public abstract class DotnetCompile */ private File win32res; - /** - * output file. If not supplied this is derived from the source file - */ - private File outputFile; - /** * flag to control action on execution trouble */ @@ -152,11 +147,6 @@ public abstract class DotnetCompile */ private boolean optimize; - /** - * sets of file to compile - */ - protected Vector filesets = new Vector(); - /** * a list of definitions to support; */ @@ -222,11 +212,6 @@ public abstract class DotnetCompile */ protected String extraOptions; - /** - * source directory upon which the search pattern is applied - */ - private File srcDir; - /** * type of target. Should be one of exe|library|module|winexe|(null) * default is exe; the actual value (if not null) is fed to the command @@ -244,7 +229,7 @@ public abstract class DotnetCompile /** * list of extra modules to refer to */ - String additionalModules; + protected String additionalModules; /** @@ -552,23 +537,6 @@ public abstract class DotnetCompile } - /** - * Overridden because we need to be able to set the srcDir. - */ - public File getSrcDir() { - return this.srcDir; - } - - /** - * Set the source directory of the files to be compiled. - * - *@param srcDirName The new SrcDir value - */ - public void setSrcDir(File srcDirName) { - this.srcDir = srcDirName; - } - - /** * Set the destination directory of files to be compiled. * @@ -595,12 +563,12 @@ public abstract class DotnetCompile */ public void setTargetType(String ttype) throws BuildException { - targetType = ttype.toLowerCase(); - if (targetType.equals("exe") || targetType.equals("library") || - targetType.equals("module") || targetType.equals("winexe")) { - targetType = targetType; + ttype = ttype.toLowerCase(); + if (ttype.equals("exe") || ttype.equals("library") || + ttype.equals("module") || ttype.equals("winexe")) { + targetType = ttype; } else { - throw new BuildException("targetType " + targetType + throw new BuildException("targetType " + ttype + " is not one of 'exe', 'module', 'winexe' or 'library'" ); } } @@ -766,17 +734,6 @@ public abstract class DotnetCompile } - - /** - * Set the name of exe/library to create. - * - *@param file The new outputFile value - */ - public void setDestFile(File file) { - outputFile = file; - } - - /** * get the argument or null for no argument needed * @@ -810,14 +767,6 @@ public abstract class DotnetCompile return failOnError; } - /** - * add a new source directory to the compile - * @param src - */ - public void addSrc(FileSet src) { - filesets.add(src); - } - /** * test for a string containing something useful * @@ -861,14 +810,6 @@ public abstract class DotnetCompile return "**/*." + getFileExtension(); } - /** - * get the destination file - * @return the dest file or null for not assigned - */ - public File getDestFile() { - return outputFile; - } - /** * do the work by building the command line and then calling it * @@ -904,98 +845,6 @@ public abstract class DotnetCompile */ public abstract String getFileExtension(); - /** - * create the list of files - * @param filesToBuild vector to add files to - * @param outputTimestamp timestamp to compare against - * @return number of files out of date - */ - protected int buildFileList(Hashtable filesToBuild, long outputTimestamp) { - int filesOutOfDate=0; - boolean scanImplicitFileset=getSrcDir()!=null || filesets.size()==0; - if(scanImplicitFileset) { - //scan for an implicit fileset if there was a srcdir set - //or there was no srcDir set but the @ - if (getSrcDir() == null) { - //if there is no src dir here, set it - setSrcDir(getProject().resolveFile(".")); - } - log("working from source directory " + getSrcDir(), Project.MSG_VERBOSE); - //get dependencies list. - DirectoryScanner scanner = super.getDirectoryScanner(getSrcDir()); - filesOutOfDate = scanOneFileset(scanner, filesToBuild, outputTimestamp); - } - //get any included source directories - for (int i = 0; i < filesets.size(); i++) { - FileSet fs = (FileSet) filesets.elementAt(i); - filesOutOfDate+=scanOneFileset(fs.getDirectoryScanner(getProject()), - filesToBuild, - outputTimestamp); - } - - return filesOutOfDate; - } - - /** - * scan through one fileset for files to include - * @param scanner - * @param filesToBuild - * @param outputTimestamp timestamp to compare against - * @return #of files out of date - * @todo: should FAT granularity be included here? - */ - protected int scanOneFileset(DirectoryScanner scanner, Hashtable filesToBuild, - long outputTimestamp) { - int filesOutOfDate = 0; - String[] dependencies = scanner.getIncludedFiles(); - File base = scanner.getBasedir(); - //add to the list - for (int i = 0; i < dependencies.length; i++) { - File targetFile = new File(base, dependencies[i]); - if(filesToBuild.get(targetFile)==null) { - log(targetFile.toString(), Project.MSG_VERBOSE); - filesToBuild.put(targetFile,targetFile); - if (targetFile.lastModified() > outputTimestamp) { - filesOutOfDate++; - log("Source file " + targetFile.toString() + " is out of date", - Project.MSG_VERBOSE); - } else { - log("Source file " + targetFile.toString() + " is up to date", - Project.MSG_VERBOSE); - } - } - } - return filesOutOfDate; - } - - /** - * add the list of files to a command - * @param filesToBuild vector of files - * @param command the command to append to - */ - protected void addFilesToCommand(Hashtable filesToBuild, NetCommand command) { - int count=filesToBuild.size(); - log("compiling " + count + " file" + ((count== 1) ? "" : "s")); - Enumeration files=filesToBuild.elements(); - while (files.hasMoreElements()) { - File file = (File) files.nextElement(); - command.addArgument(file.toString()); - } - } - - /** - * determine the timestamp of the output file - * @return a timestamp or 0 for no output file known/exists - */ - protected long getOutputFileTimestamp() { - long outputTimestamp; - if (getDestFile() != null && getDestFile().exists()) { - outputTimestamp = getDestFile().lastModified(); - } else { - outputTimestamp = 0; - } - return outputTimestamp; - } /** * fill in the common information @@ -1035,24 +884,6 @@ public abstract class DotnetCompile */ protected abstract void addCompilerSpecificOptions(NetCommand command); - /** - * finish off the command by adding all dependent files, execute - * @param command - */ - protected void addFilesAndExecute(NetCommand command) { - long outputTimestamp = getOutputFileTimestamp(); - Hashtable filesToBuild =new Hashtable(); - int filesOutOfDate = buildFileList(filesToBuild, outputTimestamp); - - //add the files to the command - addFilesToCommand(filesToBuild, command); - - //now run the command of exe + settings + files - if (filesOutOfDate > 0) { - command.runCommand(); - } - } - /** * override point for delimiting definitions * @return @@ -1138,6 +969,8 @@ public abstract class DotnetCompile || owner.getProject().getProperty(condition) != null; } } + + } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java index 3125c848c..29c8bf7dc 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java @@ -55,25 +55,16 @@ * build notes * -The reference CD to listen to while editing this file is * nap: Underworld - Everything, Everything - * -variable naming policy from Fowler's refactoring book. - * -tested against the PDC pre-beta of csc.exe; future versions will - * inevitably change things */ -// ==================================================================== -// place in the optional ant tasks package -// but in its own dotnet group -// ==================================================================== package org.apache.tools.ant.taskdefs.optional.dotnet; -// ==================================================================== -// imports -// ==================================================================== import java.io.File; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.taskdefs.MatchingTask; /** @@ -93,15 +84,14 @@ import org.apache.tools.ant.taskdefs.MatchingTask; * * The task is a directory based task, so attributes like includes="*.il" * and excludes="broken.il" can be used to control the files pulled - * in. Each file is built on its own, producing an appropriately named output - * file unless manually specified with outfile + * in. You can also use nested <src> filesets to refer to source. * *@author Steve Loughran steve_l@iseran.com - *@version 0.5 + *@version 0.6 */ public class Ilasm - extends MatchingTask { + extends DotnetBaseMatchingTask { /** * Name of the executable. The .exe suffix is deliberately not included in @@ -124,11 +114,6 @@ public class Ilasm */ protected static final String exe_title = "ilasm"; - /** - * source directory upon which the search pattern is applied - */ - private File srcDir; - /** * type of target. Should be one of exe|library|module|winexe|(null) * default is exe; the actual value (if not null) is fed to the command @@ -148,11 +133,6 @@ public class Ilasm protected boolean listing; - /** - * output file. If not supplied this is derived from the source file - */ - protected File outputFile; - /** * resource file (.res format) to include in the app. */ @@ -205,15 +185,6 @@ public class Ilasm } - /** - * Set the source directory containing the files to be compiled. - * - * @param srcDirName The new SrcDir value - */ - public void setSrcDir(File srcDirName) { - srcDir = srcDirName; - } - /** * Sets the type of target, either "exe" or "library". @@ -324,8 +295,8 @@ public class Ilasm /** - * Set the output file. - * + * Set the output file; identical to setDestFile + * @see DotnetBaseMatchingTask.setDestFile *@param params The new outputFile value */ public void setOutputFile(File params) { @@ -385,7 +356,7 @@ public class Ilasm * *@return The failFailOnError value */ - public boolean getFailFailOnError() { + public boolean getFailOnError() { return failOnError; } @@ -478,6 +449,13 @@ public class Ilasm } } + /** + * set the target type to one of exe|library + * @param targetType + */ + public void setTargetType(TargetTypes targetType) { + this.targetType = targetType.getValue(); + } /** * This is the execution entry point. Build a list of files and call ilasm @@ -491,32 +469,21 @@ public class Ilasm srcDir = getProject().resolveFile("."); } - //get dependencies list. - DirectoryScanner scanner = super.getDirectoryScanner(srcDir); - String[] dependencies = scanner.getIncludedFiles(); - log("assembling " + dependencies.length + " file" + ((dependencies.length == 1) ? "" : "s")); - String baseDir = scanner.getBasedir().toString(); - //add to the command - for (int i = 0; i < dependencies.length; i++) { - String targetFile = dependencies[i]; - targetFile = baseDir + File.separator + targetFile; - executeOneFile(targetFile); - } + NetCommand command = buildIlasmCommand(); + + addFilesAndExecute(command); } // end execute /** - * do the work for one file by building the command line then calling it - * - *@param targetFile name of the the file to assemble - *@throws BuildException if the assembly failed and FailOnError is true + * build up our ilasm command + * @return */ - public void executeOneFile(String targetFile) - throws BuildException { + private NetCommand buildIlasmCommand() { NetCommand command = new NetCommand(this, exe_title, exe_name); - command.setFailOnError(getFailFailOnError()); + command.setFailOnError(getFailOnError()); //fill in args command.addArgument(getDebugParameter()); command.addArgument(getTargetTypeParameter()); @@ -532,10 +499,23 @@ public class Ilasm * command.addArgument(); * command.addArgument(); */ - command.addArgument(targetFile); - //now run the command of exe + settings + file - command.runCommand(); + return command; + } + + + + /** + * Target types to build. + * valid build types are exe|library|module|winexe + */ + public static class TargetTypes extends EnumeratedAttribute { + public String[] getValues() { + return new String[]{ + "exe", + "library", + }; + } } - // end executeOneFile + } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java index 708228970..94ea91524 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java @@ -65,9 +65,12 @@ package org.apache.tools.ant.taskdefs.optional.dotnet; import java.io.File; import java.io.IOException; +import java.util.Hashtable; + import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; +import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.taskdefs.Execute; import org.apache.tools.ant.taskdefs.ExecuteStreamHandler; import org.apache.tools.ant.taskdefs.LogStreamHandler; @@ -259,5 +262,38 @@ public class NetCommand { throw new BuildException(title + " failed: " + e, e, owner.getLocation()); } } + + + /** + * scan through one fileset for files to include + * @param scanner + * @param filesToBuild + * @param outputTimestamp timestamp to compare against + * @return #of files out of date + * @todo: should FAT granularity be included here? + */ + public int scanOneFileset(DirectoryScanner scanner, Hashtable filesToBuild, + long outputTimestamp) { + int filesOutOfDate = 0; + String[] dependencies = scanner.getIncludedFiles(); + File base = scanner.getBasedir(); + //add to the list + for (int i = 0; i < dependencies.length; i++) { + File targetFile = new File(base, dependencies[i]); + if (filesToBuild.get(targetFile) == null) { + owner.log(targetFile.toString(), Project.MSG_VERBOSE); + filesToBuild.put(targetFile, targetFile); + if (targetFile.lastModified() > outputTimestamp) { + filesOutOfDate++; + owner.log("Source file " + targetFile.toString() + " is out of date", + Project.MSG_VERBOSE); + } else { + owner.log("Source file " + targetFile.toString() + " is up to date", + Project.MSG_VERBOSE); + } + } + } + return filesOutOfDate; + } }