Mapper DataType

We conclude this chapter with a discussion of mappers, which is a feature added in Ant 1.3. mappers define how a set of source files relates to a set of target files. <mapper> [33] elements support the following attributes:

classname (1.3, 1.4, String, *)

The name of the class implementing the mapper. Used for creating custom mappers when the built-in mappers are not sufficient.

classpath (1.3, 1.4, Path, N)

The classpath used when looking up a custom mapper.

classpathref (1.3, 1.4, Reference, N)

Reference to a classpath defined elsewhere.

from (1.3, 1.4, String, *)

The meaning of this attribute depends on which mapper it is used with. The upcoming examples show where this is used.

refid (1.3, 1.4, Reference, N)

A reference to another mapper. If specified, this should be the only attribute listed. This allows you to define a mapper once and use it in several places throughout a buildfile. The upcoming examples show where this is of use.

to (1.3, 1.4, String, *)

The meaning of this attribute depends on which mapper it is used with.

type (1.3, 1.4, Enum, *)

One of identity, flatten, glob, merge, or regexp. Defines the type of built-in mapper to use.

Exactly one of the type or classname attributes is required. The from and to attributes may be required, depending on the mapper.

Example

Let’s look at a quick example before we talk about the specific types of mappers. Example 4-2 presents a buildfile that creates a backup copy of all .java files, appending the .bak extension to each filename.

Example 4-2. Backing up files with a glob mapper

<?xml version="1.0"?>
<project name="mapper demo" default="backupFiles" basedir=".">

  <!-- define a mapper for backing up files -->
  <mapper id="backupMapper" type="glob" from="*.java" to="*.java.bak"/>

  <target name="clean">
    <delete dir="bak"/>
  </target>

  <target name="prepare">
    <mkdir dir="bak"/>
  </target>

  <target name="backupFiles" depends="prepare">
    <copy todir="bak">
      <!-- select the files to copy with a fileset -->
      <fileset dir="src" includes="**/*.java"/>
      <mapper refid="backupMapper"/>
    </copy>
  </target>
</project>

The example also shows another usage of the fileset DataType, used by the copy task to select which files are copied. The copy task is what copies the files. The nested fileset defines the set of files to be copied. The nested mapper references the mapper created earlier in the buildfile, as well as specifies how the files are to be renamed as they are copied. As the files are copied, they are renamed according to the pattern specified by the mapper.

This example used a type of mapper known as a glob mapper, which generates a set of target filenames based on a simple wildcard pattern that is applied to a set of input file names. There are several mapper types available. Let’s look at each of them.

The Identity Mapper

The identity mapper maps source files to target files with the same name. It is the default mapper used by the copy task, so you rarely need to define your own identity mapper. Table 4-2 shows results from the following identity mapper:

<mapper type="identity"/>

Table 4-2. Identity mapper results

Source file

Target file

Customer.java

Customer.java

com/oreilly/data/Account.java

com/oreilly/data/Account.java

The Flatten Mapper

The flatten mapper removes all path information from filenames. This might be useful if you want to copy a set of files from several different directories into a single target directory. Table 4-3 shows results from the following flatten mapper:

<mapper type="flatten"/>

Table 4-3. Flatten mapper results

Source file

Target file

Customer.java

Customer.java

com/oreilly/data/Account.java

Account.java

The Glob Mapper

The glob mapper determines target filenames based on simple wildcard patterns. This is useful when you want to rename groups of files that already have consistent filenames, such as all those that end in Test.java. The to and from attributes define patterns containing at most one * character. When a source filename matches the from pattern, a target filename is created. The to attribute’s * is replaced by matching text from the from attribute’s *. Table 4-4 shows results from the following glob mapper:

<mapper type="glob" from="*Test.java" to="*UnitTest.java">

Table 4-4. Glob mapper results

Source file

Target file

Customer.java

none

com/oreilly/data/Account.java

none

CustomerTest.java

CustomerUnitTest.java

com/oreilly/tests/CustomerTest.java

com/oreilly/tests/CustomerUnitTest.java

The “none” text in the first two rows of Table 4-4 indicates that in a copy operation using a glob mapper, the files that do not map are simply not copied.

The Merge Mapper

The merge mapper maps any set of source filenames to the same target filename, as specified by the to attribute. The from attribute is ignored. The merge mapper is useful when you want to compare timestamps of a set of source files against a single target file. This is how the uptodate task works, as described in Chapter 7. Table 4-5 shows results from the following merge mapper:

<mapper type="merge" to="oreilly.zip">

Table 4-5. Merge mapper results

Source file

Target file

Customer.java

oreilly.zip

com/oreilly/data/Account.java

oreilly.zip

The Regexp Mapper

The regexp mapper is similar to the glob mapper, but uses regular expressions instead of simple * characters. The exact syntax of those regular expressions entirely depends on which underlying regular expression library is being used. The mechanism Ant uses for selecting the library is described shortly.

A class implementing the org.apache.tools.ant.util.regexp.RegexpMatcher interface must be provided by the library, regardless of which regular expression library you choose to use in support of the regexp mapper. Ant includes implementation classes for the following libraries:

JDK 1.4

Included with J2SE 1.4, available at http://java.sun.com

jakarta-regexp

Available at http://jakarta.apache.org/regexp/

jakarta-ORO

Available at http://jakarta.apache.org/oro/

To determine which library to use, Ant first looks at the ant.regexp.matcherimpl system property. If this specifies a class implementing the RegexpMatcher interface, then that library is used. Otherwise, it tries searching the classpath for a suitable library in the order just listed, beginning with JDK 1.4. If none is found, the task fails.



[33] In Ant 1.4.1, the mapper DataType is always represented by a <mapper> XML element. Other DataTypes are not so consistent.

Get Ant: The Definitive Guide now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.