Browse Source

Make <apply> work really parallel and not parallel on a per fileset basis.

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-ffa450edef68
master
Stefan Bodewig 24 years ago
parent
commit
eefa2aba55
6 changed files with 245 additions and 389 deletions
  1. +5
    -0
      WHATSNEW
  2. +61
    -14
      docs/manual/CoreTasks/apply.html
  3. +0
    -156
      docs/manual/CoreTasks/execon.html
  4. +1
    -2
      docs/manual/coretasklist.html
  5. +176
    -31
      src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java
  6. +2
    -186
      src/main/org/apache/tools/ant/taskdefs/Transform.java

+ 5
- 0
WHATSNEW View File

@@ -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
===========================================



+ 61
- 14
docs/manual/CoreTasks/apply.html View File

@@ -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 &lt;apply&gt; 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>&lt;srcfile&gt;</code> element between your
<p><code>&lt;targetfile&gt;</code> is similar to
<code>&lt;srcfile&gt;</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>&lt;env&gt;</code> elements. See the
@@ -124,6 +143,34 @@ description in the section about <a href="exec.html#env">exec</a></p>
<code>&lt;env&gt;</code>.</p>
<h3>Examples</h3>
<blockquote><pre>
&lt;apply executable=&quot;ls&quot; &gt;
&lt;arg value=&quot;-l&quot;/&gt;
&lt;fileset dir=&quot;/tmp&quot;&gt;
&lt;patternset&gt;
&lt;exclude name=&quot;**/*.txt&quot;/&gt;
&lt;/patternset&gt;
&lt;/fileset&gt;
&lt;fileset refid=&quot;other.files&quot;/&gt;
&lt;/apply&gt;
</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>
&lt;apply executable=&quot;somecommand&quot; parallel=&quot;false&quot; &gt;
&lt;arg value=&quot;arg1&quot;/&gt;
&lt;srfile/&gt;
&lt;arg value=&quot;arg2&quot;/&gt;
&lt;fileset dir=&quot;/tmp&quot;/&gt;
&lt;/apply&gt;
</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>
&lt;apply executable=&quot;cc&quot; dest=&quot;src/C&quot; parallel=&quot;false&quot;&gt;
&lt;arg value=&quot;-c&quot;/&gt;
&lt;arg value=&quot;-o&quot;/&gt;


+ 0
- 156
docs/manual/CoreTasks/execon.html View File

@@ -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>&lt;fileset&gt;</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 &quot;os.name&quot; 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>&lt;fileset&gt;</code>
elements to define the files for this task and refer to
<code>&lt;fileset&gt;</code>s defined elsewhere.</p>
<h4>arg</h4>
<p>Command line arguments should be specified as nested
<code>&lt;arg&gt;</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>&lt;srcfile&gt;</code> element between your
<code>&lt;arg&gt;</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>&lt;env&gt;</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>&lt;env&gt;</code>.</p>
<h3>Examples</h3>
<blockquote><pre>
&lt;execon executable=&quot;ls&quot; &gt;
&lt;arg value=&quot;-l&quot;/&gt;
&lt;fileset dir=&quot;/tmp&quot;&gt;
&lt;patternset&gt;
&lt;exclude name=&quot;**/*.txt&quot;/&gt;
&lt;/patternset&gt;
&lt;/fileset&gt;
&lt;fileset refid=&quot;other.files&quot;/&gt;
&lt;/execon&gt;
</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>
&lt;execon executable=&quot;somecommand&quot; parallel=&quot;false&quot; &gt;
&lt;arg value=&quot;arg1&quot;/&gt;
&lt;srfile/&gt;
&lt;arg value=&quot;arg2&quot;/&gt;
&lt;fileset dir=&quot;/tmp&quot;/&gt;
&lt;/execon&gt;
</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 &copy; 2000,2001 Apache Software Foundation. All rights
Reserved.</p>

</body>
</html>


+ 1
- 2
docs/manual/coretasklist.html View File

@@ -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>


+ 176
- 31
src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java View File

@@ -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 &lt;srcfile&gt; been specified before &lt;targetfile&gt;
*/
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();
}
}

/**


+ 2
- 186
src/main/org/apache/tools/ant/taskdefs/Transform.java View File

@@ -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 &lt;srcfile&gt; been specified before &lt;targetfile&gt;
*/
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 {}

Loading…
Cancel
Save