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"/> | |||