1 18 19 package org.apache.tools.ant.taskdefs; 20 21 import java.io.File ; 22 import java.util.Arrays ; 23 import java.util.Vector ; 24 import java.util.Iterator ; 25 import java.util.Comparator ; 26 27 import org.apache.tools.ant.Project; 28 import org.apache.tools.ant.BuildException; 29 import org.apache.tools.ant.taskdefs.condition.Os; 30 import org.apache.tools.ant.types.FileSet; 31 import org.apache.tools.ant.types.PatternSet; 32 import org.apache.tools.ant.types.ResourceCollection; 33 import org.apache.tools.ant.types.resources.Sort; 34 import org.apache.tools.ant.types.resources.Restrict; 35 import org.apache.tools.ant.types.resources.Resources; 36 import org.apache.tools.ant.types.resources.FileResource; 37 import org.apache.tools.ant.types.resources.FileResourceIterator; 38 import org.apache.tools.ant.types.resources.comparators.Reverse; 39 import org.apache.tools.ant.types.resources.comparators.FileSystem; 40 import org.apache.tools.ant.types.resources.comparators.ResourceComparator; 41 import org.apache.tools.ant.types.resources.selectors.Exists; 42 import org.apache.tools.ant.types.resources.selectors.ResourceSelector; 43 import org.apache.tools.ant.types.selectors.OrSelector; 44 import org.apache.tools.ant.types.selectors.AndSelector; 45 import org.apache.tools.ant.types.selectors.NotSelector; 46 import org.apache.tools.ant.types.selectors.DateSelector; 47 import org.apache.tools.ant.types.selectors.FileSelector; 48 import org.apache.tools.ant.types.selectors.NoneSelector; 49 import org.apache.tools.ant.types.selectors.SizeSelector; 50 import org.apache.tools.ant.types.selectors.DepthSelector; 51 import org.apache.tools.ant.types.selectors.DependSelector; 52 import org.apache.tools.ant.types.selectors.ExtendSelector; 53 import org.apache.tools.ant.types.selectors.SelectSelector; 54 import org.apache.tools.ant.types.selectors.PresentSelector; 55 import org.apache.tools.ant.types.selectors.ContainsSelector; 56 import org.apache.tools.ant.types.selectors.FilenameSelector; 57 import org.apache.tools.ant.types.selectors.MajoritySelector; 58 import org.apache.tools.ant.types.selectors.ContainsRegexpSelector; 59 import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; 60 61 75 public class Delete extends MatchingTask { 76 private static final int DELETE_RETRY_SLEEP_MILLIS = 10; 77 private static final ResourceComparator REVERSE_FILESYSTEM = new Reverse(new FileSystem()); 78 private static final ResourceSelector EXISTS = new Exists(); 79 80 private static class ReverseDirs implements ResourceCollection { 81 static final Comparator REVERSE = new Comparator () { 82 public int compare(Object foo, Object bar) { 83 return ((Comparable ) foo).compareTo(bar) * -1; 84 } 85 }; 86 private File basedir; 87 private String [] dirs; 88 ReverseDirs(File basedir, String [] dirs) { 89 this.basedir = basedir; 90 this.dirs = dirs; 91 Arrays.sort(this.dirs, REVERSE); 92 } 93 public Iterator iterator() { 94 return new FileResourceIterator(basedir, dirs); 95 } 96 public boolean isFilesystemOnly() { return true; } 97 public int size() { return dirs.length; } 98 } 99 100 protected File file = null; 102 protected File dir = null; 103 protected Vector filesets = new Vector (); 104 protected boolean usedMatchingTask = false; 105 protected boolean includeEmpty = false; 107 108 private int verbosity = Project.MSG_VERBOSE; 109 private boolean quiet = false; 110 private boolean failonerror = true; 111 private boolean deleteOnExit = false; 112 private Resources rcs = null; 113 115 120 public void setFile(File file) { 121 this.file = file; 122 } 123 124 129 public void setDir(File dir) { 130 this.dir = dir; 131 getImplicitFileSet().setDir(dir); 132 } 133 134 139 public void setVerbose(boolean verbose) { 140 if (verbose) { 141 this.verbosity = Project.MSG_INFO; 142 } else { 143 this.verbosity = Project.MSG_VERBOSE; 144 } 145 } 146 147 156 public void setQuiet(boolean quiet) { 157 this.quiet = quiet; 158 if (quiet) { 159 this.failonerror = false; 160 } 161 } 162 163 168 public void setFailOnError(boolean failonerror) { 169 this.failonerror = failonerror; 170 } 171 172 178 public void setDeleteOnExit(boolean deleteOnExit) { 179 this.deleteOnExit = deleteOnExit; 180 } 181 182 183 188 public void setIncludeEmptyDirs(boolean includeEmpty) { 189 this.includeEmpty = includeEmpty; 190 } 191 192 196 public void addFileset(FileSet set) { 197 filesets.addElement(set); 198 } 199 200 204 public void add(ResourceCollection rc) { 205 if (rc == null) { 206 return; 207 } 208 rcs = (rcs == null) ? new Resources() : rcs; 209 rcs.add(rc); 210 } 211 212 216 public PatternSet.NameEntry createInclude() { 217 usedMatchingTask = true; 218 return super.createInclude(); 219 } 220 221 225 public PatternSet.NameEntry createIncludesFile() { 226 usedMatchingTask = true; 227 return super.createIncludesFile(); 228 } 229 230 234 public PatternSet.NameEntry createExclude() { 235 usedMatchingTask = true; 236 return super.createExclude(); 237 } 238 239 243 public PatternSet.NameEntry createExcludesFile() { 244 usedMatchingTask = true; 245 return super.createExcludesFile(); 246 } 247 248 252 public PatternSet createPatternSet() { 253 usedMatchingTask = true; 254 return super.createPatternSet(); 255 } 256 257 263 public void setIncludes(String includes) { 264 usedMatchingTask = true; 265 super.setIncludes(includes); 266 } 267 268 274 public void setExcludes(String excludes) { 275 usedMatchingTask = true; 276 super.setExcludes(excludes); 277 } 278 279 286 public void setDefaultexcludes(boolean useDefaultExcludes) { 287 usedMatchingTask = true; 288 super.setDefaultexcludes(useDefaultExcludes); 289 } 290 291 297 public void setIncludesfile(File includesfile) { 298 usedMatchingTask = true; 299 super.setIncludesfile(includesfile); 300 } 301 302 308 public void setExcludesfile(File excludesfile) { 309 usedMatchingTask = true; 310 super.setExcludesfile(excludesfile); 311 } 312 313 319 public void setCaseSensitive(boolean isCaseSensitive) { 320 usedMatchingTask = true; 321 super.setCaseSensitive(isCaseSensitive); 322 } 323 324 329 public void setFollowSymlinks(boolean followSymlinks) { 330 usedMatchingTask = true; 331 super.setFollowSymlinks(followSymlinks); 332 } 333 334 338 public void addSelector(SelectSelector selector) { 339 usedMatchingTask = true; 340 super.addSelector(selector); 341 } 342 343 347 public void addAnd(AndSelector selector) { 348 usedMatchingTask = true; 349 super.addAnd(selector); 350 } 351 352 356 public void addOr(OrSelector selector) { 357 usedMatchingTask = true; 358 super.addOr(selector); 359 } 360 361 365 public void addNot(NotSelector selector) { 366 usedMatchingTask = true; 367 super.addNot(selector); 368 } 369 370 374 public void addNone(NoneSelector selector) { 375 usedMatchingTask = true; 376 super.addNone(selector); 377 } 378 379 383 public void addMajority(MajoritySelector selector) { 384 usedMatchingTask = true; 385 super.addMajority(selector); 386 } 387 388 392 public void addDate(DateSelector selector) { 393 usedMatchingTask = true; 394 super.addDate(selector); 395 } 396 397 401 public void addSize(SizeSelector selector) { 402 usedMatchingTask = true; 403 super.addSize(selector); 404 } 405 406 410 public void addFilename(FilenameSelector selector) { 411 usedMatchingTask = true; 412 super.addFilename(selector); 413 } 414 415 419 public void addCustom(ExtendSelector selector) { 420 usedMatchingTask = true; 421 super.addCustom(selector); 422 } 423 424 428 public void addContains(ContainsSelector selector) { 429 usedMatchingTask = true; 430 super.addContains(selector); 431 } 432 433 437 public void addPresent(PresentSelector selector) { 438 usedMatchingTask = true; 439 super.addPresent(selector); 440 } 441 442 446 public void addDepth(DepthSelector selector) { 447 usedMatchingTask = true; 448 super.addDepth(selector); 449 } 450 451 455 public void addDepend(DependSelector selector) { 456 usedMatchingTask = true; 457 super.addDepend(selector); 458 } 459 460 464 public void addContainsRegexp(ContainsRegexpSelector selector) { 465 usedMatchingTask = true; 466 super.addContainsRegexp(selector); 467 } 468 469 474 public void addModified(ModifiedSelector selector) { 475 usedMatchingTask = true; 476 super.addModified(selector); 477 } 478 479 484 public void add(FileSelector selector) { 485 usedMatchingTask = true; 486 super.add(selector); 487 } 488 489 493 public void execute() throws BuildException { 494 if (usedMatchingTask) { 495 log("DEPRECATED - Use of the implicit FileSet is deprecated. " 496 + "Use a nested fileset element instead.", quiet ? Project.MSG_VERBOSE : verbosity); 497 } 498 499 if (file == null && dir == null && filesets.size() == 0 && rcs == null) { 500 throw new BuildException("At least one of the file or dir " 501 + "attributes, or a nested resource collection, " 502 + "must be set."); 503 } 504 505 if (quiet && failonerror) { 506 throw new BuildException("quiet and failonerror cannot both be " 507 + "set to true", getLocation()); 508 } 509 510 if (file != null) { 512 if (file.exists()) { 513 if (file.isDirectory()) { 514 log("Directory " + file.getAbsolutePath() 515 + " cannot be removed using the file attribute. " 516 + "Use dir instead.", quiet ? Project.MSG_VERBOSE : verbosity); 517 } else { 518 log("Deleting: " + file.getAbsolutePath()); 519 520 if (!delete(file)) { 521 handle("Unable to delete file " + file.getAbsolutePath()); 522 } 523 } 524 } else { 525 log("Could not find file " + file.getAbsolutePath() 526 + " to delete.", quiet ? Project.MSG_VERBOSE : verbosity); 527 } 528 } 529 530 if (dir != null && dir.exists() && dir.isDirectory() 532 && !usedMatchingTask) { 533 540 if (verbosity == Project.MSG_VERBOSE) { 541 log("Deleting directory " + dir.getAbsolutePath()); 542 } 543 removeDir(dir); 544 } 545 Resources resourcesToDelete = new Resources(); 546 resourcesToDelete.setProject(getProject()); 547 Resources filesetDirs = new Resources(); 548 filesetDirs.setProject(getProject()); 549 FileSet implicit = null; 550 if (usedMatchingTask && dir != null && dir.isDirectory()) { 551 implicit = getImplicitFileSet(); 553 implicit.setProject(getProject()); 554 filesets.add(implicit); 555 } 556 557 for (int i = 0, size = filesets.size(); i < size; i++) { 558 FileSet fs = (FileSet) filesets.get(i); 559 if (fs.getProject() == null) { 560 log("Deleting fileset with no project specified;" 561 + " assuming executing project", Project.MSG_VERBOSE); 562 fs = (FileSet) fs.clone(); 563 fs.setProject(getProject()); 564 } 565 if (!fs.getDir().isDirectory()) { 566 handle("Directory does not exist:" + fs.getDir()); 567 } else { 568 resourcesToDelete.add(fs); 569 if (includeEmpty) { 570 filesetDirs.add(new ReverseDirs(fs.getDir(), fs 571 .getDirectoryScanner().getIncludedDirectories())); 572 } 573 } 574 } 575 resourcesToDelete.add(filesetDirs); 576 if (rcs != null) { 577 Restrict exists = new Restrict(); 579 exists.add(EXISTS); 580 exists.add(rcs); 581 Sort s = new Sort(); 582 s.add(REVERSE_FILESYSTEM); 583 s.add(exists); 584 resourcesToDelete.add(s); 585 } 586 try { 587 if (resourcesToDelete.isFilesystemOnly()) { 588 for (Iterator iter = resourcesToDelete.iterator(); iter.hasNext();) { 589 FileResource r = (FileResource) iter.next(); 590 if (!r.isExists()) { 593 continue; 594 } 595 if (!(r.isDirectory()) || r.getFile().list().length == 0) { 596 log("Deleting " + r, verbosity); 597 if (!delete(r.getFile()) && failonerror) { 598 handle("Unable to delete " 599 + (r.isDirectory() ? "directory " : "file ") + r); 600 } 601 } 602 } 603 } else { 604 handle(getTaskName() + " handles only filesystem resources"); 605 } 606 } catch (Exception e) { 607 handle(e); 608 } finally { 609 if (implicit != null) { 610 filesets.remove(implicit); 611 } 612 } 613 } 614 615 619 private void handle(String msg) { 620 handle(new BuildException(msg)); 621 } 622 623 private void handle(Exception e) { 624 if (failonerror) { 625 throw (e instanceof BuildException) 626 ? (BuildException) e : new BuildException(e); 627 } 628 log(e, quiet ? Project.MSG_VERBOSE : verbosity); 629 } 630 631 636 private boolean delete(File f) { 637 if (!f.delete()) { 638 if (Os.isFamily("windows")) { 639 System.gc(); 640 } 641 try { 642 Thread.sleep(DELETE_RETRY_SLEEP_MILLIS); 643 } catch (InterruptedException ex) { 644 } 646 if (!f.delete()) { 647 if (deleteOnExit) { 648 int level = quiet ? Project.MSG_VERBOSE : Project.MSG_INFO; 649 log("Failed to delete " + f + ", calling deleteOnExit." 650 + " This attempts to delete the file when the Ant jvm" 651 + " has exited and might not succeed.", level); 652 f.deleteOnExit(); 653 return true; 654 } 655 return false; 656 } 657 } 658 return true; 659 } 660 661 666 protected void removeDir(File d) { 667 String [] list = d.list(); 668 if (list == null) { 669 list = new String [0]; 670 } 671 for (int i = 0; i < list.length; i++) { 672 String s = list[i]; 673 File f = new File (d, s); 674 if (f.isDirectory()) { 675 removeDir(f); 676 } else { 677 log("Deleting " + f.getAbsolutePath(), quiet ? Project.MSG_VERBOSE : verbosity); 678 if (!delete(f)) { 679 handle("Unable to delete file " + f.getAbsolutePath()); 680 } 681 } 682 } 683 log("Deleting directory " + d.getAbsolutePath(), verbosity); 684 if (!delete(d)) { 685 handle("Unable to delete directory " + dir.getAbsolutePath()); 686 } 687 } 688 689 696 protected void removeFiles(File d, String [] files, String [] dirs) { 697 if (files.length > 0) { 698 log("Deleting " + files.length + " files from " 699 + d.getAbsolutePath(), quiet ? Project.MSG_VERBOSE : verbosity); 700 for (int j = 0; j < files.length; j++) { 701 File f = new File (d, files[j]); 702 log("Deleting " + f.getAbsolutePath(), 703 quiet ? Project.MSG_VERBOSE : verbosity); 704 if (!delete(f)) { 705 handle("Unable to delete file " + f.getAbsolutePath()); 706 } 707 } 708 } 709 710 if (dirs.length > 0 && includeEmpty) { 711 int dirCount = 0; 712 for (int j = dirs.length - 1; j >= 0; j--) { 713 File currDir = new File (d, dirs[j]); 714 String [] dirFiles = currDir.list(); 715 if (dirFiles == null || dirFiles.length == 0) { 716 log("Deleting " + currDir.getAbsolutePath(), 717 quiet ? Project.MSG_VERBOSE : verbosity); 718 if (!delete(currDir)) { 719 handle("Unable to delete directory " 720 + currDir.getAbsolutePath()); 721 } else { 722 dirCount++; 723 } 724 } 725 } 726 727 if (dirCount > 0) { 728 log("Deleted " 729 + dirCount 730 + " director" + (dirCount == 1 ? "y" : "ies") 731 + " form " + d.getAbsolutePath(), 732 quiet ? Project.MSG_VERBOSE : verbosity); 733 } 734 } 735 } 736 } 737 | Popular Tags |