git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@513829 13f79535-47bb-0310-9956-ffa450edef68master
@@ -79,7 +79,9 @@ Other changes: | |||
* If you try and use a type in a namespace (or an antlib), and the type is not | |||
recognized but there are other definitions in that namespace, Ant lists what | |||
the known definitions are. This helps you find spelling errors. | |||
the known definitions are. This helps you find spelling errors. | |||
* Add a <last> resource collection, corresponding to <first>. | |||
Changes from Ant 1.6.5 to Ant 1.7.0 | |||
=================================== | |||
@@ -153,7 +153,7 @@ implementations are also usable as single-element | |||
<p>The classpath can also be specified as nested classpath element, | |||
where <b><classpath></b> is a <a | |||
href="../using.html#path">path-like</a> structure.</p> | |||
href="../using.html#path">path-like structure</a>.</p> | |||
<h4><a name="zipentry">zipentry</a></h4> | |||
@@ -317,6 +317,8 @@ Ant's "legacy" datatypes have been modified to behave as Resource Collections: | |||
<li><a href="#sort">sort</a> - sorted resource collection</li> | |||
<li><a href="#first">first</a> - first <i>n</i> resources from a | |||
nested collection</li> | |||
<li><a href="#last">last</a> - last <i>n</i> resources from a | |||
nested collection</li> | |||
<li><a href="#tokens">tokens</a> - <a href="#string">string</a> tokens | |||
gathered from a nested collection</li> | |||
<li><a href="#union">union</a> - set union of nested resource collections</li> | |||
@@ -770,6 +772,34 @@ larger collection.</p> | |||
<p>A single resource collection is required.</p> | |||
</blockquote> | |||
<h4><a name="last">last</a></h4> | |||
<p>Includes the last <i>count</i> resources from a nested resource collection. | |||
This can be used in conjunction with the <a href="#sort">sort</a> collection, | |||
for example, to select the last few oldest, largest, etc. resources from a | |||
larger collection.</p> | |||
<blockquote> | |||
<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">count</td> | |||
<td valign="top">The number of resources to include</td> | |||
<td valign="top" align="center">No, default 1</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">cache</td> | |||
<td valign="top">Whether to cache results; disabling | |||
may seriously impact performance</td> | |||
<td valign="top" align="center">No, default <i>true</i></td> | |||
</tr> | |||
</table> | |||
<h4>Parameters specified as nested elements</h4> | |||
<p>A single resource collection is required.</p> | |||
</blockquote> | |||
<h4><a name="tokens">tokens</a></h4> | |||
<p>Includes the <a href="#string">string</a> tokens gathered from a nested | |||
resource collection. Uses the same tokenizers supported by the | |||
@@ -55,6 +55,7 @@ intersect=org.apache.tools.ant.types.resources.Intersect | |||
sort=org.apache.tools.ant.types.resources.Sort | |||
resources=org.apache.tools.ant.types.resources.Resources | |||
first=org.apache.tools.ant.types.resources.First | |||
last=org.apache.tools.ant.types.resources.Last | |||
tarfileset=org.apache.tools.ant.types.TarFileSet | |||
tokens=org.apache.tools.ant.types.resources.Tokens | |||
@@ -21,44 +21,19 @@ import java.util.Iterator; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import org.apache.tools.ant.BuildException; | |||
/** | |||
* ResourceCollection that contains the first <code>count</code> elements of | |||
* another ResourceCollection. | |||
* another ResourceCollection, a la the UNIX head command. | |||
* @since Ant 1.7 | |||
*/ | |||
public class First extends BaseResourceCollectionWrapper { | |||
private static final String BAD_COUNT | |||
= "count of first resources should be set to an int >= 0"; | |||
private int count = 1; | |||
/** | |||
* Set the number of resources to be included. | |||
* @param i the count as <code>int</count>. | |||
*/ | |||
public synchronized void setCount(int i) { | |||
count = i; | |||
} | |||
/** | |||
* Get the number of resources to be included. Default is 1. | |||
* @return the count as <code>int</count>. | |||
*/ | |||
public synchronized int getCount() { | |||
return count; | |||
} | |||
public class First extends SizeLimitCollection { | |||
/** | |||
* Take the first <code>count</code> elements. | |||
* @return a Collection of Resources. | |||
*/ | |||
protected Collection getCollection() { | |||
int ct = getCount(); | |||
if (ct < 0) { | |||
throw new BuildException(BAD_COUNT); | |||
} | |||
int ct = getValidCount(); | |||
Iterator iter = getResourceCollection().iterator(); | |||
ArrayList al = new ArrayList(ct); | |||
for (int i = 0; i < ct && iter.hasNext(); i++) { | |||
@@ -0,0 +1,69 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
* | |||
*/ | |||
package org.apache.tools.ant.types.resources; | |||
import java.util.Iterator; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.types.ResourceCollection; | |||
/** | |||
* ResourceCollection that contains the last <code>count</code> elements of | |||
* another ResourceCollection, a la the UNIX tail command. | |||
* @since Ant 1.7.1 | |||
*/ | |||
public class Last extends SizeLimitCollection { | |||
/** | |||
* Take the last <code>count</code> elements. | |||
* @return a Collection of Resources. | |||
*/ | |||
protected Collection getCollection() { | |||
int count = getValidCount(); | |||
ResourceCollection rc = getResourceCollection(); | |||
int i = count; | |||
Iterator iter = rc.iterator(); | |||
int size = rc.size(); | |||
for (; i < size; i++) iter.next(); | |||
ArrayList al = new ArrayList(count); | |||
for (; iter.hasNext(); i++) { | |||
al.add(iter.next()); | |||
} | |||
int found = al.size(); | |||
if (found == count || (size < count && found == size)) { | |||
return al; | |||
} | |||
//mismatch: | |||
String msg = "Resource collection " + rc + " reports size " + size | |||
+ " but returns " + i + " elements."; | |||
//size was understated -> too many results; warn and continue: | |||
if (found > count) { | |||
log(msg, Project.MSG_WARN); | |||
return al.subList(found - count, found); | |||
} | |||
//size was overstated; we missed some and are now in error-land: | |||
throw new BuildException(msg); | |||
} | |||
} |
@@ -0,0 +1,70 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
* | |||
*/ | |||
package org.apache.tools.ant.types.resources; | |||
import org.apache.tools.ant.BuildException; | |||
/** | |||
* ResourceCollection that imposes a size limit on another ResourceCollection. | |||
* @since Ant 1.7.1 | |||
*/ | |||
public abstract class SizeLimitCollection extends BaseResourceCollectionWrapper { | |||
private static final String BAD_COUNT | |||
= "size-limited collection count should be set to an int >= 0"; | |||
private int count = 1; | |||
/** | |||
* Set the number of resources to be included. | |||
* @param i the count as <code>int</count>. | |||
*/ | |||
public synchronized void setCount(int i) { | |||
count = i; | |||
} | |||
/** | |||
* Get the number of resources to be included. Default is 1. | |||
* @return the count as <code>int</count>. | |||
*/ | |||
public synchronized int getCount() { | |||
return count; | |||
} | |||
/** | |||
* Efficient size implementation. | |||
* @return int size | |||
*/ | |||
public synchronized int size() { | |||
int sz = getResourceCollection().size(); | |||
int ct = getValidCount(); | |||
return sz < ct ? sz : ct; | |||
} | |||
/** | |||
* Get the count, verifying it is >= 0. | |||
* @return int count | |||
*/ | |||
protected int getValidCount() { | |||
int ct = getCount(); | |||
if (ct < 0) { | |||
throw new BuildException(BAD_COUNT); | |||
} | |||
return ct; | |||
} | |||
} |
@@ -0,0 +1,140 @@ | |||
<project xmlns:au="antlib:org.apache.ant.antunit"> | |||
<tokens id="testrc"> | |||
<string value="1,2,3,4,5" /> | |||
<stringtokenizer delims="," /> | |||
</tokens> | |||
<target name="testfirst0"> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<first count="0"><resources refid="testrc" /></first> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testfirst1"> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<difference> | |||
<first><resources refid="testrc" /></first> | |||
<string value="1" /> | |||
</difference> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testfirst2"> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<difference> | |||
<first count="2"><resources refid="testrc" /></first> | |||
<resources> | |||
<string value="1" /> | |||
<string value="2" /> | |||
</resources> | |||
</difference> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testfirst5"> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<difference> | |||
<first count="5"><resources refid="testrc" /></first> | |||
<resources refid="testrc" /> | |||
</difference> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testfirst6"> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<difference> | |||
<first count="6"><resources refid="testrc" /></first> | |||
<resources refid="testrc" /> | |||
</difference> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testfirst-1"> | |||
<au:expectfailure expectedmessage="size-limited collection count should be set to an int >= 0"> | |||
<resourcecount> | |||
<first count="-1"><resources refid="testrc" /></first> | |||
</resourcecount> | |||
</au:expectfailure> | |||
</target> | |||
<target name="testlast0"> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<last count="0"><resources refid="testrc" /></last> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testlast1"> | |||
<pathconvert> | |||
<last count="1"><resources refid="testrc" /></last> | |||
</pathconvert> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<difference> | |||
<last><resources refid="testrc" /></last> | |||
<string value="5" /> | |||
</difference> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testlast2"> | |||
<pathconvert> | |||
<last count="2"><resources refid="testrc" /></last> | |||
</pathconvert> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<difference> | |||
<last count="2"><resources refid="testrc" /></last> | |||
<resources> | |||
<string value="4" /> | |||
<string value="5" /> | |||
</resources> | |||
</difference> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testlast5"> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<difference> | |||
<last count="5"><resources refid="testrc" /></last> | |||
<resources refid="testrc" /> | |||
</difference> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testlast6"> | |||
<au:assertTrue> | |||
<resourcecount count="0"> | |||
<difference> | |||
<last count="6"><resources refid="testrc" /></last> | |||
<resources refid="testrc" /> | |||
</difference> | |||
</resourcecount> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testlast-1"> | |||
<au:expectfailure expectedmessage="size-limited collection count should be set to an int >= 0"> | |||
<resourcecount> | |||
<last count="-1"><resources refid="testrc" /></last> | |||
</resourcecount> | |||
</au:expectfailure> | |||
</target> | |||
</project> |