diff --git a/WHATSNEW b/WHATSNEW index 54f53a0f5..2b725fdd8 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -138,6 +138,9 @@ Other changes: * Added SimpleBigProjectLogger, intermediate between NoBannerLogger and BigProjectLogger. + * supports new attributes enablemultiplemappings + and cache. + Changes from Ant 1.8.0RC1 TO Ant 1.8.0 ====================================== diff --git a/docs/manual/CoreTypes/resources.html b/docs/manual/CoreTypes/resources.html index 21969801e..355d127c0 100644 --- a/docs/manual/CoreTypes/resources.html +++ b/docs/manual/CoreTypes/resources.html @@ -1081,9 +1081,32 @@ larger collection. Since Ant 1.7.1.

use mappedresources with tasks that only allow file-system based resources.

-

mappedresources doesn't support any attributes.

-
+

Parameters specified as attributes

+ + + + + + + + + + + + + + + + + +
AttributeDescriptionRequired
cacheWhether to cache results; enabling + may improve performance. Since Ant 1.8.1No, default false
enablemultiplemappings + 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. + since Ant 1.8.1.No - defaults to false.
+

Parameters specified as nested elements

A single resource collection is required.

A single mapper can be used to map diff --git a/src/main/org/apache/tools/ant/types/resources/MappedResource.java b/src/main/org/apache/tools/ant/types/resources/MappedResource.java index 13d2c548f..82071ed8c 100644 --- a/src/main/org/apache/tools/ant/types/resources/MappedResource.java +++ b/src/main/org/apache/tools/ant/types/resources/MappedResource.java @@ -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()); + } } diff --git a/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java b/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java index 6d551bff1..89ea297c6 100644 --- a/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java +++ b/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java @@ -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; } } diff --git a/src/tests/antunit/taskdefs/copy-test.xml b/src/tests/antunit/taskdefs/copy-test.xml index 612a0a1bc..2207d2899 100644 --- a/src/tests/antunit/taskdefs/copy-test.xml +++ b/src/tests/antunit/taskdefs/copy-test.xml @@ -116,6 +116,48 @@ public class NullByteStreamResource extends Resource { actual="${output}/bar.txt"/> + + + + Hello, world! + + + + + + + + + + + + + + + + + + + + Hello, world! + + + + + + + + + + + + + + +