## 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 `${file.separator}` 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`

#### 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, 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 `optional.jar` from the Ant release you are using and one of the supported regular expression libraries. 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 `optional.jar` in `ANT_HOME/lib` and the library in a nested `<classpath>`.

Ant will choose the regular-expression library based on the following algorithm:

- If the system property `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.
- If it has not been set, first try the JDK 1.4 classes, then jakarta-ORO and finally try jakarta-regexp.

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`

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

Copyright © 2000-2004 The Apache Software Foundation. All rights Reserved.