git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@936200 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -138,6 +138,9 @@ Other changes: | |||
| * Added SimpleBigProjectLogger, intermediate between NoBannerLogger and | |||
| BigProjectLogger. | |||
| * <mappedresources> supports new attributes enablemultiplemappings | |||
| and cache. | |||
| Changes from Ant 1.8.0RC1 TO Ant 1.8.0 | |||
| ====================================== | |||
| @@ -1081,9 +1081,32 @@ larger collection. <strong>Since Ant 1.7.1</strong>.</p> | |||
| use <em>mappedresources</em> with tasks that only allow file-system | |||
| based resources.</p> | |||
| <p><em>mappedresources</em> doesn't support any attributes.</p> | |||
| <blockquote> | |||
| <h4>Parameters specified as attributes</h4> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">cache</td> | |||
| <td valign="top">Whether to cache results; enabling | |||
| may improve performance. <em>Since Ant 1.8.1</em></td> | |||
| <td valign="top" align="center">No, default <i>false</i></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">enablemultiplemappings</td> | |||
| <td valign="top"> | |||
| If true the the collection will use all the mappings for a | |||
| given source path. If false the it will only process the first | |||
| resource. | |||
| <em>since Ant 1.8.1</em>.</td> | |||
| <td align="center">No - defaults to false.</td> | |||
| </tr> | |||
| </table> | |||
| <h4>Parameters specified as nested elements</h4> | |||
| <p>A single resource collection is required.</p> | |||
| <p>A single <a href="mapper.html">mapper</a> can be used to map | |||
| @@ -75,4 +75,28 @@ public class MappedResource extends ResourceDecorator { | |||
| ? null : getResource().as(clazz); | |||
| } | |||
| /** | |||
| * Get the hash code for this Resource. | |||
| * @since Ant 1.8.1 | |||
| */ | |||
| public int hashCode() { | |||
| String n = getName(); | |||
| return n == null ? super.hashCode() : n.hashCode(); | |||
| } | |||
| /** | |||
| * Equality check based on the resource's name in addition to the | |||
| * resource itself. | |||
| * @since Ant 1.8.1 | |||
| */ | |||
| public boolean equals(Object other) { | |||
| if (other == null || !other.getClass().equals(getClass())) { | |||
| return false; | |||
| } | |||
| MappedResource m = (MappedResource) other; | |||
| String myName = getName(); | |||
| String otherName = m.getName(); | |||
| return (myName == null ? otherName == null : myName.equals(otherName)) | |||
| && getResource().equals(m.getResource()); | |||
| } | |||
| } | |||
| @@ -17,6 +17,8 @@ | |||
| */ | |||
| package org.apache.tools.ant.types.resources; | |||
| import java.util.ArrayList; | |||
| import java.util.Collection; | |||
| import java.util.Iterator; | |||
| import java.util.Stack; | |||
| import org.apache.tools.ant.BuildException; | |||
| @@ -28,6 +30,7 @@ import org.apache.tools.ant.types.Resource; | |||
| import org.apache.tools.ant.types.ResourceCollection; | |||
| import org.apache.tools.ant.util.FileNameMapper; | |||
| import org.apache.tools.ant.util.IdentityMapper; | |||
| import org.apache.tools.ant.util.MergingMapper; | |||
| /** | |||
| * Wrapper around a resource collections that maps the names of the | |||
| @@ -39,6 +42,9 @@ public class MappedResourceCollection | |||
| private ResourceCollection nested = null; | |||
| private Mapper mapper = null; | |||
| private boolean enableMultipleMappings = false; | |||
| private boolean cache = false; | |||
| private Collection cachedColl = null; | |||
| /** | |||
| * Adds the required nested ResourceCollection. | |||
| @@ -55,6 +61,7 @@ public class MappedResourceCollection | |||
| getLocation()); | |||
| } | |||
| setChecked(false); | |||
| cachedColl = null; | |||
| nested = c; | |||
| } | |||
| @@ -73,6 +80,7 @@ public class MappedResourceCollection | |||
| } | |||
| setChecked(false); | |||
| mapper = new Mapper(getProject()); | |||
| cachedColl = null; | |||
| return mapper; | |||
| } | |||
| @@ -85,6 +93,29 @@ public class MappedResourceCollection | |||
| createMapper().add(fileNameMapper); | |||
| } | |||
| /** | |||
| * Set method of handling mappers that return multiple | |||
| * mappings for a given source path. | |||
| * @param enableMultipleMappings If true the type will | |||
| * use all the mappings for a given source path, if | |||
| * false, only the first mapped name is | |||
| * processed. | |||
| * By default, this setting is false to provide backward | |||
| * compatibility with earlier releases. | |||
| * @since Ant 1.8.1 | |||
| */ | |||
| public void setEnableMultipleMappings(boolean enableMultipleMappings) { | |||
| this.enableMultipleMappings = enableMultipleMappings; | |||
| } | |||
| /** | |||
| * Set whether to cache collections. | |||
| * @since Ant 1.8.1 | |||
| */ | |||
| public void setCache(boolean cache) { | |||
| this.cache = cache; | |||
| } | |||
| /** | |||
| * {@inheritDoc} | |||
| */ | |||
| @@ -105,7 +136,7 @@ public class MappedResourceCollection | |||
| return ((MappedResourceCollection) getCheckedRef()).size(); | |||
| } | |||
| checkInitialized(); | |||
| return nested.size(); | |||
| return cacheCollection().size(); | |||
| } | |||
| /** | |||
| @@ -116,7 +147,7 @@ public class MappedResourceCollection | |||
| return ((MappedResourceCollection) getCheckedRef()).iterator(); | |||
| } | |||
| checkInitialized(); | |||
| return new MappedIterator(nested.iterator(), mapper); | |||
| return cacheCollection().iterator(); | |||
| } | |||
| /** | |||
| @@ -140,6 +171,7 @@ public class MappedResourceCollection | |||
| (MappedResourceCollection) super.clone(); | |||
| c.nested = nested; | |||
| c.mapper = mapper; | |||
| c.cachedColl = null; | |||
| return c; | |||
| } catch (CloneNotSupportedException e) { | |||
| throw new BuildException(e); | |||
| @@ -180,30 +212,32 @@ public class MappedResourceCollection | |||
| dieOnCircularReference(); | |||
| } | |||
| private static class MappedIterator implements Iterator { | |||
| private final Iterator sourceIterator; | |||
| private final FileNameMapper mapper; | |||
| private synchronized Collection cacheCollection() { | |||
| if (cachedColl == null || !cache) { | |||
| cachedColl = getCollection(); | |||
| } | |||
| return cachedColl; | |||
| } | |||
| private MappedIterator(Iterator source, Mapper m) { | |||
| sourceIterator = source; | |||
| if (m != null) { | |||
| mapper = m.getImplementation(); | |||
| private Collection getCollection() { | |||
| Collection collected = new ArrayList(); | |||
| FileNameMapper m = | |||
| mapper != null ? mapper.getImplementation() : new IdentityMapper(); | |||
| for (Iterator iter = nested.iterator(); iter.hasNext(); ) { | |||
| Resource r = (Resource) iter.next(); | |||
| if (enableMultipleMappings) { | |||
| String[] n = m.mapFileName(r.getName()); | |||
| if (n != null) { | |||
| for (int i = 0; i < n.length; i++) { | |||
| collected.add(new MappedResource(r, | |||
| new MergingMapper(n[i])) | |||
| ); | |||
| } | |||
| } | |||
| } else { | |||
| mapper = new IdentityMapper(); | |||
| collected.add(new MappedResource(r, m)); | |||
| } | |||
| } | |||
| public boolean hasNext() { | |||
| return sourceIterator.hasNext(); | |||
| } | |||
| public Object next() { | |||
| return new MappedResource((Resource) sourceIterator.next(), | |||
| mapper); | |||
| } | |||
| public void remove() { | |||
| throw new UnsupportedOperationException(); | |||
| } | |||
| return collected; | |||
| } | |||
| } | |||
| @@ -116,6 +116,48 @@ public class NullByteStreamResource extends Resource { | |||
| actual="${output}/bar.txt"/> | |||
| </target> | |||
| <target name="testMappedResourcesMultipleTrue"> | |||
| <mkdir dir="${input}"/> | |||
| <mkdir dir="${output}"/> | |||
| <echo file="${input}/foo.txt">Hello, world!</echo> | |||
| <copy todir="${output}"> | |||
| <mappedresources enableMultipleMappings="true"> | |||
| <fileset dir="${input}"/> | |||
| <compositemapper> | |||
| <globmapper from="foo.*" to="bar.*"/> | |||
| <globmapper from="foo.*" to="baz.*"/> | |||
| </compositemapper> | |||
| </mappedresources> | |||
| </copy> | |||
| <au:assertFileDoesntExist file="${output}/foo.txt"/> | |||
| <au:assertFileExists file="${output}/bar.txt"/> | |||
| <au:assertFileExists file="${output}/baz.txt"/> | |||
| <au:assertFilesMatch expected="${input}/foo.txt" | |||
| actual="${output}/bar.txt"/> | |||
| <au:assertFilesMatch expected="${input}/foo.txt" | |||
| actual="${output}/baz.txt"/> | |||
| </target> | |||
| <target name="testMappedResourcesMultipleFalse"> | |||
| <mkdir dir="${input}"/> | |||
| <mkdir dir="${output}"/> | |||
| <echo file="${input}/foo.txt">Hello, world!</echo> | |||
| <copy todir="${output}"> | |||
| <mappedresources enableMultipleMappings="false"> | |||
| <fileset dir="${input}"/> | |||
| <compositemapper> | |||
| <globmapper from="foo.*" to="bar.*"/> | |||
| <globmapper from="foo.*" to="baz.*"/> | |||
| </compositemapper> | |||
| </mappedresources> | |||
| </copy> | |||
| <au:assertFileDoesntExist file="${output}/foo.txt"/> | |||
| <au:assertFileExists file="${output}/bar.txt"/> | |||
| <au:assertFileDoesntExist file="${output}/baz.txt"/> | |||
| <au:assertFilesMatch expected="${input}/foo.txt" | |||
| actual="${output}/bar.txt"/> | |||
| </target> | |||
| <target name="testIncludeEmptyDirsDefaultsToTrue" | |||
| description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47168"> | |||
| <mkdir dir="${input}/foo"/> | |||