--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/FileSystemLoopException.java Sun Oct 03 19:39:25 2010 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system loop, or cycle, is encountered.
+ *
+ * @since 1.7
+ * @see Files#walkFileTree
+ */
+
+public class FileSystemLoopException
+ extends FileSystemException
+{
+ private static final long serialVersionUID = 4843039591949217617L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file causing the cycle or {@code null} if
+ * not known
+ */
+ public FileSystemLoopException(String file) {
+ super(file);
+ }
+}
--- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Sun Oct 03 19:39:25 2010 +0100
@@ -38,7 +38,6 @@
class FileTreeWalker {
private final boolean followLinks;
- private final boolean detectCycles;
private final LinkOption[] linkOptions;
private final FileVisitor<? super Path> visitor;
private final int maxDepth;
@@ -48,17 +47,15 @@
int maxDepth)
{
boolean fl = false;
- boolean dc = false;
for (FileVisitOption option: options) {
+ // will throw NPE if options contains null
switch (option) {
- case FOLLOW_LINKS : fl = true; break;
- case DETECT_CYCLES : dc = true; break;
+ case FOLLOW_LINKS : fl = true; break;
default:
throw new AssertionError("Should not get here");
}
}
this.followLinks = fl;
- this.detectCycles = fl | dc;
this.linkOptions = (fl) ? new LinkOption[0] :
new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
this.visitor = visitor;
@@ -68,13 +65,11 @@
/**
* Walk file tree starting at the given file
*/
- void walk(Path start) {
+ void walk(Path start) throws IOException {
FileVisitResult result = walk(start,
0,
new ArrayList<AncestorDirectory>());
- if (result == null) {
- throw new NullPointerException("Visitor returned 'null'");
- }
+ Objects.nonNull(result, "FileVisitor returned null");
}
/**
@@ -88,11 +83,8 @@
private FileVisitResult walk(Path file,
int depth,
List<AncestorDirectory> ancestors)
+ throws IOException
{
- // depth check
- if (depth > maxDepth)
- return FileVisitResult.CONTINUE;
-
// if attributes are cached then use them if possible
BasicFileAttributes attrs = null;
if ((depth > 0) &&
@@ -137,13 +129,13 @@
return visitor.visitFileFailed(file, exc);
}
- // file is not a directory so invoke visitFile method
- if (!attrs.isDirectory()) {
+ // at maximum depth or file is not a directory
+ if (depth >= maxDepth || !attrs.isDirectory()) {
return visitor.visitFile(file, attrs);
}
- // check for cycles
- if (detectCycles) {
+ // check for cycles when following links
+ if (followLinks) {
Object key = attrs.fileKey();
// if this directory and ancestor has a file key then we compare
@@ -153,19 +145,23 @@
if (key != null && ancestorKey != null) {
if (key.equals(ancestorKey)) {
// cycle detected
- return visitor.visitFile(file, attrs);
+ return visitor.visitFileFailed(file,
+ new FileSystemLoopException(file.toString()));
}
} else {
+ boolean isSameFile = false;
try {
- if (file.isSameFile(ancestor.file())) {
- // cycle detected
- return visitor.visitFile(file, attrs);
- }
+ isSameFile = file.isSameFile(ancestor.file());
} catch (IOException x) {
// ignore
} catch (SecurityException x) {
// ignore
}
+ if (isSameFile) {
+ // cycle detected
+ return visitor.visitFileFailed(file,
+ new FileSystemLoopException(file.toString()));
+ }
}
}
@@ -181,7 +177,7 @@
try {
stream = file.newDirectoryStream();
} catch (IOException x) {
- return visitor.preVisitDirectoryFailed(file, x);
+ return visitor.visitFileFailed(file, x);
} catch (SecurityException x) {
// ignore, as per spec
return FileVisitResult.CONTINUE;
@@ -192,20 +188,14 @@
// invoke preVisitDirectory and then visit each entry
try {
- result = visitor.preVisitDirectory(file);
+ result = visitor.preVisitDirectory(file, attrs);
if (result != FileVisitResult.CONTINUE) {
return result;
}
- // if an I/O occurs during iteration then a CME is thrown. We
- // need to distinguish this from a CME thrown by the visitor.
- boolean inAction = false;
-
try {
for (Path entry: stream) {
- inAction = true;
result = walk(entry, depth+1, ancestors);
- inAction = false;
// returning null will cause NPE to be thrown
if (result == null || result == FileVisitResult.TERMINATE)
@@ -215,17 +205,9 @@
if (result == FileVisitResult.SKIP_SIBLINGS)
break;
}
- } catch (ConcurrentModificationException x) {
- // if CME thrown because the iteration failed then remember
- // the IOException so that it is notified to postVisitDirectory
- if (!inAction) {
- // iteration failed
- Throwable t = x.getCause();
- if (t instanceof IOException)
- ioe = (IOException)t;
- }
- if (ioe == null)
- throw x;
+ } catch (DirectoryIteratorException e) {
+ // IOException will be notified to postVisitDirectory
+ ioe = e.getCause();
}
} finally {
try {
@@ -238,7 +220,7 @@
} finally {
// remove key from trail if doing cycle detection
- if (detectCycles) {
+ if (followLinks) {
ancestors.remove(ancestors.size()-1);
}
}
--- a/jdk/src/share/classes/java/nio/file/FileVisitOption.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/src/share/classes/java/nio/file/FileVisitOption.java Sun Oct 03 19:39:25 2010 +0100
@@ -37,9 +37,5 @@
/**
* Follow symbolic links.
*/
- FOLLOW_LINKS,
- /**
- * Detect cycles in the file tree.
- */
- DETECT_CYCLES;
+ FOLLOW_LINKS;
}
--- a/jdk/src/share/classes/java/nio/file/FileVisitor.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/src/share/classes/java/nio/file/FileVisitor.java Sun Oct 03 19:39:25 2010 +0100
@@ -40,33 +40,28 @@
* Path start = ...
* Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
* @Override
- * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- * try {
- * file.delete();
- * } catch (IOException exc) {
- * // failed to delete, do error handling here
- * }
+ * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ * throws IOException
+ * {
+ * file.delete();
* return FileVisitResult.CONTINUE;
* }
* @Override
- * public FileVisitResult postVisitDirectory(Path dir, IOException e) {
- * if (e == null) {
- * try {
- * dir.delete();
- * } catch (IOException exc) {
- * // failed to delete, do error handling here
- * }
- * } else {
+ * public FileVisitResult postVisitDirectory(Path dir, IOException e)
+ * throws IOException
+ * {
+ * if (e != null) {
* // directory iteration failed
+ * throw e;
* }
+ * dir.delete();
* return FileVisitResult.CONTINUE;
* }
* });
* </pre>
- * <p> Furthermore, suppose we want to copy a file tree rooted at a source
- * directory to a target location. In that case, symbolic links should be
- * followed and the target directory should be created before the entries in
- * the directory are copied.
+ * <p> Furthermore, suppose we want to copy a file tree to a target location.
+ * In that case, symbolic links should be followed and the target directory
+ * should be created before the entries in the directory are copied.
* <pre>
* final Path source = ...
* final Path target = ...
@@ -74,25 +69,21 @@
* Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
* new SimpleFileVisitor<Path>() {
* @Override
- * public FileVisitResult preVisitDirectory(Path dir) {
+ * public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ * throws IOException
+ * {
* try {
* dir.copyTo(target.resolve(source.relativize(dir)));
* } catch (FileAlreadyExistsException e) {
* // ignore
- * } catch (IOException e) {
- * // copy failed, do error handling here
- * // skip rest of directory and descendants
- * return SKIP_SUBTREE;
* }
* return CONTINUE;
* }
* @Override
- * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- * try {
- * file.copyTo(target.resolve(source.relativize(file)));
- * } catch (IOException e) {
- * // copy failed, do error handling here
- * }
+ * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ * throws IOException
+ * {
+ * file.copyTo(target.resolve(source.relativize(file)));
* return CONTINUE;
* }
* });
@@ -114,22 +105,16 @@
*
* @param dir
* a reference to the directory
+ * @param attrs
+ * the directory's basic attributes
*
* @return the visit result
+ *
+ * @throws IOException
+ * if an I/O error occurs
*/
- FileVisitResult preVisitDirectory(T dir);
-
- /**
- * Invoked for a directory that could not be opened.
- *
- * @param dir
- * a reference to the directory
- * @param exc
- * the I/O exception thrown from the attempt to open the directory
- *
- * @return the visit result
- */
- FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);
+ FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
+ throws IOException;
/**
* Invoked for a file in a directory.
@@ -140,21 +125,30 @@
* the file's basic attributes
*
* @return the visit result
+ *
+ * @throws IOException
+ * if an I/O error occurs
*/
- FileVisitResult visitFile(T file, BasicFileAttributes attrs);
+ FileVisitResult visitFile(T file, BasicFileAttributes attrs)
+ throws IOException;
/**
- * Invoked for a file when its basic file attributes could not be read.
+ * Invoked for a file that could not be visited. This method is invoked
+ * if the file's attributes could not be read, the file is a directory
+ * that could not be opened, and other reasons.
*
* @param file
* a reference to the file
* @param exc
- * the I/O exception thrown from the attempt to read the file
- * attributes
+ * the I/O exception that prevented the file from being visited
*
* @return the visit result
+ *
+ * @throws IOException
+ * if an I/O error occurs
*/
- FileVisitResult visitFileFailed(T file, IOException exc);
+ FileVisitResult visitFileFailed(T file, IOException exc)
+ throws IOException;
/**
* Invoked for a directory after entries in the directory, and all of their
@@ -171,6 +165,10 @@
* of the directory to complete prematurely
*
* @return the visit result
+ *
+ * @throws IOException
+ * if an I/O error occurs
*/
- FileVisitResult postVisitDirectory(T dir, IOException exc);
+ FileVisitResult postVisitDirectory(T dir, IOException exc)
+ throws IOException;
}
--- a/jdk/src/share/classes/java/nio/file/Files.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/src/share/classes/java/nio/file/Files.java Sun Oct 03 19:39:25 2010 +0100
@@ -135,9 +135,9 @@
* FileVisitor} invoked for each file encountered. File tree traversal
* completes when all accessible files in the tree have been visited, or a
* visit method returns a result of {@link FileVisitResult#TERMINATE
- * TERMINATE}. Where a visit method terminates due an uncaught error or
- * runtime exception then the traversal is terminated and the error or
- * exception is propagated to the caller of this method.
+ * TERMINATE}. Where a visit method terminates due an {@code IOException},
+ * an uncaught error, or runtime exception, then the traversal is terminated
+ * and the error or exception is propagated to the caller of this method.
*
* <p> For each file encountered this method attempts to gets its {@link
* java.nio.file.attribute.BasicFileAttributes}. If the file is not a
@@ -146,12 +146,10 @@
* due to an I/O exception, then the {@link FileVisitor#visitFileFailed
* visitFileFailed} method is invoked with the I/O exception.
*
- * <p> Where the file is a directory, this method attempts to open it by
- * invoking its {@link Path#newDirectoryStream newDirectoryStream} method.
- * Where the directory could not be opened, due to an {@code IOException},
- * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed}
- * method is invoked with the I/O exception, after which, the file tree walk
- * continues, by default, at the next <em>sibling</em> of the directory.
+ * <p> Where the file is a directory, and the directory could not be opened,
+ * then the {@code visitFileFailed} method is invoked with the I/O exception,
+ * after which, the file tree walk continues, by default, at the next
+ * <em>sibling</em> of the directory.
*
* <p> Where the directory is opened successfully, then the entries in the
* directory, and their <em>descendants</em> are visited. When all entries
@@ -171,26 +169,25 @@
* method is invoked as specified above).
*
* <p> If the {@code options} parameter contains the {@link
- * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link
- * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps
+ * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps
* track of directories visited so that cycles can be detected. A cycle
* arises when there is an entry in a directory that is an ancestor of the
* directory. Cycle detection is done by recording the {@link
* java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
* or if file keys are not available, by invoking the {@link Path#isSameFile
* isSameFile} method to test if a directory is the same file as an
- * ancestor. When a cycle is detected the {@link FileVisitor#visitFile
- * visitFile} is invoked with the attributes of the directory. The {@link
- * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory}
- * method may be used to test if the file is a directory and that a cycle is
- * detected. The {@code preVisitDirectory} and {@code postVisitDirectory}
- * methods are not invoked.
+ * ancestor. When a cycle is detected it is treated as an I/O error, and the
+ * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
+ * an instance of {@link FileSystemLoopException}.
*
* <p> The {@code maxDepth} parameter is the maximum number of levels of
* directories to visit. A value of {@code 0} means that only the starting
* file is visited, unless denied by the security manager. A value of
* {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
- * levels should be visited.
+ * levels should be visited. The {@code visitFile} method is invoked for all
+ * files, including directories, encountered at {@code maxDepth}, unless the
+ * basic file attributes cannot be read, in which case the {@code
+ * visitFileFailed} method is invoked.
*
* <p> If a visitor returns a result of {@code null} then {@code
* NullPointerException} is thrown.
@@ -215,11 +212,14 @@
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String) checkRead} method is invoked
* to check read access to the directory.
+ * @throws IOException
+ * If an I/O error is thrown by a visitor method
*/
public static void walkFileTree(Path start,
Set<FileVisitOption> options,
int maxDepth,
FileVisitor<? super Path> visitor)
+ throws IOException
{
if (maxDepth < 0)
throw new IllegalArgumentException("'maxDepth' is negative");
@@ -245,8 +245,12 @@
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String) checkRead} method is invoked
* to check read access to the directory.
+ * @throws IOException
+ * If an I/O error is thrown by a visitor method
*/
- public static void walkFileTree(Path start, FileVisitor<? super Path> visitor) {
+ public static void walkFileTree(Path start, FileVisitor<? super Path> visitor)
+ throws IOException
+ {
walkFileTree(start,
EnumSet.noneOf(FileVisitOption.class),
Integer.MAX_VALUE,
--- a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java Sun Oct 03 19:39:25 2010 +0100
@@ -27,7 +27,7 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.io.IOException;
-import java.io.IOError;
+import java.util.Objects;
/**
* A simple visitor of files with default behavior to visit all files and to
@@ -48,70 +48,47 @@
}
/**
- * Throws NullPointerException if obj is null.
- */
- private static void checkNotNull(Object obj) {
- if (obj == null)
- throw new NullPointerException();
- }
-
- /**
* Invoked for a directory before entries in the directory are visited.
*
* <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
* CONTINUE}.
*/
@Override
- public FileVisitResult preVisitDirectory(T dir) {
- checkNotNull(dir);
+ public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
+ throws IOException
+ {
+ Objects.nonNull(dir);
+ Objects.nonNull(attrs);
return FileVisitResult.CONTINUE;
}
/**
- * Invoked for a directory that could not be opened.
- *
- * <p> Unless overridden, this method throws {@link IOError} with the I/O
- * exception as cause.
- *
- * @throws IOError
- * with the I/O exception thrown when the attempt to open the
- * directory failed
- */
- @Override
- public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) {
- checkNotNull(dir);
- checkNotNull(exc);
- throw new IOError(exc);
- }
-
- /**
* Invoked for a file in a directory.
*
* <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
* CONTINUE}.
*/
@Override
- public FileVisitResult visitFile(T file, BasicFileAttributes attrs) {
- checkNotNull(file);
- checkNotNull(attrs);
+ public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ Objects.nonNull(file);
+ Objects.nonNull(attrs);
return FileVisitResult.CONTINUE;
}
/**
- * Invoked for a file when its basic file attributes could not be read.
+ * Invoked for a file that could not be visited.
*
- * <p> Unless overridden, this method throws {@link IOError} with the I/O
- * exception as cause.
- *
- * @throws IOError
- * with the I/O exception thrown when the attempt to read the file
- * attributes failed
+ * <p> Unless overridden, this method re-throws the I/O exception that prevented
+ * the file from being visited.
*/
@Override
- public FileVisitResult visitFileFailed(T file, IOException exc) {
- checkNotNull(file);
- checkNotNull(exc);
- throw new IOError(exc);
+ public FileVisitResult visitFileFailed(T file, IOException exc)
+ throws IOException
+ {
+ Objects.nonNull(file);
+ throw exc;
}
/**
@@ -120,18 +97,16 @@
*
* <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
* CONTINUE} if the directory iteration completes without an I/O exception;
- * otherwise this method throws {@link IOError} with the I/O exception as
- * cause.
- *
- * @throws IOError
- * with the I/O exception thrown when iteration of the directory
- * completed prematurely due to an I/O error
+ * otherwise this method re-throws the I/O exception that caused the iteration
+ * of the directory to terminate prematurely.
*/
@Override
- public FileVisitResult postVisitDirectory(T dir, IOException exc) {
- checkNotNull(dir);
+ public FileVisitResult postVisitDirectory(T dir, IOException exc)
+ throws IOException
+ {
+ Objects.nonNull(dir);
if (exc != null)
- throw new IOError(exc);
+ throw exc;
return FileVisitResult.CONTINUE;
}
}
--- a/jdk/src/share/sample/nio/file/Chmod.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/src/share/sample/nio/file/Chmod.java Sun Oct 03 19:39:25 2010 +0100
@@ -285,18 +285,12 @@
}
@Override
- public FileVisitResult preVisitDirectory(FileRef dir) {
+ public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
chmod(dir, changer);
return CONTINUE;
}
@Override
- public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
- System.err.println("WARNING: " + exc);
- return CONTINUE;
- }
-
- @Override
public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
chmod(file, changer);
return CONTINUE;
--- a/jdk/src/share/sample/nio/file/Copy.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/src/share/sample/nio/file/Copy.java Sun Oct 03 19:39:25 2010 +0100
@@ -85,7 +85,7 @@
}
@Override
- public FileVisitResult preVisitDirectory(Path dir) {
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
// before visiting entries in a directory we copy the directory
// (okay if directory already exists).
CopyOption[] options = (preserve) ?
@@ -104,19 +104,9 @@
}
@Override
- public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
- System.err.format("Unable to copy: %s: %s%n", dir, exc);
- return CONTINUE;
- }
-
- @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- if (attrs.isDirectory()) {
- System.err.println("cycle detected: " + file);
- } else {
- copyFile(file, target.resolve(source.relativize(file)),
- prompt, preserve);
- }
+ copyFile(file, target.resolve(source.relativize(file)),
+ prompt, preserve);
return CONTINUE;
}
@@ -137,7 +127,11 @@
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
- System.err.format("Unable to copy: %s: %s%n", file, exc);
+ if (exc instanceof FileSystemLoopException) {
+ System.err.println("cycle detected: " + file);
+ } else {
+ System.err.format("Unable to copy: %s: %s%n", file, exc);
+ }
return CONTINUE;
}
}
--- a/jdk/src/share/sample/nio/file/WatchDir.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/src/share/sample/nio/file/WatchDir.java Sun Oct 03 19:39:25 2010 +0100
@@ -78,12 +78,10 @@
// register directory and sub-directories
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
- public FileVisitResult preVisitDirectory(Path dir) {
- try {
- register(dir);
- } catch (IOException x) {
- throw new IOError(x);
- }
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ throws IOException
+ {
+ register(dir);
return FileVisitResult.CONTINUE;
}
});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/MaxDepth.java Sun Oct 03 19:39:25 2010 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test maxDepth parameter
+ */
+
+public class MaxDepth {
+ public static void main(String[] args) throws Exception {
+ final Path top = Paths.get(args[0]);
+
+ for (int i=0; i<5; i++) {
+ Set<FileVisitOption> opts = Collections.emptySet();
+ final int maxDepth = i;
+ Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
+ // compute depth based on relative path to top directory
+ private int depth(Path file) {
+ Path rp = file.relativize(top);
+ return (rp == null) ? 0 : rp.getNameCount();
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ int d = depth(dir);
+ if (d == maxDepth)
+ throw new RuntimeException("Should not open directories at maxDepth");
+ if (d > maxDepth)
+ throw new RuntimeException("Too deep");
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ int d = depth(file);
+ if (d > maxDepth)
+ throw new RuntimeException("Too deep");
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/Misc.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/test/java/nio/file/Files/Misc.java Sun Oct 03 19:39:25 2010 +0100
@@ -30,6 +30,7 @@
import java.nio.file.*;
import java.nio.file.attribute.Attributes;
+import java.nio.file.attribute.BasicFileAttributes;
import java.io.IOException;
import java.util.*;
@@ -117,25 +118,25 @@
SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
boolean ranTheGauntlet = false;
- try { visitor.preVisitDirectory(null);
+ BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get("."));
+
+ try { visitor.preVisitDirectory(null, attrs);
} catch (NullPointerException x0) {
- try { visitor.preVisitDirectoryFailed(null, new IOException());
+ try { visitor.preVisitDirectory(dir, null);
} catch (NullPointerException x1) {
- try { visitor.preVisitDirectoryFailed(dir, null);
+ try { visitor.visitFile(null, attrs);
} catch (NullPointerException x2) {
- try { visitor.visitFile(null, Attributes.readBasicFileAttributes(Paths.get(".")));
+ try { visitor.visitFile(dir, null);
} catch (NullPointerException x3) {
- try { visitor.visitFile(dir, null);
+ try { visitor.visitFileFailed(null, new IOException());
} catch (NullPointerException x4) {
- try { visitor.visitFileFailed(null, new IOException());
+ try { visitor.visitFileFailed(dir, null);
} catch (NullPointerException x5) {
- try { visitor.visitFileFailed(dir, null);
+ try { visitor.postVisitDirectory(null, new IOException());
} catch (NullPointerException x6) {
- try { visitor.postVisitDirectory(null, new IOException());
- } catch (NullPointerException x7) {
// if we get here then all visit* methods threw NPE as expected
ranTheGauntlet = true;
- }}}}}}}}
+ }}}}}}}
if (!ranTheGauntlet)
throw new RuntimeException("A visit method did not throw NPE");
}
--- a/jdk/test/java/nio/file/Files/PrintFileTree.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/test/java/nio/file/Files/PrintFileTree.java Sun Oct 03 19:39:25 2010 +0100
@@ -56,29 +56,34 @@
final boolean reportCycles = printCycles;
Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
- public FileVisitResult preVisitDirectory(FileRef dir) {
+ @Override
+ public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
System.out.println(dir);
return FileVisitResult.CONTINUE;
}
- public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
- exc.printStackTrace();
- return FileVisitResult.CONTINUE;
- }
+ @Override
public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
if (!attrs.isDirectory() || reportCycles)
System.out.println(file);
return FileVisitResult.CONTINUE;
}
- public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
- if (exc != null) {
- exc.printStackTrace();
- return FileVisitResult.TERMINATE;
- }
+ @Override
+ public FileVisitResult postVisitDirectory(FileRef dir, IOException exc)
+ throws IOException
+ {
+ if (exc != null)
+ throw exc;
return FileVisitResult.CONTINUE;
}
- public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
- exc.printStackTrace();
- return FileVisitResult.TERMINATE;
+ @Override
+ public FileVisitResult visitFileFailed(FileRef file, IOException exc)
+ throws IOException
+ {
+ if (reportCycles && (exc instanceof FileSystemLoopException)) {
+ System.out.println(file);
+ return FileVisitResult.CONTINUE;
+ }
+ throw exc;
}
});
}
--- a/jdk/test/java/nio/file/Files/SkipSiblings.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/test/java/nio/file/Files/SkipSiblings.java Sun Oct 03 19:39:25 2010 +0100
@@ -54,32 +54,28 @@
public static void main(String[] args) throws Exception {
Path dir = Paths.get(args[0]);
- Files.walkFileTree(dir, new FileVisitor<Path>() {
- public FileVisitResult preVisitDirectory(Path dir) {
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
check(dir);
if (skip(dir))
return FileVisitResult.SKIP_SIBLINGS;
return FileVisitResult.CONTINUE;
}
- public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
- throw new RuntimeException(exc);
- }
-
+ @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
check(file);
if (skip(file))
return FileVisitResult.SKIP_SIBLINGS;
return FileVisitResult.CONTINUE;
}
+ @Override
public FileVisitResult postVisitDirectory(Path dir, IOException x) {
if (x != null)
throw new RuntimeException(x);
check(dir);
return FileVisitResult.CONTINUE;
}
- public FileVisitResult visitFileFailed(Path file, IOException x) {
- throw new RuntimeException(x);
- }
});
}
}
--- a/jdk/test/java/nio/file/Files/TerminateWalk.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/test/java/nio/file/Files/TerminateWalk.java Sun Oct 03 19:39:25 2010 +0100
@@ -49,22 +49,19 @@
public static void main(String[] args) throws Exception {
Path dir = Paths.get(args[0]);
- Files.walkFileTree(dir, new FileVisitor<Path>() {
- public FileVisitResult preVisitDirectory(Path dir) {
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
return maybeTerminate();
}
- public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
- return maybeTerminate();
- }
+ @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
return maybeTerminate();
}
+ @Override
public FileVisitResult postVisitDirectory(Path dir, IOException x) {
return maybeTerminate();
}
- public FileVisitResult visitFileFailed(Path file, IOException x) {
- return maybeTerminate();
- }
});
}
}
--- a/jdk/test/java/nio/file/Files/WalkWithSecurity.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/test/java/nio/file/Files/WalkWithSecurity.java Sun Oct 03 19:39:25 2010 +0100
@@ -116,7 +116,7 @@
}
@Override
- public FileVisitResult preVisitDirectory(Path dir) {
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
System.out.println(dir);
count++;
return FileVisitResult.CONTINUE;
--- a/jdk/test/java/nio/file/Files/walk_file_tree.sh Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/test/java/nio/file/Files/walk_file_tree.sh Sun Oct 03 19:39:25 2010 +0100
@@ -22,9 +22,9 @@
#
# @test
-# @bug 4313887
+# @bug 4313887 6907737
# @summary Unit test for walkFileTree method
-# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk
+# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
# @run shell walk_file_tree.sh
# if TESTJAVA isn't set then we assume an interactive run.
@@ -84,6 +84,10 @@
$JAVA TerminateWalk "$ROOT"
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+# test maxDepth
+$JAVA MaxDepth "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
# clean-up
rm -r "$ROOT"
--- a/jdk/test/java/nio/file/TestUtil.java Sat Oct 02 12:59:52 2010 +0100
+++ b/jdk/test/java/nio/file/TestUtil.java Sun Oct 03 19:39:25 2010 +0100
@@ -44,15 +44,10 @@
return createTemporaryDirectory(System.getProperty("java.io.tmpdir"));
}
- static void removeAll(Path dir) {
+ static void removeAll(Path dir) throws IOException {
Files.walkFileTree(dir, new FileVisitor<Path>() {
@Override
- public FileVisitResult preVisitDirectory(Path dir) {
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
- System.err.format("Error occured accessing directory %s\n", dir, exc);
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
return FileVisitResult.CONTINUE;
}
@Override