@@ -20,6 +20,9 @@ package org.apache.tools.ant; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
import java.nio.file.Paths; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
@@ -44,7 +47,6 @@ import org.apache.tools.ant.types.selectors.SelectorUtils; | |||
import org.apache.tools.ant.types.selectors.TokenizedPath; | |||
import org.apache.tools.ant.types.selectors.TokenizedPattern; | |||
import org.apache.tools.ant.util.FileUtils; | |||
import org.apache.tools.ant.util.SymbolicLinkUtils; | |||
import org.apache.tools.ant.util.VectorSet; | |||
/** | |||
@@ -227,10 +229,6 @@ public class DirectoryScanner | |||
/** Helper. */ | |||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||
/** Helper. */ | |||
private static final SymbolicLinkUtils SYMLINK_UTILS = | |||
SymbolicLinkUtils.getSymbolicLinkUtils(); | |||
/** | |||
* Patterns which should be excluded by default. | |||
* | |||
@@ -874,7 +872,7 @@ public class DirectoryScanner | |||
excludes = nullExcludes ? new String[0] : excludes; | |||
if (basedir != null && !followSymlinks | |||
&& SYMLINK_UTILS.isSymbolicLink(basedir)) { | |||
&& Files.isSymbolicLink(basedir.toPath())) { | |||
notFollowedSymlinks.add(basedir.getAbsolutePath()); | |||
basedir = null; | |||
} | |||
@@ -919,8 +917,6 @@ public class DirectoryScanner | |||
includes = nullIncludes ? null : includes; | |||
excludes = nullExcludes ? null : excludes; | |||
} | |||
} catch (final IOException ex) { | |||
throw new BuildException(ex); | |||
} finally { | |||
basedir = savedBase; | |||
synchronized (scanLock) { | |||
@@ -1220,25 +1216,23 @@ public class DirectoryScanner | |||
} | |||
if (!followSymlinks) { | |||
final ArrayList<String> noLinks = new ArrayList<>(); | |||
for (String newfile : newfiles) { | |||
try { | |||
if (SYMLINK_UTILS.isSymbolicLink(dir, newfile)) { | |||
final String name = vpath + newfile; | |||
final File file = new File(dir, newfile); | |||
if (file.isDirectory()) { | |||
dirsExcluded.addElement(name); | |||
} else if (file.isFile()) { | |||
filesExcluded.addElement(name); | |||
} | |||
accountForNotFollowedSymlink(name, file); | |||
} else { | |||
noLinks.add(newfile); | |||
for (final String newfile : newfiles) { | |||
final Path filePath; | |||
if (dir == null) { | |||
filePath = Paths.get(newfile); | |||
} else { | |||
filePath = Paths.get(dir.toPath().toString(), newfile); | |||
} | |||
if (Files.isSymbolicLink(filePath)) { | |||
final String name = vpath + newfile; | |||
final File file = new File(dir, newfile); | |||
if (file.isDirectory()) { | |||
dirsExcluded.addElement(name); | |||
} else if (file.isFile()) { | |||
filesExcluded.addElement(name); | |||
} | |||
} catch (final IOException ioe) { | |||
final String msg = "IOException caught while checking " | |||
+ "for links, couldn't get canonical path!"; | |||
// will be caught and redirected to Ant's logging system | |||
System.err.println(msg); | |||
accountForNotFollowedSymlink(name, file); | |||
} else { | |||
noLinks.add(newfile); | |||
} | |||
} | |||
@@ -1815,9 +1809,15 @@ public class DirectoryScanner | |||
private boolean causesIllegalSymlinkLoop(final String dirName, final File parent, | |||
final Deque<String> directoryNamesFollowed) { | |||
try { | |||
final Path dirPath; | |||
if (parent == null) { | |||
dirPath = Paths.get(dirName); | |||
} else { | |||
dirPath = Paths.get(parent.toPath().toString(), dirName); | |||
} | |||
if (directoryNamesFollowed.size() >= maxLevelsOfSymlinks | |||
&& Collections.frequency(directoryNamesFollowed, dirName) >= maxLevelsOfSymlinks | |||
&& SYMLINK_UTILS.isSymbolicLink(parent, dirName)) { | |||
&& Files.isSymbolicLink(dirPath)) { | |||
final List<String> files = new ArrayList<>(); | |||
File f = FILE_UTILS.resolveFile(parent, dirName); | |||
@@ -19,7 +19,9 @@ | |||
package org.apache.tools.ant.taskdefs; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
import java.nio.file.Paths; | |||
import java.util.Arrays; | |||
import java.util.Comparator; | |||
import java.util.Iterator; | |||
@@ -61,7 +63,6 @@ import org.apache.tools.ant.types.selectors.SelectSelector; | |||
import org.apache.tools.ant.types.selectors.SizeSelector; | |||
import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; | |||
import org.apache.tools.ant.util.FileUtils; | |||
import org.apache.tools.ant.util.SymbolicLinkUtils; | |||
/** | |||
* Deletes a file or directory, or set of files defined by a fileset. | |||
@@ -81,8 +82,6 @@ public class Delete extends MatchingTask { | |||
private static final ResourceComparator REVERSE_FILESYSTEM = new Reverse(new FileSystem()); | |||
private static final ResourceSelector EXISTS = new Exists(); | |||
private static FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||
private static SymbolicLinkUtils SYMLINK_UTILS = | |||
SymbolicLinkUtils.getSymbolicLinkUtils(); | |||
private static class ReverseDirs implements ResourceCollection { | |||
@@ -715,12 +714,15 @@ public class Delete extends MatchingTask { | |||
System.arraycopy(n, 0, links, 0, n.length); | |||
Arrays.sort(links, Comparator.reverseOrder()); | |||
for (int l = 0; l < links.length; l++) { | |||
try { | |||
SYMLINK_UTILS | |||
.deleteSymbolicLink(new File(links[l]), | |||
this); | |||
} catch (java.io.IOException ex) { | |||
handle(ex); | |||
final Path filePath = Paths.get(links[l]); | |||
if (!Files.isSymbolicLink(filePath)) { | |||
// it's not a symbolic link, so move on | |||
continue; | |||
} | |||
// it's a symbolic link, so delete it | |||
final boolean deleted = filePath.toFile().delete(); | |||
if (!deleted) { | |||
handle("Could not delete symbolic link at " + filePath); | |||
} | |||
} | |||
} | |||
@@ -876,14 +878,13 @@ public class Delete extends MatchingTask { | |||
} | |||
} | |||
private boolean isDanglingSymlink(File f) { | |||
try { | |||
return SYMLINK_UTILS.isDanglingSymbolicLink(f); | |||
} catch (IOException e) { | |||
log("Error while trying to detect " + f.getAbsolutePath() | |||
+ " as broken symbolic link. " + e.getMessage(), | |||
quiet ? Project.MSG_VERBOSE : verbosity); | |||
private boolean isDanglingSymlink(final File f) { | |||
if (!Files.isSymbolicLink(f.toPath())) { | |||
// it's not a symlink, so clearly it's not a dangling one | |||
return false; | |||
} | |||
// it's a symbolic link, now check the existence of the (target) file (by "following links") | |||
final boolean targetFileExists = Files.exists(f.toPath()); | |||
return !targetFileExists; | |||
} | |||
} |
@@ -19,11 +19,12 @@ | |||
package org.apache.tools.ant.types.selectors; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
import java.nio.file.Paths; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.util.FileUtils; | |||
import org.apache.tools.ant.util.SymbolicLinkUtils; | |||
/** | |||
* Container for a path that has been split into its components. | |||
@@ -39,9 +40,6 @@ public class TokenizedPath { | |||
/** Helper. */ | |||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||
/** Helper. */ | |||
private static final SymbolicLinkUtils SYMLINK_UTILS = | |||
SymbolicLinkUtils.getSymbolicLinkUtils(); | |||
/** iterations for case-sensitive scanning. */ | |||
private static final boolean[] CS_SCAN_ONLY = new boolean[] {true}; | |||
/** iterations for non-case-sensitive scanning. */ | |||
@@ -142,22 +140,16 @@ public class TokenizedPath { | |||
*/ | |||
public boolean isSymlink(File base) { | |||
for (int i = 0; i < tokenizedPath.length; i++) { | |||
try { | |||
if ((base != null | |||
&& SYMLINK_UTILS.isSymbolicLink(base, tokenizedPath[i])) | |||
|| | |||
(base == null | |||
&& SYMLINK_UTILS.isSymbolicLink(tokenizedPath[i])) | |||
) { | |||
return true; | |||
} | |||
base = new File(base, tokenizedPath[i]); | |||
} catch (IOException ioe) { | |||
String msg = "IOException caught while checking " | |||
+ "for links, couldn't get canonical path!"; | |||
// will be caught and redirected to Ant's logging system | |||
System.err.println(msg); | |||
final Path pathToTraverse; | |||
if (base == null) { | |||
pathToTraverse = Paths.get(tokenizedPath[i]); | |||
} else { | |||
pathToTraverse = Paths.get(base.toPath().toString(), tokenizedPath[i]); | |||
} | |||
if (Files.isSymbolicLink(pathToTraverse)) { | |||
return true; | |||
} | |||
base = new File(base, tokenizedPath[i]); | |||
} | |||
return false; | |||
} | |||
@@ -33,6 +33,7 @@ import java.net.URLConnection; | |||
import java.nio.channels.Channel; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
import java.nio.file.Paths; | |||
import java.nio.file.StandardOpenOption; | |||
import java.text.DecimalFormat; | |||
import java.util.ArrayList; | |||
@@ -1141,16 +1142,15 @@ public class FileUtils { | |||
* @return true if the file is a symbolic link. | |||
* @throws IOException on error. | |||
* @since Ant 1.5 | |||
* @deprecated use SymbolicLinkUtils instead | |||
* @deprecated use {@link Files#isSymbolicLink(Path)} instead | |||
*/ | |||
@Deprecated | |||
public boolean isSymbolicLink(File parent, String name) | |||
public boolean isSymbolicLink(final File parent, final String name) | |||
throws IOException { | |||
SymbolicLinkUtils u = SymbolicLinkUtils.getSymbolicLinkUtils(); | |||
if (parent == null) { | |||
return u.isSymbolicLink(name); | |||
return Files.isSymbolicLink(Paths.get(name)); | |||
} | |||
return u.isSymbolicLink(parent, name); | |||
return Files.isSymbolicLink(Paths.get(parent.toPath().toString(), name)); | |||
} | |||
/** | |||
@@ -30,6 +30,9 @@ import org.apache.tools.ant.taskdefs.Execute; | |||
* a symbolic link based on the absent support for them in Java. | |||
* | |||
* @since Ant 1.8.0 | |||
* @deprecated Starting Ant 1.10.2, this class is now deprecated in favour | |||
* of the Java {@link java.nio.file.Files} APIs introduced in | |||
* Java 7, for dealing with symbolic links | |||
*/ | |||
public class SymbolicLinkUtils { | |||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||