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.

Touch.java 9.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2000-2004 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowlegement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowlegement may appear in the software itself,
  24. * if and wherever such third-party acknowlegements normally appear.
  25. *
  26. * 4. The names "Ant" and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Group.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. */
  54. package org.apache.tools.ant.taskdefs;
  55. import java.io.File;
  56. import java.io.IOException;
  57. import java.text.DateFormat;
  58. import java.text.ParseException;
  59. import java.util.Locale;
  60. import java.util.Vector;
  61. import org.apache.tools.ant.BuildException;
  62. import org.apache.tools.ant.DirectoryScanner;
  63. import org.apache.tools.ant.Project;
  64. import org.apache.tools.ant.Task;
  65. import org.apache.tools.ant.types.FileSet;
  66. import org.apache.tools.ant.types.FileList;
  67. import org.apache.tools.ant.util.FileUtils;
  68. import org.apache.tools.ant.util.JavaEnvUtils;
  69. /**
  70. * Touch a file and/or fileset(s) and/or filelist(s);
  71. * corresponds to the Unix touch command.
  72. *
  73. * <p>If the file to touch doesn't exist, an empty one is
  74. * created. </p>
  75. *
  76. * <p>Note: Setting the modification time of files is not supported in
  77. * JDK 1.1.</p>
  78. *
  79. * @author Stefan Bodewig
  80. * @author <a href="mailto:mj@servidium.com">Michael J. Sikorsky</a>
  81. * @author <a href="mailto:shaw@servidium.com">Robert Shaw</a>
  82. *
  83. * @since Ant 1.1
  84. *
  85. * @ant.task category="filesystem"
  86. */
  87. public class Touch extends Task {
  88. private File file;
  89. private long millis = -1;
  90. private String dateTime;
  91. private Vector filesets = new Vector();
  92. private Vector filelists = new Vector();
  93. private FileUtils fileUtils;
  94. public Touch() {
  95. fileUtils = FileUtils.newFileUtils();
  96. }
  97. /**
  98. * Sets a single source file to touch. If the file does not exist
  99. * an empty file will be created.
  100. */
  101. public void setFile(File file) {
  102. this.file = file;
  103. }
  104. /**
  105. * the new modification time of the file
  106. * in milliseconds since midnight Jan 1 1970.
  107. * Optional, default=now
  108. */
  109. public void setMillis(long millis) {
  110. this.millis = millis;
  111. }
  112. /**
  113. * the new modification time of the file
  114. * in the format &quot;MM/DD/YYYY HH:MM AM <i>or</i> PM&quot;
  115. * or &quot;MM/DD/YYYY HH:MM:SS AM <i>or</i> PM&quot;.
  116. * Optional, default=now
  117. */
  118. public void setDatetime(String dateTime) {
  119. this.dateTime = dateTime;
  120. }
  121. /**
  122. * Add a set of files to touch
  123. */
  124. public void addFileset(FileSet set) {
  125. filesets.addElement(set);
  126. }
  127. /**
  128. * Add a filelist to touch
  129. */
  130. public void addFilelist(FileList list) {
  131. filelists.addElement(list);
  132. }
  133. /**
  134. * Execute the touch operation.
  135. */
  136. public void execute() throws BuildException {
  137. long savedMillis = millis;
  138. if (file == null && filesets.size() == 0 && filelists.size() == 0) {
  139. throw
  140. new BuildException("Specify at least one source - a file, filelist or "
  141. + "a fileset.");
  142. }
  143. if (file != null && file.exists() && file.isDirectory()) {
  144. throw new BuildException("Use a fileset to touch directories.");
  145. }
  146. try {
  147. if (dateTime != null) {
  148. /*
  149. * The initial version used DateFormat.SHORT for the
  150. * time format, which ignores seconds. If we want
  151. * seconds as well, we need DateFormat.MEDIUM, which
  152. * in turn would break all old build files.
  153. *
  154. * First try to parse with DateFormat.SHORT and if
  155. * that fails with MEDIUM - throw an exception if both
  156. * fail.
  157. */
  158. DateFormat df =
  159. DateFormat.getDateTimeInstance(DateFormat.SHORT,
  160. DateFormat.SHORT,
  161. Locale.US);
  162. try {
  163. setMillis(df.parse(dateTime).getTime());
  164. } catch (ParseException pe) {
  165. df =
  166. DateFormat.getDateTimeInstance(DateFormat.SHORT,
  167. DateFormat.MEDIUM,
  168. Locale.US);
  169. try {
  170. setMillis(df.parse(dateTime).getTime());
  171. } catch (ParseException pe2) {
  172. throw new BuildException(pe2.getMessage(), pe,
  173. getLocation());
  174. }
  175. }
  176. if (millis < 0) {
  177. throw new BuildException("Date of " + dateTime
  178. + " results in negative "
  179. + "milliseconds value "
  180. + "relative to epoch "
  181. + "(January 1, 1970, "
  182. + "00:00:00 GMT).");
  183. }
  184. }
  185. touch();
  186. } finally {
  187. millis = savedMillis;
  188. }
  189. }
  190. /**
  191. * Does the actual work; assumes everything has been checked by now.
  192. */
  193. protected void touch() throws BuildException {
  194. boolean resetMillis = false;
  195. if (millis < 0) {
  196. resetMillis = true;
  197. millis = System.currentTimeMillis();
  198. }
  199. if (file != null) {
  200. touch(file);
  201. }
  202. // deal with the filesets
  203. for (int i = 0; i < filesets.size(); i++) {
  204. FileSet fs = (FileSet) filesets.elementAt(i);
  205. DirectoryScanner ds = fs.getDirectoryScanner(getProject());
  206. File fromDir = fs.getDir(getProject());
  207. String[] srcFiles = ds.getIncludedFiles();
  208. String[] srcDirs = ds.getIncludedDirectories();
  209. for (int j = 0; j < srcFiles.length; j++) {
  210. touch(new File(fromDir, srcFiles[j]));
  211. }
  212. for (int j = 0; j < srcDirs.length; j++) {
  213. touch(new File(fromDir, srcDirs[j]));
  214. }
  215. }
  216. // deal with the filelists
  217. for (int i = 0; i < filelists.size(); i++) {
  218. FileList fl = (FileList) filelists.elementAt(i);
  219. File fromDir = fl.getDir(getProject());
  220. String[] srcFiles = fl.getFiles(getProject());
  221. for (int j = 0; j < srcFiles.length; j++) {
  222. touch(new File(fromDir, srcFiles[j]));
  223. }
  224. }
  225. if (resetMillis) {
  226. millis = -1;
  227. }
  228. }
  229. /**
  230. * touch a single file with the current timestamp (this.millis)
  231. * @param file file to touch
  232. * @throws BuildException
  233. */
  234. protected void touch(File file) throws BuildException {
  235. if (!file.exists()) {
  236. log("Creating " + file, Project.MSG_INFO);
  237. try {
  238. fileUtils.createNewFile(file);
  239. } catch (IOException ioe) {
  240. throw new BuildException("Could not create " + file, ioe,
  241. getLocation());
  242. }
  243. }
  244. if (!file.canWrite()) {
  245. throw new BuildException("Can not change modification date of "
  246. + "read-only file " + file);
  247. }
  248. fileUtils.setFileLastModified(file, millis);
  249. }
  250. }