diff options
8 files changed, 109 insertions, 12 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 0a9026aed..5b9639b52 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -285,6 +285,7 @@ Matthew Watson Matthew Yanos Matthias Bhend Matthias Gutheil +Matthias Johann Vill Michael Bayne Michael Clarke Michael Davey diff --git a/contributors.xml b/contributors.xml index 18cb423a6..bbdb03cd6 100644 --- a/contributors.xml +++ b/contributors.xml @@ -1184,6 +1184,11 @@ <last>Gutheil</last> </name> <name> + <first>Matthias</first> + <middle>Johann</middle> + <last>Vill</last> + </name> + <name> <first>Michael</first> <last>Bayne</last> </name> diff --git a/manual/Types/resources.html b/manual/Types/resources.html index 184ec0233..5783fd167 100644 --- a/manual/Types/resources.html +++ b/manual/Types/resources.html @@ -1420,6 +1420,14 @@ of <a href="filelist.html"><code><filelist></code></a>.</p> <td>No</td> </tr> <tr> + <td>preserveduplicates</td> + <td>Makes this <code>resourcelist</code> return all resources as + many times as they are specified. Otherwise + <code>resourcelist</code> will only return each resource, in the + order they first appear. <em>Since Ant 1.10.10</em></td> + <td>No</td> + </tr> + <tr> <td>refid</td> <td>Makes this <code>resourcelist</code> a <a href="../using.html#references">reference</a> to diff --git a/src/main/org/apache/tools/ant/types/resources/AppendableResourceCollection.java b/src/main/org/apache/tools/ant/types/resources/AppendableResourceCollection.java new file mode 100644 index 000000000..d85054ab3 --- /dev/null +++ b/src/main/org/apache/tools/ant/types/resources/AppendableResourceCollection.java @@ -0,0 +1,21 @@ +package org.apache.tools.ant.types.resources; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.ResourceCollection; + +/** + * Interface describing a collection of Resources, to which elements can be + * appended. + * + * @since Ant 1.10.10 + */ +public interface AppendableResourceCollection extends ResourceCollection { + /** + Add a ResourceCollection to the container. + + @param c the ResourceCollection to add. + @throws BuildException on error. + @since Ant 1.10.10 + */ + void add(ResourceCollection c) throws BuildException; +} diff --git a/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java b/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java index 66dbda709..b066a5f1d 100644 --- a/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java +++ b/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java @@ -37,7 +37,7 @@ import org.apache.tools.ant.types.ResourceCollection; * @since Ant 1.7 */ public abstract class BaseResourceCollectionContainer - extends DataType implements ResourceCollection, Cloneable { + extends DataType implements AppendableResourceCollection, Cloneable { private List<ResourceCollection> rc = new ArrayList<>(); private Collection<Resource> coll = null; private boolean cache = true; @@ -92,6 +92,7 @@ public abstract class BaseResourceCollectionContainer * @param c the ResourceCollection to add. * @throws BuildException on error. */ + @Override public synchronized void add(ResourceCollection c) throws BuildException { if (isReference()) { throw noChildrenAllowed(); diff --git a/src/main/org/apache/tools/ant/types/resources/ResourceList.java b/src/main/org/apache/tools/ant/types/resources/ResourceList.java index 2925cb418..9000af331 100644 --- a/src/main/org/apache/tools/ant/types/resources/ResourceList.java +++ b/src/main/org/apache/tools/ant/types/resources/ResourceList.java @@ -47,14 +47,10 @@ import org.apache.tools.ant.types.ResourceCollection; public class ResourceList extends DataType implements ResourceCollection { private final Vector<FilterChain> filterChains = new Vector<>(); private final ArrayList<ResourceCollection> textDocuments = new ArrayList<>(); - private final Union cachedResources = new Union(); - private volatile boolean cached = false; + private AppendableResourceCollection cachedResources = null; private String encoding = null; private File baseDir; - - public ResourceList() { - cachedResources.setCache(true); - } + private boolean preserveDuplicates = false; /** * Adds a source. @@ -117,6 +113,22 @@ public class ResourceList extends DataType implements ResourceCollection { } /** + * Makes this <code>resourcelist</code> return all resources as + * many times as they are specified. Otherwise + * <code>resourcelist</code> will only return each resource, in the + * order they first appear. + * + * @param preserveDuplicates boolean + * @since Ant 1.10.10 + */ + public final void setPreserveDuplicates(boolean preserveDuplicates) { + if (isReference()) { + throw tooManyAttributes(); + } + this.preserveDuplicates = preserveDuplicates; + } + + /** * Makes this instance in effect a reference to another ResourceList * instance. * @@ -207,20 +219,31 @@ public class ResourceList extends DataType implements ResourceCollection { return getCheckedRef(ResourceList.class); } + private AppendableResourceCollection newResourceCollection() { + if (preserveDuplicates) { + final Resources resources = new Resources(); + resources.setCache(true); + return resources; + } else { + final Union union = new Union(); + union.setCache(true); + return union; + } + } + private synchronized ResourceCollection cache() { - if (!cached) { + if (cachedResources == null) { dieOnCircularReference(); + this.cachedResources = newResourceCollection(); textDocuments.stream().flatMap(ResourceCollection::stream) .map(this::read).forEach(cachedResources::add); - cached = true; } return cachedResources; } private ResourceCollection read(Resource r) { try (BufferedReader reader = new BufferedReader(open(r))) { - Union streamResources = new Union(); - streamResources.setCache(true); + final AppendableResourceCollection streamResources = newResourceCollection(); reader.lines().map(this::parse).forEach(streamResources::add); return streamResources; } catch (final IOException ioe) { diff --git a/src/main/org/apache/tools/ant/types/resources/Resources.java b/src/main/org/apache/tools/ant/types/resources/Resources.java index a74557a73..a832f63e1 100644 --- a/src/main/org/apache/tools/ant/types/resources/Resources.java +++ b/src/main/org/apache/tools/ant/types/resources/Resources.java @@ -40,7 +40,7 @@ import org.apache.tools.ant.types.ResourceCollection; * making no attempt to remove duplicates, or references another ResourceCollection. * @since Ant 1.7 */ -public class Resources extends DataType implements ResourceCollection { +public class Resources extends DataType implements AppendableResourceCollection { /** static empty ResourceCollection */ public static final ResourceCollection NONE = new ResourceCollection() { @Override @@ -156,6 +156,7 @@ public class Resources extends DataType implements ResourceCollection { * Add a ResourceCollection. * @param c the ResourceCollection to add. */ + @Override public synchronized void add(ResourceCollection c) { if (isReference()) { throw noChildrenAllowed(); diff --git a/src/tests/antunit/types/resources/resourcelist-test.xml b/src/tests/antunit/types/resources/resourcelist-test.xml index 2575b6524..602ee545a 100644 --- a/src/tests/antunit/types/resources/resourcelist-test.xml +++ b/src/tests/antunit/types/resources/resourcelist-test.xml @@ -101,4 +101,41 @@ ${input}/c.txt</echo> </copy> <au:assertFileExists file="${output}/antlib.xml"/> </target> + + <target name="testDuplicatesRemoved" depends="setUp"> + <echo file="${input}/a.txt">${input}/b.txt +${input}/b.txt</echo> + <echo file="${input}/b.txt">Demo content</echo> + <echo file="${input}/c.txt">${input}/b.txt +${input}/b.txt</echo> + <pathconvert property="1b" pathsep="|" preserveduplicates="true"> + <flattenmapper/> + <resourcelist> + <resources> + <file file="${input}/a.txt"/> + <file file="${input}/c.txt"/> + </resources> + </resourcelist> + </pathconvert> + <au:assertPropertyEquals name="1b" value="b.txt"/> + </target> + + <target name="testDuplicatesPreserved" depends="setUp"> + <echo file="${input}/a.txt">${input}/b.txt +${input}/b.txt</echo> + <echo file="${input}/b.txt">Demo content</echo> + <echo file="${input}/c.txt">${input}/b.txt +${input}/b.txt</echo> + <pathconvert property="4bs" pathsep="|" preserveduplicates="true"> + <flattenmapper/> + <resourcelist preserveduplicates="true"> + <resources> + <file file="${input}/a.txt"/> + <file file="${input}/a.txt"/> + <file file="${input}/c.txt"/> + </resources> + </resourcelist> + </pathconvert> + <au:assertPropertyEquals name="4bs" value="b.txt|b.txt|b.txt|b.txt|b.txt|b.txt"/> + </target> </project> |