@@ -285,6 +285,7 @@ Matthew Watson | |||
Matthew Yanos | |||
Matthias Bhend | |||
Matthias Gutheil | |||
Matthias Johann Vill | |||
Michael Bayne | |||
Michael Clarke | |||
Michael Davey | |||
@@ -1183,6 +1183,11 @@ | |||
<first>Matthias</first> | |||
<last>Gutheil</last> | |||
</name> | |||
<name> | |||
<first>Matthias</first> | |||
<middle>Johann</middle> | |||
<last>Vill</last> | |||
</name> | |||
<name> | |||
<first>Michael</first> | |||
<last>Bayne</last> | |||
@@ -1419,6 +1419,14 @@ of <a href="filelist.html"><code><filelist></code></a>.</p> | |||
</td> | |||
<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> | |||
@@ -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; | |||
} |
@@ -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(); | |||
@@ -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. | |||
@@ -116,6 +112,22 @@ public class ResourceList extends DataType implements ResourceCollection { | |||
this.baseDir = baseDir; | |||
} | |||
/** | |||
* 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) { | |||
@@ -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(); | |||
@@ -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> |