Mapping File Names

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 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 / instead. For the regexpmapper, / 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.

Parameters specified as nested elements

The classpath can be specified via a nested <classpath>, as well - that is, a path-like structure.

Since Ant 1.6.2, 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.


The built-in mapper types are:

All built-in mappers are case-sensitive.

As of Ant 1.6.2, 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.

identity

The target file name is identical to the source file name. Both to and from will be ignored.

Examples:
<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

flatten

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.

Examples:
<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

merge

The target file name will always be the same, as defined by to - from will be ignored.

Examples:
<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

glob

Both to and from 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.

Examples:
<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="/Users/antoine/dev/asf/ant-core\d/e\*" to="*" ignoredirchar="yes"/>
        </mapper>
      </pathconvert>
      <echo>x is ${x}</echo>
    

will output "x is f/j.java".

regexp

Both to and from define regular expressions. If the source file name 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. 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. Ant comes with implementations for the java.util.regex package of JDK 1.4 or higher, jakarta-regexp and jakarta-ORO. If you compile from sources and plan to use one of them, make sure the libraries are in your CLASSPATH. For information about using gnu.regexp or gnu.rex with Ant, see this article.

This means, you need one of the supported regular expression libraries and the corresponding ant-[jakarta-oro, jakarta-regexp, 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-[jakarta-oro, jakarta-regexp, 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:

Examples:
<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="/Users/antoine/dev/asf/ant-core/d/e/(.*)" to="\1" handledirsep="yes"/>
      </chainedmapper>
    </pathconvert>
    

will set hd.prop to "f\j.java".

package

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.

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

unpackage (since Ant 1.6.0)

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.

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

composite (since Ant 1.6.2)

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.

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.

chained (since Ant 1.6.2)

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.

filtermapper (since Ant 1.6.3)

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.

scriptmapper (since Ant 1.7)

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