| @@ -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(); | |||