You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Length.java 8.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. package org.apache.tools.ant.taskdefs;
  18. import java.io.File;
  19. import java.io.PrintStream;
  20. import java.io.OutputStream;
  21. import java.io.ByteArrayOutputStream;
  22. import java.util.Vector;
  23. import java.util.HashSet;
  24. import org.apache.tools.ant.Task;
  25. import org.apache.tools.ant.Project;
  26. import org.apache.tools.ant.BuildException;
  27. import org.apache.tools.ant.DirectoryScanner;
  28. import org.apache.tools.ant.types.FileSet;
  29. import org.apache.tools.ant.types.Resource;
  30. import org.apache.tools.ant.types.EnumeratedAttribute;
  31. import org.apache.tools.ant.util.FileUtils;
  32. /**
  33. * Gets lengths: of files, byte size; of strings, length (optionally trimmed).
  34. * The task is overloaded in this way for semantic reasons, much like Available.
  35. * @since Ant 1.7
  36. */
  37. public class Length extends Task {
  38. private static final String ALL = "all";
  39. private static final String EACH = "each";
  40. private static final String STRING = "string";
  41. private String property;
  42. private String string;
  43. private Boolean trim;
  44. private Vector filesets;
  45. private String mode = ALL;
  46. /**
  47. * The property in which the length will be stored.
  48. * @param property the <code>String</code> property key.
  49. */
  50. public synchronized void setProperty(String property) {
  51. this.property = property;
  52. }
  53. /**
  54. * Set the single file for this task.
  55. * @param file the <code>File</code> whose length to retrieve.
  56. */
  57. public synchronized void setFile(File file) {
  58. FileSet fs = new FileSet();
  59. fs.setFile(file);
  60. add(fs);
  61. }
  62. /**
  63. * Add a FileSet.
  64. * @param fs the <code>FileSet</code> to add.
  65. */
  66. public synchronized void add(FileSet fs) {
  67. filesets = (filesets == null) ? new Vector() : filesets;
  68. filesets.add(fs);
  69. }
  70. /**
  71. * Set the execution mode for working with files.
  72. * @param m the <code>FileMode</code> to use.
  73. */
  74. public synchronized void setMode(FileMode m) {
  75. this.mode = m.getValue();
  76. }
  77. /**
  78. * Set the string whose length to get.
  79. * @param string <code>String</code>.
  80. */
  81. public synchronized void setString(String string) {
  82. this.string = string;
  83. this.mode = STRING;
  84. }
  85. /**
  86. * Set whether to trim in string mode.
  87. * @param trim <code>boolean</code>.
  88. */
  89. public synchronized void setTrim(boolean trim) {
  90. this.trim = trim ? Boolean.TRUE : Boolean.FALSE;
  91. }
  92. /**
  93. * Execute the length task.
  94. */
  95. public void execute() {
  96. validate();
  97. PrintStream ps = new PrintStream((property != null)
  98. ? (OutputStream) new PropertyOutputStream()
  99. : (OutputStream) new LogOutputStream(this, Project.MSG_INFO));
  100. if (STRING.equals(mode)) {
  101. ps.print(((trim != null && trim.booleanValue())
  102. ? string.trim() : string).length());
  103. ps.close();
  104. } else if (EACH.equals(mode)) {
  105. handleFilesets(new EachHandler(ps));
  106. } else if (ALL.equals(mode)) {
  107. handleFilesets(new AllHandler(ps));
  108. }
  109. }
  110. private void validate() {
  111. if (string != null) {
  112. if (filesets != null && filesets.size() > 0) {
  113. throw new BuildException("the string length function"
  114. + " is incompatible with the file length function");
  115. }
  116. if (!(STRING.equals(mode))) {
  117. throw new BuildException("the mode attribute is for use"
  118. + " with the file length function");
  119. }
  120. } else if (filesets != null && filesets.size() > 0) {
  121. if (!(EACH.equals(mode) || ALL.equals(mode))) {
  122. throw new BuildException("invalid mode setting for"
  123. + " file length function: \"" + mode + "\"");
  124. } else if (trim != null) {
  125. throw new BuildException("the trim attribute is"
  126. + " for use with the string length function only");
  127. }
  128. } else {
  129. throw new BuildException("you must set either the string attribute"
  130. + " or specify one or more files using the file attribute or"
  131. + " nested filesets");
  132. }
  133. }
  134. private void handleFilesets(Handler h) {
  135. HashSet included = new HashSet(filesets.size());
  136. for (int i = 0; i < filesets.size(); i++) {
  137. FileSet fs = (FileSet) (filesets.get(i));
  138. DirectoryScanner ds = fs.getDirectoryScanner(getProject());
  139. String[] f = ds.getIncludedFiles();
  140. for (int j = 0; j < f.length; j++) {
  141. Resource r = ds.getResource(f[j]);
  142. if (!r.isExists()) {
  143. log(r.getName() + " does not exist", Project.MSG_ERR);
  144. } else if (r.isDirectory()) {
  145. log(r.getName() + " is a directory; length unspecified",
  146. Project.MSG_ERR);
  147. } else {
  148. //clone the Resource and alter path
  149. File basedir = ds.getBasedir();
  150. if (basedir != null) {
  151. r = (Resource) (r.clone());
  152. r.setName(FileUtils.getFileUtils().resolveFile(
  153. basedir, r.getName()).getAbsolutePath());
  154. }
  155. if (included.add(r.getName())) {
  156. h.handle(r);
  157. }
  158. }
  159. }
  160. }
  161. included.clear();
  162. included = null;
  163. h.complete();
  164. }
  165. /** EnumeratedAttribute operation mode */
  166. public static class FileMode extends EnumeratedAttribute {
  167. static final String[] MODES = new String[] {EACH, ALL};
  168. /**
  169. * Return the possible values for FileMode.
  170. * @return <code>String[]</code>.
  171. */
  172. public String[] getValues() {
  173. return MODES;
  174. }
  175. }
  176. private class PropertyOutputStream extends ByteArrayOutputStream {
  177. public void close() {
  178. getProject().setNewProperty(
  179. property, new String(toByteArray()).trim());
  180. }
  181. }
  182. private abstract class Handler {
  183. PrintStream ps;
  184. Handler(PrintStream ps) {
  185. this.ps = ps;
  186. }
  187. protected abstract void handle(Resource r);
  188. void complete() {
  189. ps.close();
  190. }
  191. }
  192. private class EachHandler extends Handler {
  193. EachHandler(PrintStream ps) {
  194. super(ps);
  195. }
  196. protected void handle(Resource r) {
  197. ps.print(r.getName());
  198. ps.print(" : ");
  199. //when writing to the log, we'll see what's happening:
  200. long size = r.getSize();
  201. if (size == Resource.UNKNOWN_SIZE) {
  202. ps.println("unknown");
  203. } else {
  204. ps.println(size);
  205. }
  206. }
  207. }
  208. private class AllHandler extends Handler {
  209. long length = 0L;
  210. AllHandler(PrintStream ps) {
  211. super(ps);
  212. }
  213. protected synchronized void handle(Resource r) {
  214. long size = r.getSize();
  215. if (size == Resource.UNKNOWN_SIZE) {
  216. log("Size unknown for " + r.getName(), Project.MSG_WARN);
  217. } else {
  218. length += size;
  219. }
  220. }
  221. void complete() {
  222. ps.print(length);
  223. super.complete();
  224. }
  225. }
  226. }