1 18 19 package org.apache.tools.ant.taskdefs; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.text.DateFormat ; 24 import java.text.ParseException ; 25 import java.text.SimpleDateFormat ; 26 import java.util.Iterator ; 27 import java.util.Locale ; 28 import java.util.Vector ; 29 import org.apache.tools.ant.BuildException; 30 import org.apache.tools.ant.DirectoryScanner; 31 import org.apache.tools.ant.Project; 32 import org.apache.tools.ant.Task; 33 import org.apache.tools.ant.types.Mapper; 34 import org.apache.tools.ant.types.FileSet; 35 import org.apache.tools.ant.types.FileList; 36 import org.apache.tools.ant.types.Resource; 37 import org.apache.tools.ant.types.ResourceCollection; 38 import org.apache.tools.ant.types.resources.FileResource; 39 import org.apache.tools.ant.types.resources.Touchable; 40 import org.apache.tools.ant.types.resources.Union; 41 import org.apache.tools.ant.util.FileUtils; 42 import org.apache.tools.ant.util.FileNameMapper; 43 44 54 public class Touch extends Task { 55 56 private interface DateFormatFactory { 57 DateFormat getPrimaryFormat(); 58 DateFormat getFallbackFormat(); 59 } 60 61 private static final DateFormatFactory DEFAULT_DF_FACTORY 62 = new DateFormatFactory() { 63 73 public DateFormat getPrimaryFormat() { 74 return DateFormat.getDateTimeInstance(DateFormat.SHORT, 75 DateFormat.SHORT, Locale.US); 76 } 77 public DateFormat getFallbackFormat() { 78 return DateFormat.getDateTimeInstance(DateFormat.SHORT, 79 DateFormat.MEDIUM, Locale.US); 80 } 81 }; 82 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 83 84 private File file; 85 private long millis = -1; 86 private String dateTime; 87 private Vector filesets = new Vector (); 88 private Union resources = new Union(); 89 private boolean dateTimeConfigured; 90 private boolean mkdirs; 91 private boolean verbose = true; 92 private FileNameMapper fileNameMapper = null; 93 private DateFormatFactory dfFactory = DEFAULT_DF_FACTORY; 94 95 98 public Touch() { 99 } 100 101 106 public void setFile(File file) { 107 this.file = file; 108 } 109 110 115 public void setMillis(long millis) { 116 this.millis = millis; 117 } 118 119 126 public void setDatetime(String dateTime) { 127 if (this.dateTime != null) { 128 log("Resetting datetime attribute to " + dateTime, Project.MSG_VERBOSE); 129 } 130 this.dateTime = dateTime; 131 dateTimeConfigured = false; 132 } 133 134 140 public void setMkdirs(boolean mkdirs) { 141 this.mkdirs = mkdirs; 142 } 143 144 150 public void setVerbose(boolean verbose) { 151 this.verbose = verbose; 152 } 153 154 159 public void setPattern(final String pattern) { 160 dfFactory = new DateFormatFactory() { 161 public DateFormat getPrimaryFormat() { 162 return new SimpleDateFormat (pattern); 163 } 164 public DateFormat getFallbackFormat() { 165 return null; 166 } 167 }; 168 } 169 170 175 public void addConfiguredMapper(Mapper mapper) { 176 add(mapper.getImplementation()); 177 } 178 179 185 public void add(FileNameMapper fileNameMapper) throws BuildException { 186 if (this.fileNameMapper != null) { 187 throw new BuildException("Only one mapper may be added to the " 188 + getTaskName() + " task."); 189 } 190 this.fileNameMapper = fileNameMapper; 191 } 192 193 197 public void addFileset(FileSet set) { 198 filesets.add(set); 199 add(set); 200 } 201 202 206 public void addFilelist(FileList list) { 207 add(list); 208 } 209 210 215 public void add(ResourceCollection rc) { 216 resources.add(rc); 217 } 218 219 224 protected synchronized void checkConfiguration() throws BuildException { 225 if (file == null && resources.size() == 0) { 226 throw new BuildException("Specify at least one source" 227 + "--a file or resource collection."); 228 } 229 if (file != null && file.exists() && file.isDirectory()) { 230 throw new BuildException("Use a resource collection to touch directories."); 231 } 232 if (dateTime != null && !dateTimeConfigured) { 233 long workmillis = millis; 234 DateFormat df = dfFactory.getPrimaryFormat(); 235 ParseException pe = null; 236 try { 237 workmillis = df.parse(dateTime).getTime(); 238 } catch (ParseException peOne) { 239 df = dfFactory.getFallbackFormat(); 240 if (df == null) { 241 pe = peOne; 242 } else { 243 try { 244 workmillis = df.parse(dateTime).getTime(); 245 } catch (ParseException peTwo) { 246 pe = peTwo; 247 } 248 } 249 } 250 if (pe != null) { 251 throw new BuildException(pe.getMessage(), pe, getLocation()); 252 } 253 if (workmillis < 0) { 254 throw new BuildException("Date of " + dateTime 255 + " results in negative " 256 + "milliseconds value " 257 + "relative to epoch " 258 + "(January 1, 1970, " 259 + "00:00:00 GMT)."); 260 } 261 log("Setting millis to " + workmillis + " from datetime attribute", 262 ((millis < 0) ? Project.MSG_DEBUG : Project.MSG_VERBOSE)); 263 setMillis(workmillis); 264 dateTimeConfigured = true; 266 } 267 } 268 269 273 public void execute() throws BuildException { 274 checkConfiguration(); 275 touch(); 276 } 277 278 282 protected void touch() throws BuildException { 283 long defaultTimestamp = getTimestamp(); 284 285 if (file != null) { 286 touch(new FileResource(file.getParentFile(), file.getName()), 287 defaultTimestamp); 288 } 289 Iterator iter = resources.iterator(); 291 while (iter.hasNext()) { 292 Resource r = (Resource) iter.next(); 293 if (!(r instanceof Touchable)) { 294 throw new BuildException("Can't touch " + r); 295 } 296 touch(r, defaultTimestamp); 297 } 298 299 for (int i = 0; i < filesets.size(); i++) { 303 FileSet fs = (FileSet) filesets.elementAt(i); 304 DirectoryScanner ds = fs.getDirectoryScanner(getProject()); 305 File fromDir = fs.getDir(getProject()); 306 307 String [] srcDirs = ds.getIncludedDirectories(); 308 309 for (int j = 0; j < srcDirs.length; j++) { 310 touch(new FileResource(fromDir, srcDirs[j]), defaultTimestamp); 311 } 312 } 313 } 314 315 323 protected void touch(File file) { 324 touch(file, getTimestamp()); 325 } 326 327 private long getTimestamp() { 328 return (millis < 0) ? System.currentTimeMillis() : millis; 329 } 330 331 private void touch(Resource r, long defaultTimestamp) { 332 if (fileNameMapper == null) { 333 if (r instanceof FileResource) { 334 touch(((FileResource) r).getFile(), defaultTimestamp); 336 } else { 337 ((Touchable) r).touch(defaultTimestamp); 338 } 339 } else { 340 String [] mapped = fileNameMapper.mapFileName(r.getName()); 341 if (mapped != null && mapped.length > 0) { 342 long modTime = (r.isExists()) ? r.getLastModified() 343 : defaultTimestamp; 344 for (int i = 0; i < mapped.length; i++) { 345 touch(getProject().resolveFile(mapped[i]), modTime); 346 } 347 } 348 } 349 } 350 351 private void touch(File file, long modTime) { 352 if (!file.exists()) { 353 log("Creating " + file, 354 ((verbose) ? Project.MSG_INFO : Project.MSG_VERBOSE)); 355 try { 356 FILE_UTILS.createNewFile(file, mkdirs); 357 } catch (IOException ioe) { 358 throw new BuildException("Could not create " + file, ioe, 359 getLocation()); 360 } 361 } 362 if (!file.canWrite()) { 363 throw new BuildException("Can not change modification date of " 364 + "read-only file " + file); 365 } 366 FILE_UTILS.setFileLastModified(file, modTime); 367 } 368 369 } 370 | Popular Tags |