source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/Length.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 10.4 KB
Line 
1/*
2 * Copyright 2005 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.apache.tools.ant.taskdefs;
19
20import java.io.File;
21import java.io.PrintStream;
22import java.io.OutputStream;
23import java.io.ByteArrayOutputStream;
24import java.util.Vector;
25import java.util.Iterator;
26
27import org.apache.tools.ant.Task;
28import org.apache.tools.ant.Project;
29import org.apache.tools.ant.BuildException;
30import org.apache.tools.ant.DirectoryScanner;
31import org.apache.tools.ant.taskdefs.condition.Condition;
32import org.apache.tools.ant.types.FileSet;
33import org.apache.tools.ant.types.Resource;
34import org.apache.tools.ant.types.EnumeratedAttribute;
35import org.apache.tools.ant.util.FileUtils;
36
37/**
38 * Gets lengths: of files/resources, byte size; of strings, length (optionally trimmed).
39 * The task is overloaded in this way for semantic reasons, much like Available.
40 * @since Ant 1.6.3
41 */
42public class Length extends Task implements Condition {
43
44 private static final String ALL = "all";
45 private static final String EACH = "each";
46 private static final String STRING = "string";
47
48 private static final String LENGTH_REQUIRED
49 = "Use of the Length condition requires that the length attribute be set.";
50
51 private String property;
52 private String string;
53 private Boolean trim;
54 private String mode = ALL;
55 private When when = When.EQUAL;
56 private Long length;
57 private Vector filesets;
58
59 /**
60 * The property in which the length will be stored.
61 * @param property the <code>String</code> property key.
62 */
63 public synchronized void setProperty(String property) {
64 this.property = property;
65 }
66
67 /**
68 * Set the single file for this task.
69 * @param file the <code>File</code> whose length to retrieve.
70 */
71 public synchronized void setFile(File file) {
72 FileSet fs = new FileSet();
73 fs.setFile(file);
74 add(fs);
75 }
76
77 /**
78 * Add a FileSet.
79 * @param fs the <code>FileSet</code> to add.
80 */
81 public synchronized void add(FileSet fs) {
82 if (fs == null) {
83 return;
84 }
85 filesets = (filesets == null) ? new Vector() : filesets;
86 filesets.add(fs);
87 }
88
89 /**
90 * Set the target count number for use as a Condition.
91 * @param ell the long length to compare with.
92 */
93 public synchronized void setLength(long ell) {
94 length = new Long(ell);
95 }
96
97 /**
98 * Set the comparison criteria for use as a Condition:
99 * "equal", "greater", "less". Default is "equal".
100 * @param w EnumeratedAttribute When.
101 */
102 public synchronized void setWhen(When w) {
103 when = w;
104 }
105
106 /**
107 * Set the execution mode for working with files.
108 * @param m the <code>FileMode</code> to use.
109 */
110 public synchronized void setMode(FileMode m) {
111 this.mode = m.getValue();
112 }
113
114 /**
115 * Set the string whose length to get.
116 * @param string <code>String</code>.
117 */
118 public synchronized void setString(String string) {
119 this.string = string;
120 this.mode = STRING;
121 }
122
123 /**
124 * Set whether to trim in string mode.
125 * @param trim <code>boolean</code>.
126 */
127 public synchronized void setTrim(boolean trim) {
128 this.trim = trim ? Boolean.TRUE : Boolean.FALSE;
129 }
130
131 /**
132 * Learn whether strings will be trimmed.
133 * @return boolean trim setting.
134 */
135 public boolean getTrim() {
136 return trim != null && trim.booleanValue();
137 }
138
139 /**
140 * Execute the length task.
141 */
142 public void execute() {
143 validate();
144 PrintStream ps = new PrintStream((property != null)
145 ? (OutputStream) new PropertyOutputStream()
146 : (OutputStream) new LogOutputStream(this, Project.MSG_INFO));
147
148 if (STRING.equals(mode)) {
149 ps.print(getLength(string, getTrim()));
150 ps.close();
151 } else if (EACH.equals(mode)) {
152 handleResources(new EachHandler(ps));
153 } else if (ALL.equals(mode)) {
154 handleResources(new AllHandler(ps));
155 }
156 }
157
158 /**
159 * Fulfill the condition contract.
160 * @return true if the condition is true.
161 * @throws BuildException if an error occurs.
162 */
163 public boolean eval() {
164 validate();
165 if (length == null) {
166 throw new BuildException(LENGTH_REQUIRED);
167 }
168 Long ell = null;
169 if (STRING.equals(mode)) {
170 ell = new Long(getLength(string, getTrim()));
171 } else {
172 ConditionHandler h = new ConditionHandler();
173 handleResources(h);
174 ell = new Long(h.getLength());
175 }
176 int w = when.getIndex();
177 int comp = ell.compareTo(length);
178 return (w == 0 && comp == 0)
179 || (w == 1 && comp > 0)
180 || (w == 2 && comp < 0);
181 }
182
183 private void validate() {
184 if (string != null) {
185 if (filesets != null && filesets.size() > 0) {
186 throw new BuildException("the string length function"
187 + " is incompatible with the file length function");
188 }
189 if (!(STRING.equals(mode))) {
190 throw new BuildException("the mode attribute is for use"
191 + " with the file/resource length function");
192 }
193 } else if (filesets != null) {
194 if (!(EACH.equals(mode) || ALL.equals(mode))) {
195 throw new BuildException("invalid mode setting for"
196 + " file length function: \"" + mode + "\"");
197 } else if (trim != null) {
198 throw new BuildException("the trim attribute is"
199 + " for use with the string length function only");
200 }
201 } else {
202 throw new BuildException("you must set either the string attribute"
203 + " or specify one or more files using the file attribute or"
204 + " nested filesets");
205 }
206 }
207
208 private void handleResources(Handler h) {
209 for (Iterator i = filesets.iterator(); i.hasNext();) {
210 FileSet fs = (FileSet) i.next();
211 DirectoryScanner ds = fs.getDirectoryScanner(getProject());
212 String[] f = ds.getIncludedFiles();
213 for (int j = 0; j < f.length; j++) {
214 Resource r = ds.getResource(f[j]);
215 if (!r.isExists()) {
216 log(r.getName() + " does not exist", Project.MSG_ERR);
217 } else if (r.isDirectory()) {
218 log(r.getName() + " is a directory; length unspecified",
219 Project.MSG_ERR);
220 } else {
221 //force a full path:
222 File basedir = ds.getBasedir();
223 String s = FileUtils.getFileUtils().resolveFile(
224 basedir, r.getName()).getAbsolutePath();
225 h.handle(new Resource(s, true,
226 r.getLastModified(), false, r.getSize()));
227 }
228 }
229 }
230 h.complete();
231 }
232
233 private static long getLength(String s, boolean t) {
234 return (t ? s.trim() : s).length();
235 }
236
237 /** EnumeratedAttribute operation mode */
238 public static class FileMode extends EnumeratedAttribute {
239 static final String[] MODES = new String[] {EACH, ALL};
240
241 /**
242 * Return the possible values for FileMode.
243 * @return <code>String[]</code>.
244 */
245 public String[] getValues() {
246 return MODES;
247 }
248
249 }
250
251 /**
252 * EnumeratedAttribute for the when attribute.
253 */
254 public static class When extends EnumeratedAttribute {
255 private static final String[] VALUES
256 = new String[] {"equal", "greater", "less"};
257
258 private static final When EQUAL = new When("equal");
259
260 public When() {
261 }
262 public When(String value) {
263 setValue(value);
264 }
265 public String[] getValues() {
266 return VALUES;
267 }
268 }
269
270 private class PropertyOutputStream extends ByteArrayOutputStream {
271 public void close() {
272 getProject().setNewProperty(
273 property, new String(toByteArray()).trim());
274 }
275 }
276
277 private abstract class Handler {
278 PrintStream ps;
279 Handler(PrintStream ps) {
280 this.ps = ps;
281 }
282
283 protected abstract void handle(Resource r);
284
285 void complete() {
286 ps.close();
287 }
288 }
289
290 private class EachHandler extends Handler {
291 EachHandler(PrintStream ps) {
292 super(ps);
293 }
294 protected void handle(Resource r) {
295 ps.print(r.getName());
296 ps.print(" : ");
297 //when writing to the log, we'll see what's happening:
298 long size = r.getSize();
299 if (size == Resource.UNKNOWN_SIZE) {
300 ps.println("unknown");
301 } else {
302 ps.println(size);
303 }
304 }
305 }
306
307 private class AllHandler extends Handler {
308 long accum = 0L;
309 AllHandler(PrintStream ps) {
310 super(ps);
311 }
312 protected synchronized void handle(Resource r) {
313 long size = r.getSize();
314 if (size == Resource.UNKNOWN_SIZE) {
315 log("Size unknown for " + r.getName(), Project.MSG_WARN);
316 } else {
317 accum += size;
318 }
319 }
320 void complete() {
321 ps.print(accum);
322 super.complete();
323 }
324 }
325
326 private class ConditionHandler extends AllHandler {
327 ConditionHandler() {
328 super(null);
329 }
330 void complete() {
331 }
332 long getLength() {
333 return accum;
334 }
335 }
336}
Note: See TracBrowser for help on using the repository browser.