diff --git a/WHATSNEW b/WHATSNEW index 91fac75c3..f80af061b 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -110,6 +110,8 @@ Other changes: * Added support to the touch task for a verbose attribute to suppress logging of new file creation. +* Added length task to get strings' and files' lengths. + Changes from Ant 1.6.2 to current Ant 1.6 CVS version ===================================================== diff --git a/docs/manual/CoreTasks/length.html b/docs/manual/CoreTasks/length.html new file mode 100755 index 000000000..4717367b3 --- /dev/null +++ b/docs/manual/CoreTasks/length.html @@ -0,0 +1,68 @@ + + +
+ +Display or set a property containing length information for + a string, a file, or one or more nested filesets.
+Attribute | +Description | +Required | +
property | +The property to set. If omitted + the length is written to the log. | +No | +
file | +Single file whose length to report. | +One of these, + or one or more nested filesets | +
string | +The string whose length to report. | +|
mode | +File length mode; when "all" the resulting + value is the sum of all included files' lengths; when "each" + the task outputs the absolute path and length of each included file, + one per line. | +No; default is "all" | +
trim | +Whether to trim when operating on a string. | +No; only valid when string is set | +
You can include files via nested + filesets.
+<length string="foo" property="length.foo" /> ++
Stores the length of the string "foo" in the property named +length.foo.
+<length file="bar" property="length.bar" /> ++
Stores the length of file "bar" in the property named +length.bar.
+Copyright © 2005 The Apache Software Foundation. + All rights Reserved.
+ + + diff --git a/docs/manual/coretasklist.html b/docs/manual/coretasklist.html index de64806dc..dd35a5c6f 100644 --- a/docs/manual/coretasklist.html +++ b/docs/manual/coretasklist.html @@ -59,6 +59,7 @@ JavaString
property key.
+ */
+ public synchronized void setProperty(String property) {
+ this.property = property;
+ }
+
+ /**
+ * Set the single file for this task.
+ * @param file the File
whose length to retrieve.
+ */
+ public synchronized void setFile(File file) {
+ FileSet fs = new FileSet();
+ fs.setFile(file);
+ add(fs);
+ }
+
+ /**
+ * Add a FileSet.
+ * @param fs the FileSet
to add.
+ */
+ public synchronized void add(FileSet fs) {
+ filesets = (filesets == null) ? new Vector() : filesets;
+ filesets.add(fs);
+ }
+
+ /**
+ * Set the execution mode for working with files.
+ * @param m the FileMode
to use.
+ */
+ public synchronized void setMode(FileMode m) {
+ this.mode = m.getValue();
+ }
+
+ /**
+ * Set the string whose length to get.
+ * @param string String
.
+ */
+ public synchronized void setString(String string) {
+ this.string = string;
+ this.mode = STRING;
+ }
+
+ /**
+ * Set whether to trim in string mode.
+ * @param trim boolean
.
+ */
+ public synchronized void setTrim(boolean trim) {
+ this.trim = trim ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * Execute the length task.
+ */
+ public void execute() {
+ validate();
+ PrintStream ps = new PrintStream((property != null)
+ ? (OutputStream) new PropertyOutputStream()
+ : (OutputStream) new LogOutputStream(this, Project.MSG_INFO));
+
+ if (STRING.equals(mode)) {
+ ps.print(((trim != null && trim.booleanValue())
+ ? string.trim() : string).length());
+ ps.close();
+ } else if (EACH.equals(mode)) {
+ handleFilesets(new EachHandler(ps));
+ } else if (ALL.equals(mode)) {
+ handleFilesets(new AllHandler(ps));
+ }
+ }
+
+ private void validate() {
+ if (string != null) {
+ if (filesets != null && filesets.size() > 0) {
+ throw new BuildException("the string length function"
+ + " is incompatible with the file length function");
+ }
+ if (!(STRING.equals(mode))) {
+ throw new BuildException("the mode attribute is for use"
+ + " with the file length function");
+ }
+ } else if (filesets != null && filesets.size() > 0) {
+ if (!(EACH.equals(mode) || ALL.equals(mode))) {
+ throw new BuildException("invalid mode setting for"
+ + " file length function: \"" + mode + "\"");
+ } else if (trim != null) {
+ throw new BuildException("the trim attribute is"
+ + " for use with the string length function only");
+ }
+ } else {
+ throw new BuildException("you must set either the string attribute"
+ + " or specify one or more files using the file attribute or"
+ + " nested filesets");
+ }
+ }
+
+ private void handleFilesets(Handler h) {
+ HashSet included = new HashSet(filesets.size() * 10);
+ for (int i = 0; i < filesets.size(); i++) {
+ FileSet fs = (FileSet)(filesets.get(i));
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ File basedir = fs.getDir(getProject());
+ String[] f = ds.getIncludedFiles();
+ for (int j = 0; j < f.length; j++) {
+ included.add(FILE_UTILS.resolveFile(basedir, f[j]));
+ }
+ }
+ for (Iterator iter = included.iterator(); iter.hasNext();) {
+ h.handle((File)(iter.next()));
+ }
+ included.clear();
+ included = null;
+ h.complete();
+ }
+
+ private static long getLength(File f) {
+ //should be an existing file
+ if (!(f.isFile())) {
+ throw new BuildException("The absolute pathname " + f
+ + " does not denote an existing file.");
+ }
+ return f.length();
+ }
+
+ /** EnumeratedAttribute operation mode */
+ public static class FileMode extends EnumeratedAttribute {
+ static final String[] MODES = new String[] {EACH, ALL};
+
+ /**
+ * Return the possible values for FileMode.
+ * @return String[]
.
+ */
+ public String[] getValues() {
+ return MODES;
+ }
+
+ }
+
+ private class PropertyOutputStream extends ByteArrayOutputStream {
+ public void close() {
+ getProject().setProperty(property, new String(toByteArray()).trim());
+ }
+ }
+
+ private abstract class Handler {
+ PrintStream ps;
+ Handler(PrintStream ps) {
+ this.ps = ps;
+ }
+
+ protected abstract void handle(File f);
+
+ void complete() {
+ ps.close();
+ }
+ }
+
+ private class EachHandler extends Handler {
+ EachHandler(PrintStream ps) {
+ super(ps);
+ }
+ protected void handle(File f) {
+ ps.print(f);
+ ps.print(" : ");
+ //when writing to the log, we'll see what's happening:
+ ps.println(getLength(f));
+ }
+ }
+
+ private class AllHandler extends Handler {
+ long length = 0L;
+ AllHandler(PrintStream ps) {
+ super(ps);
+ }
+ protected synchronized void handle(File f) {
+ length += getLength(f);
+ }
+ void complete() {
+ ps.print(length);
+ super.complete();
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
index bde9ce30a..55b6c2226 100644
--- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties
+++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
@@ -81,6 +81,7 @@ presetdef=org.apache.tools.ant.taskdefs.PreSetDef
macrodef=org.apache.tools.ant.taskdefs.MacroDef
nice=org.apache.tools.ant.taskdefs.Nice
libraries=org.apache.tools.ant.taskdefs.repository.Libraries
+length=org.apache.tools.ant.taskdefs.Length
# optional tasks
image=org.apache.tools.ant.taskdefs.optional.image.Image
diff --git a/src/testcases/org/apache/tools/ant/taskdefs/LengthTest.java b/src/testcases/org/apache/tools/ant/taskdefs/LengthTest.java
new file mode 100755
index 000000000..143cf2788
--- /dev/null
+++ b/src/testcases/org/apache/tools/ant/taskdefs/LengthTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.taskdefs;
+
+import org.apache.tools.ant.BuildFileTest;
+
+public class LengthTest extends BuildFileTest {
+
+ public LengthTest(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ configureProject("src/etc/testcases/taskdefs/length.xml");
+ }
+
+ public void tearDown() {
+ executeTarget("cleanup");
+ }
+
+ public void testEach() {
+ executeTarget("testEach");
+ }
+
+ public void testAll() {
+ executeTarget("testAll");
+ }
+
+ public void testFile() {
+ executeTarget("testFile");
+ }
+
+ public void testBoth() {
+ executeTarget("testBoth");
+ }
+
+ public void testDupes() {
+ executeTarget("testDupes");
+ }
+
+ public void testString() {
+ executeTarget("testString");
+ }
+
+ public void testStringFile() {
+ expectBuildExceptionContaining("testStringFile",
+ "should fail", "incompatible");
+ }
+
+ public void testTrimFile() {
+ expectBuildExceptionContaining("testTrimFile",
+ "should fail", "string length function only");
+ }
+
+}