Browse Source

Deprecate SymbolicLinkUtils in favour of Java 7 java.nio.file.Files APIs

master
Jaikiran Pai Jaikiran Pai 7 years ago
parent
commit
242d661161
5 changed files with 65 additions and 69 deletions
  1. +27
    -27
      src/main/org/apache/tools/ant/DirectoryScanner.java
  2. +18
    -17
      src/main/org/apache/tools/ant/taskdefs/Delete.java
  3. +12
    -20
      src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
  4. +5
    -5
      src/main/org/apache/tools/ant/util/FileUtils.java
  5. +3
    -0
      src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java

+ 27
- 27
src/main/org/apache/tools/ant/DirectoryScanner.java View File

@@ -20,6 +20,9 @@ package org.apache.tools.ant;


import java.io.File; import java.io.File;
import java.io.IOException; 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.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; 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.TokenizedPath;
import org.apache.tools.ant.types.selectors.TokenizedPattern; import org.apache.tools.ant.types.selectors.TokenizedPattern;
import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.SymbolicLinkUtils;
import org.apache.tools.ant.util.VectorSet; import org.apache.tools.ant.util.VectorSet;


/** /**
@@ -227,10 +229,6 @@ public class DirectoryScanner
/** Helper. */ /** Helper. */
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();


/** Helper. */
private static final SymbolicLinkUtils SYMLINK_UTILS =
SymbolicLinkUtils.getSymbolicLinkUtils();

/** /**
* Patterns which should be excluded by default. * Patterns which should be excluded by default.
* *
@@ -874,7 +872,7 @@ public class DirectoryScanner
excludes = nullExcludes ? new String[0] : excludes; excludes = nullExcludes ? new String[0] : excludes;


if (basedir != null && !followSymlinks if (basedir != null && !followSymlinks
&& SYMLINK_UTILS.isSymbolicLink(basedir)) {
&& Files.isSymbolicLink(basedir.toPath())) {
notFollowedSymlinks.add(basedir.getAbsolutePath()); notFollowedSymlinks.add(basedir.getAbsolutePath());
basedir = null; basedir = null;
} }
@@ -919,8 +917,6 @@ public class DirectoryScanner
includes = nullIncludes ? null : includes; includes = nullIncludes ? null : includes;
excludes = nullExcludes ? null : excludes; excludes = nullExcludes ? null : excludes;
} }
} catch (final IOException ex) {
throw new BuildException(ex);
} finally { } finally {
basedir = savedBase; basedir = savedBase;
synchronized (scanLock) { synchronized (scanLock) {
@@ -1220,25 +1216,23 @@ public class DirectoryScanner
} }
if (!followSymlinks) { if (!followSymlinks) {
final ArrayList<String> noLinks = new ArrayList<>(); 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); noLinks.add(newfile);
} }
} }
@@ -1815,9 +1809,15 @@ public class DirectoryScanner
private boolean causesIllegalSymlinkLoop(final String dirName, final File parent, private boolean causesIllegalSymlinkLoop(final String dirName, final File parent,
final Deque<String> directoryNamesFollowed) { final Deque<String> directoryNamesFollowed) {
try { try {
final Path dirPath;
if (parent == null) {
dirPath = Paths.get(dirName);
} else {
dirPath = Paths.get(parent.toPath().toString(), dirName);
}
if (directoryNamesFollowed.size() >= maxLevelsOfSymlinks if (directoryNamesFollowed.size() >= maxLevelsOfSymlinks
&& Collections.frequency(directoryNamesFollowed, dirName) >= maxLevelsOfSymlinks && Collections.frequency(directoryNamesFollowed, dirName) >= maxLevelsOfSymlinks
&& SYMLINK_UTILS.isSymbolicLink(parent, dirName)) {
&& Files.isSymbolicLink(dirPath)) {


final List<String> files = new ArrayList<>(); final List<String> files = new ArrayList<>();
File f = FILE_UTILS.resolveFile(parent, dirName); File f = FILE_UTILS.resolveFile(parent, dirName);


+ 18
- 17
src/main/org/apache/tools/ant/taskdefs/Delete.java View File

@@ -19,7 +19,9 @@
package org.apache.tools.ant.taskdefs; package org.apache.tools.ant.taskdefs;


import java.io.File; 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.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.Iterator; 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.SizeSelector;
import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
import org.apache.tools.ant.util.FileUtils; 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. * 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 ResourceComparator REVERSE_FILESYSTEM = new Reverse(new FileSystem());
private static final ResourceSelector EXISTS = new Exists(); private static final ResourceSelector EXISTS = new Exists();
private static FileUtils FILE_UTILS = FileUtils.getFileUtils(); private static FileUtils FILE_UTILS = FileUtils.getFileUtils();
private static SymbolicLinkUtils SYMLINK_UTILS =
SymbolicLinkUtils.getSymbolicLinkUtils();


private static class ReverseDirs implements ResourceCollection { private static class ReverseDirs implements ResourceCollection {


@@ -715,12 +714,15 @@ public class Delete extends MatchingTask {
System.arraycopy(n, 0, links, 0, n.length); System.arraycopy(n, 0, links, 0, n.length);
Arrays.sort(links, Comparator.reverseOrder()); Arrays.sort(links, Comparator.reverseOrder());
for (int l = 0; l < links.length; l++) { 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; 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;
} }
} }

+ 12
- 20
src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java View File

@@ -19,11 +19,12 @@
package org.apache.tools.ant.types.selectors; package org.apache.tools.ant.types.selectors;


import java.io.File; 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.BuildException;
import org.apache.tools.ant.util.FileUtils; 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. * Container for a path that has been split into its components.
@@ -39,9 +40,6 @@ public class TokenizedPath {


/** Helper. */ /** Helper. */
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
/** Helper. */
private static final SymbolicLinkUtils SYMLINK_UTILS =
SymbolicLinkUtils.getSymbolicLinkUtils();
/** iterations for case-sensitive scanning. */ /** iterations for case-sensitive scanning. */
private static final boolean[] CS_SCAN_ONLY = new boolean[] {true}; private static final boolean[] CS_SCAN_ONLY = new boolean[] {true};
/** iterations for non-case-sensitive scanning. */ /** iterations for non-case-sensitive scanning. */
@@ -142,22 +140,16 @@ public class TokenizedPath {
*/ */
public boolean isSymlink(File base) { public boolean isSymlink(File base) {
for (int i = 0; i < tokenizedPath.length; i++) { 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; return false;
} }


+ 5
- 5
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -33,6 +33,7 @@ import java.net.URLConnection;
import java.nio.channels.Channel; import java.nio.channels.Channel;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
@@ -1141,16 +1142,15 @@ public class FileUtils {
* @return true if the file is a symbolic link. * @return true if the file is a symbolic link.
* @throws IOException on error. * @throws IOException on error.
* @since Ant 1.5 * @since Ant 1.5
* @deprecated use SymbolicLinkUtils instead
* @deprecated use {@link Files#isSymbolicLink(Path)} instead
*/ */
@Deprecated @Deprecated
public boolean isSymbolicLink(File parent, String name)
public boolean isSymbolicLink(final File parent, final String name)
throws IOException { throws IOException {
SymbolicLinkUtils u = SymbolicLinkUtils.getSymbolicLinkUtils();
if (parent == null) { 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));
} }


/** /**


+ 3
- 0
src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java View File

@@ -30,6 +30,9 @@ import org.apache.tools.ant.taskdefs.Execute;
* a symbolic link based on the absent support for them in Java. * a symbolic link based on the absent support for them in Java.
* *
* @since Ant 1.8.0 * @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 { public class SymbolicLinkUtils {
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();


Loading…
Cancel
Save