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 |
|
|
|