mbenson 2004/06/22 14:30:56
Modified: . Tag: ANT_16_BRANCH TODO WHATSNEW
docs/manual/CoreTypes Tag: ANT_16_BRANCH mapper.html
src/main/org/apache/tools/ant/types Tag: ANT_16_BRANCH
Mapper.java defaults.properties
src/testcases/org/apache/tools/ant/types Tag: ANT_16_BRANCH
MapperTest.java
Added: src/main/org/apache/tools/ant/util Tag: ANT_16_BRANCH
ChainedMapper.java CompositeMapper.java
ContainerMapper.java
Log:
merge nested and container <mapper>s from HEAD
Revision Changes Path
No revision
No revision
1.3.2.19 +0 -2 ant/Attic/TODO
Index: TODO
===================================================================
RCS file: /home/cvs/ant/Attic/TODO,v
retrieving revision 1.3.2.18
retrieving revision 1.3.2.19
diff -u -r1.3.2.18 -r1.3.2.19
--- TODO 22 Jun 2004 19:34:54 -0000 1.3.2.18
+++ TODO 22 Jun 2004 21:30:55 -0000 1.3.2.19
@@ -5,8 +5,6 @@
anybody else (assignments look like [Stefan]) to yourself - and please
remove items from this list once they are complete.
-* merge nested and container <mapper>s from HEAD [Matt]
-
* merge <redirector>s from HEAD [Matt]
* merge "<apply> differentiates between empty & up-to-date" from HEAD [Matt]
1.503.2.110 +5 -0 ant/WHATSNEW
Index: WHATSNEW
===================================================================
RCS file: /home/cvs/ant/WHATSNEW,v
retrieving revision 1.503.2.109
retrieving revision 1.503.2.110
diff -u -r1.503.2.109 -r1.503.2.110
--- WHATSNEW 22 Jun 2004 19:36:09 -0000 1.503.2.109
+++ WHATSNEW 22 Jun 2004 21:30:55 -0000 1.503.2.110
@@ -204,6 +204,11 @@
* <loadproperties> supports loading from a resource.
Bugzilla Report 28340.
+* Nested file mappers and a container mapper implementation have been
+ introduced. Additionally, the <mapper> element now accepts "defined"
+ nested FileNameMapper implementations directly, allowing a usage
+ comparable to those of <condition>, <filter>, and <selector>.
+
Changes from Ant 1.6.0 to Ant 1.6.1
=============================================
No revision
No revision
1.13.2.4 +96 -7 ant/docs/manual/CoreTypes/mapper.html
Index: mapper.html
===================================================================
RCS file: /home/cvs/ant/docs/manual/CoreTypes/mapper.html,v
retrieving revision 1.13.2.3
retrieving revision 1.13.2.4
diff -u -r1.13.2.3 -r1.13.2.4
--- mapper.html 9 Feb 2004 22:12:10 -0000 1.13.2.3
+++ mapper.html 22 Jun 2004 21:30:56 -0000 1.13.2.4
@@ -33,7 +33,7 @@
<tr>
<td valign="top">type</td>
<td valign="top">specifies one of the built-in implementations.</td>
- <td rowspan="2" align="center" valign="middle">Exactly one of both</td>
+ <td rowspan="2" align="center" valign="middle">Exactly one of these</td>
</tr>
<tr>
<td valign="top">classname</td>
@@ -72,14 +72,29 @@
<p>The classpath can be specified via a nested
<code><classpath></code>, as well - that is,
a <a href="../using.html#path">path</a>-like structure.</p>
+<p><b>Since Ant 1.6.2,</b> nested File Mappers can
+be supplied via either <CODE><mapper></CODE> elements or
+<a href="../CoreTasks/typedef.html"><code><typedef></code></a>'d
+implementations of <CODE>org.apache.tools.ant.util.FileNameMapper</CODE>.
+If nested File Mappers are specified by either means, the mapper will be
+implicitly configured as a <a href="#composite-mapper">composite mapper</a>.
+</p>
+<hr/>
<h3>The built-in mapper types are:</h3>
<p>All built-in mappers are case-sensitive.</p>
+<p><b>As of Ant 1.6.2,</b> 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 <i>to</i> and <i>from</i>.<br/>
+ The <code><mapper type|classname="..."></code> usage
+ form remains valid for reasons of backward compatibility.</p>
<h4><a name="identity-mapper">identity</a></h4>
<p>The target file name is identical to the source file name. Both
<code>to</code> and <code>from</code> will be ignored.</p>
<b>Examples:</b>
<blockquote><pre>
<mapper type="identity"/>
+<identitymapper />
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -110,6 +125,7 @@
<b>Examples:</b>
<blockquote><pre>
<mapper type="flatten"/>
+<flattenmapper />
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -139,6 +155,7 @@
<h5>Examples:</h5>
<blockquote><pre>
<mapper type="merge" to="archive.tar"/>
+<mergemapper to="archive.tar"/>
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -173,6 +190,7 @@
<b>Examples:</b>
<blockquote><pre>
<mapper type="glob" from="*.java"
to="*.java.bak"/>
+<globmapper from="*.java" to="*.java.bak"/>
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -198,6 +216,7 @@
</table>
<blockquote><pre>
<mapper type="glob" from="C*ies"
to="Q*y"/>
+<globmapper from="C*ies" to="Q*y"/>
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -268,6 +287,7 @@
<b>Examples:</b>
<blockquote><pre>
<mapper type="regexp" from="^(.*)\.java$$"
to="\1.java.bak"/>
+<regexpmapper from="^(.*)\.java$$"
to="\1.java.bak"/>
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -293,6 +313,7 @@
</table>
<blockquote><pre>
<mapper type="regexp" from="^(.*)/([^/]+)/([^/]*)$$"
to="\1/\2/\2-\3"/>
+<regexpmapper from="^(.*)/([^/]+)/([^/]*)$$"
to="\1/\2/\2-\3"/>
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -318,6 +339,7 @@
</table>
<blockquote><pre>
<mapper type="regexp" from="^(.*)\.(.*)$$"
to="\2.\1"/>
+<regexpmapper from="^(.*)\.(.*)$$" to="\2.\1"/>
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -350,8 +372,8 @@
with <code><uptodate></code> and <code><junit></code> output.</p>
<b>Example:</b>
<blockquote><pre>
-<mapper type="package"
- from="*Test.java" to="TEST-*Test.xml"/>
+<mapper type="package" from="*Test.java" to="TEST-*Test.xml"/>
+<packagemapper from="*Test.java" to="TEST-*Test.xml"/>
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -367,7 +389,7 @@
<td valign="top">ignored</td>
</tr>
</table>
-<h4><a name="unpackage-mapper">unpackage (since ant 1.6)</a></h4>
+<h4><a name="unpackage-mapper">unpackage (since ant 1.6.0)</a></h4>
<p>This mapper is the inverse of the <a href="#package-mapper">package</a>
mapper.
It replaces the dots in a package name with directory separators. This
is useful for matching XML formatter results against their JUnit test
@@ -376,8 +398,8 @@
</p>
<b>Example:</b>
<blockquote><pre>
-<mapper type="unpackage"
- from="TEST-*Test.xml" to="${test.src.dir}/*Test.java">
+<mapper type="unpackage" from="TEST-*Test.xml"
to="${test.src.dir}/*Test.java">
+<unpackagemapper from="TEST-*Test.xml" to="${test.src.dir}/*Test.java">
</pre></blockquote>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -389,7 +411,74 @@
<td valign="top"><code>${test.src.dir}/org/acme/AcmeTest.java</code></td>
</tr>
</table>
-
+<h4><a name="composite-mapper">composite (since ant 1.6.2)</a></h4>
+ <p>This mapper implementation can contain multiple nested mappers.
+ File mapping is performed by passing the source filename to each nested
+ <code><mapper></code> in turn, returning all results.
+ The <i>to</i> and <i>from</i> attributes are ignored.</p>
+<b>Examples:</b>
+<blockquote><pre>
+<compositemapper>
+ <identitymapper />
+ <packagemapper from="*.java" to="*"/>
+</compositemapper>
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file names</b></td>
+ </tr>
+ <tr>
+ <td valign="center" rowspan="2"><code>foo/bar/A.java</code></td>
+ <td valign="top"><code>foo/bar/A.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo.bar.A</code></td>
+ </tr>
+</table>
+ <p>The composite mapper has no corresponding
+ <code><mapper <b>type</b>></code> attribute.
+ </p>
+<h4><a name="chained-mapper">chained (since ant 1.6.2)</a></h4>
+ <p>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 <i>to</i> and <i>from</i> attributes are
ignored.</p>
+<b>Examples:</b>
+<blockquote><pre>
+<chainedmapper>
+ <flattenmapper />
+ <globmapper from="*" to="new/path/*"/>
+ <mapper>
+ <globmapper from="*" to="*1"/>
+ <globmapper from="*" to="*2"/>
+ </mapper>
+</chainedmapper>
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file names</b></td>
+ </tr>
+ <tr>
+ <td valign="center" rowspan="2"><code>foo/bar/A.java</code></td>
+ <td valign="top"><code>new/path/A.java1</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>new/path/A.java2</code></td>
+ </tr>
+ <tr>
+ <td valign="center" rowspan="2"><code>boo/far/B.java</code></td>
+ <td valign="top"><code>new/path/B.java1</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>new/path/B.java2</code></td>
+ </tr>
+</table>
+ <p>The chained mapper has no corresponding
+ <code><mapper <b>type</b>></code> attribute.
+ </p>
<hr>
<p align="center">Copyright © 2000-2004 The Apache Software Foundation.
All rights
Reserved.</p>
No revision
No revision
1.22.2.5 +76 -28 ant/src/main/org/apache/tools/ant/types/Mapper.java
Index: Mapper.java
===================================================================
RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/Mapper.java,v
retrieving revision 1.22.2.4
retrieving revision 1.22.2.5
diff -u -r1.22.2.4 -r1.22.2.5
--- Mapper.java 9 Mar 2004 17:01:54 -0000 1.22.2.4
+++ Mapper.java 22 Jun 2004 21:30:56 -0000 1.22.2.5
@@ -23,6 +23,8 @@
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.CompositeMapper;
+import org.apache.tools.ant.util.ContainerMapper;
/**
* Element to define a FileNameMapper.
@@ -31,13 +33,24 @@
public class Mapper extends DataType implements Cloneable {
protected MapperType type = null;
+ protected String classname = null;
+ protected Path classpath = null;
+ protected String from = null;
+ protected String to = null;
+
+ private ContainerMapper container = null;
+ /**
+ * Construct a new <CODE>Mapper</CODE> element.
+ * @param p the owning Ant <CODE>Project</CODE>.
+ */
public Mapper(Project p) {
setProject(p);
}
/**
- * Set the type of FileNameMapper to use.
+ * Set the type of <code>FileNameMapper</code> to use.
+ * @param type the <CODE>MapperType</CODE> enumerated attribute.
*/
public void setType(MapperType type) {
if (isReference()) {
@@ -46,7 +59,37 @@
this.type = type;
}
- protected String classname = null;
+ /**
+ * Add a nested <CODE>FileNameMapper</CODE>.
+ * @param fileNameMapper the <CODE>FileNameMapper</CODE> to add.
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (container == null) {
+ if (type == null && classname == null) {
+ container = new CompositeMapper();
+ } else {
+ FileNameMapper m = getImplementation();
+ if (m instanceof ContainerMapper) {
+ container = (ContainerMapper)m;
+ } else {
+ throw new BuildException(String.valueOf(m)
+ + " mapper implementation does not support nested
mappers!");
+ }
+ }
+ }
+ container.add(fileNameMapper);
+ }
+
+ /**
+ * Add a Mapper
+ * @param mapper the mapper to add
+ */
+ public void addConfiguredMapper(Mapper mapper) {
+ add(mapper.getImplementation());
+ }
/**
* Set the class name of the FileNameMapper to use.
@@ -58,8 +101,6 @@
this.classname = classname;
}
- protected Path classpath = null;
-
/**
* Set the classpath to load the FileNameMapper through (attribute).
*/
@@ -98,8 +139,6 @@
createClasspath().setRefid(r);
}
- protected String from = null;
-
/**
* Set the argument to FileNameMapper.setFrom
*/
@@ -110,8 +149,6 @@
this.from = from;
}
- protected String to = null;
-
/**
* Set the argument to FileNameMapper.setTo
*/
@@ -143,44 +180,55 @@
return getRef().getImplementation();
}
- if (type == null && classname == null) {
- throw new BuildException("one of the attributes type or
classname is required");
+ if (type == null && classname == null && container == null) {
+ throw new BuildException(
+ "nested mapper or "
+ + "one of the attributes type or classname is required");
+ }
+
+ if (container != null) {
+ return container;
}
if (type != null && classname != null) {
- throw new BuildException("must not specify both type and
classname attribute");
+ throw new BuildException(
+ "must not specify both type and classname attribute");
}
try {
- if (type != null) {
- classname = type.getImplementation();
- }
-
- Class c = null;
- if (classpath == null) {
- c = Class.forName(classname);
- } else {
- AntClassLoader al =
getProject().createClassLoader(classpath);
- c = Class.forName(classname, true, al);
- }
-
- FileNameMapper m = (FileNameMapper) c.newInstance();
+ FileNameMapper m
+ = (FileNameMapper)(getImplementationClass().newInstance());
final Project project = getProject();
if (project != null) {
project.setProjectReference(m);
}
m.setFrom(from);
m.setTo(to);
+
return m;
} catch (BuildException be) {
throw be;
} catch (Throwable t) {
throw new BuildException(t);
- } finally {
- if (type != null) {
- classname = null;
- }
}
+ }
+
+ /**
+ * Gets the Class object associated with the mapper implementation.
+ * @return <CODE>Class</CODE>.
+ */
+ protected Class getImplementationClass() throws ClassNotFoundException {
+
+ String classname = this.classname;
+ if (type != null) {
+ classname = type.getImplementation();
+ }
+
+ ClassLoader loader = (classpath == null)
+ ? getClass().getClassLoader()
+ : getProject().createClassLoader(classpath);
+
+ return Class.forName(classname, true, loader);
}
/**
1.19.2.3 +11 -0
ant/src/main/org/apache/tools/ant/types/defaults.properties
Index: defaults.properties
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/types/defaults.properties,v
retrieving revision 1.19.2.2
retrieving revision 1.19.2.3
diff -u -r1.19.2.2 -r1.19.2.3
--- defaults.properties 23 Dec 2003 11:10:49 -0000 1.19.2.2
+++ defaults.properties 22 Jun 2004 21:30:56 -0000 1.19.2.3
@@ -7,6 +7,17 @@
filterreader=org.apache.tools.ant.types.AntFilterReader
filterset=org.apache.tools.ant.types.FilterSet
mapper=org.apache.tools.ant.types.Mapper
+# different filename mappers
+identitymapper=org.apache.tools.ant.util.IdentityMapper
+flattenmapper=org.apache.tools.ant.util.FlatFileNameMapper
+globmapper=org.apache.tools.ant.util.GlobPatternMapper
+mergemapper=org.apache.tools.ant.util.MergingMapper
+regexpmapper=org.apache.tools.ant.util.RegexpPatternMapper
+packagemapper=org.apache.tools.ant.util.PackageNameMapper
+unpackagemapper=org.apache.tools.ant.util.UnPackageNameMapper
+compositemapper=org.apache.tools.ant.util.CompositeMapper
+chainedmapper=org.apache.tools.ant.util.ChainedMapper
+
path=org.apache.tools.ant.types.Path
patternset=org.apache.tools.ant.types.PatternSet
regexp=org.apache.tools.ant.types.RegularExpression
No revision
No revision
1.1.2.1 +0 -0 ant/src/main/org/apache/tools/ant/util/ChainedMapper.java
Index: ChainedMapper.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/util/ChainedMapper.java,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
1.1.2.1 +0 -0
ant/src/main/org/apache/tools/ant/util/CompositeMapper.java
Index: CompositeMapper.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/util/CompositeMapper.java,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
1.3.2.1 +0 -0
ant/src/main/org/apache/tools/ant/util/ContainerMapper.java
Index: ContainerMapper.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/util/ContainerMapper.java,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -r1.3 -r1.3.2.1
No revision
No revision
1.9.2.5 +75 -0
ant/src/testcases/org/apache/tools/ant/types/MapperTest.java
Index: MapperTest.java
===================================================================
RCS file:
/home/cvs/ant/src/testcases/org/apache/tools/ant/types/MapperTest.java,v
retrieving revision 1.9.2.4
retrieving revision 1.9.2.5
diff -u -r1.9.2.4 -r1.9.2.5
--- MapperTest.java 9 Mar 2004 17:02:07 -0000 1.9.2.4
+++ MapperTest.java 22 Jun 2004 21:30:56 -0000 1.9.2.5
@@ -26,6 +26,8 @@
import junit.framework.AssertionFailedError;
import java.io.File;
+import java.util.List;
+import java.util.Arrays;
/**
* JUnit 3 testcases for org.apache.tools.ant.types.Mapper.
@@ -136,6 +138,79 @@
String[] result = fmm.mapFileName("a.java");
assertEquals("a.java should match", 1, result.length);
assertEquals("a.class", result[0]);
+ }
+
+ public void testNested() {
+ Mapper mapper1 = new Mapper(project);
+ Mapper.MapperType mt = new Mapper.MapperType();
+ mt.setValue("glob");
+ mapper1.setType(mt);
+ mapper1.setFrom("from*");
+ mapper1.setTo("to*");
+
+ //mix element types
+ FileNameMapper mapper2 = new FlatFileNameMapper();
+ FileNameMapper mapper3 = new MergingMapper();
+ mapper3.setTo("mergefile");
+
+ Mapper container = new Mapper(project);
+ container.addConfiguredMapper(mapper1);
+ container.add(mapper2);
+ container.add(mapper3);
+
+ FileNameMapper fileNameMapper = container.getImplementation();
+ String[] targets = fileNameMapper.mapFileName("fromfilename");
+ assertNotNull("no filenames mapped", targets);
+ assertEquals("wrong number of filenames mapped", 3, targets.length);
+ List list = Arrays.asList(targets);
+ assertTrue("cannot find expected target \"tofilename\"",
+ list.contains("tofilename"));
+ assertTrue("cannot find expected target \"fromfilename\"",
+ list.contains("fromfilename"));
+ assertTrue("cannot find expected target \"mergefile\"",
+ list.contains("mergefile"));
+ }
+
+ public void testChained() {
+
+ // a --> b --> c --- def
+ // \-- ghi
+
+ FileNameMapper mapperAB = new GlobPatternMapper();
+ mapperAB.setFrom("a");
+ mapperAB.setTo("b");
+
+ FileNameMapper mapperBC = new GlobPatternMapper();
+ mapperBC.setFrom("b");
+ mapperBC.setTo("c");
+
+ //implicit composite
+ Mapper mapperCX = new Mapper(project);
+
+ FileNameMapper mapperDEF = new GlobPatternMapper();
+ mapperDEF.setFrom("c");
+ mapperDEF.setTo("def");
+
+ FileNameMapper mapperGHI = new GlobPatternMapper();
+ mapperGHI.setFrom("c");
+ mapperGHI.setTo("ghi");
+
+ mapperCX.add(mapperDEF);
+ mapperCX.add(mapperGHI);
+
+ Mapper chained = new Mapper(project);
+ chained.setClassname(ChainedMapper.class.getName());
+ chained.add(mapperAB);
+ chained.add(mapperBC);
+ chained.addConfiguredMapper(mapperCX);
+
+ FileNameMapper fileNameMapper = chained.getImplementation();
+ String[] targets = fileNameMapper.mapFileName("a");
+ assertNotNull("no filenames mapped", targets);
+ assertEquals("wrong number of filenames mapped", 2, targets.length);
+ List list = Arrays.asList(targets);
+ assertTrue("cannot find expected target \"def\"",
list.contains("def"));
+ assertTrue("cannot find expected target \"ghi\"",
list.contains("ghi"));
}
public void testCopyTaskWithTwoFilesets() {
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]