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]