changeset 821:a7d137d96cf5

Replace followLinks with LinkOption
author alanb
date Fri, 14 Nov 2008 11:00:20 +0000
parents 81d186c34e54
children 2ac3e64920d5
files src/share/classes/java/nio/file/FileRef.java src/share/classes/java/nio/file/FileTreeWalker.java src/share/classes/java/nio/file/LinkOption.java src/share/classes/java/nio/file/Path.java src/share/classes/java/nio/file/SecureDirectoryStream.java src/share/classes/java/nio/file/StandardCopyOption.java src/share/classes/java/nio/file/StandardOpenOption.java src/share/classes/java/nio/file/attribute/AclFileAttributeView.java src/share/classes/java/nio/file/attribute/Attributes.java src/share/classes/java/nio/file/attribute/BasicFileAttributes.java src/share/classes/java/nio/file/attribute/FileAttributeView.java src/share/classes/java/nio/file/attribute/NamedAttributeView.java src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java src/share/classes/java/nio/file/spi/AbstractPath.java src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java src/share/classes/sun/nio/fs/PollingWatchService.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFilePath.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileStore.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipUtils.java src/share/sample/nio/file/AclEdit.java src/share/sample/nio/file/Chmod.java src/share/sample/nio/file/Copy.java src/share/sample/nio/file/FileType.java src/share/sample/nio/file/WatchDir.java src/share/sample/nio/file/Xdd.java src/solaris/classes/sun/nio/fs/LinuxFileSystem.java src/solaris/classes/sun/nio/fs/SolarisFileSystem.java src/solaris/classes/sun/nio/fs/UnixChannelFactory.java src/solaris/classes/sun/nio/fs/UnixCopyFile.java src/solaris/classes/sun/nio/fs/UnixFileSystem.java src/solaris/classes/sun/nio/fs/UnixPath.java src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java src/windows/classes/sun/nio/fs/WindowsChannelFactory.java src/windows/classes/sun/nio/fs/WindowsFileCopy.java src/windows/classes/sun/nio/fs/WindowsPath.java test/java/nio/file/DirectoryStream/Filters.java test/java/nio/file/DirectoryStream/SecureDS.java test/java/nio/file/Path/CopyAndMove.java test/java/nio/file/Path/Links.java test/java/nio/file/Path/Misc.java test/java/nio/file/Path/SBC.java test/java/nio/file/Path/TemporaryFiles.java test/java/nio/file/attribute/AclFileAttributeView/Basic.java test/java/nio/file/attribute/Attributes/Basic.java test/java/nio/file/attribute/BasicFileAttributeView/Basic.java test/java/nio/file/attribute/DosFileAttributeView/Basic.java test/java/nio/file/attribute/NamedAttributeView/Basic.java test/java/nio/file/attribute/PosixFileAttributeView/Basic.java
diffstat 49 files changed, 412 insertions(+), 312 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/nio/file/FileRef.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/FileRef.java	Fri Nov 14 11:00:20 2008 +0000
@@ -55,10 +55,10 @@
  *
  * <p> Access to associated metadata or file attributes requires an appropriate
  * {@link FileAttributeView FileAttributeView}. The {@link
- * #getFileAttributeView(Class,boolean) getFileAttributeView(Class,boolean)}
+ * #getFileAttributeView(Class,LinkOption[]) getFileAttributeView(Class,LinkOption[])}
  * method may be used to obtain a file attribute view that defines type-safe
  * methods to read or update file attributes. The {@link
- * #getFileAttributeView(String,boolean) getFileAttributeView(String,boolean)}
+ * #getFileAttributeView(String,LinkOption[]) getFileAttributeView(String,LinkOption[])}
  * method may be used to obtain a file attribute view where dynamic access to
  * file attributes where required.
  *
@@ -256,21 +256,29 @@
      * basic attributes of a file. Invoking this method to select a file
      * attribute view of that type will always return an instance of that class.
      *
-     * <p> The {@code followLinks} parameter determines if links should be followed
-     * by the file attribute view. This parameter is ignored by implementations
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled by the resulting file attribute view for the case that the
+     * file is a symbolic link. By default, symbolic links are followed. If the
+     * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
+     * symbolic links are not followed. This option is ignored by implementations
      * that do not support symbolic links.
      *
      * @param   type
      *          The {@code Class} object corresponding to the file attribute view
-     * @param   followLinks
-     *          {@code true} if the links should be followed
+     * @param   options
+     *          Options indicating how symbolic links are handled
      *
      * @return  A file attribute view of the specified type, or {@code null} if
      *          the attribute view type is not available
      *
+     * @throws  UnsupportedOperationException
+     *          If options contains an unsupported option. This exception is
+     *          specified to allow the {@code LinkOption} enum be extended
+     *          in future releases.
+     *
      * @see Attributes#readBasicFileAttributes
      */
-    <V extends FileAttributeView> V getFileAttributeView(Class<V> type, boolean followLinks);
+    <V extends FileAttributeView> V getFileAttributeView(Class<V> type, LinkOption... options);
 
     /**
      * Returns a file attribute view of the given name.
@@ -285,19 +293,27 @@
      * method to select a file attribute view named {@code "basic"} will always
      * return an instance of that class.
      *
-     * <p> The {@code followLinks} parameter determines if links should be followed
-     * by the file attribute view. This parameter is ignored by implementations
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled by the resulting file attribute view for the case that the
+     * file is a symbolic link. By default, symbolic links are followed. If the
+     * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
+     * symbolic links are not followed. This option is ignored by implementations
      * that do not support symbolic links.
      *
      * @param   name
      *          The name of the file attribute view
-     * @param   followLinks
-     *          {@code true} if the links should be followed
+     * @param   options
+     *          Options indicating how symbolic links are handled
      *
      * @return  A file attribute view of the given name, or {@code null} if
      *          the attribute view is not available
+     *
+     * @throws  UnsupportedOperationException
+     *          If options contains an unsupported option. This exception is
+     *          specified to allow the {@code LinkOption} enum be extended
+     *          in future releases.
      */
-    FileAttributeView getFileAttributeView(String name, boolean followLinks);
+    FileAttributeView getFileAttributeView(String name, LinkOption... options);
 
     /**
      * Tests if the file referenced by this object is the same file referenced
--- a/src/share/classes/java/nio/file/FileTreeWalker.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/FileTreeWalker.java	Fri Nov 14 11:00:20 2008 +0000
@@ -38,6 +38,7 @@
 class FileTreeWalker {
     private final boolean followLinks;
     private final boolean detectCycles;
+    private final LinkOption[] linkOptions;
     private final FileVisitor<? super Path> visitor;
 
     FileTreeWalker(Set<FileVisitOption> options, FileVisitor<? super Path> visitor) {
@@ -55,6 +56,8 @@
         }
         this.followLinks = fl;
         this.detectCycles = fl | dc;
+        this.linkOptions = (fl) ? new LinkOption[0] :
+            new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
         this.visitor = visitor;
     }
 
@@ -95,11 +98,12 @@
         // links then a link target might not exist so get attributes of link
         try {
             try {
-                attrs = Attributes.readBasicFileAttributes(file, followLinks);
+                attrs = Attributes.readBasicFileAttributes(file, linkOptions);
             } catch (IOException x1) {
                 if (followLinks) {
                     try {
-                        attrs = Attributes.readBasicFileAttributes(file, false);
+                        attrs = Attributes
+                            .readBasicFileAttributes(file, LinkOption.NOFOLLOW_LINKS);
                     } catch (IOException x2) {
                         exc = x2;
                     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/nio/file/LinkOption.java	Fri Nov 14 11:00:20 2008 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the options as to how symbolic links are handled.
+ *
+ * @since 1.7
+ */
+
+public enum LinkOption implements OpenOption, CopyOption {
+    /**
+     * Do not follow symbolic links.
+     *
+     * @see FileRef#getFileAttributeView(Class,LinkOption[])
+     * @see Path#copyTo
+     * @see SecureDirectoryStream#newByteChannel
+     */
+    NOFOLLOW_LINKS;
+}
--- a/src/share/classes/java/nio/file/Path.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/Path.java	Fri Nov 14 11:00:20 2008 +0000
@@ -101,8 +101,7 @@
  * Attributes.readBasicFileAttributes} method:
  * <pre>
  *     Path file = ...
- *     boolean followLinks = ...
- *     BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file, followLinks);
+ *     BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
  * </pre>
  *
  * <a name="interop"><h4>Interoperability</h4></a>
@@ -723,7 +722,7 @@
      *     copied to the target file. </td>
      * </tr>
      * <tr>
-     *   <td> {@link StandardCopyOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
+     *   <td> {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
      *   <td> Symbolic-links are not followed. If the file, located by this path,
      *     is a symbolic-link then the link is copied rather than the target of
      *     the link. It is implementation specific if file attributes can be
@@ -971,7 +970,7 @@
      *     DirectoryStream.Filter&lt;Path&gt; filter = new DirectoryStream.Filter&lt;Path&gt;() {
      *         public boolean accept(Path file) {
      *             try {
-     *                 long size = Attributes.readBasicFileAttributes(file, false).size();
+     *                 long size = Attributes.readBasicFileAttributes(file).size();
      *                 return (size > 8192L);
      *             } catch (IOException e) {
      *                 // failed to get size
--- a/src/share/classes/java/nio/file/SecureDirectoryStream.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/SecureDirectoryStream.java	Fri Nov 14 11:00:20 2008 +0000
@@ -126,7 +126,7 @@
      * path. When the parameter is a relative path then the file to open or
      * create is relative to this open directory. In addition to the options
      * defined by the {@code Path.newByteChannel} method, the {@link
-     * StandardOpenOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
+     * LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
      * ensure that this method fails if the file is a symbolic link.
      *
      * <p> The channel, once created, is not dependent upon the directory stream
@@ -310,8 +310,8 @@
      *          The path of the file
      * @param   type
      *          The {@code Class} object corresponding to the file attribute view
-     * @param   followLinks
-     *          {@code true} if links should be followed
+     * @param   options
+     *          Options indicating how symbolic links are handled
      *
      * @return  A new file attribute view of the specified type bound to a
      *          this directory stream, or {@code null} if the attribute view
@@ -320,5 +320,5 @@
      */
     public abstract <V extends FileAttributeView> V getFileAttributeView(Path path,
                                                                          Class<V> type,
-                                                                         boolean followLinks);
+                                                                         LinkOption... options);
 }
--- a/src/share/classes/java/nio/file/StandardCopyOption.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/StandardCopyOption.java	Fri Nov 14 11:00:20 2008 +0000
@@ -25,8 +25,6 @@
 
 package java.nio.file;
 
-import java.nio.file.attribute.*;
-
 /**
  * Defines the standard copy options.
  *
@@ -43,11 +41,6 @@
      */
     COPY_ATTRIBUTES,
     /**
-     * Do not follow links. If the file is a link then the link is copied rather
-     * than the target of the link.
-     */
-    NOFOLLOW_LINKS,
-    /**
      * Move the file as an atomic file system operation.
      */
     ATOMIC_MOVE;
--- a/src/share/classes/java/nio/file/StandardOpenOption.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/StandardOpenOption.java	Fri Nov 14 11:00:20 2008 +0000
@@ -52,15 +52,6 @@
     APPEND,
 
     /**
-     * If the file exists and is a symbolic link then fail (by throwing an
-     * {@link java.io.IOException}). This option may be ignored by
-     * implementations that do not support symbolic links.
-     *
-     * @see SecureDirectoryStream#newByteChannel
-     */
-    NOFOLLOW_LINKS,
-
-    /**
      * If the file already exists and it is opened for {@link #WRITE}
      * access, then its length is truncated to 0. This option is ignored
      * if the file is opened only for {@link #READ} access.
@@ -101,10 +92,10 @@
      * file is open. Consequently, security sensitive applications should take
      * care when using this option.
      *
-     * <p> For security reasons, this option may imply the {@link #NOFOLLOW_LINKS}
-     * option. In other words, if the option is present when opening an existing
-     * file that is a symbolic link then it may fail (by throwing
-     * {@link java.io.IOException}).
+     * <p> For security reasons, this option may imply the {@link
+     * LinkOption#NOFOLLOW_LINKS} option. In other words, if the option is present
+     * when opening an existing file that is a symbolic link then it may fail
+     * (by throwing {@link java.io.IOException}).
      */
     DELETE_ON_CLOSE,
 
--- a/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java	Fri Nov 14 11:00:20 2008 +0000
@@ -75,7 +75,7 @@
  *         .lookupPrincipalByName("joe");
  *
  *     // get view
- *     AclFileAttributeView view = file.newFileAttributeView(AclFileAttributeView.class, true);
+ *     AclFileAttributeView view = file.newFileAttributeView(AclFileAttributeView.class);
  *
  *     // create ACE to give "joe" read access
  *     AclEntry entry = AclEntry.newBuilder()
--- a/src/share/classes/java/nio/file/attribute/Attributes.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/attribute/Attributes.java	Fri Nov 14 11:00:20 2008 +0000
@@ -81,7 +81,7 @@
      * <p> <b>Usage Example:</b>
      * Suppose we want to set the DOS "hidden" attribute:
      * <pre>
-     *    Attributes.setAttribute(file, followLinks, "dos:hidden", true);
+     *    Attributes.setAttribute(file, "dos:hidden", true);
      * </pre>
      *
      * @param   file
@@ -114,7 +114,7 @@
         throws IOException
     {
         String[] s = split(attribute);
-        FileAttributeView view = file.getFileAttributeView(s[0], true);
+        FileAttributeView view = file.getFileAttributeView(s[0]);
         if (view == null)
             throw new UnsupportedOperationException("View '" + s[0] + "' not available");
         view.setAttribute(s[1], value);
@@ -123,12 +123,6 @@
     /**
      * Reads the value of a file attribute.
      *
-     * <p> The {@code followLinks} parameter indicates if symbolic links
-     * should be followed and is only used when the file is a symbolic link.
-     * When the value of the parameter is {@code true}, the file attribute of
-     * the file that is the target of the link is returned; otherwise the
-     * file attribute of the symbolic link is returned.
-     *
      * <p> The {@code attribute} parameter identifies the attribute to be read
      * and takes the form:
      * <blockquote>
@@ -143,19 +137,26 @@
      * attribute view that identifies the basic set of file attributes common to
      * many file systems. <i>attribute-name</i> is the name of the attribute.
      *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
+     * the method returns the file attribute of the symbolic link.
+     *
      * <p> <b>Usage Example:</b>
      * Suppose we require the user ID of the file owner on a system that
      * supports a "{@code unix}" view:
      * <pre>
-     *    int uid = (Integer)Attributes.getAttribute(file, followLinks, "unix:uid");
+     *    int uid = (Integer)Attributes.getAttribute(file, "unix:uid");
      * </pre>
      *
      * @param   file
      *          A file reference that locates the file
-     * @param   followLinks
-     *          {@code true} to follow symbolic links; {@code false} otherwise
      * @param   attribute
      *          The attribute to read
+     * @param   options
+     *          Options indicating how symbolic links are handled
      *
      * @return  The attribute value, or {@code null} if the attribute view
      *          is not available or it does not support reading the attribute
@@ -169,12 +170,13 @@
      *          to read security sensitive attributes then the security manager
      *          may be invoked to check for additional permissions.
      */
-    public static Object getAttribute(FileRef file, boolean followLinks,
-                                      String attribute)
+    public static Object getAttribute(FileRef file,
+                                      String attribute,
+                                      LinkOption... options)
         throws IOException
     {
         String[] s = split(attribute);
-        FileAttributeView view = file.getFileAttributeView(s[0], followLinks);
+        FileAttributeView view = file.getFileAttributeView(s[0], options);
         if (view != null)
             return view.getAttribute(s[1]);
         // view not available
@@ -184,12 +186,6 @@
     /**
      * Reads a set of file attributes as a bulk operation.
      *
-     * <p> The {@code followLinks} parameter indicates if symbolic links
-     * should be followed and is only used when the file is a symbolic link.
-     * When the value of the parameter is {@code true}, the file attributes of
-     * the file that is the target of the link are returned; otherwise the
-     * file attributes of the symbolic link are returned.
-     *
      * <p> The {@code attributes} parameter identifies the attributes to be read
      * and takes the form:
      * <blockquote>
@@ -236,12 +232,19 @@
      * </table>
      * </blockquote>
      *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attributes of the final target
+     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
+     * the method returns the file attributes of the symbolic link.
+     *
      * @param   file
      *          A file reference that locates the file
-     * @param   followLinks
-     *          {@code true} to follow symbolic links; {@code false} otherwise
      * @param   attributes
      *          The attributes to read
+     * @param   options
+     *          Options indicating how symbolic links are handled
      *
      * @return  A map of the attributes returned; may be empty. The map's keys
      *          are the attribute names, its values are the attribute values
@@ -255,12 +258,13 @@
      *          to read security sensitive attributes then the security manager
      *          may be invoke to check for additional permissions.
      */
-    public static Map<String,?> readAttributes(FileRef file, boolean followLinks,
-                                               String attributes)
+    public static Map<String,?> readAttributes(FileRef file,
+                                               String attributes,
+                                               LinkOption... options)
         throws IOException
     {
         String[] s = split(attributes);
-        FileAttributeView view = file.getFileAttributeView(s[0], followLinks);
+        FileAttributeView view = file.getFileAttributeView(s[0], options);
         if (view != null) {
             // further split attributes into the first and rest.
             String[] names = s[1].split(",");
@@ -278,24 +282,25 @@
     /**
      * Reads the basic file attributes of a file.
      *
-     * <p> The {@code followLinks} parameter indicates if symbolic links
-     * should be followed and is only used when the file is a symbolic link.
-     * When the value of the parameter is {@code true}, the file attributes of
-     * the file that is the target of the link are returned; otherwise the
-     * file attributes of the symbolic link are returned. To determine if a file
-     * a symbolic link then invoke this method with the {@code followLinks}
-     * parameter set to {@code false} and use the {@link
-     * BasicFileAttributes#isSymbolicLink isSymbolicLink} method. The {@code
-     * followLinks} is ignored by implementations that do not support symbolic
-     * links.
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attributes of the final target
+     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
+     * the method returns the file attributes of the symbolic link. This option
+     * should be used where there is a need to determine if a file is a
+     * symbolic link:
+     * <pre>
+     *    boolean isSymbolicLink = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS).isSymbolicLink();
+     * </pre>
      *
      * <p> It is implementation specific if all file attributes are read as an
      * atomic operation with respect to other file system operations.
      *
      * @param   file
      *          A file reference that locates the file
-     * @param   followLinks
-     *          {@code true} to follow symbolic links; {@code false} otherwise
+     * @param   options
+     *          Options indicating how symbolic links are handled
      *
      * @return  The basic file attributes
      *
@@ -309,10 +314,10 @@
      * @see BasicFileAttributeView#readAttributes
      */
     public static BasicFileAttributes readBasicFileAttributes(FileRef file,
-                                                              boolean followLinks)
+                                                              LinkOption... options)
         throws IOException
     {
-        return file.getFileAttributeView(BasicFileAttributeView.class, followLinks)
+        return file.getFileAttributeView(BasicFileAttributeView.class, options)
             .readAttributes();
     }
 
@@ -327,16 +332,17 @@
      * specific if all file attributes are read as an atomic operation with
      * respect to other file system operations.
      *
-     * <p> The {@code followLinks} parameter indicates if symbolic links
-     * should be followed and is only used when the file is a symbolic link.
-     * When the value of the parameter is {@code true}, the file attributes of
-     * the file that is the target of the link are returned; otherwise the
-     * file attributes of the symbolic link are returned.
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attributes of the final target
+     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
+     * the method returns the file attributes of the symbolic link.
      *
      * @param   file
      *          A file reference that locates the file
-     * @param   followLinks
-     *          {@code true} to follow symbolic links; {@code false} otherwise
+     * @param   options
+     *          Options indicating how symbolic links are handled
      *
      * @return  The POSIX file attributes
      *
@@ -353,11 +359,11 @@
      * @see PosixFileAttributeView#readAttributes
      */
     public static PosixFileAttributes readPosixFileAttributes(FileRef file,
-                                                              boolean followLinks)
+                                                              LinkOption... options)
         throws IOException
     {
         PosixFileAttributeView view =
-            file.getFileAttributeView(PosixFileAttributeView.class, followLinks);
+            file.getFileAttributeView(PosixFileAttributeView.class, options);
         if (view == null)
             throw new UnsupportedOperationException();
         return view.readAttributes();
@@ -373,16 +379,17 @@
      * implementation specific if all file attributes are read as an atomic
      * operation with respect to other file system operations.
      *
-     * <p> The {@code followLinks} parameter indicates if symbolic links
-     * should be followed and is only used when the file is a symbolic link.
-     * When the value of the parameter is {@code true}, the file attributes of
-     * the file that is the target of the link are returned; otherwise the
-     * file attributes of the symbolic link are returned.
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attributes of the final target
+     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
+     * the method returns the file attributes of the symbolic link.
      *
      * @param   file
      *          A file reference that locates the file
-     * @param   followLinks
-     *          {@code true} to follow symbolic links; {@code false} otherwise
+     * @param   options
+     *          Options indicating how symbolic links are handled
      *
      * @return  The DOS file attributes
      *
@@ -398,11 +405,11 @@
      * @see DosFileAttributeView#readAttributes
      */
     public static DosFileAttributes readDosFileAttributes(FileRef file,
-                                                          boolean followLinks)
+                                                          LinkOption... options)
         throws IOException
     {
         DosFileAttributeView view =
-            file.getFileAttributeView(DosFileAttributeView.class, followLinks);
+            file.getFileAttributeView(DosFileAttributeView.class, options);
         if (view == null)
             throw new UnsupportedOperationException();
         return view.readAttributes();
@@ -434,7 +441,7 @@
      */
     public static UserPrincipal getOwner(FileRef file) throws IOException {
         FileOwnerAttributeView view =
-            file.getFileAttributeView(FileOwnerAttributeView.class, true);
+            file.getFileAttributeView(FileOwnerAttributeView.class);
         if (view == null)
             throw new UnsupportedOperationException();
         return view.getOwner();
@@ -468,7 +475,7 @@
             throws IOException
     {
         FileOwnerAttributeView view =
-            file.getFileAttributeView(FileOwnerAttributeView.class, true);
+            file.getFileAttributeView(FileOwnerAttributeView.class);
         if (view == null)
             throw new UnsupportedOperationException();
         view.setOwner(owner);
@@ -502,7 +509,7 @@
      */
     public static List<AclEntry> getAcl(FileRef file) throws IOException {
         AclFileAttributeView view =
-            file.getFileAttributeView(AclFileAttributeView.class, true);
+            file.getFileAttributeView(AclFileAttributeView.class);
         if (view == null)
             throw new UnsupportedOperationException();
         return view.getAcl();
@@ -537,7 +544,7 @@
         throws IOException
     {
         AclFileAttributeView view =
-            file.getFileAttributeView(AclFileAttributeView.class, true);
+            file.getFileAttributeView(AclFileAttributeView.class);
         if (view == null)
             throw new UnsupportedOperationException();
         view.setAcl(acl);
@@ -581,7 +588,7 @@
                                            TimeUnit unit)
         throws IOException
     {
-        file.getFileAttributeView(BasicFileAttributeView.class, true)
+        file.getFileAttributeView(BasicFileAttributeView.class)
             .setTimes(lastModifiedTime, null, null, unit);
     }
 
@@ -620,7 +627,7 @@
                                          TimeUnit unit)
         throws IOException
     {
-        file.getFileAttributeView(BasicFileAttributeView.class, true)
+        file.getFileAttributeView(BasicFileAttributeView.class)
             .setTimes(null, lastAccessTime, null, unit);
     }
 
@@ -658,7 +665,7 @@
         throws IOException
     {
         PosixFileAttributeView view =
-            file.getFileAttributeView(PosixFileAttributeView.class, true);
+            file.getFileAttributeView(PosixFileAttributeView.class);
         if (view == null)
             throw new UnsupportedOperationException();
         view.setPermissions(perms);
--- a/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java	Fri Nov 14 11:00:20 2008 +0000
@@ -37,7 +37,7 @@
  * <p> <b>Usage Example:</b>
  * <pre>
  *    FileRef file = ...
- *    BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file, true);
+ *    BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
  * </pre>
  *
  * @since 1.7
--- a/src/share/classes/java/nio/file/attribute/FileAttributeView.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/attribute/FileAttributeView.java	Fri Nov 14 11:00:20 2008 +0000
@@ -33,8 +33,8 @@
  *
  * @since 1.7
  *
- * @see java.nio.file.FileRef#getFileAttributeView(Class,boolean)
- * @see java.nio.file.FileRef#getFileAttributeView(String,boolean)
+ * @see java.nio.file.FileRef#getFileAttributeView(Class,java.nio.file.LinkOption[])
+ * @see java.nio.file.FileRef#getFileAttributeView(String,java.nio.file.LinkOption[])
  */
 
 public interface FileAttributeView
--- a/src/share/classes/java/nio/file/attribute/NamedAttributeView.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/attribute/NamedAttributeView.java	Fri Nov 14 11:00:20 2008 +0000
@@ -139,7 +139,7 @@
      * Suppose we want to read a file's MIME type that is stored as a named
      * attribute:
      * <pre>
-     *    NamedAttributeView view = file.getFileAttributeView(NamedAttributeView.class, true);
+     *    NamedAttributeView view = file.getFileAttributeView(NamedAttributeView.class);
      *    String name = "user.mimetype";
      *    ByteBuffer buf = ByteBuffer.allocate(view.size(name));
      *    view.read(name, buf);
@@ -195,7 +195,7 @@
      * <p> <b>Usage Example:</b>
      * Suppose we want to write a file's MIME type as a named attribute:
      * <pre>
-     *    NamedAttributeView view = file.getFileAttributeView(NamedAttributeView.class, true);
+     *    NamedAttributeView view = file.getFileAttributeView(NamedAttributeView.class);
      *    view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
      * </pre>
      *
--- a/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java	Fri Nov 14 11:00:20 2008 +0000
@@ -61,7 +61,7 @@
  * Suppose we need to print out the owner and access permissions of a file:
  * <pre>
  *     FileRef file = ...
- *     PosixFileAttributes attrs = file.newFileAttributeView(PosixFileAttributeView.class, true)
+ *     PosixFileAttributes attrs = file.newFileAttributeView(PosixFileAttributeView.class)
  *         .readAttributes();
  *     System.out.format("%s %s%n",
  *         atts.owner().getName(),
--- a/src/share/classes/java/nio/file/spi/AbstractPath.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/java/nio/file/spi/AbstractPath.java	Fri Nov 14 11:00:20 2008 +0000
@@ -396,7 +396,7 @@
             }
             newOptions[i] = option;
         }
-        newOptions[len] = StandardCopyOption.NOFOLLOW_LINKS;
+        newOptions[len] = LinkOption.NOFOLLOW_LINKS;
         newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
         return newOptions;
     }
@@ -406,8 +406,8 @@
      */
     private static class CopyOptions {
         boolean replaceExisting = false;
+        boolean copyAttributes = false;
         boolean followLinks = true;
-        boolean copyAttributes = false;
 
         private CopyOptions() { }
 
@@ -418,7 +418,7 @@
                     result.replaceExisting = true;
                     continue;
                 }
-                if (option == StandardCopyOption.NOFOLLOW_LINKS) {
+                if (option == LinkOption.NOFOLLOW_LINKS) {
                     result.followLinks = false;
                     continue;
                 }
@@ -442,10 +442,12 @@
         throws IOException
     {
         CopyOptions opts = CopyOptions.parse(options);
+        LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
+            new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
 
         // attributes of source file
         BasicFileAttributes attrs = Attributes
-            .readBasicFileAttributes(this, opts.followLinks);
+            .readBasicFileAttributes(this, linkOptions);
         if (attrs.isSymbolicLink())
             throw new IOException("Copying of symbolic links not supported");
 
@@ -464,7 +466,7 @@
         // copy basic attributes to target
         if (opts.copyAttributes) {
             BasicFileAttributeView view = target
-                .getFileAttributeView(BasicFileAttributeView.class, opts.followLinks);
+                .getFileAttributeView(BasicFileAttributeView.class, linkOptions);
             try {
                 view.setTimes(attrs.lastModifiedTime(),
                               attrs.lastAccessTime(),
--- a/src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java	Fri Nov 14 11:00:20 2008 +0000
@@ -114,6 +114,6 @@
             result.put(USABLE_SPACE_NAME, attrs.usableSpace());
         if (unallocated)
             result.put(UNALLOCATED_SPACE_NAME, attrs.unallocatedSpace());
-        return result;
+        return Collections.unmodifiableMap(result);
     }
 }
--- a/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java	Fri Nov 14 11:00:20 2008 +0000
@@ -27,7 +27,6 @@
 
 import java.nio.file.FileRef;
 import java.nio.file.spi.FileTypeDetector;
-//import java.nio.file.spi.FileTypeDetector.Result;
 import java.io.IOException;
 import sun.nio.fs.MimeType;
 
--- a/src/share/classes/sun/nio/fs/PollingWatchService.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/classes/sun/nio/fs/PollingWatchService.java	Fri Nov 14 11:00:20 2008 +0000
@@ -152,7 +152,7 @@
         throws IOException
     {
         // check file is a directory and get its file key if possible
-        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path, true);
+        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
         if (!attrs.isDirectory()) {
             throw new NotDirectoryException(path.toString());
         }
@@ -296,7 +296,7 @@
                 for (Path entry: stream) {
                     // don't follow links
                     long lastModified = Attributes
-                        .readBasicFileAttributes(entry, false)
+                        .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
                         .lastModifiedTime();
                     entries.put(entry.getName(),
                                 new CacheEntry(lastModified, tickCount));
@@ -370,7 +370,7 @@
                     long lastModified = 0L;
                     try {
                         lastModified = Attributes
-                            .readBasicFileAttributes(entry, false)
+                            .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
                             .lastModifiedTime();
                     } catch (IOException x) {
                         // unable to get attributes of entry. If file has just
--- a/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFilePath.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFilePath.java	Fri Nov 14 11:00:20 2008 +0000
@@ -134,7 +134,8 @@
             begin();
             try {
                 ZipFilePath resolved = getResolvedPathForZip();
-                return Attributes.readBasicFileAttributes(resolved, false).isDirectory();
+                return Attributes.readBasicFileAttributes(resolved, LinkOption.NOFOLLOW_LINKS)
+                    .isDirectory();
             } catch (IOException e) {
                 return false;
             }
@@ -778,7 +779,7 @@
 
     @Override
     @SuppressWarnings("unchecked")
-    public <V extends FileAttributeView> V getFileAttributeView(Class<V> type, boolean followLinks) {
+    public <V extends FileAttributeView> V getFileAttributeView(Class<V> type, LinkOption... options) {
         if (type == null)
             throw new NullPointerException();
         if (type == BasicFileAttributeView.class)
@@ -791,7 +792,7 @@
     }
 
     @Override
-    public FileAttributeView getFileAttributeView(String name, boolean followLinks) {
+    public FileAttributeView getFileAttributeView(String name, LinkOption... options) {
         if (name.equals("basic"))
             return new ZipFileBasicAttributeView(this);
         if (name.equals("zip"))
--- a/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileStore.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileStore.java	Fri Nov 14 11:00:20 2008 +0000
@@ -204,7 +204,7 @@
             // get the size of the zip file
             String file = fileStore.name();
             Path path = FileSystems.getDefault().getPath(file);
-            final long size = Attributes.readBasicFileAttributes(path, true).size();
+            final long size = Attributes.readBasicFileAttributes(path).size();
             return new FileStoreSpaceAttributes() {
 
                 public long totalSpace() {
--- a/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipUtils.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipUtils.java	Fri Nov 14 11:00:20 2008 +0000
@@ -358,7 +358,7 @@
             if (zfp.getNameCount() == 0) { //zfp.equals(zfp.getRoot())
                 Path p = Paths.get(zfp.getFileSystem().getZipFileSystemFile());
                 try {
-                    long time = java.nio.file.attribute.Attributes.readBasicFileAttributes(p, false).lastModifiedTime();
+                    long time = java.nio.file.attribute.Attributes.readBasicFileAttributes(p).lastModifiedTime();
                     zei.lastModifiedTime = javaTimeToDosTime(time);
                 } catch (IOException e) {
                     throw e;
--- a/src/share/sample/nio/file/AclEdit.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/sample/nio/file/AclEdit.java	Fri Nov 14 11:00:20 2008 +0000
@@ -239,7 +239,7 @@
 
         // read file's ACL
         AclFileAttributeView view =
-            file.getFileAttributeView(AclFileAttributeView.class, true);
+            file.getFileAttributeView(AclFileAttributeView.class);
         if (view == null) {
             System.err.println("ACLs not supported on this platform");
             System.exit(-1);
--- a/src/share/sample/nio/file/Chmod.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/sample/nio/file/Chmod.java	Fri Nov 14 11:00:20 2008 +0000
@@ -94,19 +94,6 @@
      * </tr>
      * </table>
      *
-     * <p> <b>Usage Example:</b>
-     * Suppose we require to change the permissions of files in a directory so
-     * that the others read, write, and execute permissions are removed.
-     * <pre>
-     *   PosixFilePermission.Changer changer = PosixFilePermissions.compile("o=");
-     *   DirectoryStream stream = ...
-     *   for (DirectoryEntry entry: stream) {
-     *       Set&lt;PosixFilePermission&gt; perms = Attributes
-     *           readPosixFileAttributes(entry, true).permissions();
-     *       Attributes.setPosixFilePermissions(entry, changer.change(perms));
-     *   }
-     * </pre>
-     *
      * @param   exprs
      *          List of one or more <em>symbolic mode expressions</em>
      *
@@ -280,7 +267,7 @@
     static void chmod(FileRef file, Changer changer) {
         try {
             Set<PosixFilePermission> perms = Attributes
-                .readPosixFileAttributes(file, true).permissions();
+                .readPosixFileAttributes(file).permissions();
             Attributes.setPosixFilePermissions(file, changer.change(perms));
         } catch (IOException x) {
             System.err.println(x);
--- a/src/share/sample/nio/file/Copy.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/sample/nio/file/Copy.java	Fri Nov 14 11:00:20 2008 +0000
@@ -125,7 +125,7 @@
             // fix up modification time of directory when done
             if (exc == null && preserve) {
                 try {
-                    BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir, true);
+                    BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
                     Path newdir = target.resolve(source.relativize(dir));
                     Attributes.setLastModifiedTime(newdir,
                         attrs.lastModifiedTime(), attrs.resolution());
@@ -189,7 +189,7 @@
         // check if target is a directory
         boolean isDir = false;
         try {
-            isDir = Attributes.readBasicFileAttributes(target, true).isDirectory();
+            isDir = Attributes.readBasicFileAttributes(target).isDirectory();
         } catch (IOException x) {
         }
 
@@ -205,7 +205,7 @@
             } else {
                 // not recursive so source must not be a directory
                 try {
-                    if (Attributes.readBasicFileAttributes(source[i], true).isDirectory()) {
+                    if (Attributes.readBasicFileAttributes(source[i]).isDirectory()) {
                         System.err.format("%s: is a directory%n", source[i]);
                         continue;
                     }
--- a/src/share/sample/nio/file/FileType.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/sample/nio/file/FileType.java	Fri Nov 14 11:00:20 2008 +0000
@@ -41,7 +41,7 @@
         }
         for (String arg: args) {
             Path file = Paths.get(arg);
-            BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file, true);
+            BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
 
             String type;
             if (attrs.isDirectory()) {
--- a/src/share/sample/nio/file/WatchDir.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/sample/nio/file/WatchDir.java	Fri Nov 14 11:00:20 2008 +0000
@@ -30,10 +30,11 @@
  */
 
 import java.nio.file.*;
+import static java.nio.file.StandardWatchEventKind.*;
+import static java.nio.file.LinkOption.*;
 import java.nio.file.attribute.*;
 import java.io.*;
 import java.util.*;
-import static java.nio.file.StandardWatchEventKind.*;
 
 /**
  * Example to watch a directory (or tree) for changes to files.
@@ -142,7 +143,7 @@
                 // register it and its sub-directories
                 if (recursive && (kind == ENTRY_CREATE)) {
                     try {
-                        if (Attributes.readBasicFileAttributes(child, false).isDirectory()) {
+                        if (Attributes.readBasicFileAttributes(child, NOFOLLOW_LINKS).isDirectory()) {
                             registerAll(child);
                         }
                     } catch (IOException x) {
--- a/src/share/sample/nio/file/Xdd.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/share/sample/nio/file/Xdd.java	Fri Nov 14 11:00:20 2008 +0000
@@ -65,7 +65,7 @@
 
         }
         NamedAttributeView view = file.
-            getFileAttributeView(NamedAttributeView.class, true);
+            getFileAttributeView(NamedAttributeView.class);
 
 
         // list named attributes
--- a/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java	Fri Nov 14 11:00:20 2008 +0000
@@ -82,22 +82,28 @@
 
     @Override
     @SuppressWarnings("unchecked")
-    public <V extends FileAttributeView> V newFileAttributeView(Class<V> view, UnixPath file, boolean followLinks) {
+    public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
+                                                                UnixPath file,
+                                                                LinkOption... options)
+    {
         if (view == DosFileAttributeView.class)
-            return (V) new LinuxDosFileAttributeView(file, followLinks);
+            return (V) new LinuxDosFileAttributeView(file, followLinks(options));
         if (view == NamedAttributeView.class)
-            return (V) new LinuxNamedAttributeView(file, followLinks);
-        return super.newFileAttributeView(view, file, followLinks);
+            return (V) new LinuxNamedAttributeView(file, followLinks(options));
+        return super.newFileAttributeView(view, file, options);
     }
 
     @Override
     @SuppressWarnings("unchecked")
-    public FileAttributeView newFileAttributeView(String name, UnixPath file, boolean followLinks) {
+    public FileAttributeView newFileAttributeView(String name,
+                                                  UnixPath file,
+                                                  LinkOption... options)
+    {
         if (name.equals("dos"))
-            return new LinuxDosFileAttributeView(file, followLinks);
+            return new LinuxDosFileAttributeView(file, followLinks(options));
         if (name.equals("xattr"))
-            return new LinuxNamedAttributeView(file, followLinks);
-        return super.newFileAttributeView(name, file, followLinks);
+            return new LinuxNamedAttributeView(file, followLinks(options));
+        return super.newFileAttributeView(name, file, options);
     }
 
     // lazy initialization of the list of supported attribute views
--- a/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Fri Nov 14 11:00:20 2008 +0000
@@ -87,22 +87,27 @@
 
     @Override
     @SuppressWarnings("unchecked")
-    public <V extends FileAttributeView> V newFileAttributeView(Class<V> view, UnixPath file, boolean followLinks) {
+    public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
+                                                                UnixPath file, LinkOption... options)
+    {
         if (view == AclFileAttributeView.class)
-            return (V) new SolarisAclFileAttributeView(file, followLinks);
+            return (V) new SolarisAclFileAttributeView(file, followLinks(options));
         if (view == NamedAttributeView.class) {
-            return(V) new SolarisNamedAttributeView(file, followLinks);
+            return(V) new SolarisNamedAttributeView(file, followLinks(options));
         }
-        return super.newFileAttributeView(view, file, followLinks);
+        return super.newFileAttributeView(view, file, options);
     }
 
     @Override
-    protected FileAttributeView newFileAttributeView(String name, UnixPath file, boolean followLinks) {
+    protected FileAttributeView newFileAttributeView(String name,
+                                                     UnixPath file,
+                                                     LinkOption... options)
+    {
         if (name.equals("acl"))
-            return new SolarisAclFileAttributeView(file, followLinks);
+            return new SolarisAclFileAttributeView(file, followLinks(options));
         if (name.equals("xattr"))
-            return new SolarisNamedAttributeView(file, followLinks);
-        return super.newFileAttributeView(name, file, followLinks);
+            return new SolarisNamedAttributeView(file, followLinks(options));
+        return super.newFileAttributeView(name, file, options);
     }
 
     // lazy initialization of the list of supported attribute views
--- a/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java	Fri Nov 14 11:00:20 2008 +0000
@@ -69,6 +69,10 @@
             Flags flags = new Flags();
             for (OpenOption option: options) {
                 if (!(option instanceof StandardOpenOption)) {
+                    if (option == LinkOption.NOFOLLOW_LINKS) {
+                        flags.noFollowLinks = true;
+                        continue;
+                    }
                     if (option == null)
                         throw new NullPointerException();
                     throw new UnsupportedOperationException("Unsupported open option");
@@ -77,7 +81,6 @@
                     case READ : flags.read = true; break;
                     case WRITE : flags.write = true; break;
                     case APPEND : flags.append = true; break;
-                    case NOFOLLOW_LINKS: flags.noFollowLinks = true; break;
                     case TRUNCATE_EXISTING : flags.truncateExisting = true; break;
                     case CREATE : flags.create = true; break;
                     case CREATE_NEW : flags.createNew = true; break;
--- a/src/solaris/classes/sun/nio/fs/UnixCopyFile.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/solaris/classes/sun/nio/fs/UnixCopyFile.java	Fri Nov 14 11:00:20 2008 +0000
@@ -68,7 +68,7 @@
                     flags.replaceExisting = true;
                     continue;
                 }
-                if (option == StandardCopyOption.NOFOLLOW_LINKS) {
+                if (option == LinkOption.NOFOLLOW_LINKS) {
                     flags.followLinks = false;
                     continue;
                 }
@@ -103,6 +103,10 @@
                     flags.replaceExisting = true;
                     continue;
                 }
+                if (option == LinkOption.NOFOLLOW_LINKS) {
+                    // ignore
+                    continue;
+                }
                 if (option == null)
                     throw new NullPointerException();
                 throw new UnsupportedOperationException("Unsupported copy option");
--- a/src/solaris/classes/sun/nio/fs/UnixFileSystem.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/solaris/classes/sun/nio/fs/UnixFileSystem.java	Fri Nov 14 11:00:20 2008 +0000
@@ -288,13 +288,26 @@
     private static final String GLOB_SYNTAX = "glob";
     private static final String REGEX_SYNTAX = "regex";
 
+    protected boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption option: options) {
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            throw new AssertionError("Should not get here");
+        }
+        return followLinks;
+    }
+
     @SuppressWarnings("unchecked")
     protected <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
                                                                    UnixPath file,
-                                                                   boolean followLinks)
+                                                                   LinkOption... options)
     {
         if (view == null)
             throw new NullPointerException();
+        boolean followLinks = followLinks(options);
         Class<?> c = view;
         if (c == BasicFileAttributeView.class)
             return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
@@ -311,8 +324,9 @@
 
     protected FileAttributeView newFileAttributeView(String name,
                                                      UnixPath file,
-                                                     boolean followLinks)
+                                                     LinkOption... options)
     {
+        boolean followLinks = followLinks(options);
         if (name.equals("basic"))
             return UnixFileAttributeViews.createBasicView(file, followLinks);
         if (name.equals("posix"))
--- a/src/solaris/classes/sun/nio/fs/UnixPath.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/solaris/classes/sun/nio/fs/UnixPath.java	Fri Nov 14 11:00:20 2008 +0000
@@ -895,19 +895,18 @@
     @Override
     @SuppressWarnings("unchecked")
     public <V extends FileAttributeView> V
-        getFileAttributeView(Class<V> type, boolean followLinks)
+        getFileAttributeView(Class<V> type, LinkOption... options)
     {
         FileAttributeView view = getFileSystem()
-            .newFileAttributeView(type, this, followLinks);
+            .newFileAttributeView(type, this, options);
         if (view == null)
             return null;
         return (V) view;
     }
 
     @Override
-    public FileAttributeView getFileAttributeView(String name, boolean followLinks)
-    {
-        return getFileSystem().newFileAttributeView(name, this, followLinks);
+    public FileAttributeView getFileAttributeView(String name, LinkOption... options) {
+        return getFileSystem().newFileAttributeView(name, this, options);
     }
 
     @Override
--- a/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java	Fri Nov 14 11:00:20 2008 +0000
@@ -299,9 +299,10 @@
     @Override
     public <V extends FileAttributeView> V getFileAttributeView(Path obj,
                                                                 Class<V> type,
-                                                                boolean followLinks)
+                                                                LinkOption... options)
     {
         UnixPath file = getName(obj);
+        boolean followLinks = file.getFileSystem().followLinks(options);
         return getFileAttributeViewImpl(file, type, followLinks);
     }
 
--- a/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java	Fri Nov 14 11:00:20 2008 +0000
@@ -251,11 +251,11 @@
         // NOFOLLOW_LINKS and NOFOLLOW_REPARSEPOINT mean open reparse point
         boolean okayToFollowLinks = true;
         if (dwCreationDisposition != CREATE_NEW &&
-            (options.contains(StandardOpenOption.NOFOLLOW_LINKS) ||
+            (options.contains(LinkOption.NOFOLLOW_LINKS) ||
              options.contains(NOFOLLOW_REPARSEPOINT) ||
              deleteOnClose))
         {
-            if (options.contains(StandardOpenOption.NOFOLLOW_LINKS))
+            if (options.contains(LinkOption.NOFOLLOW_LINKS))
                 okayToFollowLinks = false;
             dwFlagsAndAttributes |= FILE_FLAG_OPEN_REPARSE_POINT;
         }
--- a/src/windows/classes/sun/nio/fs/WindowsFileCopy.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/windows/classes/sun/nio/fs/WindowsFileCopy.java	Fri Nov 14 11:00:20 2008 +0000
@@ -59,7 +59,7 @@
                 replaceExisting = true;
                 continue;
             }
-            if (option == StandardCopyOption.NOFOLLOW_LINKS) {
+            if (option == LinkOption.NOFOLLOW_LINKS) {
                 followLinks = false;
                 continue;
             }
@@ -274,6 +274,10 @@
                 replaceExisting = true;
                 continue;
             }
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                // ignore
+                continue;
+            }
             if (option == null) throw new NullPointerException();
             throw new UnsupportedOperationException("Unsupported copy option");
         }
--- a/src/windows/classes/sun/nio/fs/WindowsPath.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/src/windows/classes/sun/nio/fs/WindowsPath.java	Fri Nov 14 11:00:20 2008 +0000
@@ -882,13 +882,26 @@
         WindowsFileCopy.move(this, target, options);
     }
 
+    private boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption option: options) {
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            throw new AssertionError("Should not get here");
+        }
+        return followLinks;
+    }
+
     @Override
     @SuppressWarnings("unchecked")
     public <V extends FileAttributeView> V
-        getFileAttributeView(Class<V> view, boolean followLinks)
+        getFileAttributeView(Class<V> view, LinkOption... options)
     {
         if (view == null)
             throw new NullPointerException();
+        boolean followLinks = followLinks(options);
         if (view == BasicFileAttributeView.class)
             return (V) WindowsFileAttributeViews.createBasicView(this, followLinks);
         if (view == DosFileAttributeView.class)
@@ -904,8 +917,8 @@
     }
 
     @Override
-    public FileAttributeView getFileAttributeView(String name, boolean followLinks)
-    {
+    public FileAttributeView getFileAttributeView(String name, LinkOption... options) {
+        boolean followLinks = followLinks(options);
         if (name.equals("basic"))
             return WindowsFileAttributeViews.createBasicView(this, followLinks);
         if (name.equals("dos"))
@@ -931,8 +944,7 @@
         } catch (WindowsException x) {
             x.rethrowAsIOException(this);
         } finally {
-            if (sd != null)
-                sd.release();
+            sd.release();
         }
         return this;
     }
@@ -970,8 +982,7 @@
             x.rethrowAsIOException(this);
             return null;  // keep compiler happy
         } finally {
-            if (sd != null)
-                sd.release();
+            sd.release();
         }
     }
 
@@ -1000,8 +1011,7 @@
             x.rethrowAsIOException(this);
             return null;  // keep compiler happy
         } finally {
-            if (sd != null)
-                sd.release();
+            sd.release();
         }
     }
 
--- a/test/java/nio/file/DirectoryStream/Filters.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/DirectoryStream/Filters.java	Fri Nov 14 11:00:20 2008 +0000
@@ -41,7 +41,7 @@
         return new DirectoryStream.Filter<FileRef>() {
             public boolean accept(FileRef file) {
                 try {
-                    long size = Attributes.readBasicFileAttributes(file, true).size();
+                    long size = Attributes.readBasicFileAttributes(file).size();
                     return size >= min;
                 } catch (IOException e) {
                     throw new IOError(e);
@@ -108,7 +108,7 @@
     }
 
     static boolean isBig(Path file) throws IOException {
-        long size = Attributes.readBasicFileAttributes(file, true).size();
+        long size = Attributes.readBasicFileAttributes(file).size();
         return size >= BIG_FILE_THRESHOLD;
     }
 
--- a/test/java/nio/file/DirectoryStream/SecureDS.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/DirectoryStream/SecureDS.java	Fri Nov 14 11:00:20 2008 +0000
@@ -29,6 +29,7 @@
 
 import java.nio.file.*;
 import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.LinkOption.*;
 import java.nio.file.attribute.*;
 import java.nio.channels.*;
 import java.io.IOException;
@@ -109,43 +110,43 @@
 
         // Test: getFileAttributeView to access attributes of entries
         assertTrue(stream
-            .getFileAttributeView(fileEntry, BasicFileAttributeView.class, true)
+            .getFileAttributeView(fileEntry, BasicFileAttributeView.class)
                 .readAttributes()
                     .isRegularFile());
         assertTrue(stream
-            .getFileAttributeView(fileEntry, BasicFileAttributeView.class, false)
+            .getFileAttributeView(fileEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
                 .readAttributes()
                     .isRegularFile());
         assertTrue(stream
-            .getFileAttributeView(dirEntry, BasicFileAttributeView.class, true)
+            .getFileAttributeView(dirEntry, BasicFileAttributeView.class)
                 .readAttributes()
                     .isDirectory());
         assertTrue(stream
-            .getFileAttributeView(dirEntry, BasicFileAttributeView.class, false)
+            .getFileAttributeView(dirEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
                 .readAttributes()
                     .isDirectory());
         if (supportsLinks) {
             assertTrue(stream
-                .getFileAttributeView(link1Entry, BasicFileAttributeView.class, true)
+                .getFileAttributeView(link1Entry, BasicFileAttributeView.class)
                     .readAttributes()
                         .isRegularFile());
             assertTrue(stream
-                .getFileAttributeView(link1Entry, BasicFileAttributeView.class, false)
+                .getFileAttributeView(link1Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
                     .readAttributes()
                         .isSymbolicLink());
             assertTrue(stream
-                .getFileAttributeView(link2Entry, BasicFileAttributeView.class, true)
+                .getFileAttributeView(link2Entry, BasicFileAttributeView.class)
                     .readAttributes()
                         .isDirectory());
             assertTrue(stream
-                .getFileAttributeView(link2Entry, BasicFileAttributeView.class, false)
+                .getFileAttributeView(link2Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
                     .readAttributes()
                         .isSymbolicLink());
         }
 
         // Test: dynamic access to entry attributes
         view = stream
-             .getFileAttributeView(fileEntry, PosixFileAttributeView.class, false);
+             .getFileAttributeView(fileEntry, PosixFileAttributeView.class, NOFOLLOW_LINKS);
         if (view != null) {
             attrs = view.readAttributes("owner", "size");
             UserPrincipal owner = (UserPrincipal)attrs.get("owner");
@@ -160,8 +161,10 @@
         if (supportsLinks) {
             stream.newByteChannel(link1Entry, opts).close();
             try {
-                stream.newByteChannel(link1Entry,
-                    EnumSet.of(READ, NOFOLLOW_LINKS)).close();
+                Set<OpenOption> mixed = new HashSet<OpenOption>();
+                mixed.add(READ);
+                mixed.add(NOFOLLOW_LINKS);
+                stream.newByteChannel(link1Entry, mixed).close();
                 shouldNotGetHere();
             } catch (IOException x) { }
         }
@@ -245,7 +248,7 @@
         if (supportsLinks) {
             stream1.move(linkEntry, stream2, target);
             assertTrue(dir2.resolve(target)
-                .getFileAttributeView(BasicFileAttributeView.class, false)
+                .getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
                 .readAttributes()
                 .isSymbolicLink());
             stream2.deleteFile(target);
@@ -287,11 +290,11 @@
             shouldNotGetHere();
         } catch (NullPointerException x) { }
         try {
-            stream.getFileAttributeView(null, BasicFileAttributeView.class, true);
+            stream.getFileAttributeView(null, BasicFileAttributeView.class);
             shouldNotGetHere();
         } catch (NullPointerException x) { }
         try {
-            stream.getFileAttributeView(file, null, true);
+            stream.getFileAttributeView(file, null);
             shouldNotGetHere();
         } catch (NullPointerException x) { }
         try {
--- a/test/java/nio/file/Path/CopyAndMove.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/Path/CopyAndMove.java	Fri Nov 14 11:00:20 2008 +0000
@@ -30,6 +30,7 @@
 import java.nio.ByteBuffer;
 import java.nio.file.*;
 import static java.nio.file.StandardCopyOption.*;
+import static java.nio.file.LinkOption.*;
 import java.nio.file.attribute.*;
 import java.io.*;
 import java.util.*;
@@ -111,7 +112,7 @@
         throws IOException
     {
         NamedAttributeView view = file
-            .getFileAttributeView(NamedAttributeView.class, true);
+            .getFileAttributeView(NamedAttributeView.class);
         Map<String,ByteBuffer> result = new HashMap<String,ByteBuffer>();
         for (String name: view.list()) {
             int size = view.size(name);
@@ -137,15 +138,15 @@
         // get file attributes of source file
         String os = System.getProperty("os.name");
         if (os.equals("SunOS") || os.equals("Linux")) {
-            posixAttributes = Attributes.readPosixFileAttributes(source, false);
+            posixAttributes = Attributes.readPosixFileAttributes(source, NOFOLLOW_LINKS);
             basicAttributes = posixAttributes;
         }
         if (os.startsWith("Windows")) {
-            dosAttributes = Attributes.readDosFileAttributes(source, false);
+            dosAttributes = Attributes.readDosFileAttributes(source, NOFOLLOW_LINKS);
             basicAttributes = dosAttributes;
         }
         if (basicAttributes == null)
-            basicAttributes = Attributes.readBasicFileAttributes(source, false);
+            basicAttributes = Attributes.readBasicFileAttributes(source, NOFOLLOW_LINKS);
 
         // hash file contents if regular file
         int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;
@@ -182,18 +183,18 @@
 
         // verify basic attributes
         checkBasicAttributes(basicAttributes,
-            Attributes.readBasicFileAttributes(target, false));
+            Attributes.readBasicFileAttributes(target, NOFOLLOW_LINKS));
 
         // verify POSIX attributes
         if (posixAttributes != null && !basicAttributes.isSymbolicLink()) {
             checkPosixAttributes(posixAttributes,
-                Attributes.readPosixFileAttributes(target, false));
+                Attributes.readPosixFileAttributes(target, NOFOLLOW_LINKS));
         }
 
         // verify DOS attributes
         if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {
             checkDosAttributes(dosAttributes,
-                Attributes.readDosFileAttributes(target, false));
+                Attributes.readDosFileAttributes(target, NOFOLLOW_LINKS));
         }
 
         // verify named attributes
@@ -549,15 +550,18 @@
 
         // get attributes of source and target file to verify copy
         boolean followLinks = true;
+        LinkOption[] linkOptions = new LinkOption[0];
         boolean copyAttributes = false;
         for (CopyOption opt : options) {
-            if (opt == NOFOLLOW_LINKS)
+            if (opt == NOFOLLOW_LINKS) {
                 followLinks = false;
+                linkOptions = new LinkOption[] { NOFOLLOW_LINKS };
+            }
             if (opt == COPY_ATTRIBUTES)
                 copyAttributes = true;
         }
         BasicFileAttributes basicAttributes = Attributes
-            .readBasicFileAttributes(source, followLinks);
+            .readBasicFileAttributes(source, linkOptions);
 
         // check hash if regular file
         if (basicAttributes.isRegularFile())
@@ -570,21 +574,21 @@
         // check that attributes are copied
         if (copyAttributes && followLinks) {
             checkBasicAttributes(basicAttributes,
-                Attributes.readBasicFileAttributes(source, followLinks));
+                Attributes.readBasicFileAttributes(source, linkOptions));
 
             // check POSIX attributes are copied
             String os = System.getProperty("os.name");
             if (os.equals("SunOS") || os.equals("Linux")) {
                 checkPosixAttributes(
-                    Attributes.readPosixFileAttributes(source, followLinks),
-                    Attributes.readPosixFileAttributes(target, followLinks));
+                    Attributes.readPosixFileAttributes(source, linkOptions),
+                    Attributes.readPosixFileAttributes(target, linkOptions));
             }
 
             // check DOS attributes are copied
             if (os.startsWith("Windows")) {
                 checkDosAttributes(
-                    Attributes.readDosFileAttributes(source, followLinks),
-                    Attributes.readDosFileAttributes(target, followLinks));
+                    Attributes.readDosFileAttributes(source, linkOptions),
+                    Attributes.readDosFileAttributes(target, linkOptions));
             }
 
             // check named attributes are copied
@@ -922,12 +926,12 @@
         String os = System.getProperty("os.name");
         boolean isWindows = os.startsWith("Windows");
         boolean isUnix = os.equals("SunOS") || os.equals("Linux");
-        boolean isDirectory = Attributes.readBasicFileAttributes(file, false)
+        boolean isDirectory = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS)
             .isDirectory();
 
         if (isUnix) {
             Set<PosixFilePermission> perms = Attributes
-                .readPosixFileAttributes(file, false).permissions();
+                .readPosixFileAttributes(file, NOFOLLOW_LINKS).permissions();
             PosixFilePermission[] toChange = {
                 PosixFilePermission.GROUP_READ,
                 PosixFilePermission.GROUP_WRITE,
@@ -948,7 +952,7 @@
 
         if (isWindows) {
             DosFileAttributeView view = file
-                .getFileAttributeView(DosFileAttributeView.class, false);
+                .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS);
             // only set or unset the hidden attribute
             view.setHidden(heads());
         }
@@ -961,7 +965,7 @@
 
         if (addNamedAttributes) {
             NamedAttributeView view = file
-                .getFileAttributeView(NamedAttributeView.class, true);
+                .getFileAttributeView(NamedAttributeView.class);
             int n = rand.nextInt(16);
             while (n > 0) {
                 byte[] value = new byte[1 + rand.nextInt(100)];
--- a/test/java/nio/file/Path/Links.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/Path/Links.java	Fri Nov 14 11:00:20 2008 +0000
@@ -95,15 +95,15 @@
             }
             try {
                 Object key1 = Attributes
-                    .readBasicFileAttributes(foo, true).fileKey();
+                    .readBasicFileAttributes(foo).fileKey();
                 Object key2 = Attributes
-                    .readBasicFileAttributes(bar, true).fileKey();
+                    .readBasicFileAttributes(bar).fileKey();
                 assertTrue((key1 == null) || (key1.equals(key2)));
 
                 assertTrue(Attributes
-                    .readBasicFileAttributes(foo, true).linkCount() >= 2);
+                    .readBasicFileAttributes(foo).linkCount() >= 2);
                 assertTrue(Attributes
-                    .readBasicFileAttributes(bar, true).linkCount() >= 2);
+                    .readBasicFileAttributes(bar).linkCount() >= 2);
 
             } finally {
                 bar.delete();
--- a/test/java/nio/file/Path/Misc.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/Path/Misc.java	Fri Nov 14 11:00:20 2008 +0000
@@ -131,7 +131,7 @@
          * Test: Edit ACL to deny WRITE and EXECUTE
          */
         AclFileAttributeView view = file
-            .getFileAttributeView(AclFileAttributeView.class, true);
+            .getFileAttributeView(AclFileAttributeView.class);
         if (view != null &&
             file.getFileStore().supportsFileAttributeView("acl"))
         {
@@ -171,7 +171,7 @@
          */
         if (isWindows) {
             DosFileAttributeView dview =
-                file.getFileAttributeView(DosFileAttributeView.class, true);
+                file.getFileAttributeView(DosFileAttributeView.class);
             dview.setReadOnly(true);
             try {
                 file.checkAccess(AccessMode.WRITE);
@@ -181,7 +181,7 @@
             dview.setReadOnly(false);
 
             // Read-only attribute does not make direcory read-only
-            dview = dir.getFileAttributeView(DosFileAttributeView.class, true);
+            dview = dir.getFileAttributeView(DosFileAttributeView.class);
             boolean save = dview.readAttributes().isReadOnly();
             dview.setReadOnly(true);
             dir.checkAccess(AccessMode.WRITE);
--- a/test/java/nio/file/Path/SBC.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/Path/SBC.java	Fri Nov 14 11:00:20 2008 +0000
@@ -257,9 +257,9 @@
             // ln -s foo link
             Path link = dir.resolve("link").createSymbolicLink(file);
 
-            // open with NOFOLLOW_LINK options
+            // open with NOFOLLOW_LINKS option
             try {
-                link.newByteChannel(READ, NOFOLLOW_LINKS);
+                link.newByteChannel(READ, LinkOption.NOFOLLOW_LINKS);
                 throw new RuntimeException();
             } catch (IOException x) {
             } finally {
--- a/test/java/nio/file/Path/TemporaryFiles.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/Path/TemporaryFiles.java	Fri Nov 14 11:00:20 2008 +0000
@@ -45,7 +45,7 @@
         // check file permissions are 0600 or more secure
         if (file.getFileStore().supportsFileAttributeView("posix")) {
             Set<PosixFilePermission> perms = Attributes
-                .readPosixFileAttributes(file, false).permissions();
+                .readPosixFileAttributes(file).permissions();
             perms.remove(PosixFilePermission.OWNER_READ);
             perms.remove(PosixFilePermission.OWNER_WRITE);
             if (!perms.isEmpty())
--- a/test/java/nio/file/attribute/AclFileAttributeView/Basic.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/attribute/AclFileAttributeView/Basic.java	Fri Nov 14 11:00:20 2008 +0000
@@ -51,7 +51,7 @@
             file.createFile();
 
         AclFileAttributeView view = file
-            .getFileAttributeView(AclFileAttributeView.class, true);
+            .getFileAttributeView(AclFileAttributeView.class);
 
         // print existing ACL
         List<AclEntry> acl = view.getAcl();
--- a/test/java/nio/file/attribute/Attributes/Basic.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/attribute/Attributes/Basic.java	Fri Nov 14 11:00:20 2008 +0000
@@ -57,46 +57,46 @@
         throws IOException
     {
         // getAttribute
-        checkEqual(attrs.size(), Attributes.getAttribute(file, true, "size"));
+        checkEqual(attrs.size(), Attributes.getAttribute(file, "size"));
         checkEqual(attrs.lastModifiedTime(),
-                   Attributes.getAttribute(file, true, "basic:lastModifiedTime"));
+                   Attributes.getAttribute(file, "basic:lastModifiedTime"));
         checkEqual(attrs.lastAccessTime(),
-                   Attributes.getAttribute(file, true, "lastAccessTime"));
+                   Attributes.getAttribute(file, "lastAccessTime"));
         checkEqual(attrs.creationTime(),
-                   Attributes.getAttribute(file, true, "basic:creationTime"));
-        assertTrue((Boolean)Attributes.getAttribute(file, true, "isRegularFile"));
-        assertTrue(!(Boolean)Attributes.getAttribute(file, true, "basic:isDirectory"));
-        assertTrue(!(Boolean)Attributes.getAttribute(file, true, "isSymbolicLink"));
-        assertTrue(!(Boolean)Attributes.getAttribute(file, true, "basic:isOther"));
+                   Attributes.getAttribute(file, "basic:creationTime"));
+        assertTrue((Boolean)Attributes.getAttribute(file, "isRegularFile"));
+        assertTrue(!(Boolean)Attributes.getAttribute(file, "basic:isDirectory"));
+        assertTrue(!(Boolean)Attributes.getAttribute(file, "isSymbolicLink"));
+        assertTrue(!(Boolean)Attributes.getAttribute(file, "basic:isOther"));
         checkEqual(attrs.linkCount(),
-                   (Integer)Attributes.getAttribute(file, true, "linkCount"));
-        checkEqual(attrs.fileKey(), Attributes.getAttribute(file, true, "basic:fileKey"));
+                   (Integer)Attributes.getAttribute(file, "linkCount"));
+        checkEqual(attrs.fileKey(), Attributes.getAttribute(file, "basic:fileKey"));
 
         // setAttribute
         if (attrs.resolution() == TimeUnit.MILLISECONDS) {
             long modTime = attrs.lastModifiedTime();
             Attributes.setAttribute(file, "basic:lastModifiedTime", 0L);
-            assertTrue(Attributes.readBasicFileAttributes(file, true).lastModifiedTime() == 0L);
+            assertTrue(Attributes.readBasicFileAttributes(file).lastModifiedTime() == 0L);
             Attributes.setAttribute(file, "lastModifiedTime", modTime);
-            assertTrue(Attributes.readBasicFileAttributes(file, true).lastModifiedTime() == modTime);
+            assertTrue(Attributes.readBasicFileAttributes(file).lastModifiedTime() == modTime);
         }
 
         // readAttributes
         Map<String,?> map;
-        map = Attributes.readAttributes(file, true, "*");
+        map = Attributes.readAttributes(file, "*");
         assertTrue(map.size() >= 11);
         checkEqual(attrs.isRegularFile(), map.get("isRegularFile")); // check one
 
-        map = Attributes.readAttributes(file, true, "basic:*");
+        map = Attributes.readAttributes(file, "basic:*");
         assertTrue(map.size() >= 11);
         checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime")); // check one
 
-        map = Attributes.readAttributes(file, true, "size,lastModifiedTime");
+        map = Attributes.readAttributes(file, "size,lastModifiedTime");
         assertTrue(map.size() == 2);
         checkEqual(attrs.size(), map.get("size"));
         checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
 
-        map = Attributes.readAttributes(file, true,
+        map = Attributes.readAttributes(file,
             "basic:lastModifiedTime,lastAccessTime,linkCount,ShouldNotExist");
         assertTrue(map.size() == 3);
         checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
@@ -112,11 +112,11 @@
 
         // getAttribute
         checkEqual(attrs.permissions(),
-                   Attributes.getAttribute(file, true, "posix:permissions"));
+                   Attributes.getAttribute(file, "posix:permissions"));
         checkEqual(attrs.owner(),
-                   Attributes.getAttribute(file, true, "posix:owner"));
+                   Attributes.getAttribute(file, "posix:owner"));
         checkEqual(attrs.group(),
-                   Attributes.getAttribute(file, true, "posix:group"));
+                   Attributes.getAttribute(file, "posix:group"));
 
         // setAttribute
         Set<PosixFilePermission> orig = attrs.permissions();
@@ -125,19 +125,19 @@
         newPerms.remove(PosixFilePermission.OTHERS_WRITE);
         newPerms.remove(PosixFilePermission.OTHERS_EXECUTE);
         Attributes.setAttribute(file, "posix:permissions", newPerms);
-        checkEqual(Attributes.readPosixFileAttributes(file, true).permissions(), newPerms);
+        checkEqual(Attributes.readPosixFileAttributes(file).permissions(), newPerms);
         Attributes.setAttribute(file, "posix:permissions", orig);
-        checkEqual(Attributes.readPosixFileAttributes(file, true).permissions(), orig);
+        checkEqual(Attributes.readPosixFileAttributes(file).permissions(), orig);
         Attributes.setAttribute(file, "posix:owner", attrs.owner());
         Attributes.setAttribute(file, "posix:group", attrs.group());
 
         // readAttributes
         Map<String,?> map;
-        map = Attributes.readAttributes(file, true, "posix:*");
+        map = Attributes.readAttributes(file, "posix:*");
         assertTrue(map.size() >= 14);
         checkEqual(attrs.permissions(), map.get("permissions")); // check one
 
-        map = Attributes.readAttributes(file, true, "posix:size,owner,ShouldNotExist");
+        map = Attributes.readAttributes(file, "posix:size,owner,ShouldNotExist");
         assertTrue(map.size() == 2);
         checkEqual(attrs.size(), map.get("size"));
         checkEqual(attrs.owner(), map.get("owner"));
@@ -146,23 +146,23 @@
     // Exercise getAttribute/setAttribute/readAttributes on unix attributes
     static void checkUnixAttributes(FileRef file) throws IOException {
         // getAttribute
-        int mode = (Integer)Attributes.getAttribute(file, true, "unix:mode");
-        long ino = (Long)Attributes.getAttribute(file, true, "unix:ino");
-        long dev = (Long)Attributes.getAttribute(file, true, "unix:dev");
-        long rdev = (Long)Attributes.getAttribute(file, true, "unix:rdev");
-        int uid = (Integer)Attributes.getAttribute(file, true, "unix:uid");
-        int gid = (Integer)Attributes.getAttribute(file, true, "unix:gid");
-        long ctime = (Long)Attributes.getAttribute(file, true, "unix:ctime");
+        int mode = (Integer)Attributes.getAttribute(file, "unix:mode");
+        long ino = (Long)Attributes.getAttribute(file, "unix:ino");
+        long dev = (Long)Attributes.getAttribute(file, "unix:dev");
+        long rdev = (Long)Attributes.getAttribute(file, "unix:rdev");
+        int uid = (Integer)Attributes.getAttribute(file, "unix:uid");
+        int gid = (Integer)Attributes.getAttribute(file, "unix:gid");
+        long ctime = (Long)Attributes.getAttribute(file, "unix:ctime");
 
         // readAttributes
         Map<String,?> map;
-        map = Attributes.readAttributes(file, true, "unix:*");
+        map = Attributes.readAttributes(file, "unix:*");
         assertTrue(map.size() >= 21);
 
-        map = Attributes.readAttributes(file, true, "unix:size,uid,gid,ShouldNotExist");
+        map = Attributes.readAttributes(file, "unix:size,uid,gid,ShouldNotExist");
         assertTrue(map.size() == 3);
         checkEqual(map.get("size"),
-                   Attributes.readBasicFileAttributes(file, true).size());
+                   Attributes.readBasicFileAttributes(file).size());
     }
 
     // Exercise getAttribute/setAttribute/readAttributes on dos attributes
@@ -173,48 +173,48 @@
 
         // getAttribute
         checkEqual(attrs.isReadOnly(),
-                   Attributes.getAttribute(file, true, "dos:readonly"));
+                   Attributes.getAttribute(file, "dos:readonly"));
         checkEqual(attrs.isHidden(),
-                   Attributes.getAttribute(file, true, "dos:hidden"));
+                   Attributes.getAttribute(file, "dos:hidden"));
         checkEqual(attrs.isSystem(),
-                   Attributes.getAttribute(file, true, "dos:system"));
+                   Attributes.getAttribute(file, "dos:system"));
         checkEqual(attrs.isArchive(),
-                   Attributes.getAttribute(file, true, "dos:archive"));
+                   Attributes.getAttribute(file, "dos:archive"));
 
         // setAttribute
         boolean value;
 
         value = attrs.isReadOnly();
         Attributes.setAttribute(file, "dos:readonly", !value);
-        checkEqual(Attributes.readDosFileAttributes(file, true).isReadOnly(), !value);
+        checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), !value);
         Attributes.setAttribute(file, "dos:readonly", value);
-        checkEqual(Attributes.readDosFileAttributes(file, true).isReadOnly(), value);
+        checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), value);
 
         value = attrs.isHidden();
         Attributes.setAttribute(file, "dos:hidden", !value);
-        checkEqual(Attributes.readDosFileAttributes(file, true).isHidden(), !value);
+        checkEqual(Attributes.readDosFileAttributes(file).isHidden(), !value);
         Attributes.setAttribute(file, "dos:hidden", value);
-        checkEqual(Attributes.readDosFileAttributes(file, true).isHidden(), value);
+        checkEqual(Attributes.readDosFileAttributes(file).isHidden(), value);
 
         value = attrs.isSystem();
         Attributes.setAttribute(file, "dos:system", !value);
-        checkEqual(Attributes.readDosFileAttributes(file, true).isSystem(), !value);
+        checkEqual(Attributes.readDosFileAttributes(file).isSystem(), !value);
         Attributes.setAttribute(file, "dos:system", value);
-        checkEqual(Attributes.readDosFileAttributes(file, true).isSystem(), value);
+        checkEqual(Attributes.readDosFileAttributes(file).isSystem(), value);
 
         value = attrs.isArchive();
         Attributes.setAttribute(file, "dos:archive", !value);
-        checkEqual(Attributes.readDosFileAttributes(file, true).isArchive(), !value);
+        checkEqual(Attributes.readDosFileAttributes(file).isArchive(), !value);
         Attributes.setAttribute(file, "dos:archive", value);
-        checkEqual(Attributes.readDosFileAttributes(file, true).isArchive(), value);
+        checkEqual(Attributes.readDosFileAttributes(file).isArchive(), value);
 
         // readAttributes
         Map<String,?> map;
-        map = Attributes.readAttributes(file, true, "dos:*");
+        map = Attributes.readAttributes(file, "dos:*");
         assertTrue(map.size() >= 15);
         checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
 
-        map = Attributes.readAttributes(file, true, "dos:size,hidden,ShouldNotExist");
+        map = Attributes.readAttributes(file, "dos:size,hidden,ShouldNotExist");
         assertTrue(map.size() == 2);
         checkEqual(attrs.size(), map.get("size"));
         checkEqual(attrs.isHidden(), map.get("hidden"));
@@ -225,18 +225,18 @@
         FileStore store = file.getFileStore();
         try {
             checkBasicAttributes(file,
-                Attributes.readBasicFileAttributes(file, true));
+                Attributes.readBasicFileAttributes(file));
 
             if (store.supportsFileAttributeView("posix"))
                 checkPosixAttributes(file,
-                    Attributes.readPosixFileAttributes(file, true));
+                    Attributes.readPosixFileAttributes(file));
 
             if (store.supportsFileAttributeView("unix"))
                 checkUnixAttributes(file);
 
             if (store.supportsFileAttributeView("dos"))
                 checkDosAttributes(file,
-                    Attributes.readDosFileAttributes(file, true));
+                    Attributes.readDosFileAttributes(file));
         } finally {
             file.delete();
         }
--- a/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java	Fri Nov 14 11:00:20 2008 +0000
@@ -43,7 +43,7 @@
     static void checkAttributesOfDirectory(Path dir)
         throws IOException
     {
-        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir, true);
+        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
         check(attrs.isDirectory(), "is a directory");
         check(!attrs.isRegularFile(), "is not a regular file");
         check(!attrs.isSymbolicLink(), "is not a link");
@@ -61,7 +61,7 @@
     static void checkAttributesOfFile(Path dir, Path file)
         throws IOException
     {
-        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file, true);
+        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
         check(attrs.isRegularFile(), "is a regular file");
         check(!attrs.isDirectory(), "is not a directory");
         check(!attrs.isSymbolicLink(), "is not a link");
@@ -79,8 +79,8 @@
         // copy last-modified time and file create time from directory to file,
         // re-read attribtues, and check they match
         BasicFileAttributeView view =
-            file.getFileAttributeView(BasicFileAttributeView.class, true);
-        BasicFileAttributes dirAttrs = Attributes.readBasicFileAttributes(dir, true);
+            file.getFileAttributeView(BasicFileAttributeView.class);
+        BasicFileAttributes dirAttrs = Attributes.readBasicFileAttributes(dir);
         view.setTimes(dirAttrs.lastModifiedTime(), null, null, dirAttrs.resolution());
         if (dirAttrs.creationTime() != -1L) {
             view.setTimes(null, null, dirAttrs.creationTime(), dirAttrs.resolution());
@@ -101,7 +101,8 @@
     static void checkAttributesOfLink(Path link)
         throws IOException
     {
-        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(link, false);
+        BasicFileAttributes attrs = Attributes
+            .readBasicFileAttributes(link, LinkOption.NOFOLLOW_LINKS);
         check(attrs.isSymbolicLink(), "is a link");
         check(!attrs.isDirectory(), "is a directory");
         check(!attrs.isRegularFile(), "is not a regular file");
--- a/test/java/nio/file/attribute/DosFileAttributeView/Basic.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/attribute/DosFileAttributeView/Basic.java	Fri Nov 14 11:00:20 2008 +0000
@@ -28,6 +28,7 @@
  */
 
 import java.nio.file.*;
+import static java.nio.file.LinkOption.*;
 import java.nio.file.attribute.*;
 import java.util.*;
 import java.io.IOException;
@@ -77,7 +78,7 @@
         file.newOutputStream().close();
         try {
             testAttributes(file
-                .getFileAttributeView(DosFileAttributeView.class, true));
+                .getFileAttributeView(DosFileAttributeView.class));
 
             // Following tests use a symbolic link so skip if not supported
             if (!TestUtil.supportsLinks(dir))
@@ -87,13 +88,13 @@
 
             // test following links
             testAttributes(link
-                .getFileAttributeView(DosFileAttributeView.class, true));
+                .getFileAttributeView(DosFileAttributeView.class));
 
             // test not following links
             try {
                 try {
                     testAttributes(link
-                        .getFileAttributeView(DosFileAttributeView.class, false));
+                        .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
                 } catch (IOException x) {
                     // access to link attributes not supported
                     return;
@@ -103,31 +104,31 @@
                 // run test on target of link (which leaves them all un-set)
                 // check that attributes of link remain all set
                 setAll(link
-                    .getFileAttributeView(DosFileAttributeView.class, false), true);
+                    .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), true);
                 testAttributes(link
-                    .getFileAttributeView(DosFileAttributeView.class, true));
-                DosFileAttributes attrs = Attributes.readDosFileAttributes(link, false);
+                    .getFileAttributeView(DosFileAttributeView.class));
+                DosFileAttributes attrs = Attributes.readDosFileAttributes(link, NOFOLLOW_LINKS);
                 check(attrs.isReadOnly());
                 check(attrs.isHidden());
                 check(attrs.isArchive());
                 check(attrs.isSystem());
                 setAll(link
-                    .getFileAttributeView(DosFileAttributeView.class, false), false);
+                    .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), false);
 
                 // set all attributes on target
                 // run test on link (which leaves them all un-set)
                 // check that attributes of target remain all set
                 setAll(link
-                    .getFileAttributeView(DosFileAttributeView.class, true), true);
+                    .getFileAttributeView(DosFileAttributeView.class), true);
                 testAttributes(link
-                    .getFileAttributeView(DosFileAttributeView.class, false));
-                attrs = Attributes.readDosFileAttributes(link, false);
+                    .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
+                attrs = Attributes.readDosFileAttributes(link, NOFOLLOW_LINKS);
                 check(attrs.isReadOnly());
                 check(attrs.isHidden());
                 check(attrs.isArchive());
                 check(attrs.isSystem());
                 setAll(link
-                    .getFileAttributeView(DosFileAttributeView.class, true), false);
+                    .getFileAttributeView(DosFileAttributeView.class), false);
             } finally {
                 link.delete(false);
             }
--- a/test/java/nio/file/attribute/NamedAttributeView/Basic.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/attribute/NamedAttributeView/Basic.java	Fri Nov 14 11:00:20 2008 +0000
@@ -30,6 +30,7 @@
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.nio.file.*;
+import static java.nio.file.LinkOption.*;
 import java.nio.file.attribute.*;
 import java.util.Iterator;
 import java.util.Random;
@@ -53,9 +54,9 @@
         return false;
     }
 
-    static void test(Path file, boolean followLinks) throws IOException {
+    static void test(Path file, LinkOption... options) throws IOException {
         NamedAttributeView view = file
-            .getFileAttributeView(NamedAttributeView.class, followLinks);
+            .getFileAttributeView(NamedAttributeView.class, options);
         ByteBuffer buf = rand.nextBoolean() ?
             ByteBuffer.allocate(100) : ByteBuffer.allocateDirect(100);
 
@@ -107,7 +108,7 @@
 
     static void miscTests(Path file) throws IOException {
         NamedAttributeView view = file
-            .getFileAttributeView(NamedAttributeView.class, true);
+            .getFileAttributeView(NamedAttributeView.class);
         view.write(ATTR_NAME, ByteBuffer.wrap(ATTR_VALUE.getBytes()));
 
         // NullPointerException
@@ -167,7 +168,7 @@
             // test access to named attributes of regular file
             Path file = dir.resolve("foo.html").createFile();
             try {
-                test(file, true);
+                test(file);
             } finally {
                 file.delete();
             }
@@ -175,7 +176,7 @@
             // test access to named attributes of directory
             file = dir.resolve("foo").createDirectory();
             try {
-                test(file, true);
+                test(file);
             } finally {
                 file.delete();
             }
@@ -185,7 +186,7 @@
                 Path target = dir.resolve("doesnotexist");
                 Path link = dir.resolve("link").createSymbolicLink(target);
                 try {
-                    test(link, false);
+                    test(link, NOFOLLOW_LINKS);
                 } catch (IOException x) {
                     // access to attributes of sym link may not be supported
                 } finally {
--- a/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java	Fri Nov 14 09:43:00 2008 +0000
+++ b/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java	Fri Nov 14 11:00:20 2008 +0000
@@ -28,6 +28,7 @@
  */
 
 import java.nio.file.*;
+import static java.nio.file.LinkOption.*;
 import java.nio.file.attribute.*;
 import java.io.IOException;
 import java.util.*;
@@ -103,7 +104,7 @@
         file.newOutputStream(options, attr).close();
         try {
             checkSecure(requested,  file
-                .getFileAttributeView(PosixFileAttributeView.class, true)
+                .getFileAttributeView(PosixFileAttributeView.class)
                 .readAttributes()
                 .permissions());
         } finally {
@@ -114,7 +115,7 @@
         file.createDirectory(attr);
         try {
             checkSecure(requested,  file
-                .getFileAttributeView(PosixFileAttributeView.class, true)
+                .getFileAttributeView(PosixFileAttributeView.class)
                 .readAttributes()
                 .permissions());
         } finally {
@@ -137,7 +138,7 @@
         try {
             // get initial permissions so that we can restore them later
             PosixFileAttributeView view = file
-                .getFileAttributeView(PosixFileAttributeView.class, true);
+                .getFileAttributeView(PosixFileAttributeView.class);
             Set<PosixFilePermission> save = view.readAttributes()
                 .permissions();
 
@@ -179,7 +180,7 @@
             link.createSymbolicLink(file);
             try {
                 PosixFileAttributes attrs = Attributes
-                    .readPosixFileAttributes(link, false);
+                    .readPosixFileAttributes(link, NOFOLLOW_LINKS);
                 if (!attrs.isSymbolicLink()) {
                     throw new RuntimeException("not a link");
                 }
@@ -243,7 +244,7 @@
 
             // read attributes of directory to get owner/group
             PosixFileAttributeView view = file
-                .getFileAttributeView(PosixFileAttributeView.class, true);
+                .getFileAttributeView(PosixFileAttributeView.class);
             PosixFileAttributes attrs = view.readAttributes();
 
             // set to existing owner/group
@@ -274,7 +275,7 @@
             .getUserPrincipalLookupService();
 
         // read attributes of directory to get owner/group
-        PosixFileAttributes attrs = Attributes.readPosixFileAttributes(dir, true);
+        PosixFileAttributes attrs = Attributes.readPosixFileAttributes(dir);
 
         // lookup owner and check it matches file's owner
         System.out.format("lookup: %s\n", attrs.owner().getName());
@@ -325,7 +326,7 @@
         System.out.println("-- Exceptions --");
 
         PosixFileAttributeView view = dir
-            .getFileAttributeView(PosixFileAttributeView.class, true);
+            .getFileAttributeView(PosixFileAttributeView.class);
 
         // NullPointerException
         try {