Some tasks take source files and create target files. Depending on
the task, it may be quite obvious which name a target file will have
(using javac, you know there will be
.class
files for your .java
files) - in
other cases you may want to specify the target files, either to help
Apache Ant or to get an extra bit of functionality.
While source files are usually specified as filesets, you don't specify target files directly -
instead, you tell Ant how to find the target file(s) for one source file. An
instance of org.apache.tools.ant.util.FileNameMapper
is
responsible for this. It constructs target file names based on rules
that can be parameterized with from
and to
attributes - the exact meaning of which is implementation-dependent.
These instances are defined in <mapper>
elements
with the following attributes:
Attribute | Description | Required |
type | specifies one of the built-in implementations. | Exactly one of these |
classname | specifies the implementation by class name. | |
classpath | the classpath to use when looking up
classname . |
No |
classpathref | the classpath to use, given as reference to a path defined elsewhere. | No |
from | the from attribute for the given
implementation. |
Depends on implementation. |
to | the to attribute for the given
implementation. |
Depends on implementation. |
Note that Ant will not automatically convert / or \ characters in
the to
and from
attributes to the correct
directory separator of your current platform. If you need to specify
this separator, use ${file.separator}
instead.
For the regexpmapper, ${file.separator}
will not work,
as on windows it is the '\' character, and this is an escape character
for regular expressions, one should use the handledirsep
attribute
instead.
The classpath can be specified via a nested
<classpath>
, as well - that is,
a path-like structure.
Since Ant 1.7.0, nested File Mappers can
be supplied via either <mapper>
elements or
<typedef>
'd
implementations of org.apache.tools.ant.util.FileNameMapper
.
If nested File Mappers are specified by either means, the mapper will be
implicitly configured as a composite mapper.
All built-in mappers are case-sensitive.
As of Ant 1.7.0, each of the built-in mapper implementation
types is directly accessible using a specific tagname. This makes it
possible for filename mappers to support attributes in addition to
the generally available to and from.
The <mapper type|classname="...">
usage
form remains valid for reasons of backward compatibility.
The target file name is identical to the source file name. Both
to
and from
will be ignored.
<mapper type="identity"/> <identitymapper/>
Source file name | Target file name |
A.java |
A.java |
foo/bar/B.java |
foo/bar/B.java |
C.properties |
C.properties |
Classes/dir/dir2/A.properties |
Classes/dir/dir2/A.properties |
The target file name is identical to the source file name, with all
leading directory information stripped off. Both to
and
from
will be ignored.
<mapper type="flatten"/> <flattenmapper/>
Source file name | Target file name |
A.java |
A.java |
foo/bar/B.java |
B.java |
C.properties |
C.properties |
Classes/dir/dir2/A.properties |
A.properties |
The target file name will always be the same, as defined by
to
- from
will be ignored.
<mapper type="merge" to="archive.tar"/> <mergemapper to="archive.tar"/>
Source file name | Target file name |
A.java |
archive.tar |
foo/bar/B.java |
archive.tar |
C.properties |
archive.tar |
Classes/dir/dir2/A.properties |
archive.tar |
Both to
and from
are required and define patterns that may
contain at most one *
. For each source file that matches
the from
pattern, a target file name will be constructed
from the to
pattern by substituting the *
in
the to
pattern with the text that matches the
*
in the from
pattern. Source file names
that don't match the from
pattern will be ignored.
<mapper type="glob" from="*.java" to="*.java.bak"/> <globmapper from="*.java" to="*.java.bak"/>
Source file name | Target file name |
A.java |
A.java.bak |
foo/bar/B.java |
foo/bar/B.java.bak |
C.properties |
ignored |
Classes/dir/dir2/A.properties |
ignored |
<mapper type="glob" from="C*ies" to="Q*y"/> <globmapper from="C*ies" to="Q*y"/>
Source file name | Target file name |
A.java |
ignored |
foo/bar/B.java |
ignored |
C.properties |
Q.property |
Classes/dir/dir2/A.properties |
Qlasses/dir/dir2/A.property |
The globmapper mapper can take the following extra attributes.
Attribute | Description | Required |
casesensitive | If this is false, the mapper will ignore case when matching the glob pattern. This attribute can be true or false, the default is true. Since Ant 1.6.3. | No |
handledirsep | If this is specified, the mapper will ignore the difference between the normal directory separator characters - \ and /. This attribute can be true or false, the default is false. This attribute is useful for cross-platform build files. Since Ant 1.6.3. | No |
An example:
<pathconvert property="x" targetos="unix"> <path path="Aj.Java"/> <mapper> <chainedmapper> <flattenmapper/> <globmapper from="a*.java" to="*.java.bak" casesensitive="no"/> </chainedmapper> </mapper> </pathconvert> <echo>x is ${x}</echo>
will output "x is j.java.bak".
and
<pathconvert property="x" targetos="unix"> <path path="d/e/f/j.java"/> <mapper> <globmapper from="${basedir}\d/e\*" to="*" handledirsep="yes"/> </mapper> </pathconvert> <echo>x is ${x}</echo>
will output "x is f/j.java".
Both to
and from
are required and define
regular expressions. If the source file name (as a whole or in part)
matches the from
pattern, the target file name will be
constructed from the
to
pattern, using \0
to \9
as
back-references for the full match (\0
) or the matches of
the subexpressions in parentheses. The to
pattern
determines the whole file name, so if you wanted to
replace the extension of a file you should not use from="\.old$"
to=".new"
but rather from="(.*)\.old$" to="\1.new"
(or rather use a glob mapper in this case).
Source files not matching the from
pattern will be
ignored.
Note that you need to escape a dollar-sign ($
) with
another dollar-sign in Ant.
The regexp mapper needs a supporting library and an implementation
of org.apache.tools.ant.util.regexp.RegexpMatcher
that
hides the specifics of the library. Since Ant 1.8.0 Ant
requires Java 1.4 to run, so the implementation based on
the java.util.regex
package will always be available.
You can still use the now retired Jakarta ORO or Jakarta Regex instead if your
provide the corresponding jar in your CLASSPATH.
For information about using gnu.regexp or gnu.rex with Ant, see this article.
If you want to use one of the regular expression
libraries other than java.util.regex
you need to also use
the corresponding ant-[apache-oro, apache-regexp].jar
from the Ant release you are using.
Make sure, both will be loaded from the same
classpath, that is either put them into your CLASSPATH
,
ANT_HOME/lib
directory or a nested
<classpath>
element of the mapper - you cannot have
ant-[apache-oro, apache-regexp].jar
in ANT_HOME/lib
and the library
in a nested <classpath>
.
Ant will choose the regular-expression library based on the following algorithm:
ant.regexp.matcherimpl
has been set, it is taken as the
name of the class implementing
org.apache.tools.ant.util.regexp.RegexpMatcher
that
should be used.<mapper type="regexp" from="^(.*)\.java$$" to="\1.java.bak"/> <regexpmapper from="^(.*)\.java$$" to="\1.java.bak"/>
Source file name | Target file name |
A.java |
A.java.bak |
foo/bar/B.java |
foo/bar/B.java.bak |
C.properties |
ignored |
Classes/dir/dir2/A.properties |
ignored |
<mapper type="regexp" from="^(.*)/([^/]+)/([^/]*)$$" to="\1/\2/\2-\3"/> <regexpmapper from="^(.*)/([^/]+)/([^/]*)$$" to="\1/\2/\2-\3"/>
Source file name | Target file name |
A.java |
ignored |
foo/bar/B.java |
foo/bar/bar-B.java |
C.properties |
ignored |
Classes/dir/dir2/A.properties |
Classes/dir/dir2/dir2-A.properties |
<mapper type="regexp" from="^(.*)\.(.*)$$" to="\2.\1"/> <regexpmapper from="^(.*)\.(.*)$$" to="\2.\1"/>
Source file name | Target file name |
A.java |
java.A |
foo/bar/B.java |
java.foo/bar/B |
C.properties |
properties.C |
Classes/dir/dir2/A.properties |
properties.Classes/dir/dir2/A |
<mapper type="regexp" from="^(.*?)(\$$[^/\\\.]*)?\.class$$" to="\1.java"/> <regexpmapper from="^(.*?)(\$$[^/\\\.]*)?\.class$$" to="\1.java"/>
Source file name | Target file name |
ClassLoader.class |
ClassLoader.java |
java/lang/ClassLoader.class |
java/lang/ClassLoader.java |
java\lang\ClassLoader$1.class |
java\lang\ClassLoader.java |
java/lang/ClassLoader$foo$1.class |
java/lang/ClassLoader.java |
The regexpmapper mapper can take the following extra attributes.
Attribute | Description | Required |
casesensitive | If this is false, the mapper will ignore case when matching the pattern. This attribute can be true or false, the default is true. Since Ant 1.6.3. | No |
handledirsep | If this is specified, the mapper will treat a \ character in a filename as a / for the purposes of matching. This attribute can be true or false, the default is false. This attribute is useful for cross-platform build files. Since Ant 1.6.3. | No |
An example:
<pathconvert property="x" targetos="unix"> <path path="Aj.Java"/> <chainedmapper> <flattenmapper/> <regexpmapper from="a(.*)\.java" to="\1.java.bak" casesensitive="no"/> </chainedmapper> </pathconvert> <echo>x is ${x}</echo>
will output "x is j.java.bak".
and
<pathconvert property="hd.prop" targetos="windows"> <path path="d\e/f\j.java"/> <chainedmapper> <regexpmapper from="${basedir}/d/e/(.*)" to="\1" handledirsep="yes"/> </chainedmapper> </pathconvert>
will set hd.prop
to "f\j.java".
Sharing the same syntax as the glob mapper,
the package mapper replaces
directory separators found in the matched source pattern with dots in the target
pattern placeholder. This mapper is particularly useful in combination
with <uptodate>
and <junit>
output.
The to and from attributes are both required.
Example:<mapper type="package" from="*Test.java" to="TEST-*Test.xml"/> <packagemapper from="*Test.java" to="TEST-*Test.xml"/>
Source file name | Target file name |
org/apache/tools/ant/util/PackageMapperTest.java |
TEST-org.apache.tools.ant.util.PackageMapperTest.xml |
org/apache/tools/ant/util/Helper.java |
ignored |
This mapper is the inverse of the package mapper. It replaces the dots in a package name with directory separators. This is useful for matching XML formatter results against their JUnit test test cases. The mapper shares the sample syntax as the glob mapper.
The to and from attributes are both required.
Example:<mapper type="unpackage" from="TEST-*Test.xml" to="${test.src.dir}/*Test.java"> <unpackagemapper from="TEST-*Test.xml" to="${test.src.dir}/*Test.java">
Source file name | Target file name |
TEST-org.acme.AcmeTest.xml |
${test.src.dir}/org/acme/AcmeTest.java |
This mapper implementation can contain multiple nested mappers.
File mapping is performed by passing the source filename to each nested
<mapper>
in turn, returning all results.
The to and from attributes are ignored.
Starting with Ant 1.8.0 the order of the mapped results is the same as the order of the nested mappers; prior to Ant 1.8.0 the order has been undefined.
Examples:<compositemapper> <identitymapper/> <packagemapper from="*.java" to="*"/> </compositemapper>
Source file name | Target file names |
foo/bar/A.java |
foo/bar/A.java |
foo.bar.A |
The composite mapper has no corresponding
<mapper type>
attribute.
This mapper implementation can contain multiple nested mappers. File mapping is performed by passing the source filename to the first nested mapper, its results to the second, and so on. The target filenames generated by the last nested mapper comprise the ultimate results of the mapping operation. The to and from attributes are ignored.
Examples:<chainedmapper> <flattenmapper/> <globmapper from="*" to="new/path/*"/> <mapper> <globmapper from="*" to="*1"/> <globmapper from="*" to="*2"/> </mapper> </chainedmapper>
Source file name | Target file names |
foo/bar/A.java |
new/path/A.java1 |
new/path/A.java2 |
|
boo/far/B.java |
new/path/B.java1 |
new/path/B.java2 |
The chained mapper has no corresponding
<mapper type>
attribute.
This mapper implementation applies a filterchain to the source file name.
Examples:<filtermapper> <replacestring from="\" to="/"/> </filtermapper>
Source file name | Target file names |
foo\bar\A.java |
foo/bar/A.java |
<filtermapper> <scriptfilter language="beanshell"> self.setToken(self.getToken().toUpperCase()); </scriptfilter> </filtermapper>
Source file name | Target file names |
foo\bar\A.java |
FOO\BAR\A.JAVA |
The filtermapper has no corresponding
<mapper type>
attribute.
This mapper executes a script written in Apache BSF or JSR 223 supported language, once per file to map.
The script can be declared inline or in a specified file.See the Script task for an explanation of scripts and dependencies.
Attribute | Description | Required |
language | Scripting language | Yes |
manager | The script engine manager to use. See the script task for using this attribute. | No - default is "auto" |
src | File containing the script | No |
setbeans | whether to have all properties, references and targets as global variables in the script. since Ant 1.8.0 | No, default is "true". |
classpath | The classpath to pass into the script. | No |
classpathref | The classpath to use, given as a reference to a path defined elsewhere. | No |
This filename mapper can take a nested <classpath> element. See the script task on how to use this element.
Example:
<scriptmapper language="javascript"> self.addMappedName(source.toUpperCase()); self.addMappedName(source.toLowerCase()); </scriptmapper>
Source file name | Target file names |
foo\bar\A.java |
FOO\BAR\A.JAVA |
foo\bar\a.java |
To use this mapper, the scripts need access to the source file, and the ability to return multiple mappings. Here are the relevant beans and their methods. The script is called once for every source file, with the list of mapped names reset after every invocation.
Script bean | Description |
source: String |
The file/path to map |
self |
the scriptmapper itself |
self.addMappedName(String name) |
Add a new mapping |
self.clear() |
Reset the list of files. |
The scriptmapper has no corresponding
<mapper type>
attribute.
This mapper supports an arbitrary number of nested mappers and returns the results of the first mapper that matches. This is different from composite mapper which collects the results of all matching children.
Examples:<firstmatchmapper> <globmapper from="*.txt" to="*.bak"/> <globmapper from="*A.*" to="*B.*"/> </firstmatchmapper>
Source file name | Target file names |
foo/bar/A.txt |
foo/bar/A.bak |
foo/bar/A.java |
foo/bar/B.java |
The firstmatchmapper has no corresponding
<mapper type>
attribute.
This mapper strips a configured number of leading directories from the source file name.
Examples:<cutdirsmapper dirs="1"/>
Source file name | Target file names |
foo/bar/A.txt |
bar/A.txt |
The cutdirsmapper has no
corresponding <mapper type>
attribute.
Attribute | Description | Required |
dirs | Number of directories to strip (must be a positive number). | Yes |