changeset 698:cbf58d8a3fec

Second installation of small API fixes for b96 - Rename getConnectedAddress to getRemoteAddress - DatagramChannel should not implement MulticastChannel directly - SecureDirectoryStream#delete has race conditions - Override of set/get/readAttributes in specific AttributeView types confusing - Path#iterator spec missing - NamedAttributeView#getAttribute/readAttributes return null/empty map -
author alanb
date Tue, 07 Oct 2008 18:00:58 +0100
parents 06c5f60e40e9
children 44edf677e97e
files src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java src/share/classes/java/nio/channels/AsynchronousSocketChannel.java src/share/classes/java/nio/channels/DatagramChannel.java src/share/classes/java/nio/channels/MulticastChannel.java src/share/classes/java/nio/channels/SocketChannel.java src/share/classes/java/nio/file/DirectoryStream.java src/share/classes/java/nio/file/FileSystem.java src/share/classes/java/nio/file/FileVisitor.java src/share/classes/java/nio/file/Path.java src/share/classes/java/nio/file/Paths.java src/share/classes/java/nio/file/SecureDirectoryStream.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/BasicFileAttributeView.java src/share/classes/java/nio/file/attribute/DosFileAttributeView.java src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.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/FileSystemProvider.java src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java src/share/classes/sun/nio/ch/DatagramChannelImpl.java src/share/classes/sun/nio/ch/SocketChannelImpl.java src/share/classes/sun/nio/fs/AbstractNamedAttributeView.java src/share/sample/nio/multicast/Reader.java src/solaris/classes/sun/nio/fs/LinuxNamedAttributeView.java src/solaris/classes/sun/nio/fs/SolarisFileSystem.java src/solaris/classes/sun/nio/fs/SolarisNamedAttributeView.java src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java src/solaris/classes/sun/nio/fs/UnixFileSystem.java src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java src/windows/classes/sun/nio/fs/WindowsFileSystem.java src/windows/classes/sun/nio/fs/WindowsNamedAttributeView.java test/java/nio/channels/AsynchronousSocketChannel/Basic.java test/java/nio/channels/DatagramChannel/BasicMulticastTests.java test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java test/java/nio/channels/etc/NetworkChannelTests.java test/java/nio/file/DirectoryStream/SecureDS.java test/java/nio/file/spi/TestProvider.java
diffstat 39 files changed, 369 insertions(+), 400 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java	Tue Oct 07 18:00:58 2008 +0100
@@ -51,7 +51,8 @@
  * connected until it is disconnected or closed.
  *
  * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
- * setOption} method. Channels of this type support the following options:
+ * setOption} method. An asynchronousdatagram channel to an Internet Protocol
+ * (IP) socket supports the following options:
  * <blockquote>
  * <table border>
  *   <tr>
@@ -125,7 +126,7 @@
  */
 
 public abstract class AsynchronousDatagramChannel
-    implements AsynchronousByteChannel, NetworkChannel, MulticastChannel
+    implements AsynchronousByteChannel, NetworkChannel
 {
     private final AsynchronousChannelProvider provider;
 
@@ -244,7 +245,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      */
-    public abstract SocketAddress getConnectedAddress() throws IOException;
+    public abstract SocketAddress getRemoteAddress() throws IOException;
 
     /**
      * Connects this channel's socket.
--- a/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java	Tue Oct 07 18:00:58 2008 +0100
@@ -47,7 +47,7 @@
  * <p> A newly-created channel is connected by invoking its {@link #connect connect}
  * method; once connected, a channel remains connected until it is closed.  Whether
  * or not a socket channel is connected may be determined by invoking its {@link
- * #getConnectedAddress getConnectedAddress} method. An attempt to invoke an I/O
+ * #getRemoteAddress getRemoteAddress} method. An attempt to invoke an I/O
  * operation upon an unconnected channel will cause a {@link NotYetConnectedException}
  * to be thrown.
  *
@@ -265,7 +265,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      */
-    public abstract SocketAddress getConnectedAddress() throws IOException;
+    public abstract SocketAddress getRemoteAddress() throws IOException;
 
     // -- asynchronous operations --
 
@@ -310,7 +310,7 @@
      *          If a security manager has been installed
      *          and it does not permit access to the given remote endpoint
      *
-     * @see #getConnectedAddress
+     * @see #getRemoteAddress
      */
     public abstract <A> Future<Void> connect(SocketAddress remote,
                                              A attachment,
--- a/src/share/classes/java/nio/channels/DatagramChannel.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/channels/DatagramChannel.java	Tue Oct 07 18:00:58 2008 +0100
@@ -36,7 +36,7 @@
 /**
  * A selectable channel for datagram-oriented sockets.
  *
- * <p> A datagram channel is created by invoking one of the {@link #open open} methods
+ * <p> {@note revised} A datagram channel is created by invoking one of the {@link #open open} methods
  * of this class. It is not possible to create a channel for an arbitrary,
  * pre-existing datagram socket. A newly-created datagram channel is open but not
  * connected. A datagram channel need not be connected in order for the {@link #send
@@ -53,7 +53,8 @@
  * be determined by invoking its {@link #isConnected isConnected} method.
  *
  * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
- * setOption} method. Datagram channels support the following options:
+ * setOption} method. A datagram channel to an Internet Protocol socket supports
+ * the following options:
  * <blockquote>
  * <table border>
  *   <tr>
@@ -99,6 +100,10 @@
  * </blockquote>
  * Additional (implementation specific) options may also be supported.
  *
+ * <p> Furthermore, a datagram channel to an Internet Protocol socket supports
+ * multicasting and may be cast to a {@link MulticastChannel} so as to join a
+ * multicast group and receive multicast datagrams sent to the group.
+ *
  * <p> Datagram channels are safe for use by multiple concurrent threads.  They
  * support concurrent reading and writing, though at most one thread may be
  * reading and at most one thread may be writing at any given time.  </p>
@@ -106,11 +111,12 @@
  * @author Mark Reinhold
  * @author JSR-51 Expert Group
  * @since 1.4
+ * @updated 1.7
  */
 
 public abstract class DatagramChannel
     extends AbstractSelectableChannel
-    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel
+    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
 {
 
     /**
@@ -311,6 +317,7 @@
     public abstract DatagramChannel disconnect() throws IOException;
 
     /**
+     * {@note new}
      * Returns the remote address to which this channel's socket is connected.
      *
      * @return  The remote address; {@code null} if the channel is not {@link
@@ -321,7 +328,7 @@
      *
      * @since 1.7
      */
-    public abstract SocketAddress getConnectedAddress() throws IOException;
+    public abstract SocketAddress getRemoteAddress() throws IOException;
 
     /**
      * Receives a datagram via this channel.
--- a/src/share/classes/java/nio/channels/MulticastChannel.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/channels/MulticastChannel.java	Tue Oct 07 18:00:58 2008 +0100
@@ -113,7 +113,7 @@
  *
  *     InetAddress group = InetAddress.getByName("225.4.5.6");
  *
- *     MembershipKey key = dc.join(group, ni);
+ *     MembershipKey key = ((MulticastChannel)dc).join(group, ni);
  * </pre>
  *
  * @since 1.7
--- a/src/share/classes/java/nio/channels/SocketChannel.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/channels/SocketChannel.java	Tue Oct 07 18:00:58 2008 +0100
@@ -35,7 +35,7 @@
 /**
  * A selectable channel for stream-oriented connecting sockets.
  *
- * <p> A socket channel is created by invoking one of the {@link #open open}
+ * <p> {@note revised} A socket channel is created by invoking one of the {@link #open open}
  * methods of this class.  It is not possible to create a channel for an arbitrary,
  * pre-existing socket. A newly-created socket channel is open but not yet
  * connected.  An attempt to invoke an I/O operation upon an unconnected
@@ -110,6 +110,7 @@
  * @author Mark Reinhold
  * @author JSR-51 Expert Group
  * @since 1.4
+ * @updated 1.7
  */
 
 public abstract class SocketChannel
@@ -237,6 +238,7 @@
         throws IOException;
 
     /**
+     * {@note new}
      * Shutdown the connection for reading without closing the channel.
      *
      * <p> Once shutdown for reading then further reads on the channel will
@@ -257,6 +259,7 @@
     public abstract SocketChannel shutdownInput() throws IOException;
 
     /**
+     * {@note new}
      * Shutdown the connection for writing without closing the channel.
      *
      * <p> Once shutdown for writing then further attempts to write to the
@@ -426,6 +429,7 @@
     public abstract boolean finishConnect() throws IOException;
 
     /**
+     * {@note new}
      * Returns the remote address to which this channel's socket is connected.
      *
      * <p> Where the channel is bound and connected to an Internet Protocol
@@ -440,7 +444,7 @@
      *
      * @since 1.7
      */
-    public abstract SocketAddress getConnectedAddress() throws IOException;
+    public abstract SocketAddress getRemoteAddress() throws IOException;
 
     // -- ByteChannel operations --
 
--- a/src/share/classes/java/nio/file/DirectoryStream.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/DirectoryStream.java	Tue Oct 07 18:00:58 2008 +0100
@@ -101,21 +101,7 @@
      * A task that decides if a directory entry should be accepted or filtered.
      * A {@code Filter} is passed as the parameter to the {@link
      * Path#newDirectoryStream(DirectoryStream.Filter) newDirectoryStream} method
-     * when opening directory to iterate over the entries in the directory.
-     *
-     * <p> <b>Usage Example:</b>
-     * Suppose we require a filter that accepts files that are 8k or larger.
-     * <pre>
-     *    DirectoryStream.Filter&lt;FileRef&gt; filter = new DirectoryStream.Filter&lt;FileRef&gt;() {
-     *        public boolean accept(FileRef file) {
-     *            try {
-     *                return (Attributes.readBasicFileAttributes(file, false).size() >= 8192L);
-     *            } catch (IOException e) {
-     *                :
-     *            }
-     *        }
-     *    };
-     * </pre>
+     * when opening a directory to iterate over the entries in the directory.
      *
      * <p> The {@link DirectoryStreamFilters} class defines factory methods to
      * create filters for a number of common usages and also methods to combine
--- a/src/share/classes/java/nio/file/FileSystem.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/FileSystem.java	Tue Oct 07 18:00:58 2008 +0100
@@ -49,9 +49,8 @@
  *   <li><p> The {@link #getNameMatcher  getNameMatcher} method is used
  *     to create a {@link PathMatcher} that performs match operations on
  *     file names. </p></li>
- *   <li><p> The {@link #getFileStores getFileStores} method enumerates the
- *     underlying {@link FileStore file-stores}, returning an object to iterate
- *     over them.  </p></li>
+ *   <li><p> The {@link #getFileStores getFileStores} method returns an iterator
+ *     over the underlying {@link FileStore file-stores}. </p></li>
  *   <li><p> The {@link #getUserPrincipalLookupService getUserPrincipalLookupService}
  *     method returns the {@link UserPrincipalLookupService} to lookup users or
  *     groups by name. </p></li>
@@ -194,7 +193,7 @@
     /**
      * Returns an object to iterate over the underlying file stores.
      *
-     * <p> The elements of the returned object's iterator are the {@link
+     * <p> The elements of the returned iterator are the {@link
      * FileStore FileStores} for this file system. The order of the elements is
      * not defined and the file stores may change during the lifetime of the
      * Java virtual machine. When an I/O error occurs, perhaps because a file
--- a/src/share/classes/java/nio/file/FileVisitor.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/FileVisitor.java	Tue Oct 07 18:00:58 2008 +0100
@@ -33,9 +33,40 @@
  * {@link Files#walkFileTree walkFileTree} utility method to visit each file
  * in a tree.
  *
- * <p> <b>Usage Example:</b>
- * Suppose we want to copy a file tree rooted at a source directory to a
- * target location.
+ * <p> <b>Usage Examples:</b>
+ * Suppose we want to delete a file tree. In that case, each directory should
+ * be deleted after the entries in the directory are deleted.
+ * <pre>
+ *     Path start = ...
+ *     Files.walkFileTree(start, new SimpleFileVisitor&lt;Path&gt;() {
+ *         &#64;Override
+ *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ *             try {
+ *                 file.delete(false);
+ *             } catch (IOException exc) {
+ *                 // failed to delete
+ *             }
+ *             return FileVisitResult.CONTINUE;
+ *         }
+ *         &#64;Override
+ *         public FileVisitResult postVisitDirectory(Path dir, IOException e) {
+ *             if (e == null) {
+ *                 try {
+ *                     dir.delete(false);
+ *                 } catch (IOException exc) {
+ *                     // failed to delete
+ *                 }
+ *             } else {
+ *                 // directory iteration failed
+ *             }
+ *             return FileVisitResult.CONTINUE;
+ *         }
+ *     });
+ * </pre>
+ * <p> Furthermore, suppose we want to copy a file tree rooted at a source
+ * directory to a target location. In that case, symbolic links should be
+ * followed and the target directory should be created before the entries in
+ * the directory are copied.
  * <pre>
  *     final Path source = ...
  *     final Path target = ...
@@ -49,7 +80,7 @@
  *                 } catch (FileAlreadyExistsException e) {
  *                      // ignore
  *                 } catch (IOException e) {
- *                     // copy failed
+ *                     // copy failed, skip rest of directory and descendants
  *                     return SKIP_SUBTREE;
  *                 }
  *                 return CONTINUE;
--- a/src/share/classes/java/nio/file/Path.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/Path.java	Tue Oct 07 18:00:58 2008 +0100
@@ -956,6 +956,23 @@
      * directory that execute in a race-free manner then the returned directory
      * stream is a {@link SecureDirectoryStream}.
      *
+     * <p> <b>Usage Example:</b>
+     * Suppose we require to iterate over the files in a directory that are
+     * larger than 8KB.
+     * <pre>
+     *     Path dir = ...
+     *     DirectoryStream&lt;Path&gt; stream = dir.newDirectoryStream(new DirectoryStream.Filter&lt;Path&gt;() {
+     *         public boolean accept(Path file) {
+     *             try {
+     *                 long size = Attributes.readBasicFileAttributes(file, false).size();
+     *                 return (size > 8192L);
+     *             } catch (IOException e) {
+     *                 // failed to get size
+     *             }
+     *             return false;
+     *         }
+     *     });
+     * </pre>
      * @param   filter
      *          The directory stream filter
      *
@@ -1460,6 +1477,22 @@
                                       WatchEvent.Modifier... modifiers)
         throws IOException;
 
+    // -- Iterable --
+
+    /**
+     * Returns an iterator over the name elements of this path.
+     *
+     * <p> The first element returned by the iterator represents the name
+     * element that is closest to the root in the directory hierarchy, the
+     * second element is the next closest, and so on. The last element returned
+     * is the name of the file or directory denoted by this path. The {@link
+     * #getRoot root} component, if present, is not returned by the iterator.
+     *
+     * @return  An iterator over the name elements of this path.
+     */
+    @Override
+    public abstract Iterator<Path> iterator();
+
     // -- compareTo/equals/hashCode --
 
     /**
--- a/src/share/classes/java/nio/file/Paths.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/Paths.java	Tue Oct 07 18:00:58 2008 +0100
@@ -27,6 +27,7 @@
 
 import java.nio.file.spi.FileSystemProvider;
 import java.net.URI;
+import java.util.Iterator;
 
 /**
  * This class consists exclusively of static methods that return a {@link Path}
--- a/src/share/classes/java/nio/file/SecureDirectoryStream.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/SecureDirectoryStream.java	Tue Oct 07 18:00:58 2008 +0100
@@ -51,7 +51,10 @@
  * java.util.Iterator#remove() remove} method removes the directory entry for
  * the last element returned by the iterator. In the case of a {@code
  * SecureDirectoryStream} the {@code remove} method behaves as if by invoking
- * the {@link #delete delete} method defined by this interface.
+ * the {@link #deleteFile deleteFile} or {@link #deleteDirectory deleteDirectory}
+ * methods defined by this interface. The {@code remove} may require to examine
+ * the file to determine if the file is a directory, and consequently, it may
+ * not be atomic with respect to other file system operations.
  *
  * <p> In the case of the default {@link java.nio.file.spi.FileSystemProvider
  * provider}, and a security manager is set, then the permission checks are
@@ -160,20 +163,19 @@
      *          if the file is opened for writing.
      */
     public abstract SeekableByteChannel newByteChannel(Path path,
-                                                               Set<? extends OpenOption> options,
-                                                               FileAttribute<?>... attrs)
+                                                       Set<? extends OpenOption> options,
+                                                       FileAttribute<?>... attrs)
         throws IOException;
 
     /**
-     * Deletes a file in this directory.
+     * Deletes a file.
      *
-     * <p> This method works in exactly the manner specified by the {@link
-     * FileRef#delete delete} method for the case that the {@code path}
-     * parameter is an {@link Path#isAbsolute absolute} path. When the parameter
-     * is a relative path then the file to delete is relative to this open
-     * directory. An implementation may require to examine the file to determine
-     * if the file is a directory and consequently this method may not be atomic
-     * with respect to an attacker that replaces the file.
+     * <p> Unlike the {@link FileRef#delete delete()} method, this method
+     * does not first examine the file to determine if the file is a directory.
+     * Whether a directory is deleted by this method is system dependent and
+     * therefore not specified. If the file is a symbolic-link then the link is
+     * deleted (not the final target of the link). When the parameter is a
+     * relative path then the file to delete is relative to this open directory.
      *
      * @param   path
      *          The path of the file to delete
@@ -182,9 +184,6 @@
      *          If the directory stream is closed
      * @throws  NoSuchFileException
      *          If the the file does not exist <i>(optional specific exception)</i>
-     * @throws  DirectoryNotEmptyException
-     *          If the file is a directory and could not otherwise be deleted
-     *          because the directory is not empty <i>(optional specific exception)</i>
      * @throws  IOException
      *          If an I/O error occurs
      * @throws  SecurityException
@@ -192,7 +191,35 @@
      *          installed, the {@link SecurityManager#checkDelete(String) checkDelete}
      *          method is invoked to check delete access to the file
      */
-    public abstract void delete(Path path) throws IOException;
+    public abstract void deleteFile(Path path) throws IOException;
+
+    /**
+     * Deletes a directory.
+     *
+     * <p> Unlike the {@link FileRef#delete delete()} method, this method
+     * does not first examine the file to determine if the file is a directory.
+     * Whether non-directories are deleted by this method is system dependent and
+     * therefore not specified. When the parameter is a relative path then the
+     * directory to delete is relative to this open directory.
+     *
+     * @param   path
+     *          The path of the directory to delete
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          If the directory stream is closed
+     * @throws  NoSuchFileException
+     *          If the the directory does not exist <i>(optional specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          If the directory could not otherwise be deleted because it is
+     *          not empty <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String) checkDelete}
+     *          method is invoked to check delete access to the directory
+     */
+    public abstract void deleteDirectory(Path path) throws IOException;
 
     /**
      * Move a file from this directory to another directory.
--- a/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -111,6 +111,14 @@
  * </table>
  * </blockquote>
  *
+ * <p> The {@link #getAttribute getAttribute} or {@link #readAttributes
+ * readAttributes} methods may be used to read the ACL or owner attributes as if
+ * by invoking the {@link #getAcl getAcl} or {@link #getOwner getOwner} methods.
+ *
+ * <p> The {@link #setAttribute setAttribute} method may be used to update the
+ * ACL or owner attributes as if by invoking the {@link #setAcl setAcl} or {@link
+ * #setOwner setOwner} methods.
+ *
  * <h4> Setting the ACL when creating a file </h4>
  *
  * <p> Implementations supporting this attribute view may also support setting
@@ -143,41 +151,6 @@
     String name();
 
     /**
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkRead(String) checkRead} method
-     *          denies read access to the file.
-     */
-    @Override
-    Object getAttribute(String attribute) throws IOException;
-
-    /**
-     * @throws  UnsupportedOperationException           {@inheritDoc}
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkRead(String) checkWrite} method
-     *          denies write access to the file.
-     */
-    @Override
-    void setAttribute(String attribute, Object value) throws IOException;
-
-    /**
-     *
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkRead(String) checkRead} method
-     *          denies read access to the file.
-     */
-    @Override
-    Map<String,?> readAttributes(String first, String... rest) throws IOException;
-
-    /**
      * Reads the access control list.
      *
      * <p> When the file system uses an ACL model that differs from the NFSv4
--- a/src/share/classes/java/nio/file/attribute/Attributes.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/attribute/Attributes.java	Tue Oct 07 18:00:58 2008 +0100
@@ -251,6 +251,7 @@
             String first = names[0];
             String[] rest = new String[rem];
             if (rem > 0) System.arraycopy(names, 1, rest, 0, rem);
+
             return view.readAttributes(first, rest);
         }
         // view not available
--- a/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -25,7 +25,6 @@
 
 package java.nio.file.attribute;
 
-import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.io.IOException;
 
@@ -95,6 +94,17 @@
  * </table>
  * </blockquote>
  *
+ * <p> The {@link #getAttribute getAttribute} or {@link #readAttributes
+ * readAttributes(String,String[])} methods may be used to read any of these
+ * attributes as if by invoking the {@link #readAttributes readAttributes()}
+ * method.
+ *
+ * <p> The {@link #setAttribute setAttribute} method may be used to update the
+ * file's last modified time, last access time or create time attributes as if
+ * by invoking the {@link #setTimes setTimes} method. In that case, the time
+ * value is interpreted in {@link TimeUnit#MILLISECONDS milliseconds} and
+ * converted to the precision supported by the file system.
+ *
  * @since 1.7
  * @see Attributes
  */
@@ -110,52 +120,6 @@
     String name();
 
     /**
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, its  {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the file
-     */
-    @Override
-    Object getAttribute(String attribute) throws IOException;
-
-    /**
-     * Sets/updates the value of an attribute.
-     *
-     * <p> This method may be used to update the file's last modified time, last
-     * access time or create time attributes as if by invoking the {@link
-     * #setTimes setTimes} method. The time value is interpreted in {@link
-     * TimeUnit#MILLISECONDS milliseconds} and converted to the precision
-     * supported by the file system.
-     *
-     * @param   attribute
-     *          The attribute name (case sensitive)
-     * @param   value
-     *          The attribute value
-     *
-     * @throws  IllegalArgumentException
-     *          If the time value is negative
-     * @throws  UnsupportedOperationException           {@inheritDoc}
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, its  {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method is invoked to check write access to the file
-     */
-    @Override
-    void setAttribute(String attribute, Object value) throws IOException;
-
-    /**
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the file
-     */
-    @Override
-    Map<String,?> readAttributes(String first, String... rest) throws IOException;
-
-    /**
      * Reads the basic file attributes as a bulk operation.
      *
      * <p> It is implementation specific if all file attributes are read as an
--- a/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -65,6 +65,19 @@
  * </table>
  * </blockquote>
  *
+ * <p> The {@link #getAttribute getAttribute} or {@link #readAttributes
+ * readAttributes(String,String[])} methods may be used to read any of these
+ * attributes, or any of the attributes defined by {@link BasicFileAttributeView}
+ * as if by invoking the {@link #readAttributes readAttributes()} method.
+ *
+ * <p> The {@link #setAttribute setAttribute} method may be used to update the
+ * file's last modified time, last access time or create time attributes as
+ * defined by {@link BasicFileAttributeView}. It may also be used to update
+ * the isReadOnly, isHidden, isSystem, and isArchive attributes as if by
+ * invoking the {@link #setReadOnly setReadOnly}, {@link #setHidden setHidden},
+ * {@link #setSystem setSystem}, and {@link #setArchive setArchive} methods
+ * respectively.
+ *
  * @since 1.7
  */
 
--- a/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -25,7 +25,6 @@
 
 package java.nio.file.attribute;
 
-import java.util.Map;
 import java.io.IOException;
 
 /**
@@ -42,7 +41,7 @@
  * is identified by the name {@code "owner"}, and the value of the attribute is
  * a {@link UserPrincipal}. The {@link #readAttributes readAttributes}, {@link
  * #getAttribute getAttribute} and {@link #setAttribute setAttributes} methods
- * may be used to read or update the file owner by attribute name.
+ * may be used to read or update the file owner.
  *
  * @since 1.7
  */
@@ -58,40 +57,6 @@
     String name();
 
     /**
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkRead(String) checkRead} method
-     *          denies read access to the file.
-     */
-    @Override
-    Object getAttribute(String attribute) throws IOException;
-
-    /**
-     * @throws  UnsupportedOperationException           {@inheritDoc}
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkRead(String) checkWrite} method
-     *          denies write access to the file.
-     */
-    @Override
-    void setAttribute(String attribute, Object value) throws IOException;
-
-    /**
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkRead(String) checkRead} method
-     *          denies read access to the file.
-     */
-    @Override
-    Map<String,?> readAttributes(String first, String... rest) throws IOException;
-
-    /**
      * Read the file owner.
      *
      * <p> It it implementation specific the file owner can be a {@link
--- a/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -54,6 +54,10 @@
  *   </tr>
  * </table>
  * </blockquote>
+ * <p> The {@link #getAttribute getAttribute} or {@link #readAttributes
+ * readAttributes(String,String[])} methods may be used to read any of these
+ * attributes as if by invoking the {@link #readAttributes readAttributes()}
+ * method.
  *
  * @since 1.7
  */
@@ -69,43 +73,6 @@
     String name();
 
     /**
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the file used to {@link
-     *          FileRef#getFileStore obtain} access to the file
-     *          system, and in addition it checks {@link RuntimePermission}<tt>
-     *          ("getFileStoreAttributes")</tt>
-     */
-    @Override
-    Object getAttribute(String attribute) throws IOException;
-
-    /**
-     * Sets/updates the value of an attribute.
-     *
-     * <p> This attribute view may not be used to update any file store
-     * attributes so this method always throws {@code UnsupportedOperationException}.
-     *
-     * @throws  UnsupportedOperationException       {@inheritDoc}
-     */
-    @Override
-    void setAttribute(String attribute, Object value) throws IOException;
-
-    /**
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the file used to {@link
-     *          FileRef#getFileStore obtain} access to the file
-     *          system, and in addition it checks {@link RuntimePermission}<tt>
-     *          ("getFileStoreAttributes")</tt>
-     */
-    @Override
-    Map<String,?> readAttributes(String first, String... rest) throws IOException;
-
-    /**
      * Reads the disk space attributes as a bulk operation.
      *
      * <p> It is file system specific if all attributes are read as an
--- a/src/share/classes/java/nio/file/attribute/NamedAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/attribute/NamedAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -26,28 +26,27 @@
 package java.nio.file.attribute;
 
 import java.nio.ByteBuffer;
-import java.util.Map;
 import java.io.IOException;
 
 /**
  * A file attribute view that provides a view of a file's <em>named
- * attributes</em>. This {@code FileAttributeView} provides a view of a file's
- * named attributes as a set of name/value pairs. It is primarily intended for
- * file system implementations that support a mechanism to associate metadata
- * with a file that is not meaningful to the file system. It may also be
- * emulated on file systems that do not support this feature directly but
- * instead support <em>named subfiles</em>, a concept whereby a file may have
- * several named streams. The details of such emulation is highly
- * implementation specific and therefore not specified.
+ * attributes</em>. Named attributes are typically <em>user-defined</em> and
+ * used to store metadata with a file that is not meaningful to the file system.
+ * It is primarily intended for file system implementations that support such a
+ * mechanism directly but may be emulated by other means. For example, some
+ * file systems have support for <em>extended attributes</em> or <em>named
+ * streams</em>. The details of such emulation is highly implementation specific
+ * and therefore not specified.
  *
- * <p> This {@code FileAttributeView} represents an attribute name as a {@code
- * String}. An implementation may require to encode and decode from the platform
- * or file system representation when accessing the attribute. The {@link #read
- * read} and {@link #write write} methods are defined to read into or write from
- * a {@link ByteBuffer}. This {@code FileAttributeView} is not intended to be
- * used where the size of an attribute value is larger than  {@link
- * Integer#MAX_VALUE}.
-
+ * <p> This {@code FileAttributeView} provides a view of a file's named
+ * attributes as a set of name/value pairs, where the attribute name is
+ * represented by a {@code String}. An implementation may require to encode and
+ * decode from the platform or file system representation when accessing the
+ * attribute. The {@link #read read} and {@link #write write} methods are defined
+ * to read into or write from a {@link ByteBuffer}. This {@code FileAttributeView}
+ * is not intended to be used where the size of an attribute value is larger than
+ * {@link Integer#MAX_VALUE}.
+ *
  * <p> Named attributes may be used in some implementations to store security
  * related attributes so consequently, in the case of the default provider at
  * least, all methods that access named attributes require the
@@ -58,6 +57,9 @@
  * supportsFileAttributeView} method may be used to test if a specific {@link
  * java.nio.file.FileStore FileStore} supports the storage of named attributes.
  *
+ * <p> {@note There has some feedback that the read/write methods should use
+ * byte arrays instead of ByteBuffers.}
+ *
  * @since 1.7
  */
 
@@ -72,60 +74,15 @@
     String name();
 
     /**
-     * Reads the value of an attribute.
+     * Returns an object to iterate over the names of the file's named attributes.
+     * The ordering that the names are returned is not specified. The iterator is
+     * weakly consistent. It is thread safe. It may or may not reflect updates
+     * to the list of named attributes that occur after the {@code Iterator} is
+     * created. The iterator's {@link java.util.Iterator#remove remove} method
+     * removes the named attribute for the last element returned by the iterator,
+     * as if by invoking the {@link #delete delete} method.
      *
-     * <p> In this release, this method may not be used to read the value of a
-     * named attribute. Consequently this method will return {@code null}.
-     *
-     * @throws  IOException                             {@inheritDoc}
-     */
-    @Override
-    Object getAttribute(String attribute) throws IOException;
-
-    /**
-     * Writes the value of an named attribute from a buffer.
-     *
-     * <p> The {@code value} parameter is a {@link ByteBuffer} and this method
-     * writes the value of the attribute from the buffer as if by invoking
-     * the {@link #write write} method.
-     *
-     * @throws  UnsupportedOperationException           {@inheritDoc}
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, and it denies {@link
-     *          RuntimePermission}<tt>("accessNamedAttributes")</tt>
-     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method denies write access to the file.
-     */
-    @Override
-    void setAttribute(String attribute, Object value) throws IOException;
-
-    /**
-     * Reads all, or a subset, of the attributes supported by this file attribute
-     * view.
-     *
-     * <p> In this release, file attribute views of this type may not be used
-     * to read the value of named attributes. Consequently this method will
-     * return an empty {@code Map}.
-     *
-     * @throws  IOException                             {@inheritDoc}
-     */
-    @Override
-    Map<String,?> readAttributes(String first, String... rest) throws IOException;
-
-    /**
-     * Returns an object to iterate over the names of the file's named
-     * attributes. The ordering that the names are returned is not specified.
-     * The iterator is weakly consistent. It is thread safe. It may or may not
-     * reflect updates to the list of named attributes that occur after the
-     * {@code Iterable} is created. The iterator's {@link
-     * java.util.Iterator#remove remove} method removes the named attribute for
-     * the last element returned by the iterator, as if by invoking the delete
-     * {@link #delete delete} method.
-     *
-     * @return  An object to iterate over the names of the file's named
-     *          attributes
+     * @return  An iterator over the names of the file's named attributes
      *
      * @throws  IOException
      *          If an I/O error occurs
@@ -171,6 +128,17 @@
      * {@code p} is the buffer's position. Upon return the buffer's position
      * will be equal to {@code p + n}; its limit will not have changed.
      *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to read a file's MIME type that is stored as a named
+     * attribute:
+     * <pre>
+     *    NamedAttributeView view = file.getFileAttributeView(NamedAttributeView, true);
+     *    String name = "user.mimetype";
+     *    ByteBuffer buf = ByteBuffer.allocate(view.size(name));
+     *    view.read(name, buf);
+     *    String value = Charset.defaultCharset().decode(buf.flip()).toString();
+     * </pre>
+     *
      * @param   name
      *          The attribute name
      * @param   dst
@@ -216,6 +184,13 @@
      * attribute name or value exceed an implementation specific maximum size
      * then an {@code IOException} is thrown.
      *
+     * <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, true);
+     *    view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
+     * </pre>
+     *
      * @param   name
      *          The attribute name
      * @param   src
--- a/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -27,7 +27,6 @@
 
 import java.nio.file.*;
 import java.util.Set;
-import java.util.Map;
 import java.io.IOException;
 
 /**
@@ -96,6 +95,18 @@
  * </table>
  * </blockquote>
  *
+ * <p> The {@link #getAttribute getAttribute} or {@link #readAttributes
+ * readAttributes(String,String[])} methods may be used to read any of these
+ * attributes, or any of the attributes defined by {@link BasicFileAttributeView}
+ * as if by invoking the {@link #readAttributes readAttributes()} method.
+ *
+ * <p> The {@link #setAttribute setAttribute} method may be used to update the
+ * file's last modified time, last access time or create time attributes as
+ * defined by {@link BasicFileAttributeView}. It may also be used to update
+ * the permissions, owner, or group-owner as if by invoking the {@link
+ * #setPermissions setPermissions}, {@link #setOwner setOwner}, and {@link
+ * #setGroup setGroup} methods respectively.
+ *
  * <h4> Setting Initial Permissions </h4>
  * <p> Implementations supporting this attribute view may also support setting
  * the initial permissions when creating a file or directory. The
@@ -142,47 +153,6 @@
     String name();
 
     /**
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
-     *          method denies read access to the file. If this method is invoked
-     *          to read the file's permissions, owner, or group then the
-     *          security manager is also invoked to check {@link RuntimePermission}
-     *          <tt>("accessUserInformation")</tt>.
-     */
-    @Override
-    Object getAttribute(String attribute) throws IOException;
-
-    /**
-     * @throws  IllegalArgumentException                {@inheritDoc}
-     * @throws  UnsupportedOperationException           {@inheritDoc}
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, its {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method denies write access to the file. If this method is invoked
-     *          to update the file's permissions, owner, or group then the
-     *          security manager is also invoked to check {@link RuntimePermission}
-     *          <tt>("accessUserInformation")</tt>.
-     */
-    @Override
-    void setAttribute(String attribute, Object value) throws IOException;
-
-    /**
-     * @throws  IOException                             {@inheritDoc}
-     * @throws  SecurityException
-     *          In the case of the default provider, a security manager is
-     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
-     *          method denies read access to the file. If this method is invoked
-     *          to read the file's permissions, owner, or group then the
-     *          security manager is also invoked to check {@link RuntimePermission}
-     *          <tt>("accessUserInformation")</tt>.
-     */
-    @Override
-    Map<String,?> readAttributes(String first, String... rest) throws IOException;
-
-    /**
      * @throws  IOException                {@inheritDoc}
      * @throws  SecurityException
      *          In the case of the default provider, a security manager is
--- a/src/share/classes/java/nio/file/spi/FileSystemProvider.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/java/nio/file/spi/FileSystemProvider.java	Tue Oct 07 18:00:58 2008 +0100
@@ -140,20 +140,20 @@
     }
 
     /**
-     * Returns a list of the installed file system providers.
+     * Returns an object to iterate over the installed file system providers.
      *
      * <p> The first invocation of this method causes the default provider to be
      * initialized (if not already initialized) and loads any other installed
      * providers as described by the {@link FileSystems} class.
      *
-     * @return  An unmodifiable list of the installed providers. The list
-     *          contains at least one element, that is the default file system
-     *          provider
+     * @return  An object to iterate over the installed file system providers. The
+     *          iterator returns at least one element, that is the default file
+     *          system provider
      *
      * @throws  ServiceConfigurationError
      *          When an error occurs while loading a service provider
      */
-    public static List<FileSystemProvider> installedProviders() {
+    public static Iterable<FileSystemProvider> installedProviders() {
         if (installedProviders == null) {
             // ensure default provider is initialized
             FileSystemProvider defaultProvider = FileSystems.getDefault().provider();
--- a/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Tue Oct 07 18:00:58 2008 +0100
@@ -455,7 +455,7 @@
 
     @Override
     @SuppressWarnings("unchecked")
-    public final SocketAddress getConnectedAddress() {
+    public final SocketAddress getRemoteAddress() {
         return (isOpen()) ? remoteAddress : null;
     }
 
@@ -524,7 +524,7 @@
                     sb.append(" local=");
                     sb.append(local.toString());
                 }
-                SocketAddress remote = getConnectedAddress();
+                SocketAddress remote = getRemoteAddress();
                 if (remote != null) {
                     sb.append(" remote=");
                     sb.append(remote.toString());
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Tue Oct 07 18:00:58 2008 +0100
@@ -40,7 +40,7 @@
 
 class DatagramChannelImpl
     extends DatagramChannel
-    implements SelChImpl
+    implements MulticastChannel, SelChImpl
 {
 
     // Used to make native read and write calls
@@ -155,7 +155,7 @@
     }
 
     @Override
-    public SocketAddress getConnectedAddress() throws IOException {
+    public SocketAddress getRemoteAddress() throws IOException {
         synchronized (stateLock) {
             if (!isOpen())
                 return null;
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Tue Oct 07 18:00:58 2008 +0100
@@ -134,7 +134,7 @@
     }
 
     @Override
-    public SocketAddress getConnectedAddress() throws IOException {
+    public SocketAddress getRemoteAddress() throws IOException {
         synchronized (stateLock) {
             if (!isOpen())
                 return null;
--- a/src/share/classes/sun/nio/fs/AbstractNamedAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/classes/sun/nio/fs/AbstractNamedAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -112,9 +112,11 @@
 
     @Override
     public final Object getAttribute(String attribute) throws IOException {
-        if (attribute == null)
-            throw new NullPointerException();
-        return null;
+        int size = size(attribute);
+        ByteBuffer buf = ByteBuffer.allocate(size);
+        read(attribute, buf);
+        buf.flip();
+        return buf;
     }
 
     @Override
@@ -125,9 +127,42 @@
     }
 
     @Override
-    public final Map<String,?> readAttributes(String first, String... rest) {
-        if (first == null || rest == null)
-            throw new NullPointerException();
-        return Collections.emptyMap();
+    public final Map<String,?> readAttributes(String first, String... rest)
+        throws IOException
+    {
+        // names of attributes to return
+        List<String> names = new ArrayList<String>();
+
+        boolean readAll = false;
+        if (first.equals("*")) {
+            readAll = true;
+        } else {
+            names.add(first);
+            for (String name: rest) {
+                if (name.equals("*")) {
+                    readAll = true;
+                    break;
+                }
+                names.add(name);
+            }
+        }
+        if (readAll) {
+            names.clear();
+            for (String name: list()) {
+                names.add(name);
+            }
+        }
+
+        // allocate buffer for each value and return as map
+        Map<String,ByteBuffer> result = new HashMap<String,ByteBuffer>();
+        for (String name: names) {
+            int size = size(name);
+            ByteBuffer buf = ByteBuffer.allocate(size);
+            read(name, buf);
+            result.put(name, buf);
+            buf.flip();
+        }
+
+        return result;
     }
 }
--- a/src/share/sample/nio/multicast/Reader.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/share/sample/nio/multicast/Reader.java	Tue Oct 07 18:00:58 2008 +0100
@@ -101,14 +101,14 @@
 
         if (includeList.isEmpty()) {
             // join group and block addresses on the exclude list
-            MembershipKey key = dc.join(target.group(), target.interf());
+            MembershipKey key = ((MulticastChannel)dc).join(target.group(), target.interf());
             for (InetAddress source: excludeList) {
                 key.block(source);
             }
         } else {
             // join with source-specific membership for each source
             for (InetAddress source: includeList) {
-                dc.join(target.group(), target.interf(), source);
+                ((MulticastChannel)dc).join(target.group(), target.interf(), source);
             }
         }
 
--- a/src/solaris/classes/sun/nio/fs/LinuxNamedAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/solaris/classes/sun/nio/fs/LinuxNamedAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -26,13 +26,11 @@
 package sun.nio.fs;
 
 import java.nio.file.*;
-import java.nio.file.attribute.NamedAttributeView;
 import java.nio.ByteBuffer;
 import java.io.IOException;
 import java.util.*;
 import sun.misc.Unsafe;
 
-import static sun.nio.fs.UnixNativeDispatcher.*;
 import static sun.nio.fs.UnixConstants.*;
 import static sun.nio.fs.LinuxNativeDispatcher.*;
 
--- a/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Tue Oct 07 18:00:58 2008 +0100
@@ -100,6 +100,8 @@
     protected FileAttributeView newFileAttributeView(String name, UnixPath file, boolean followLinks) {
         if (name.equals("acl"))
             return new SolarisAclFileAttributeView(file, followLinks);
+        if (name.equals("xattr"))
+            return new SolarisNamedAttributeView(file, followLinks);
         return super.newFileAttributeView(name, file, followLinks);
     }
 
--- a/src/solaris/classes/sun/nio/fs/SolarisNamedAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/solaris/classes/sun/nio/fs/SolarisNamedAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -26,7 +26,6 @@
 package sun.nio.fs;
 
 import java.nio.file.*;
-import java.nio.file.attribute.NamedAttributeView;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.io.IOException;
--- a/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java	Tue Oct 07 18:00:58 2008 +0100
@@ -245,7 +245,8 @@
             // use (race-free) unlinkat if available
             try {
                 if (stream instanceof UnixSecureDirectoryStream) {
-                    ((UnixSecureDirectoryStream)stream).delete(entry.getName());
+                    ((UnixSecureDirectoryStream)stream)
+                        .implDelete(entry.getName(), false, 0);
                 } else {
                     entry.delete(true);
                 }
--- a/src/solaris/classes/sun/nio/fs/UnixFileSystem.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixFileSystem.java	Tue Oct 07 18:00:58 2008 +0100
@@ -131,14 +131,16 @@
      */
     @Override
     public final Iterable<Path> getRootDirectories() {
+        List<Path> roots;
         try {
             SecurityManager sm = System.getSecurityManager();
             if (sm != null)
                 sm.checkRead(rootDirectory.toString());
-            return Arrays.asList((Path)rootDirectory);
+            roots = Collections.unmodifiableList(Arrays.asList((Path)rootDirectory));
         } catch (SecurityException x) {
-            return Collections.emptyList();
+            roots = Collections.emptyList();
         }
+        return roots;
     }
 
     /**
@@ -224,7 +226,6 @@
     @Override
     public final Iterable<FileStore> getFileStores() {
         Iterator<UnixMountEntry> entries = getMountEntries().iterator();
-
         final FileStoreIterator iterator = new FileStoreIterator(entries);
         return new Iterable<FileStore>() {
             public Iterator<FileStore> iterator() {
--- a/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java	Tue Oct 07 18:00:58 2008 +0100
@@ -168,10 +168,12 @@
     }
 
     /**
-     * Deletes file in this directory
+     * Deletes file/directory in this directory. Works in a race-free manner
+     * when invoked with flags.
      */
-    @Override
-    public void delete(Path obj) throws IOException {
+    void implDelete(Path obj, boolean haveFlags, int flags)
+        throws IOException
+    {
         UnixPath file = getName(obj);
 
         // permission check using name resolved against original path of directory
@@ -185,21 +187,24 @@
             if (!ds.isOpen())
                 throw new ClosedDirectoryStreamException();
 
-            // need file attribute to know if file is directory
-            UnixFileAttributes attrs = null;
+            if (!haveFlags) {
+                // need file attribute to know if file is directory. This creates
+                // a race in that the file may be replaced by a directory or a
+                // directory replaced by a file between the time we query the
+                // file type and unlink it.
+                UnixFileAttributes attrs = null;
+                try {
+                    attrs = UnixFileAttributes.get(dfd, file.asByteArray(), false);
+                } catch (UnixException x) {
+                    x.rethrowAsIOException(file);
+                }
+                flags = (attrs.isDirectory()) ? AT_REMOVEDIR : 0;
+            }
+
             try {
-                attrs = UnixFileAttributes.get(dfd, file.asByteArray(), false);
+                unlinkat(dfd, file.asByteArray(), flags);
             } catch (UnixException x) {
-                x.rethrowAsIOException(file);
-            }
-            // there is a race here. If a file is replaced by a direcory or
-            // a direcory replaced by a file then the following will either
-            // fail or unlink a directory (if that is allowed).
-            try {
-                int flag = (attrs.isDirectory()) ? AT_REMOVEDIR : 0;
-                unlinkat(dfd, file.asByteArray(), flag);
-            } catch (UnixException x) {
-                if (attrs.isDirectory()) {
+                if ((flags & AT_REMOVEDIR) != 0) {
                     if (x.errno() == EEXIST || x.errno() == ENOTEMPTY) {
                         throw new DirectoryNotEmptyException(null);
                     }
@@ -211,6 +216,15 @@
         }
     }
 
+    @Override
+    public void deleteFile(Path file) throws IOException {
+        implDelete(file, true, 0);
+    }
+
+    @Override
+    public void deleteDirectory(Path dir) throws IOException {
+        implDelete(dir, true, AT_REMOVEDIR);
+    }
 
     /**
      * Rename/move file in this directory to another (open) directory
--- a/src/windows/classes/sun/nio/fs/WindowsFileSystem.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/windows/classes/sun/nio/fs/WindowsFileSystem.java	Tue Oct 07 18:00:58 2008 +0100
@@ -140,7 +140,7 @@
                 result.add(WindowsPath.createFromNormalizedPath(this, root));
             }
         }
-        return result;
+        return Collections.unmodifiableList(result);
     }
 
     /**
--- a/src/windows/classes/sun/nio/fs/WindowsNamedAttributeView.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/src/windows/classes/sun/nio/fs/WindowsNamedAttributeView.java	Tue Oct 07 18:00:58 2008 +0100
@@ -167,7 +167,6 @@
                 buffer.release();
             CloseHandle(handle);
         }
-
         return new Iterable<String>() {
             @Override
             public Iterator<String> iterator() {
--- a/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Tue Oct 07 18:00:58 2008 +0100
@@ -155,7 +155,7 @@
             throw new RuntimeException("Not bound to local address");
 
         // check remote address
-        InetSocketAddress remote = (InetSocketAddress)ch.getConnectedAddress();
+        InetSocketAddress remote = (InetSocketAddress)ch.getRemoteAddress();
         if (remote.getPort() != server.address().getPort())
             throw new RuntimeException("Connected to unexpected port");
         if (!remote.getAddress().equals(server.address().getAddress()))
--- a/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java	Tue Oct 07 18:00:58 2008 +0100
@@ -55,8 +55,8 @@
             .bind(new InetSocketAddress(source, 0));
 
         // check existing key is returned
-        MembershipKey key = dc.join(group, nif);
-        MembershipKey other = dc.join(group, nif);
+        MembershipKey key = ((MulticastChannel)dc).join(group, nif);
+        MembershipKey other = ((MulticastChannel)dc).join(group, nif);
         if (other != key) {
             throw new RuntimeException("existing key not returned");
         }
@@ -79,8 +79,8 @@
 
         // source-specific
         try {
-            key = dc.join(group, nif, source);
-            other = dc.join(group, nif, source);
+            key = ((MulticastChannel)dc).join(group, nif, source);
+            other = ((MulticastChannel)dc).join(group, nif, source);
             if (other != key) {
                 throw new RuntimeException("existing key not returned");
             }
@@ -123,18 +123,18 @@
 
         // IllegalStateException
         MembershipKey key;
-        key = dc.join(group, nif);
+        key = ((MulticastChannel)dc).join(group, nif);
         try {
-            dc.join(group, nif, thisHost);
+            ((MulticastChannel)dc).join(group, nif, thisHost);
             throw new RuntimeException("IllegalStateException not thrown");
         } catch (IllegalStateException x) {
         } catch (UnsupportedOperationException x) {
         }
         key.drop();
         try {
-            key = dc.join(group, nif, thisHost);
+            key = ((MulticastChannel)dc).join(group, nif, thisHost);
             try {
-                dc.join(group, nif);
+                ((MulticastChannel)dc).join(group, nif);
                 throw new RuntimeException("IllegalStateException not thrown");
             } catch (IllegalStateException x) {
             }
@@ -144,12 +144,12 @@
 
         // IllegalArgumentException
         try {
-            dc.join(notGroup, nif);
+            ((MulticastChannel)dc).join(notGroup, nif);
             throw new RuntimeException("IllegalArgumentException not thrown");
         } catch (IllegalArgumentException x) {
         }
         try {
-            dc.join(notGroup, nif, thisHost);
+            ((MulticastChannel)dc).join(notGroup, nif, thisHost);
             throw new RuntimeException("IllegalArgumentException not thrown");
         } catch (IllegalArgumentException x) {
         } catch (UnsupportedOperationException x) {
@@ -157,17 +157,17 @@
 
         // NullPointerException
         try {
-            dc.join(null, nif);
+            ((MulticastChannel)dc).join(null, nif);
             throw new RuntimeException("NullPointerException not thrown");
         } catch (NullPointerException x) {
         }
         try {
-            dc.join(group, null);
+            ((MulticastChannel)dc).join(group, null);
             throw new RuntimeException("NullPointerException not thrown");
         } catch (NullPointerException x) {
         }
         try {
-            dc.join(group, nif, null);
+            ((MulticastChannel)dc).join(group, nif, null);
             throw new RuntimeException("NullPointerException not thrown");
         } catch (NullPointerException x) {
         } catch (UnsupportedOperationException x) {
@@ -177,12 +177,12 @@
 
         // ClosedChannelException
         try {
-            dc.join(group, nif);
+            ((MulticastChannel)dc).join(group, nif);
             throw new RuntimeException("ClosedChannelException not thrown");
         } catch (ClosedChannelException x) {
         }
         try {
-            dc.join(group, nif, thisHost);
+            ((MulticastChannel)dc).join(group, nif, thisHost);
             throw new RuntimeException("ClosedChannelException not thrown");
         } catch (ClosedChannelException x) {
         } catch (UnsupportedOperationException x) {
--- a/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java	Tue Oct 07 18:00:58 2008 +0100
@@ -142,7 +142,7 @@
         // join group
         System.out.format("join %s @ %s\n", group.getHostAddress(),
             nif.getName());
-        MembershipKey key = dc.join(group, nif);
+        MembershipKey key = ((MulticastChannel)dc).join(group, nif);
 
         // send message to group
         int port = ((InetSocketAddress)dc.getLocalAddress()).getPort();
@@ -181,14 +181,14 @@
             nif.getName(), bogus.getHostAddress());
         try {
             // may throw UOE
-            key = dc.join(group, nif, bogus);
+            key = ((MulticastChannel)dc).join(group, nif, bogus);
 
             id = sendDatagram(source, nif, group, port);
             receiveDatagram(dc, null, id);
 
             System.out.format("join %s @ %s only-source %s\n", group.getHostAddress(),
                 nif.getName(), source.getHostAddress());
-            key = dc.join(group, nif, source);
+            key = ((MulticastChannel)dc).join(group, nif, source);
 
             id = sendDatagram(source, nif, group, port);
             receiveDatagram(dc, source, id);
--- a/test/java/nio/channels/etc/NetworkChannelTests.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/test/java/nio/channels/etc/NetworkChannelTests.java	Tue Oct 07 18:00:58 2008 +0100
@@ -109,7 +109,7 @@
     }
 
     /**
-     * Exercise getConnectedAddress method (SocketChannel only)
+     * Exercise getRemoteAddress method (SocketChannel only)
      */
     static void connectedAddressTests() throws IOException {
         ServerSocketChannel ssc = ServerSocketChannel.open()
@@ -121,19 +121,19 @@
         SocketChannel sc = SocketChannel.open();
 
         // not connected
-        if (sc.getConnectedAddress() != null)
-            throw new RuntimeException("getConnectedAddress returned address when not connected");
+        if (sc.getRemoteAddress() != null)
+            throw new RuntimeException("getRemoteAddress returned address when not connected");
 
         // connected
         sc.connect(server);
-        SocketAddress remote = sc.getConnectedAddress();
+        SocketAddress remote = sc.getRemoteAddress();
         if (!remote.equals(server))
-            throw new RuntimeException("getConnectedAddress returned incorrect address");
+            throw new RuntimeException("getRemoteAddress returned incorrect address");
 
         // closed
         sc.close();
-        if (sc.getConnectedAddress() != null)
-            throw new RuntimeException("getConnectedAddress returned address when closed");
+        if (sc.getRemoteAddress() != null)
+            throw new RuntimeException("getRemoteAddress returned address when closed");
 
         ssc.close();
     }
--- a/test/java/nio/file/DirectoryStream/SecureDS.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/test/java/nio/file/DirectoryStream/SecureDS.java	Tue Oct 07 18:00:58 2008 +0100
@@ -156,11 +156,11 @@
 
         // Test: delete
         if (supportsLinks) {
-            stream.delete(link1Entry);
-            stream.delete(link2Entry);
+            stream.deleteFile(link1Entry);
+            stream.deleteFile(link2Entry);
         }
-        stream.delete(dirEntry);
-        stream.delete(fileEntry);
+        stream.deleteDirectory(dirEntry);
+        stream.deleteFile(fileEntry);
 
         // Test: remove
         // (requires resetting environment to get new iterator)
@@ -210,13 +210,13 @@
         stream1.move(fileEntry, stream2, target);
         assertTrue(dir1.resolve(fileEntry).notExists());
         assertTrue(dir2.resolve(target).exists());
-        stream2.delete(target);
+        stream2.deleteFile(target);
 
         // Test: move dir1/mydir -> dir2/newfile
         stream1.move(dirEntry, stream2, target);
         assertTrue(dir1.resolve(dirEntry).notExists());
         assertTrue(dir2.resolve(target).exists());
-        stream2.delete(target);
+        stream2.deleteDirectory(target);
 
         // Test: move dir1/mylink -> dir2/newfile
         if (supportsLinks) {
@@ -225,7 +225,7 @@
                 .getFileAttributeView(BasicFileAttributeView.class, false)
                 .readAttributes()
                 .isSymbolicLink());
-            stream2.delete(target);
+            stream2.deleteFile(target);
         }
 
         // Test: move between devices
@@ -241,7 +241,7 @@
                     shouldNotGetHere();
                 } catch (AtomicMoveNotSupportedException x) { }
                 ts.close();
-                stream1.delete(fileEntry);
+                stream1.deleteFile(fileEntry);
             }
         }
 
@@ -300,7 +300,11 @@
             shouldNotGetHere();
         } catch (NullPointerException x) { }
         try {
-            stream.delete(null);
+            stream.deleteFile(null);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.deleteDirectory(null);
             shouldNotGetHere();
         } catch (NullPointerException x) { }
 
@@ -322,7 +326,7 @@
             shouldNotGetHere();
         } catch (ClosedDirectoryStreamException x) { }
         try {
-            stream.delete(file);
+            stream.deleteFile(file);
             shouldNotGetHere();
         } catch (ClosedDirectoryStreamException x) { }
 
--- a/test/java/nio/file/spi/TestProvider.java	Tue Oct 07 14:11:10 2008 +0100
+++ b/test/java/nio/file/spi/TestProvider.java	Tue Oct 07 18:00:58 2008 +0100
@@ -25,8 +25,7 @@
 import java.nio.file.*;
 import java.nio.file.attribute.*;
 import java.net.URI;
-import java.util.Set;
-import java.util.Map;
+import java.util.*;
 import java.io.IOException;
 
 public class TestProvider extends FileSystemProvider {