View | Details | Raw Unified | Return to bug 1550
Collapse All | Expand All

(-)Delete.java (-16 / +157 lines)
Lines 60-71 Link Here
60
import java.util.*;
60
import java.util.*;
61
61
62
/**
62
/**
63
 * Deletes a file or directory, or set of files defined by a fileset.
63
 * Deletes a file or directory or link, or set of files defined by a fileset.
64
 * The original delete task would delete a file, or a set of files 
64
 * The original delete task would delete a file, or a set of files 
65
 * using the include/exclude syntax.  The deltree task would delete a 
65
 * using the include/exclude syntax.  The deltree task would delete a 
66
 * directory tree.  This task combines the functionality of these two
66
 * directory tree.  This task combines the functionality of these two
67
 * originally distinct tasks.
67
 * originally distinct tasks.
68
 * <p>Currently Delete extends MatchingTask.  This is intend <i>only</i>
68
 * <p>Currently Delete extends MatchingTask.  This is intended <i>only</i>
69
 * to provide backwards compatibility for a release.  The future position
69
 * to provide backwards compatibility for a release.  The future position
70
 * is to use nested filesets exclusively.</p>
70
 * is to use nested filesets exclusively.</p>
71
 * 
71
 * 
Lines 73-78 Link Here
73
 * @author Tom Dimock <a href="mailto:tad1@cornell.edu">tad1@cornell.edu</a>
73
 * @author Tom Dimock <a href="mailto:tad1@cornell.edu">tad1@cornell.edu</a>
74
 * @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com</a>
74
 * @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com</a>
75
 * @author Jon S. Stevens <a href="mailto:jon@latchkey.com">jon@latchkey.com</a>
75
 * @author Jon S. Stevens <a href="mailto:jon@latchkey.com">jon@latchkey.com</a>
76
 * @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a>
76
 */
77
 */
77
public class Delete extends MatchingTask {
78
public class Delete extends MatchingTask {
78
    protected File file = null;
79
    protected File file = null;
Lines 90-106 Link Here
90
     *
91
     *
91
     * @param file the file to be deleted
92
     * @param file the file to be deleted
92
     */
93
     */
93
    public void setFile(File file) {
94
    public void setFile(String file) {
94
        this.file = file;
95
        /*
96
        Parameter changed to from File String to ensure symlinks
97
        don't get translated.
98
        */
99
        this.file = new File(file);
95
    }
100
    }
96
101
97
    /**
102
    /**
98
     * Set the directory from which files are to be deleted
103
     * Set the directory from which files are to be deleted
99
     *
104
     *
100
     * @param dir the directory path.
105
     * @param dir the directory path.
106
     */
107
    public void setDir(String dir) {
108
        /*
109
        Parameter changed from File to String to ensure symlinks
110
        don't get translated.
101
     */
111
     */
102
    public void setDir(File dir) {
112
        this.dir = new File(dir);
103
        this.dir = dir;
104
    }
113
    }
105
114
106
    /**
115
    /**
Lines 239-244 Link Here
239
     * Delete the file(s).
248
     * Delete the file(s).
240
     */
249
     */
241
    public void execute() throws BuildException {
250
    public void execute() throws BuildException {
251
        boolean isLink = false;
242
        if (usedMatchingTask) {
252
        if (usedMatchingTask) {
243
            log("DEPRECATED - Use of the implicit FileSet is deprecated.  Use a nested fileset element instead.");
253
            log("DEPRECATED - Use of the implicit FileSet is deprecated.  Use a nested fileset element instead.");
244
        }
254
        }
Lines 252-262 Link Here
252
                                     location);
262
                                     location);
253
        }
263
        }
254
        
264
        
255
256
        // delete the single file
265
        // delete the single file
257
        if (file != null) {
266
        if (file != null) {
258
            if (file.exists()) {
267
            if (file.exists()) {
259
                if (file.isDirectory()) {
268
                isLink = isLink(file);
269
                if (isLink) {
270
                    log("Deleting Link: " + file.getAbsolutePath());
271
                    removeLink(file);
272
                } else if (file.isDirectory()) {
260
                    log("Directory " + file.getAbsolutePath() + " cannot be removed using the file attribute.  Use dir instead.");
273
                    log("Directory " + file.getAbsolutePath() + " cannot be removed using the file attribute.  Use dir instead.");
261
                } else {
274
                } else {
262
                    log("Deleting: " + file.getAbsolutePath());
275
                    log("Deleting: " + file.getAbsolutePath());
Lines 277-283 Link Here
277
        }
290
        }
278
291
279
        // delete the directory
292
        // delete the directory
280
        if (dir != null && dir.exists() && dir.isDirectory() && !usedMatchingTask) {
293
        if (dir != null && dir.exists()) {
294
            isLink = isLink(dir);
295
            if (isLink) {
296
                log("Deleting Link: " + dir.getAbsolutePath());
297
                removeLink(dir);
298
            } else if (dir.isDirectory() && !usedMatchingTask) {
281
            /*
299
            /*
282
               If verbosity is MSG_VERBOSE, that mean we are doing regular logging
300
               If verbosity is MSG_VERBOSE, that mean we are doing regular logging
283
               (backwards as that sounds).  In that case, we want to print one
301
               (backwards as that sounds).  In that case, we want to print one
Lines 289-294 Link Here
289
            }
307
            }
290
            removeDir(dir);
308
            removeDir(dir);
291
        }
309
        }
310
        }
292
311
293
        // delete the files in the filesets
312
        // delete the files in the filesets
294
        for (int i=0; i<filesets.size(); i++) {
313
        for (int i=0; i<filesets.size(); i++) {
Lines 328-337 Link Here
328
        }
347
        }
329
    }
348
    }
330
349
350
331
//************************************************************************
351
//************************************************************************
332
//  protected and private methods
352
//  protected and private methods
333
//************************************************************************
353
//************************************************************************
334
354
355
    /**
356
     * Does the case of a file name contribute to its distinctiveness?
357
     */
358
    protected boolean isCaseSensitive() {
359
        boolean isCaseSensitive = true;
360
        if (System.getProperty("os.name").startsWith("Windows")
361
            || System.getProperty("os.name")
362
                     .toLowerCase()
363
                     .indexOf("mac") > -1) {
364
            isCaseSensitive = false;
365
        }
366
        return isCaseSensitive;
367
    }
368
369
    /**
370
     * Is the file a symbolic link?
371
     * @param file the file to be tested to see if it is a symbolic link
372
     */
373
    protected boolean isLink(File file) {
374
        boolean isLink = false;
375
        try {
376
            String canonicalPath = file.getCanonicalPath();
377
            String absolutePath = file.getAbsolutePath();
378
            if (isCaseSensitive()) {
379
                isLink = !canonicalPath.equals(absolutePath);
380
            } else {
381
                isLink = !canonicalPath.equalsIgnoreCase(absolutePath);
382
            }
383
        } catch (IOException ioe) {
384
            if (failonerror) {
385
                throw new BuildException(ioe.getMessage(), ioe, location);
386
            } else {
387
                log(ioe.getMessage(),
388
                    quiet ? Project.MSG_VERBOSE : Project.MSG_WARN);
389
            }
390
        }
391
        return isLink;
392
    }
393
394
    /**
395
     * Removing a sym link is a three step process:
396
     * 1. Rename the actual file the symlink is pointing to,
397
     *    thus making it a dangling symlink
398
     * 2. Delete Symlink now that the actual file is safe
399
     * 3. Rename the temporary file back to what it was earlier.
400
     * @param link the symbolic link to be removed
401
     */
402
    protected boolean removeLink(File link) {
403
        boolean retValue = true;
404
        try {
405
            String canonicalPath = link.getCanonicalPath();
406
            String absolutePath = link.getAbsolutePath();
407
            File canonicalFile = new File(canonicalPath);
408
            String canonicalTempFile = canonicalFile + ".ant.tmp";
409
            File temporaryFile = new File(canonicalTempFile);
410
            boolean movedToTmp = canonicalFile.renameTo(temporaryFile);
411
            boolean movedToOrig = false;
412
            boolean deleted = false;
413
            if (movedToTmp) {
414
                deleted = link.delete(); //SymLink is deleted here.
415
                File backToOriginalFile = new File(canonicalPath);
416
                File newFile = new File(canonicalTempFile);
417
                canonicalFile.delete(); //Remove dangling reference
418
                // Rename temporary file back to original file
419
                movedToOrig = newFile.renameTo(backToOriginalFile);
420
            }
421
            String message = null;
422
            if (!movedToTmp) {
423
                message = "Unable to create temp file for "
424
                              + "deleting symbolic link "
425
                              + absolutePath;
426
            }
427
            if (!deleted) {
428
                message = "Unable to delete symbolic link " + absolutePath;
429
            }
430
            if (!movedToOrig) {
431
                if (message == null) {
432
                    message = "";
433
                }
434
                message += "Unable to rename temp file " + canonicalTempFile +
435
                               " back to " + canonicalFile;
436
            }
437
            if (message != null && !message.equals("")) {
438
                retValue = false;
439
                if(failonerror) {
440
                    throw new BuildException(message);
441
                }
442
                else {
443
                    log(message,
444
                        quiet ? Project.MSG_VERBOSE : Project.MSG_WARN);
445
                }
446
            }
447
        } catch (IOException ioe) {
448
            if (failonerror) {
449
                throw new BuildException(ioe.getMessage(), ioe, location);
450
            } else {
451
                log(ioe.getMessage(),
452
                    quiet ? Project.MSG_VERBOSE : Project.MSG_WARN);
453
            }
454
        }
455
        return retValue;
456
    }
457
335
    protected void removeDir(File d) {
458
    protected void removeDir(File d) {
336
        String[] list = d.list();
459
        String[] list = d.list();
337
        if (list == null) list = new String[0];
460
        if (list == null) list = new String[0];
Lines 343-349 Link Here
343
            } else {
466
            } else {
344
                log("Deleting " + f.getAbsolutePath(), verbosity);
467
                log("Deleting " + f.getAbsolutePath(), verbosity);
345
                if (!f.delete()) {
468
                if (!f.delete()) {
346
                    String message="Unable to delete file " + f.getAbsolutePath();
469
                    String message="Unable to delete file "
470
                                       + f.getAbsolutePath();
347
                    if(failonerror)
471
                    if(failonerror)
348
                        throw new BuildException(message);
472
                        throw new BuildException(message);
349
                    else
473
                    else
Lines 354-360 Link Here
354
        }
478
        }
355
        log("Deleting directory " + d.getAbsolutePath(), verbosity);
479
        log("Deleting directory " + d.getAbsolutePath(), verbosity);
356
        if (!d.delete()) {
480
        if (!d.delete()) {
357
            String message="Unable to delete directory " + dir.getAbsolutePath();
481
            String message="Unable to delete directory "
482
                               + dir.getAbsolutePath();
358
            if(failonerror)
483
            if(failonerror)
359
                throw new BuildException(message);
484
                throw new BuildException(message);
360
            else
485
            else
Lines 372-388 Link Here
372
     */
497
     */
373
    protected void removeFiles(File d, String[] files, String[] dirs) {
498
    protected void removeFiles(File d, String[] files, String[] dirs) {
374
        if (files.length > 0) {
499
        if (files.length > 0) {
375
            log("Deleting " + files.length + " files from " + d.getAbsolutePath());
500
            log("Deleting " + files.length + " files from "
501
                    + d.getAbsolutePath());
376
            for (int j=0; j<files.length; j++) {
502
            for (int j=0; j<files.length; j++) {
377
                File f = new File(d, files[j]);
503
                File f = new File(d, files[j]);
504
                if (isLink(f)) {
505
                    log("Deleting Link: " + f.getAbsolutePath(), verbosity);
506
                    removeLink(f);
507
                } else {
378
                log("Deleting " + f.getAbsolutePath(), verbosity);
508
                log("Deleting " + f.getAbsolutePath(), verbosity);
379
                if (!f.delete()) {
509
                if (!f.delete()) {
380
                    String message="Unable to delete file " + f.getAbsolutePath();
510
                        String message="Unable to delete file "
511
                                           + f.getAbsolutePath();
381
                    if(failonerror)
512
                    if(failonerror)
382
                        throw new BuildException(message);
513
                        throw new BuildException(message);
383
                    else
514
                    else
384
                        log(message,
515
                        log(message,
385
                            quiet ? Project.MSG_VERBOSE : Project.MSG_WARN);
516
                                quiet ? Project.MSG_VERBOSE :
517
                                        Project.MSG_WARN);
518
                    }
386
                }
519
                }
387
            }
520
            }
388
        }
521
        }
Lines 391-396 Link Here
391
            int dirCount = 0;
524
            int dirCount = 0;
392
            for (int j=dirs.length-1; j>=0; j--) {
525
            for (int j=dirs.length-1; j>=0; j--) {
393
                File dir = new File(d, dirs[j]);
526
                File dir = new File(d, dirs[j]);
527
                if (isLink(dir)) {
528
                    log("Deleting Link: " + dir.getAbsolutePath());
529
                    boolean removed = removeLink(dir);
530
                    if (removed) {
531
                        dirCount++;
532
                    }
533
                } else {
394
                String[] dirFiles = dir.list();
534
                String[] dirFiles = dir.list();
395
                if (dirFiles == null || dirFiles.length == 0) {
535
                if (dirFiles == null || dirFiles.length == 0) {
396
                    log("Deleting " + dir.getAbsolutePath(), verbosity);
536
                    log("Deleting " + dir.getAbsolutePath(), verbosity);
Lines 401-412 Link Here
401
                            throw new BuildException(message);
541
                            throw new BuildException(message);
402
                        else
542
                        else
403
                            log(message,
543
                            log(message,
404
                                quiet ? Project.MSG_VERBOSE : Project.MSG_WARN);
544
                                    quiet ? Project.MSG_VERBOSE :
545
                                            Project.MSG_WARN);
405
                    } else {
546
                    } else {
406
                        dirCount++;
547
                        dirCount++;
407
                    }
548
                    }
408
                }
549
                }
409
            }
550
            }
551
            }
410
552
411
            if (dirCount > 0) {
553
            if (dirCount > 0) {
412
                log("Deleted " + dirCount + " director" +
554
                log("Deleted " + dirCount + " director" +
Lines 416-419 Link Here
416
        }
558
        }
417
    }
559
    }
418
}
560
}
419

Return to bug 1550