From 11ba5bbc2d5c55c3586fc71bf2f5ce205e40036d Mon Sep 17 00:00:00 2001 From: Matthias Vill Date: Tue, 27 Oct 2020 22:22:45 +0100 Subject: [PATCH] #64854 Add preserveduplicates option to ResourceList --- CONTRIBUTORS | 1 + contributors.xml | 5 +++ manual/Types/resources.html | 8 ++++ .../AppendableResourceCollection.java | 21 +++++++++ .../BaseResourceCollectionContainer.java | 3 +- .../ant/types/resources/ResourceList.java | 43 ++++++++++++++----- .../tools/ant/types/resources/Resources.java | 3 +- .../types/resources/resourcelist-test.xml | 37 ++++++++++++++++ 8 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 src/main/org/apache/tools/ant/types/resources/AppendableResourceCollection.java 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 @@ -1183,6 +1183,11 @@ Matthias Gutheil + + Matthias + Johann + Vill + Michael Bayne 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 @@ -1419,6 +1419,14 @@ of <filelist>.

No + + preserveduplicates + Makes this resourcelist return all resources as + many times as they are specified. Otherwise + resourcelist will only return each resource, in the + order they first appear. Since Ant 1.10.10 + No + refid Makes this resourcelist 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 rc = new ArrayList<>(); private Collection 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 filterChains = new Vector<>(); private final ArrayList 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. @@ -116,6 +112,22 @@ public class ResourceList extends DataType implements ResourceCollection { this.baseDir = baseDir; } + /** + * Makes this resourcelist return all resources as + * many times as they are specified. Otherwise + * resourcelist 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 + + + ${input}/b.txt +${input}/b.txt + Demo content + ${input}/b.txt +${input}/b.txt + + + + + + + + + + + + + + ${input}/b.txt +${input}/b.txt + Demo content + ${input}/b.txt +${input}/b.txt + + + + + + + + + + + +