PR: 1763 Merge <apply> and <execon> into a single task (and keep Transform as an empty class for backwards compatibility at the source level). git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269330 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -108,6 +108,8 @@ Other changes: | |||
| * New update attribute for <zip> and friends - update an existing | |||
| archive instead of creating a new one. | |||
| * <apply> and <execon> have been merged into a single task. | |||
| Fixed bugs: | |||
| ----------- | |||
| @@ -175,6 +177,9 @@ Fixed bugs: | |||
| * <junit> tries to include all necessary classes for the task itself | |||
| to the classpath when running in fork mode - doesn't work for JDK 1.1 | |||
| * <apply> and <execon> do now execute the command only once, if you | |||
| specify the parallel attribute - instead of once per fileset. | |||
| Changes from Ant 1.2 to Ant 1.3 | |||
| =========================================== | |||
| @@ -7,17 +7,23 @@ | |||
| <body> | |||
| <h2><a name="apply">Apply</a></h2> | |||
| <h2><a name="apply">Apply/<i>ExecOn</i></a></h2> | |||
| <p><i>The name execon is deprecated and only kept for backwards | |||
| compatibilty.</i></p> | |||
| <h3>Description</h3> | |||
| <p>Executes a system command. When the <i>os</i> attribute is specified, then | |||
| the command is only executed when Ant is run on one of the specified operating | |||
| systems.</p> | |||
| <p>The files and/or directories of a number of <a | |||
| href="../CoreTypes/fileset.html">FileSet</a>s are passed as arguments to the system | |||
| command. The timestamp of each source file is compared to the | |||
| timestamp of a target file which is defined by a nested <a | |||
| href="../CoreTypes/mapper.html">mapper</a> element. At least one fileset and exactly | |||
| one mapper element are required.</p> | |||
| href="../CoreTypes/fileset.html">FileSet</a>s are passed as arguments | |||
| to the system command.</p> | |||
| <p>If you specify a nested <a | |||
| href="../CoreTypes/mapper.html">mapper</a> and the destdir attribute, | |||
| the timestamp of each source file is compared to the timestamp of a | |||
| target file which is defined by the nested mapper element and searched | |||
| for in the given destdir.</p> | |||
| <p>At least one fileset is required, you must not specify more than | |||
| one mapper.</p> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| @@ -36,7 +42,7 @@ one mapper element are required.</p> | |||
| <td valign="top">the directory where the <apply> expects the target files will be placed by the | |||
| command, when it is executed. | |||
| </td> | |||
| <td align="center" valign="top">Yes</td> | |||
| <td align="center" valign="top">Yes, if you specify a nested mapper</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">dir</td> | |||
| @@ -67,12 +73,6 @@ one mapper element are required.</p> | |||
| returncode other than 0.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">newenvironment</td> | |||
| <td valign="top">Do not propagate old environment when new environment | |||
| variables are specified.</td> | |||
| <td align="center" valign="top">No, default is <i>false</i></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">skipemptyfilesets</td> | |||
| <td valign="top">Don't run the command, if no source files have | |||
| @@ -95,6 +95,23 @@ one mapper element are required.</p> | |||
| the names of directories are considered.</td> | |||
| <td align="center" valign="top">No, default is <i>file</i></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">newenvironment</td> | |||
| <td valign="top">Do not propagate old environment when new environment | |||
| variables are specified.</td> | |||
| <td align="center" valign="top">No, default is <i>false</i></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">vmlauncher</td> | |||
| <td valign="top">Run command using the Java VM's execution facilities | |||
| where available. If set to false the underlying OS's shell, | |||
| either directly or through the antRun scripts, will be used. | |||
| Under some operating systems, this gives access to facilities | |||
| not normally available through the VM including, under Windows, | |||
| being able to execute scripts, rather than their associated | |||
| interpreter.</td> | |||
| <td align="center" valign="top">No, default is <i>true</i></td> | |||
| </tr> | |||
| </table> | |||
| <h3>Parameters specified as nested elements</h3> | |||
| <h4>fileset</h4> | |||
| @@ -114,7 +131,9 @@ use a nested <code><srcfile></code> element between your | |||
| <p><code><targetfile></code> is similar to | |||
| <code><srcfile></code> and marks the position of the target | |||
| filename on the command line. If omitted, the target filenames will | |||
| not be added to the command line at all.</p> | |||
| not be added to the command line at all. This element can only be | |||
| specified, if you also define a nested mapper and the destdir | |||
| attribute.</p> | |||
| <h4>env</h4> | |||
| <p>It is possible to specify environment variables to pass to the | |||
| system command via nested <code><env></code> elements. See the | |||
| @@ -124,6 +143,34 @@ description in the section about <a href="exec.html#env">exec</a></p> | |||
| <code><env></code>.</p> | |||
| <h3>Examples</h3> | |||
| <blockquote><pre> | |||
| <apply executable="ls" > | |||
| <arg value="-l"/> | |||
| <fileset dir="/tmp"> | |||
| <patternset> | |||
| <exclude name="**/*.txt"/> | |||
| </patternset> | |||
| </fileset> | |||
| <fileset refid="other.files"/> | |||
| </apply> | |||
| </pre></blockquote> | |||
| <p>invokes <code>ls -l</code>, adding the absolute filenames of all | |||
| files below <code>/tmp</code> not ending in <code>.txt</code> and all | |||
| files of the FileSet with <code>id</code> <code>other.files</code> to | |||
| the command line.</p> | |||
| <blockquote><pre> | |||
| <apply executable="somecommand" parallel="false" > | |||
| <arg value="arg1"/> | |||
| <srfile/> | |||
| <arg value="arg2"/> | |||
| <fileset dir="/tmp"/> | |||
| </apply> | |||
| </pre></blockquote> | |||
| <p>invokes <code>somecommand arg1 SOURCEFILENAME arg2</code> for each | |||
| file in <code>/tmp</code> replacing SOURCEFILENAME with the absolute | |||
| filename of each file in turn. If <code>parallel</code> had been set | |||
| to true, SOURCEFILENAME would be replaced with the absolute filenames | |||
| of all files separated by spaces.</p> | |||
| <blockquote><pre> | |||
| <apply executable="cc" dest="src/C" parallel="false"> | |||
| <arg value="-c"/> | |||
| <arg value="-o"/> | |||
| @@ -1,156 +0,0 @@ | |||
| <html> | |||
| <head> | |||
| <meta http-equiv="Content-Language" content="en-us"> | |||
| <title>Ant User Manual</title> | |||
| </head> | |||
| <body> | |||
| <h2><a name="execon">ExecOn</a></h2> | |||
| <h3>Description</h3> | |||
| <p>Executes a system command. When the <i>os</i> attribute is specified, then | |||
| the command is only executed when Ant is run on one of the specified operating | |||
| systems.</p> | |||
| <p>The files and/or directories of a number of <a | |||
| href="../CoreTypes/fileset.html">FileSet</a>s are passed as arguments to the system | |||
| command. At least one nested <code><fileset></code> is required.</p> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">executable</td> | |||
| <td valign="top">the command to execute without any command line | |||
| arguments.</td> | |||
| <td align="center" valign="top">Yes</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">dir</td> | |||
| <td valign="top">the directory in which the command should be executed.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">os</td> | |||
| <td valign="top">list of Operating Systems on which the command may be | |||
| executed. If the current OS's name is contained in this list, the command will | |||
| be executed. The OS's name is determined by the Java Virtual machine and is set | |||
| in the "os.name" system property.</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">output</td> | |||
| <td valign="top">the file to which the output of the command should be | |||
| redirected.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">timeout</td> | |||
| <td valign="top">Stop the command if it doesn't finish within the | |||
| specified time (given in milliseconds).</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">failonerror</td> | |||
| <td valign="top">Stop the buildprocess if the command exits with a | |||
| returncode other than 0.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">newenvironment</td> | |||
| <td valign="top">Do not propagate old environment when new environment | |||
| variables are specified.</td> | |||
| <td align="center" valign="top">No, default is <i>false</i></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">vmlauncher</td> | |||
| <td valign="top">Run command using the Java VM's execution facilities | |||
| where available. If set to false the underlying OS's shell, | |||
| either directly or through the antRun scripts, will be used. | |||
| Under some operating systems, this gives access to facilities | |||
| not nomrally available through the VM including, under Windows, | |||
| being able to execute scripts, rather than their associated | |||
| interpreter.</td> | |||
| <td align="center" valign="top">No, default is <i>true</i></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">skipemptyfilesets</td> | |||
| <td valign="top">Don't run the command, if no source files have | |||
| been found.</td> | |||
| <td align="center" valign="top">No, default is <i>false</i></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">parallel</td> | |||
| <td valign="top">Run the command only once, appending all files as | |||
| arguments. If false, command will be executed once for every file. | |||
| Defaults to false. </td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">type</td> | |||
| <td valign="top">One of <i>file</i>, <i>dir</i> or | |||
| <i>both</i>. If set to <i>file</i>, only the names of plain | |||
| files will be sent to the command. If set to <i>dir</i>, only | |||
| the names of directories are considered.</td> | |||
| <td align="center" valign="top">No, default is <i>file</i></td> | |||
| </tr> | |||
| </table> | |||
| <h3>Parameters specified as nested elements</h3> | |||
| <h4>fileset</h4> | |||
| <p>You can use any number of nested <code><fileset></code> | |||
| elements to define the files for this task and refer to | |||
| <code><fileset></code>s defined elsewhere.</p> | |||
| <h4>arg</h4> | |||
| <p>Command line arguments should be specified as nested | |||
| <code><arg></code> elements. See <a | |||
| href="../using.html#arg">Command line arguments</a>.</p> | |||
| <h4>srcfile</h4> | |||
| <p>By default the file names of the source files will be added to the | |||
| end of the command line. If you need to place it somewhere different, | |||
| use a nested <code><srcfile></code> element between your | |||
| <code><arg></code> elements to mark the insertion point.</p> | |||
| <h4>env</h4> | |||
| <p>It is possible to specify environment variables to pass to the | |||
| system command via nested <code><env></code> elements. See the | |||
| description in the section about <a href="exec.html#env">exec</a></p> | |||
| <p>Please note that the environment of the current Ant process is | |||
| <b>not</b> passed to the system command if you specify variables using | |||
| <code><env></code>.</p> | |||
| <h3>Examples</h3> | |||
| <blockquote><pre> | |||
| <execon executable="ls" > | |||
| <arg value="-l"/> | |||
| <fileset dir="/tmp"> | |||
| <patternset> | |||
| <exclude name="**/*.txt"/> | |||
| </patternset> | |||
| </fileset> | |||
| <fileset refid="other.files"/> | |||
| </execon> | |||
| </pre></blockquote> | |||
| <p>invokes <code>ls -l</code>, adding the absolute filenames of all | |||
| files below <code>/tmp</code> not ending in <code>.txt</code> and all | |||
| files of the FileSet with <code>id</code> <code>other.files</code> to | |||
| the command line.</p> | |||
| <blockquote><pre> | |||
| <execon executable="somecommand" parallel="false" > | |||
| <arg value="arg1"/> | |||
| <srfile/> | |||
| <arg value="arg2"/> | |||
| <fileset dir="/tmp"/> | |||
| </execon> | |||
| </pre></blockquote> | |||
| <p>invokes <code>somecommand arg1 SOURCEFILENAME arg2</code> for each | |||
| file in <code>/tmp</code> replacing SOURCEFILENAME with the absolute | |||
| filename of each file in turn. If <code>parallel</code> had been set | |||
| to true, SOURCEFILENAME would be replaced with the absolute filenames | |||
| of all files separated by spaces.</p> | |||
| <hr> | |||
| <p align="center">Copyright © 2000,2001 Apache Software Foundation. All rights | |||
| Reserved.</p> | |||
| </body> | |||
| </html> | |||
| @@ -23,7 +23,7 @@ | |||
| <a href="CoreTasks/ant.html">Ant</a><br> | |||
| <a href="CoreTasks/antcall.html">AntCall</a><br> | |||
| <a href="CoreTasks/antstructure.html">AntStructure</a><br> | |||
| <a href="CoreTasks/apply.html">Apply</a><br> | |||
| <a href="CoreTasks/apply.html">Apply/<i>ExecOn</i></a><br> | |||
| <a href="CoreTasks/available.html">Available</a><br> | |||
| <a href="CoreTasks/chmod.html">Chmod</a><br> | |||
| <a href="CoreTasks/copy.html">Copy</a><br> | |||
| @@ -36,7 +36,6 @@ | |||
| <a href="CoreTasks/ear.html">Ear</a><br> | |||
| <a href="CoreTasks/echo.html">Echo</a><br> | |||
| <a href="CoreTasks/exec.html">Exec</a><br> | |||
| <a href="CoreTasks/execon.html">ExecOn</a><br> | |||
| <a href="CoreTasks/fail.html">Fail</a><br> | |||
| <a href="CoreTasks/filter.html">Filter</a><br> | |||
| <a href="CoreTasks/fixcrlf.html">FixCRLF</a><br> | |||
| @@ -56,7 +56,9 @@ package org.apache.tools.ant.taskdefs; | |||
| import org.apache.tools.ant.*; | |||
| import org.apache.tools.ant.types.*; | |||
| import org.apache.tools.ant.util.*; | |||
| import java.util.Hashtable; | |||
| import java.util.Vector; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| @@ -74,6 +76,15 @@ public class ExecuteOn extends ExecTask { | |||
| protected String type = "file"; | |||
| protected Commandline.Marker srcFilePos = null; | |||
| private boolean skipEmpty = false; | |||
| protected Commandline.Marker targetFilePos = null; | |||
| protected Mapper mapperElement = null; | |||
| protected FileNameMapper mapper = null; | |||
| protected File destDir = null; | |||
| /** | |||
| * Has <srcfile> been specified before <targetfile> | |||
| */ | |||
| protected boolean srcIsFirst = true; | |||
| /** | |||
| * Adds a set of files (nested fileset attribute). | |||
| @@ -103,6 +114,13 @@ public class ExecuteOn extends ExecTask { | |||
| skipEmpty = skip; | |||
| } | |||
| /** | |||
| * Set the destination directory. | |||
| */ | |||
| public void setDest(File destDir) { | |||
| this.destDir = destDir; | |||
| } | |||
| /** | |||
| * Marker that indicates where the name of the source file should | |||
| * be put on the command line. | |||
| @@ -116,18 +134,62 @@ public class ExecuteOn extends ExecTask { | |||
| return srcFilePos; | |||
| } | |||
| /** | |||
| * Marker that indicates where the name of the target file should | |||
| * be put on the command line. | |||
| */ | |||
| public Commandline.Marker createTargetfile() { | |||
| if (targetFilePos != null) { | |||
| throw new BuildException(taskType + " doesn\'t support multiple targetfile elements.", | |||
| location); | |||
| } | |||
| targetFilePos = cmdl.createMarker(); | |||
| srcIsFirst = (srcFilePos != null); | |||
| return targetFilePos; | |||
| } | |||
| /** | |||
| * Defines the FileNameMapper to use (nested mapper element). | |||
| */ | |||
| public Mapper createMapper() throws BuildException { | |||
| if (mapperElement != null) { | |||
| throw new BuildException("Cannot define more than one mapper", | |||
| location); | |||
| } | |||
| mapperElement = new Mapper(project); | |||
| return mapperElement; | |||
| } | |||
| protected void checkConfiguration() { | |||
| if ("execon".equals(taskName)) { | |||
| log("!! execon is deprecated. Use apply instead. !!"); | |||
| } | |||
| super.checkConfiguration(); | |||
| if (filesets.size() == 0) { | |||
| throw new BuildException("no filesets specified", location); | |||
| } | |||
| if (targetFilePos != null || mapperElement != null | |||
| || destDir != null) { | |||
| if (mapperElement == null) { | |||
| throw new BuildException("no mapper specified", location); | |||
| } | |||
| if (mapperElement == null) { | |||
| throw new BuildException("no dest attribute specified", | |||
| location); | |||
| } | |||
| mapper = mapperElement.getImplementation(); | |||
| } | |||
| } | |||
| protected void runExec(Execute exe) throws BuildException { | |||
| try { | |||
| Vector fileNames = new Vector(); | |||
| Vector baseDirs = new Vector(); | |||
| for (int i=0; i<filesets.size(); i++) { | |||
| Vector v = new Vector(); | |||
| FileSet fs = (FileSet) filesets.elementAt(i); | |||
| File base = fs.getDir(project); | |||
| DirectoryScanner ds = fs.getDirectoryScanner(project); | |||
| @@ -135,36 +197,28 @@ public class ExecuteOn extends ExecTask { | |||
| if (!"dir".equals(type)) { | |||
| String[] s = getFiles(base, ds); | |||
| for (int j=0; j<s.length; j++) { | |||
| v.addElement(s[j]); | |||
| fileNames.addElement(s[j]); | |||
| baseDirs.addElement(base); | |||
| } | |||
| } | |||
| if (!"file".equals(type)) { | |||
| String[] s = getDirs(base, ds);; | |||
| for (int j=0; j<s.length; j++) { | |||
| v.addElement(s[j]); | |||
| fileNames.addElement(s[j]); | |||
| baseDirs.addElement(base); | |||
| } | |||
| } | |||
| if (v.size() == 0 && skipEmpty) { | |||
| if (fileNames.size() == 0 && skipEmpty) { | |||
| log("Skipping fileset for directory " | |||
| + base + ". It is empty.", Project.MSG_INFO); | |||
| continue; | |||
| } | |||
| String[] s = new String[v.size()]; | |||
| v.copyInto(s); | |||
| int err = -1; | |||
| if (parallel) { | |||
| String[] command = getCommandline(s, base); | |||
| log("Executing " + Commandline.toString(command), | |||
| Project.MSG_VERBOSE); | |||
| exe.setCommandline(command); | |||
| runExecute(exe); | |||
| } else { | |||
| if (!parallel) { | |||
| String[] s = new String[fileNames.size()]; | |||
| fileNames.copyInto(s); | |||
| for (int j=0; j<s.length; j++) { | |||
| String[] command = getCommandline(s[j], base); | |||
| log("Executing " + Commandline.toString(command), | |||
| @@ -172,9 +226,23 @@ public class ExecuteOn extends ExecTask { | |||
| exe.setCommandline(command); | |||
| runExecute(exe); | |||
| } | |||
| fileNames.removeAllElements(); | |||
| baseDirs.removeAllElements(); | |||
| } | |||
| } | |||
| if (parallel) { | |||
| String[] s = new String[fileNames.size()]; | |||
| fileNames.copyInto(s); | |||
| File[] b = new File[baseDirs.size()]; | |||
| baseDirs.copyInto(b); | |||
| String[] command = getCommandline(s, b); | |||
| log("Executing " + Commandline.toString(command), | |||
| Project.MSG_VERBOSE); | |||
| exe.setCommandline(command); | |||
| runExecute(exe); | |||
| } | |||
| } catch (IOException e) { | |||
| throw new BuildException("Execute failed: " + e, e, location); | |||
| } finally { | |||
| @@ -189,22 +257,87 @@ public class ExecuteOn extends ExecTask { | |||
| * @param srcFiles The filenames to add to the commandline | |||
| * @param baseDir filenames are relative to this dir | |||
| */ | |||
| protected String[] getCommandline(String[] srcFiles, File baseDir) { | |||
| protected String[] getCommandline(String[] srcFiles, File[] baseDirs) { | |||
| Vector targets = new Vector(); | |||
| if (targetFilePos != null) { | |||
| Hashtable addedFiles = new Hashtable(); | |||
| for (int i=0; i<srcFiles.length; i++) { | |||
| String[] subTargets = mapper.mapFileName(srcFiles[i]); | |||
| if (subTargets != null) { | |||
| for (int j=0; j<subTargets.length; j++) { | |||
| String name = (new File(destDir, subTargets[j])).getAbsolutePath(); | |||
| if (!addedFiles.contains(name)) { | |||
| targets.addElement(name); | |||
| addedFiles.put(name, name); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| String[] targetFiles = new String[targets.size()]; | |||
| targets.copyInto(targetFiles); | |||
| String[] orig = cmdl.getCommandline(); | |||
| String[] result = new String[orig.length+srcFiles.length]; | |||
| String[] result = new String[orig.length+srcFiles.length+targetFiles.length]; | |||
| int index = orig.length; | |||
| int srcIndex = orig.length; | |||
| if (srcFilePos != null) { | |||
| index = srcFilePos.getPosition(); | |||
| srcIndex = srcFilePos.getPosition(); | |||
| } | |||
| System.arraycopy(orig, 0, result, 0, index); | |||
| if (targetFilePos != null) { | |||
| int targetIndex = targetFilePos.getPosition(); | |||
| if (srcIndex < targetIndex | |||
| || (srcIndex == targetIndex && srcIsFirst)) { | |||
| // 0 --> srcIndex | |||
| System.arraycopy(orig, 0, result, 0, srcIndex); | |||
| // srcIndex --> targetIndex | |||
| System.arraycopy(orig, srcIndex, result, | |||
| srcIndex + srcFiles.length, | |||
| targetIndex - srcIndex); | |||
| // targets are already absolute file names | |||
| System.arraycopy(targetFiles, 0, result, | |||
| targetIndex + srcFiles.length, | |||
| targetFiles.length); | |||
| // targetIndex --> end | |||
| System.arraycopy(orig, targetIndex, result, | |||
| targetIndex + srcFiles.length + targetFiles.length, | |||
| orig.length - targetIndex); | |||
| } else { | |||
| // 0 --> targetIndex | |||
| System.arraycopy(orig, 0, result, 0, targetIndex); | |||
| // targets are already absolute file names | |||
| System.arraycopy(targetFiles, 0, result, | |||
| targetIndex, | |||
| targetFiles.length); | |||
| // targetIndex --> srcIndex | |||
| System.arraycopy(orig, targetIndex, result, | |||
| targetIndex + targetFiles.length, | |||
| srcIndex - targetIndex); | |||
| // srcIndex --> end | |||
| System.arraycopy(orig, srcIndex, result, | |||
| srcIndex + srcFiles.length + targetFiles.length, | |||
| orig.length - srcIndex); | |||
| srcIndex += targetFiles.length; | |||
| } | |||
| } else { // no targetFilePos | |||
| System.arraycopy(orig, 0, result, 0, srcIndex); | |||
| } | |||
| // fill in source file names | |||
| for (int i=0; i < srcFiles.length; i++) { | |||
| result[index+i] = (new File(baseDir, srcFiles[i])).getAbsolutePath(); | |||
| result[srcIndex+i] = | |||
| (new File(baseDirs[i], srcFiles[i])).getAbsolutePath(); | |||
| } | |||
| System.arraycopy(orig, index, result, index+srcFiles.length, | |||
| orig.length-index); | |||
| return result; | |||
| } | |||
| @@ -215,23 +348,35 @@ public class ExecuteOn extends ExecTask { | |||
| * @param baseDir filename is relative to this dir | |||
| */ | |||
| protected String[] getCommandline(String srcFile, File baseDir) { | |||
| return getCommandline(new String[] {srcFile}, baseDir); | |||
| return getCommandline(new String[] {srcFile}, new File[] {baseDir}); | |||
| } | |||
| /** | |||
| * Return the list of files from this DirectoryScanner that should | |||
| * be included on the command line. | |||
| */ | |||
| protected String[] getFiles(File basedir, DirectoryScanner ds) { | |||
| return ds.getIncludedFiles(); | |||
| protected String[] getFiles(File baseDir, DirectoryScanner ds) { | |||
| if (mapper != null) { | |||
| SourceFileScanner sfs = new SourceFileScanner(this); | |||
| return sfs.restrict(ds.getIncludedFiles(), baseDir, destDir, | |||
| mapper); | |||
| } else { | |||
| return ds.getIncludedFiles(); | |||
| } | |||
| } | |||
| /** | |||
| * Return the list of Directories from this DirectoryScanner that | |||
| * should be included on the command line. | |||
| */ | |||
| protected String[] getDirs(File basedir, DirectoryScanner ds) { | |||
| return ds.getIncludedDirectories(); | |||
| protected String[] getDirs(File baseDir, DirectoryScanner ds) { | |||
| if (mapper != null) { | |||
| SourceFileScanner sfs = new SourceFileScanner(this); | |||
| return sfs.restrict(ds.getIncludedDirectories(), baseDir, destDir, | |||
| mapper); | |||
| } else { | |||
| return ds.getIncludedDirectories(); | |||
| } | |||
| } | |||
| /** | |||
| @@ -54,193 +54,9 @@ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.File; | |||
| import java.util.Hashtable; | |||
| import java.util.Vector; | |||
| import org.apache.tools.ant.*; | |||
| import org.apache.tools.ant.types.*; | |||
| import org.apache.tools.ant.util.*; | |||
| /** | |||
| * Executes a given command, supplying a set of files as arguments. | |||
| * | |||
| * <p>Only those files that are newer than their corresponding target | |||
| * files will be handeled, the rest will be ignored.</p> | |||
| * Has been merged into ExecuteOn, empty class for backwards compatibility. | |||
| * | |||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| */ | |||
| public class Transform extends ExecuteOn { | |||
| protected Commandline.Marker targetFilePos = null; | |||
| protected Mapper mapperElement = null; | |||
| protected FileNameMapper mapper = null; | |||
| protected File destDir = null; | |||
| /** | |||
| * Has <srcfile> been specified before <targetfile> | |||
| */ | |||
| protected boolean srcIsFirst = true; | |||
| /** | |||
| * Set the destination directory. | |||
| */ | |||
| public void setDest(File destDir) { | |||
| this.destDir = destDir; | |||
| } | |||
| /** | |||
| * Marker that indicates where the name of the target file should | |||
| * be put on the command line. | |||
| */ | |||
| public Commandline.Marker createTargetfile() { | |||
| if (targetFilePos != null) { | |||
| throw new BuildException(taskType + " doesn\'t support multiple targetfile elements.", | |||
| location); | |||
| } | |||
| targetFilePos = cmdl.createMarker(); | |||
| srcIsFirst = (srcFilePos != null); | |||
| return targetFilePos; | |||
| } | |||
| /** | |||
| * Defines the FileNameMapper to use (nested mapper element). | |||
| */ | |||
| public Mapper createMapper() throws BuildException { | |||
| if (mapperElement != null) { | |||
| throw new BuildException("Cannot define more than one mapper", | |||
| location); | |||
| } | |||
| mapperElement = new Mapper(project); | |||
| return mapperElement; | |||
| } | |||
| protected void checkConfiguration() { | |||
| super.checkConfiguration(); | |||
| if (mapperElement == null) { | |||
| throw new BuildException("no mapper specified", location); | |||
| } | |||
| if (destDir == null) { | |||
| throw new BuildException("no dest attribute specified", location); | |||
| } | |||
| mapper = mapperElement.getImplementation(); | |||
| } | |||
| /** | |||
| * Return the list of files from this DirectoryScanner that should | |||
| * be included on the command line - i.e. only those that are | |||
| * newer than the corresponding target files. | |||
| */ | |||
| protected String[] getFiles(File baseDir, DirectoryScanner ds) { | |||
| SourceFileScanner sfs = new SourceFileScanner(this); | |||
| return sfs.restrict(ds.getIncludedFiles(), baseDir, destDir, mapper); | |||
| } | |||
| /** | |||
| * Return the list of Directories from this DirectoryScanner that | |||
| * should be included on the command line - i.e. only those that | |||
| * are newer than the corresponding target files. | |||
| */ | |||
| protected String[] getDirs(File baseDir, DirectoryScanner ds) { | |||
| SourceFileScanner sfs = new SourceFileScanner(this); | |||
| return sfs.restrict(ds.getIncludedDirectories(), baseDir, destDir, | |||
| mapper); | |||
| } | |||
| /** | |||
| * Construct the command line for parallel execution. | |||
| * | |||
| * @param srcFiles The filenames to add to the commandline | |||
| * @param baseDir filenames are relative to this dir | |||
| */ | |||
| protected String[] getCommandline(String[] srcFiles, File baseDir) { | |||
| if (targetFilePos == null) { | |||
| return super.getCommandline(srcFiles, baseDir); | |||
| } | |||
| Vector targets = new Vector(); | |||
| Hashtable addedFiles = new Hashtable(); | |||
| for (int i=0; i<srcFiles.length; i++) { | |||
| String[] subTargets = mapper.mapFileName(srcFiles[i]); | |||
| if (subTargets != null) { | |||
| for (int j=0; j<subTargets.length; j++) { | |||
| String name = (new File(destDir, subTargets[j])).getAbsolutePath(); | |||
| if (!addedFiles.contains(name)) { | |||
| targets.addElement(name); | |||
| addedFiles.put(name, name); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| String[] targetFiles = new String[targets.size()]; | |||
| targets.copyInto(targetFiles); | |||
| String[] orig = cmdl.getCommandline(); | |||
| String[] result = new String[orig.length+srcFiles.length+targetFiles.length]; | |||
| int srcIndex = orig.length; | |||
| if (srcFilePos != null) { | |||
| srcIndex = srcFilePos.getPosition(); | |||
| } | |||
| int targetIndex = targetFilePos.getPosition(); | |||
| if (srcIndex < targetIndex || (srcIndex == targetIndex && srcIsFirst)) { | |||
| // 0 --> srcIndex | |||
| System.arraycopy(orig, 0, result, 0, srcIndex); | |||
| // srcIndex --> targetIndex | |||
| System.arraycopy(orig, srcIndex, result, | |||
| srcIndex + srcFiles.length, | |||
| targetIndex - srcIndex); | |||
| // targets are already absolute file names | |||
| System.arraycopy(targetFiles, 0, result, | |||
| targetIndex + srcFiles.length, | |||
| targetFiles.length); | |||
| // targetIndex --> end | |||
| System.arraycopy(orig, targetIndex, result, | |||
| targetIndex + srcFiles.length + targetFiles.length, | |||
| orig.length - targetIndex); | |||
| } else { | |||
| // 0 --> targetIndex | |||
| System.arraycopy(orig, 0, result, 0, targetIndex); | |||
| // targets are already absolute file names | |||
| System.arraycopy(targetFiles, 0, result, | |||
| targetIndex, | |||
| targetFiles.length); | |||
| // targetIndex --> srcIndex | |||
| System.arraycopy(orig, targetIndex, result, | |||
| targetIndex + targetFiles.length, | |||
| srcIndex - targetIndex); | |||
| // srcIndex --> end | |||
| System.arraycopy(orig, srcIndex, result, | |||
| srcIndex + srcFiles.length + targetFiles.length, | |||
| orig.length - srcIndex); | |||
| srcIndex += targetFiles.length; | |||
| } | |||
| for (int i=0; i < srcFiles.length; i++) { | |||
| result[srcIndex+i] = | |||
| (new File(baseDir, srcFiles[i])).getAbsolutePath(); | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * Construct the command line for serial execution. | |||
| * | |||
| * @param srcFile The filename to add to the commandline | |||
| * @param baseDir filename is relative to this dir | |||
| */ | |||
| protected String[] getCommandline(String srcFile, File baseDir) { | |||
| return getCommandline(new String[] {srcFile}, baseDir); | |||
| } | |||
| } | |||
| public class Transform extends ExecuteOn {} | |||