Browse Source

Remove "strip-duplicates" behavior from; add condition behavior to, Length task.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@278120 13f79535-47bb-0310-9956-ffa450edef68
master
Matthew Jason Benson 20 years ago
parent
commit
6bd9a3ed78
5 changed files with 333 additions and 33 deletions
  1. +17
    -0
      docs/manual/CoreTasks/conditions.html
  2. +16
    -3
      docs/manual/CoreTasks/length.html
  3. +142
    -2
      src/etc/testcases/taskdefs/length.xml
  4. +113
    -28
      src/main/org/apache/tools/ant/taskdefs/Length.java
  5. +45
    -0
      src/testcases/org/apache/tools/ant/taskdefs/LengthTest.java

+ 17
- 0
docs/manual/CoreTasks/conditions.html View File

@@ -605,6 +605,23 @@ Probe for the maven repository being reachable.
<p>
Probe for the maven repository being reachable using the hostname, ten second timeout..
</p>

<h4>length</h4>
<p>This condition is a facet of the <a href="length.html">Length</a> task.
It is used to test the length of a string or one or more files.
<b>Since Ant 1.6.3</b>
</p>

Verify a string is of a certain length:
<pre>
&lt;length string=&quot; foo &quot; trim="true" length=&quot;3&quot;/&gt;
</pre>

Verify a file is not empty:
<pre>
&lt;length file=&quot;foo&quot; when=&quot;greater&quot; length=&quot;0&quot;/&gt;
</pre>

<hr>
<p align="center">Copyright &copy; 2001-2005 Apache Software
Foundation. All rights Reserved.</p>


+ 16
- 3
docs/manual/CoreTasks/length.html View File

@@ -11,7 +11,8 @@
<h2>Length</h2>
<h3>Description</h3>
<p>Display or set a property containing length information for
a string, a file, or one or more nested filesets.</p>
a string, a file, or one or more nested filesets. Can also
be used as a condition. <b>Since Ant 1.6.3</b></p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -22,7 +23,8 @@
<tr>
<td valign="top">property</td>
<td valign="top">The property to set. If omitted
the length is written to the log.</td>
the results are written to the log. Ignored when
processing as a condition.</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
@@ -40,7 +42,7 @@
<td valign="top">File length mode; when &quot;all&quot; the resulting
value is the sum of all included files' lengths; when &quot;each&quot;
the task outputs the absolute path and length of each included file,
one per line.</td>
one per line. Ignored when processing as a condition.</td>
<td valign="top" align="center">No; default is &quot;all&quot;</td>
</tr>
<tr>
@@ -48,6 +50,17 @@
<td valign="top">Whether to trim when operating on a string.</td>
<td valign="top" align="center">No; only valid when string is set</td>
</tr>
<tr>
<td valign="top">length</td>
<td valign="top">Comparison length for processing as a condition.</td>
<td valign="top" align="center">Yes, in condition mode</td>
</tr>
<tr>
<td valign="top">when</td>
<td valign="top">Comparison type: "equal", "greater", "less"
for use when operating as a condition.</td>
<td valign="top" align="center">No; default is "equal"</td>
</tr>
</table>
<h3>Parameters specified as nested elements</h3>
<h4>fileset</h4><p>You can include files via nested


+ 142
- 2
src/etc/testcases/taskdefs/length.xml View File

@@ -35,6 +35,27 @@
</fail>
</target>

<target name="testEachCondition" depends="init">
<length mode="each" property="length.each">
<fileset id="fs" dir="${dir}" />
</length>
<length string="${foo}${bar}........${line.separator}"
property="length.expected" />
<fail>
<!-- test that both files are represented, and that the
output is the expected length; do not assume order. -->
<condition>
<not>
<and>
<contains string="${length.each}" substring="${foo} : 3" />
<contains string="${length.each}" substring="${bar} : 3" />
<length string="${length.each}" length="${length.expected}" />
</and>
</not>
</condition>
</fail>
</target>

<target name="testAll" depends="init">
<length property="length.all">
<fileset id="foo" file="${dir.a}/foo" />
@@ -49,6 +70,19 @@
</fail>
</target>

<target name="testAllCondition" depends="init">
<fail>
<condition>
<not>
<length length="6">
<fileset id="foo" file="${dir.a}/foo" />
<fileset id="bar" file="${dir.b}/bar" />
</length>
</not>
</condition>
</fail>
</target>

<target name="testFile" depends="init">
<length property="length.foo" file="${dir.a}/foo" />
<fail>
@@ -60,6 +94,16 @@
</fail>
</target>

<target name="testFileCondition" depends="init">
<fail>
<condition>
<not>
<length length="3" file="${dir.a}/foo" />
</not>
</condition>
</fail>
</target>

<target name="testBoth" depends="init">
<length property="length.foo" file="${dir.a}/foo">
<fileset file="${dir.b}/bar" />
@@ -73,6 +117,18 @@
</fail>
</target>

<target name="testBothCondition" depends="init">
<fail>
<condition>
<not>
<length length="6" file="${dir.a}/foo">
<fileset file="${dir.b}/bar" />
</length>
</not>
</condition>
</fail>
</target>

<target name="testDupes" depends="init">
<length property="length.foo" file="${dir.a}/foo">
<fileset dir="${dir}" />
@@ -80,7 +136,19 @@
<fail>
<condition>
<not>
<equals arg1="6" arg2="${length.foo}" />
<equals arg1="9" arg2="${length.foo}" />
</not>
</condition>
</fail>
</target>

<target name="testDupesCondition" depends="init">
<fail>
<condition>
<not>
<length length="9" file="${dir.a}/foo">
<fileset dir="${dir}" />
</length>
</not>
</condition>
</fail>
@@ -97,6 +165,58 @@
</fail>
</target>

<target name="testStringCondition">
<fail>
<condition>
<not>
<length string="foo" length="3" />
</not>
</condition>
</fail>
</target>

<target name="testTrimString">
<length string=" foo " trim="true" property="length.string" />
<fail>
<condition>
<not>
<equals arg1="3" arg2="${length.string}" />
</not>
</condition>
</fail>
</target>

<target name="testTrimStringCondition">
<fail>
<condition>
<not>
<length string=" foo " trim="true" length="3" />
</not>
</condition>
</fail>
</target>

<target name="testNoTrimString">
<length string=" foo " property="length.string" />
<fail>
<condition>
<not>
<equals arg1="5" arg2="${length.string}" />
</not>
</condition>
</fail>
</target>

<target name="testNoTrimStringCondition">
<fail>
<condition>
<not>
<length string=" foo " length="5" />
</not>
</condition>
</fail>
</target>

<target name="testTrimFile" description="should fail">
<length file="${ant.file}" trim="false" />
</target>
@@ -117,11 +237,14 @@
</fail>
</target>

<target name="testZipFileSet" depends="init">
<target name="zip" depends="init">
<zip destfile="${zipfile}">
<fileset file="${foo}" />
<fileset file="${bar}" />
</zip>
</target>

<target name="testZipFileSet" depends="zip">
<length property="length.zipfile1">
<zipfileset src="${zipfile}" />
</length>
@@ -140,6 +263,23 @@
</fail>
</target>

<target name="testZipFileSetCondition" depends="zip">
<fail>
<condition>
<not>
<and>
<length length="6">
<zipfileset src="${zipfile}" />
</length>
<length length="3">
<zipfileset src="${zipfile}" includes="bar" />
</length>
</and>
</not>
</condition>
</fail>
</target>

<target name="cleanup">
<delete dir="${dir}" />
<delete file="${zipfile}" />


+ 113
- 28
src/main/org/apache/tools/ant/taskdefs/Length.java View File

@@ -22,33 +22,39 @@ import java.io.PrintStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.util.Vector;
import java.util.HashSet;
import java.util.Iterator;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.condition.Condition;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.util.FileUtils;

/**
* Gets lengths: of files, byte size; of strings, length (optionally trimmed).
* Gets lengths: of files/resources, byte size; of strings, length (optionally trimmed).
* The task is overloaded in this way for semantic reasons, much like Available.
* @since Ant 1.6.3
*/
public class Length extends Task {
public class Length extends Task implements Condition {

private static final String ALL = "all";
private static final String EACH = "each";
private static final String STRING = "string";

private static final String LENGTH_REQUIRED
= "Use of the Length condition requires that the length attribute be set.";

private String property;
private String string;
private Boolean trim;
private Vector filesets;
private String mode = ALL;
private When when = When.EQUAL;
private Long length;
private Vector filesets;

/**
* The property in which the length will be stored.
@@ -73,10 +79,30 @@ public class Length extends Task {
* @param fs the <code>FileSet</code> to add.
*/
public synchronized void add(FileSet fs) {
if (fs == null) {
return;
}
filesets = (filesets == null) ? new Vector() : filesets;
filesets.add(fs);
}

/**
* Set the target count number for use as a Condition.
* @param ell the long length to compare with.
*/
public synchronized void setLength(long ell) {
length = new Long(ell);
}

/**
* Set the comparison criteria for use as a Condition:
* "equal", "greater", "less". Default is "equal".
* @param w EnumeratedAttribute When.
*/
public synchronized void setWhen(When w) {
when = w;
}

/**
* Set the execution mode for working with files.
* @param m the <code>FileMode</code> to use.
@@ -102,6 +128,14 @@ public class Length extends Task {
this.trim = trim ? Boolean.TRUE : Boolean.FALSE;
}

/**
* Learn whether strings will be trimmed.
* @return boolean trim setting.
*/
public boolean getTrim() {
return trim != null && trim.booleanValue();
}

/**
* Execute the length task.
*/
@@ -112,14 +146,38 @@ public class Length extends Task {
: (OutputStream) new LogOutputStream(this, Project.MSG_INFO));

if (STRING.equals(mode)) {
ps.print(((trim != null && trim.booleanValue())
? string.trim() : string).length());
ps.print(getLength(string, getTrim()));
ps.close();
} else if (EACH.equals(mode)) {
handleFilesets(new EachHandler(ps));
handleResources(new EachHandler(ps));
} else if (ALL.equals(mode)) {
handleFilesets(new AllHandler(ps));
handleResources(new AllHandler(ps));
}
}

/**
* Fulfill the condition contract.
* @return true if the condition is true.
* @throws BuildException if an error occurs.
*/
public boolean eval() {
validate();
if (length == null) {
throw new BuildException(LENGTH_REQUIRED);
}
Long ell = null;
if (STRING.equals(mode)) {
ell = new Long(getLength(string, getTrim()));
} else {
ConditionHandler h = new ConditionHandler();
handleResources(h);
ell = new Long(h.getLength());
}
int w = when.getIndex();
int comp = ell.compareTo(length);
return (w == 0 && comp == 0)
|| (w == 1 && comp > 0)
|| (w == 2 && comp < 0);
}

private void validate() {
@@ -130,9 +188,9 @@ public class Length extends Task {
}
if (!(STRING.equals(mode))) {
throw new BuildException("the mode attribute is for use"
+ " with the file length function");
+ " with the file/resource length function");
}
} else if (filesets != null && filesets.size() > 0) {
} else if (filesets != null) {
if (!(EACH.equals(mode) || ALL.equals(mode))) {
throw new BuildException("invalid mode setting for"
+ " file length function: \"" + mode + "\"");
@@ -147,10 +205,9 @@ public class Length extends Task {
}
}

private void handleFilesets(Handler h) {
HashSet included = new HashSet(filesets.size());
for (int i = 0; i < filesets.size(); i++) {
FileSet fs = (FileSet) (filesets.get(i));
private void handleResources(Handler h) {
for (Iterator i = filesets.iterator(); i.hasNext();) {
FileSet fs = (FileSet) i.next();
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
String[] f = ds.getIncludedFiles();
for (int j = 0; j < f.length; j++) {
@@ -161,24 +218,22 @@ public class Length extends Task {
log(r.getName() + " is a directory; length unspecified",
Project.MSG_ERR);
} else {
//clone the Resource and alter path
//force a full path:
File basedir = ds.getBasedir();
if (basedir != null) {
r = (Resource) (r.clone());
r.setName(FileUtils.getFileUtils().resolveFile(
basedir, r.getName()).getAbsolutePath());
}
if (included.add(r.getName())) {
h.handle(r);
}
String s = FileUtils.getFileUtils().resolveFile(
basedir, r.getName()).getAbsolutePath();
h.handle(new Resource(s, true,
r.getLastModified(), false, r.getSize()));
}
}
}
included.clear();
included = null;
h.complete();
}

private static long getLength(String s, boolean t) {
return (t ? s.trim() : s).length();
}

/** EnumeratedAttribute operation mode */
public static class FileMode extends EnumeratedAttribute {
static final String[] MODES = new String[] {EACH, ALL};
@@ -193,6 +248,25 @@ public class Length extends Task {

}

/**
* EnumeratedAttribute for the when attribute.
*/
public static class When extends EnumeratedAttribute {
private static final String[] VALUES
= new String[] {"equal", "greater", "less"};

private static final When EQUAL = new When("equal");

public When() {
}
public When(String value) {
setValue(value);
}
public String[] getValues() {
return VALUES;
}
}

private class PropertyOutputStream extends ByteArrayOutputStream {
public void close() {
getProject().setNewProperty(
@@ -231,7 +305,7 @@ public class Length extends Task {
}

private class AllHandler extends Handler {
long length = 0L;
long accum = 0L;
AllHandler(PrintStream ps) {
super(ps);
}
@@ -240,12 +314,23 @@ public class Length extends Task {
if (size == Resource.UNKNOWN_SIZE) {
log("Size unknown for " + r.getName(), Project.MSG_WARN);
} else {
length += size;
accum += size;
}
}
void complete() {
ps.print(length);
ps.print(accum);
super.complete();
}
}

private class ConditionHandler extends AllHandler {
ConditionHandler() {
super(null);
}
void complete() {
}
long getLength() {
return accum;
}
}
}

+ 45
- 0
src/testcases/org/apache/tools/ant/taskdefs/LengthTest.java View File

@@ -37,26 +37,66 @@ public class LengthTest extends BuildFileTest {
executeTarget("testEach");
}

public void testEachCondition() {
executeTarget("testEachCondition");
}

public void testAll() {
executeTarget("testAll");
}

public void testAllCondition() {
executeTarget("testAllCondition");
}

public void testFile() {
executeTarget("testFile");
}

public void testFileCondition() {
executeTarget("testFileCondition");
}

public void testBoth() {
executeTarget("testBoth");
}

public void testBothCondition() {
executeTarget("testBothCondition");
}

public void testDupes() {
executeTarget("testDupes");
}

public void testDupesCondition() {
executeTarget("testDupesCondition");
}

public void testString() {
executeTarget("testString");
}

public void testStringCondition() {
executeTarget("testStringCondition");
}

public void testTrimString() {
executeTarget("testTrimString");
}

public void testTrimStringCondition() {
executeTarget("testTrimStringCondition");
}

public void testNoTrimString() {
executeTarget("testNoTrimString");
}

public void testNoTrimStringCondition() {
executeTarget("testNoTrimStringCondition");
}

public void testStringFile() {
expectBuildExceptionContaining("testStringFile",
"should fail", "incompatible");
@@ -74,4 +114,9 @@ public class LengthTest extends BuildFileTest {
public void testZipFileSet() {
executeTarget("testZipFileSet");
}

public void testZipFileSetCondition() {
executeTarget("testZipFileSetCondition");
}

}

Loading…
Cancel
Save