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 | * 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 | 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 | 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, | <p>The classpath can also be specified as nested classpath element, | ||||
| where <b><classpath></b> is a <a | 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> | <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="#sort">sort</a> - sorted resource collection</li> | ||||
| <li><a href="#first">first</a> - first <i>n</i> resources from a | <li><a href="#first">first</a> - first <i>n</i> resources from a | ||||
| nested collection</li> | 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 | <li><a href="#tokens">tokens</a> - <a href="#string">string</a> tokens | ||||
| gathered from a nested collection</li> | gathered from a nested collection</li> | ||||
| <li><a href="#union">union</a> - set union of nested resource collections</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> | <p>A single resource collection is required.</p> | ||||
| </blockquote> | </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> | <h4><a name="tokens">tokens</a></h4> | ||||
| <p>Includes the <a href="#string">string</a> tokens gathered from a nested | <p>Includes the <a href="#string">string</a> tokens gathered from a nested | ||||
| resource collection. Uses the same tokenizers supported by the | 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 | sort=org.apache.tools.ant.types.resources.Sort | ||||
| resources=org.apache.tools.ant.types.resources.Resources | resources=org.apache.tools.ant.types.resources.Resources | ||||
| first=org.apache.tools.ant.types.resources.First | first=org.apache.tools.ant.types.resources.First | ||||
| last=org.apache.tools.ant.types.resources.Last | |||||
| tarfileset=org.apache.tools.ant.types.TarFileSet | tarfileset=org.apache.tools.ant.types.TarFileSet | ||||
| tokens=org.apache.tools.ant.types.resources.Tokens | tokens=org.apache.tools.ant.types.resources.Tokens | ||||
| @@ -21,44 +21,19 @@ import java.util.Iterator; | |||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.Collection; | import java.util.Collection; | ||||
| import org.apache.tools.ant.BuildException; | |||||
| /** | /** | ||||
| * ResourceCollection that contains the first <code>count</code> elements of | * ResourceCollection that contains the first <code>count</code> elements of | ||||
| * another ResourceCollection. | |||||
| * another ResourceCollection, a la the UNIX head command. | |||||
| * @since Ant 1.7 | * @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. | * Take the first <code>count</code> elements. | ||||
| * @return a Collection of Resources. | * @return a Collection of Resources. | ||||
| */ | */ | ||||
| protected Collection getCollection() { | protected Collection getCollection() { | ||||
| int ct = getCount(); | |||||
| if (ct < 0) { | |||||
| throw new BuildException(BAD_COUNT); | |||||
| } | |||||
| int ct = getValidCount(); | |||||
| Iterator iter = getResourceCollection().iterator(); | Iterator iter = getResourceCollection().iterator(); | ||||
| ArrayList al = new ArrayList(ct); | ArrayList al = new ArrayList(ct); | ||||
| for (int i = 0; i < ct && iter.hasNext(); i++) { | 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> | |||||