--- a/make/com/sun/nio/sctp/mapfile-vers Mon Jun 29 15:05:15 2009 +0100
+++ b/make/com/sun/nio/sctp/mapfile-vers Mon Jun 29 15:08:52 2009 +0100
@@ -27,6 +27,7 @@ SUNWprivate_1.1 {
global:
Java_sun_nio_ch_SctpNet_socket0;
Java_sun_nio_ch_SctpNet_bindx;
+ Java_sun_nio_ch_SctpNet_branch0;
Java_sun_nio_ch_SctpNet_getLocalAddresses0;
Java_sun_nio_ch_SctpNet_getRemoteAddresses0;
Java_sun_nio_ch_SctpNet_getPrimAddrOption0;
--- a/make/java/java/FILES_java.gmk Mon Jun 29 15:05:15 2009 +0100
+++ b/make/java/java/FILES_java.gmk Mon Jun 29 15:08:52 2009 +0100
@@ -412,6 +412,7 @@ JAVA_JAVA_java = \
java/io/FileReader.java \
java/io/PipedReader.java \
java/io/StringReader.java \
+ java/io/TempFileHelper.java \
java/io/Writer.java \
java/io/BufferedWriter.java \
java/io/PrintWriter.java \
--- a/make/java/nio/FILES_java.gmk Mon Jun 29 15:05:15 2009 +0100
+++ b/make/java/nio/FILES_java.gmk Mon Jun 29 15:08:52 2009 +0100
@@ -86,8 +86,6 @@ FILES_src = \
java/nio/file/CopyOption.java \
java/nio/file/DirectoryNotEmptyException.java \
java/nio/file/DirectoryStream.java \
- java/nio/file/DirectoryStreamFilters.java \
- java/nio/file/FileAction.java \
java/nio/file/FileAlreadyExistsException.java \
java/nio/file/FileRef.java \
java/nio/file/FileStore.java \
@@ -141,6 +139,7 @@ FILES_src = \
java/nio/file/attribute/FileStoreAttributeView.java \
java/nio/file/attribute/FileStoreSpaceAttributeView.java \
java/nio/file/attribute/FileStoreSpaceAttributes.java \
+ java/nio/file/attribute/FileTime.java \
java/nio/file/attribute/GroupPrincipal.java \
java/nio/file/attribute/UserDefinedFileAttributeView.java \
java/nio/file/attribute/PosixFileAttributeView.java \
@@ -151,7 +150,6 @@ FILES_src = \
java/nio/file/attribute/UserPrincipalLookupService.java \
java/nio/file/attribute/UserPrincipalNotFoundException.java \
\
- java/nio/file/spi/AbstractPath.java \
java/nio/file/spi/FileSystemProvider.java \
java/nio/file/spi/FileTypeDetector.java \
\
@@ -248,8 +246,8 @@ FILES_src = \
\
sun/nio/fs/AbstractAclFileAttributeView.java \
sun/nio/fs/AbstractBasicFileAttributeView.java \
- sun/nio/fs/AbstractFileStoreSpaceAttributeView.java \
sun/nio/fs/AbstractFileTypeDetector.java \
+ sun/nio/fs/AbstractPath.java \
sun/nio/fs/AbstractPoller.java \
sun/nio/fs/AbstractUserDefinedFileAttributeView.java \
sun/nio/fs/AbstractWatchKey.java \
@@ -258,12 +256,13 @@ FILES_src = \
sun/nio/fs/Cancellable.java \
sun/nio/fs/DefaultFileSystemProvider.java \
sun/nio/fs/DefaultFileTypeDetector.java \
+ sun/nio/fs/DynamicFileAttributeView.java \
sun/nio/fs/FileOwnerAttributeViewImpl.java \
sun/nio/fs/Globs.java \
- sun/nio/fs/MimeType.java \
sun/nio/fs/NativeBuffer.java \
sun/nio/fs/NativeBuffers.java \
sun/nio/fs/Reflect.java \
+ sun/nio/fs/Util.java \
\
java/net/DatagramSocket.java \
java/net/DatagramSocketImpl.java \
--- a/make/java/nio/mapfile-linux Mon Jun 29 15:05:15 2009 +0100
+++ b/make/java/nio/mapfile-linux Mon Jun 29 15:08:52 2009 +0100
@@ -142,7 +142,7 @@ SUNWprivate_1.1 {
Java_sun_nio_fs_LinuxNativeDispatcher_fremovexattr0;
Java_sun_nio_fs_LinuxNativeDispatcher_setmntent0;
Java_sun_nio_fs_LinuxNativeDispatcher_endmntent;
- Java_sun_nio_fs_UnixNativeDispatcher_initIDs;
+ Java_sun_nio_fs_UnixNativeDispatcher_init;
Java_sun_nio_fs_UnixNativeDispatcher_getcwd;
Java_sun_nio_fs_UnixNativeDispatcher_strerror;
Java_sun_nio_fs_UnixNativeDispatcher_dup;
--- a/make/java/nio/mapfile-solaris Mon Jun 29 15:05:15 2009 +0100
+++ b/make/java/nio/mapfile-solaris Mon Jun 29 15:08:52 2009 +0100
@@ -120,7 +120,7 @@ SUNWprivate_1.1 {
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs;
- Java_sun_nio_fs_UnixNativeDispatcher_initIDs;
+ Java_sun_nio_fs_UnixNativeDispatcher_init;
Java_sun_nio_fs_UnixNativeDispatcher_getcwd;
Java_sun_nio_fs_UnixNativeDispatcher_strerror;
Java_sun_nio_fs_UnixNativeDispatcher_dup;
--- a/src/share/classes/java/io/File.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/io/File.java Mon Jun 29 15:08:52 2009 +0100
@@ -30,14 +30,14 @@ import java.net.URL;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
-import java.util.*;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
+import java.util.List;
+import java.util.ArrayList;
import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.security.SecureRandom;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.FileAttribute;
import sun.security.action.GetPropertyAction;
-
/**
* An abstract representation of file and directory pathnames.
@@ -787,7 +787,7 @@ public class File
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
*
- * @see Attributes#readBasicFileAttributes
+ * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public boolean isDirectory() {
SecurityManager security = System.getSecurityManager();
@@ -813,7 +813,7 @@ public class File
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
*
- * @see Attributes#readBasicFileAttributes
+ * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public boolean isFile() {
SecurityManager security = System.getSecurityManager();
@@ -863,7 +863,7 @@ public class File
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
*
- * @see Attributes#readBasicFileAttributes
+ * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public long lastModified() {
SecurityManager security = System.getSecurityManager();
@@ -887,7 +887,7 @@ public class File
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
*
- * @see Attributes#readBasicFileAttributes
+ * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public long length() {
SecurityManager security = System.getSecurityManager();
@@ -1369,9 +1369,10 @@ public class File
* Sets the owner's or everybody's write permission for this abstract
* pathname.
*
- * <p> The {@link Attributes Attributes} class defines methods that operate
- * on file attributes including file permissions. This may be used when
- * finer manipulation of file permissions is required.
+ * <p> The {@link java.nio.file.attribute.Attributes Attributes} class
+ * defines methods that operate on file attributes including file
+ * permissions. This may be used when finer manipulation of file permissions
+ * is required.
*
* @param writable
* If <code>true</code>, sets the access permission to allow write
@@ -1436,9 +1437,10 @@ public class File
* Sets the owner's or everybody's read permission for this abstract
* pathname.
*
- * <p> The {@link Attributes Attributes} class defines methods that operate
- * on file attributes including file permissions. This may be used when
- * finer manipulation of file permissions is required.
+ * <p> The {@link java.nio.file.attribute.Attributes Attributes} class
+ * defines methods that operate on file attributes including file
+ * permissions. This may be used when finer manipulation of file permissions
+ * is required.
*
* @param readable
* If <code>true</code>, sets the access permission to allow read
@@ -1509,9 +1511,10 @@ public class File
* Sets the owner's or everybody's execute permission for this abstract
* pathname.
*
- * <p> The {@link Attributes Attributes} class defines methods that operate
- * on file attributes including file permissions. This may be used when
- * finer manipulation of file permissions is required.
+ * <p> The {@link java.nio.file.attribute.Attributes Attributes} class
+ * defines methods that operate on file attributes including file
+ * permissions. This may be used when finer manipulation of file permissions
+ * is required.
*
* @param executable
* If <code>true</code>, sets the access permission to allow execute
@@ -1748,16 +1751,17 @@ public class File
return fs.getSpace(this, FileSystem.SPACE_USABLE);
}
-
/* -- Temporary files -- */
- private static class TemporaryDirectory {
- private TemporaryDirectory() { }
-
- static final String valueAsString = fs.normalize(
- AccessController.doPrivileged(new GetPropertyAction("java.io.tmpdir")));
- static final File valueAsFile =
- new File(valueAsString, fs.prefixLength(valueAsString));
+ static class TempDirectory {
+ private TempDirectory() { }
+
+ // temporary directory location
+ private static final File tmpdir = new File(fs.normalize(AccessController
+ .doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
+ static File location() {
+ return tmpdir;
+ }
// file name generation
private static final SecureRandom random = new SecureRandom();
@@ -1770,25 +1774,6 @@ public class File
}
return new File(dir, prefix + Long.toString(n) + suffix);
}
-
- // default file permissions
- static final FileAttribute<Set<PosixFilePermission>> defaultPosixFilePermissions =
- PosixFilePermissions.asFileAttribute(EnumSet
- .of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE));
- static final boolean isPosix = isPosix();
- static boolean isPosix() {
- return AccessController.doPrivileged(
- new PrivilegedAction<Boolean>() {
- public Boolean run() {
- try {
- return FileSystems.getDefault().getPath(valueAsString)
- .getFileStore().supportsFileAttributeView("posix");
- } catch (IOException e) {
- throw new IOError(e);
- }
- }
- });
- }
}
/**
@@ -1869,12 +1854,11 @@ public class File
if (suffix == null)
suffix = ".tmp";
- File tmpdir = (directory != null) ?
- directory : TemporaryDirectory.valueAsFile;
+ File tmpdir = (directory != null) ? directory : TempDirectory.location();
SecurityManager sm = System.getSecurityManager();
File f;
do {
- f = TemporaryDirectory.generateFile(prefix, suffix, tmpdir);
+ f = TempDirectory.generateFile(prefix, suffix, tmpdir);
if (sm != null) {
try {
sm.checkWrite(f.getPath());
@@ -1891,10 +1875,16 @@ public class File
/**
* Creates an empty file in the default temporary-file directory, using
- * the given prefix and suffix to generate its name. Invoking this method
+ * the given prefix and suffix to generate its name. Invoking this method
* is equivalent to invoking <code>{@link #createTempFile(java.lang.String,
* java.lang.String, java.io.File)
* createTempFile(prefix, suffix, null)}</code>.
+ *
+ * <p> The {@link #createTemporaryFile(String,String,FileAttribute[])} method
+ * provides an alternative method to create an empty file in the
+ * temporary-file directory. Files created by that method may have more
+ * restrictive access permissions to files created by this method and so
+ * may be more suited to security-sensitive applications.
*
* @param prefix The prefix string to be used in generating the file's
* name; must be at least three characters long
@@ -1926,23 +1916,19 @@ public class File
/**
* Creates an empty file in the default temporary-file directory, using
- * the given prefix and suffix to generate its name. This method is
- * equivalent to invoking the {@link #createTempFile(String,String)
- * createTempFile(prefix, suffix)} method with the addition that the
- * resulting pathname may be requested to be deleted when the Java virtual
- * machine terminates, and the initial file attributes to set atomically
- * when creating the file may be specified.
- *
- * <p> When the value of the {@code deleteOnExit} method is {@code true}
- * then the resulting file is requested to be deleted when the Java virtual
- * machine terminates as if by invoking the {@link #deleteOnExit deleteOnExit}
- * method.
+ * the given prefix and suffix to generate its name.
*
* <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
* attributes} to set atomically when creating the file. Each attribute is
* identified by its {@link FileAttribute#name name}. If more than one attribute
* of the same name is included in the array then all but the last occurrence
* is ignored.
+ *
+ * <p> Where the {@code attrs} parameter does not specify <i>access
+ * permissions</i> to set atomically when creating the file, then the
+ * resulting file may have more restrictive access permissions than files
+ * created by the {@link #createTempFile(java.lang.String, java.lang.String)}
+ * method.
*
* @param prefix
* The prefix string to be used in generating the file's
@@ -1951,9 +1937,6 @@ public class File
* The suffix string to be used in generating the file's
* name; may be {@code null}, in which case the suffix
* {@code ".tmp"} will be used
- * @param deleteOnExit
- * {@code true} if the file denoted by resulting pathname be
- * deleted when the Java virtual machine terminates
* @param attrs
* An optional list of file attributes to set atomically when creating
* the file
@@ -1961,7 +1944,7 @@ public class File
* @return An abstract pathname denoting a newly-created empty file
*
* @throws IllegalArgumentException
- * If the <code>prefix</code> argument contains fewer than three
+ * If the {@code prefix} argument contains fewer than three
* characters
* @throws UnsupportedOperationException
* If the array contains an attribute that cannot be set atomically
@@ -1971,74 +1954,19 @@ public class File
* @throws SecurityException
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
- * method does not allow a file to be created. When the {@code
- * deleteOnExit} parameter has the value {@code true} then the
- * security manager's {@link
- * java.lang.SecurityManager#checkDelete(java.lang.String)} is
- * invoked to check delete access to the file.
+ * method does not allow a file to be created.
+ *
* @since 1.7
*/
- public static File createTempFile(String prefix,
- String suffix,
- boolean deleteOnExit,
- FileAttribute<?>... attrs)
+ public static File createTemporaryFile(String prefix,
+ String suffix,
+ FileAttribute<?>... attrs)
throws IOException
{
if (prefix.length() < 3)
throw new IllegalArgumentException("Prefix string too short");
suffix = (suffix == null) ? ".tmp" : suffix;
-
- // special case POSIX environments so that 0600 is used as the file mode
- if (TemporaryDirectory.isPosix) {
- if (attrs.length == 0) {
- // no attributes so use default permissions
- attrs = new FileAttribute<?>[1];
- attrs[0] = TemporaryDirectory.defaultPosixFilePermissions;
- } else {
- // check if posix permissions given; if not use default
- boolean hasPermissions = false;
- for (int i=0; i<attrs.length; i++) {
- if (attrs[i].name().equals("posix:permissions")) {
- hasPermissions = true;
- break;
- }
- }
- if (!hasPermissions) {
- FileAttribute<?>[] copy = new FileAttribute<?>[attrs.length+1];
- System.arraycopy(attrs, 0, copy, 0, attrs.length);
- attrs = copy;
- attrs[attrs.length-1] =
- TemporaryDirectory.defaultPosixFilePermissions;
- }
- }
- }
-
- // use Path#createFile to create file
- SecurityManager sm = System.getSecurityManager();
- for (;;) {
- File f = TemporaryDirectory
- .generateFile(prefix, suffix, TemporaryDirectory.valueAsFile);
- if (sm != null && deleteOnExit)
- sm.checkDelete(f.getPath());
- try {
- f.toPath().createFile(attrs);
- if (deleteOnExit)
- DeleteOnExitHook.add(f.getPath());
- return f;
- } catch (InvalidPathException e) {
- // don't reveal temporary directory location
- if (sm != null)
- throw new IllegalArgumentException("Invalid prefix or suffix");
- throw e;
- } catch (SecurityException e) {
- // don't reveal temporary directory location
- if (sm != null)
- throw new SecurityException("Unable to create temporary file");
- throw e;
- } catch (FileAlreadyExistsException e) {
- // ignore
- }
- }
+ return TempFileHelper.createFile(prefix, suffix, attrs);
}
/* -- Basic infrastructure -- */
@@ -2153,40 +2081,45 @@ public class File
/**
* Returns a {@link Path java.nio.file.Path} object constructed from the
- * this abstract path. The first invocation of this method works as if
- * invoking it were equivalent to evaluating the expression:
+ * this abstract path. The resulting {@code Path} is associated with the
+ * {@link java.nio.file.FileSystems#getDefault default-filesystem}.
+ *
+ * <p> The first invocation of this method works as if invoking it were
+ * equivalent to evaluating the expression:
* <blockquote><pre>
- * {@link FileSystems#getDefault FileSystems.getDefault}().{@link FileSystem#getPath getPath}(this.{@link #getPath getPath}());
+ * {@link java.nio.file.FileSystems#getDefault FileSystems.getDefault}().{@link
+ * java.nio.file.FileSystem#getPath getPath}(this.{@link #getPath getPath}());
* </pre></blockquote>
* Subsequent invocations of this method return the same {@code Path}.
*
* <p> If this abstract pathname is the empty abstract pathname then this
- * method returns a {@code Path} that may be used to access to the current
+ * method returns a {@code Path} that may be used to access the current
* user directory.
*
- * @return A {@code Path} constructed from this abstract path. The resulting
- * {@code Path} is associated with the {@link FileSystems#getDefault
- * default-filesystem}.
+ * @return a {@code Path} constructed from this abstract path
*
* @throws InvalidPathException
- * If a {@code Path} object cannot be constructed from the abstract
+ * if a {@code Path} object cannot be constructed from the abstract
* path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
*
* @since 1.7
*/
public Path toPath() {
- if (filePath == null) {
+ Path result = filePath;
+ if (result == null) {
synchronized (this) {
- if (filePath == null) {
+ result = filePath;
+ if (result == null) {
if (path.length() == 0) {
// assume default file system treats "." as current directory
- filePath = Paths.get(".");
+ result = Paths.get(".");
} else {
- filePath = Paths.get(path);
+ result = Paths.get(path);
}
+ filePath = result;
}
}
}
- return filePath;
+ return result;
}
}
--- a/src/share/classes/java/lang/annotation/ElementType.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/lang/annotation/ElementType.java Mon Jun 29 15:08:52 2009 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 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
@@ -40,6 +40,12 @@ public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
+ /** Uses of a type */
+ TYPE_USE,
+
+ /** type parameters */
+ TYPE_PARAMETER,
+
/** Field declaration (includes enum constants) */
FIELD,
--- a/src/share/classes/java/lang/management/PlatformComponent.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/lang/management/PlatformComponent.java Mon Jun 29 15:08:52 2009 +0100
@@ -34,7 +34,6 @@ import java.util.logging.LogManager;
import java.util.logging.LogManager;
import java.nio.BufferPoolMXBean;
import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import com.sun.management.HotSpotDiagnosticMXBean;
@@ -198,10 +197,7 @@ enum PlatformComponent {
"java.nio", "BufferPool", keyProperties("name"),
new MXBeanFetcher<BufferPoolMXBean>() {
public List<BufferPoolMXBean> getMXBeans() {
- List<BufferPoolMXBean> pools = new ArrayList<BufferPoolMXBean>(2);
- pools.add( sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPoolMXBean() );
- pools.add( sun.nio.ch.FileChannelImpl.getMappedBufferPoolMXBean() );
- return pools;
+ return ManagementFactoryHelper.getBufferPoolMXBeans();
}
}),
--- a/src/share/classes/java/nio/Bits.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/Bits.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,11 +26,8 @@ package java.nio;
package java.nio;
import java.security.AccessController;
-import java.security.PrivilegedAction;
import sun.misc.Unsafe;
import sun.misc.VM;
-import javax.management.ObjectName;
-import javax.management.MalformedObjectNameException;
/**
* Access to bits, native and otherwise.
@@ -676,55 +673,34 @@ class Bits {
}
}
- // -- Management interface for monitoring of direct buffer usage --
+ // -- Monitoring of direct buffer usage --
static {
// setup access to this package in SharedSecrets
sun.misc.SharedSecrets.setJavaNioAccess(
new sun.misc.JavaNioAccess() {
@Override
- public BufferPoolMXBean getDirectBufferPoolMXBean() {
- return LazyInitialization.directBufferPoolMXBean;
+ public sun.misc.JavaNioAccess.BufferPool getDirectBufferPool() {
+ return new sun.misc.JavaNioAccess.BufferPool() {
+ @Override
+ public String getName() {
+ return "direct";
+ }
+ @Override
+ public long getCount() {
+ return Bits.count;
+ }
+ @Override
+ public long getTotalCapacity() {
+ return Bits.usedMemory;
+ }
+ @Override
+ public long getMemoryUsed() {
+ return Bits.reservedMemory;
+ }
+ };
}
- }
- );
- }
-
- // Lazy initialization of management interface
- private static class LazyInitialization {
- static final BufferPoolMXBean directBufferPoolMXBean = directBufferPoolMXBean();
-
- private static BufferPoolMXBean directBufferPoolMXBean() {
- final String pool = "direct";
- final ObjectName obj;
- try {
- obj = new ObjectName("java.nio:type=BufferPool,name=" + pool);
- } catch (MalformedObjectNameException x) {
- throw new AssertionError(x);
- }
- return new BufferPoolMXBean() {
- @Override
- public ObjectName getObjectName() {
- return obj;
- }
- @Override
- public String getName() {
- return pool;
- }
- @Override
- public long getCount() {
- return Bits.count;
- }
- @Override
- public long getTotalCapacity() {
- return Bits.usedMemory;
- }
- @Override
- public long getMemoryUsed() {
- return Bits.reservedMemory;
- }
- };
- }
+ });
}
// -- Bulk get/put acceleration --
--- a/src/share/classes/java/nio/Direct-X-Buffer.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/Direct-X-Buffer.java Mon Jun 29 15:08:52 2009 +0100
@@ -30,7 +30,6 @@ import sun.misc.Cleaner;
import sun.misc.Cleaner;
import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
-import sun.nio.ch.FileChannelImpl;
class Direct$Type$Buffer$RW$$BO$
--- a/src/share/classes/java/nio/channels/SeekableByteChannel.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/channels/SeekableByteChannel.java Mon Jun 29 15:08:52 2009 +0100
@@ -47,7 +47,7 @@ import java.io.IOException;
* so that method invocations on the implementation class can be chained.
*
* @since 1.7
- * @see java.nio.file.FileRef#newByteChannel
+ * @see java.nio.file.Path#newByteChannel
*/
public interface SeekableByteChannel
--- a/src/share/classes/java/nio/file/AccessMode.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/AccessMode.java Mon Jun 29 15:08:52 2009 +0100
@@ -30,7 +30,7 @@ package java.nio.file;
*
* @since 1.7
*
- * @see FileRef#checkAccess
+ * @see Path#checkAccess
*/
public enum AccessMode {
--- a/src/share/classes/java/nio/file/DirectoryStream.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/DirectoryStream.java Mon Jun 29 15:08:52 2009 +0100
@@ -27,6 +27,7 @@ package java.nio.file;
import java.util.Iterator;
import java.io.Closeable;
+import java.io.IOException;
/**
* An object to iterate over the entries in a directory. A directory stream
@@ -50,13 +51,10 @@ import java.io.Closeable;
*
* <p> A {@code DirectoryStream} is opened upon creation and is closed by
* invoking the {@link #close close} method. Closing the directory stream
- * releases any resources associated with the stream. The {@link
- * Files#withDirectory Files.withDirectory} utility method is useful for cases
- * where a task is performed on entries in a directory. This method automatically
- * closes the directory stream when iteration is complete (or an error occurs).
- * Once a directory stream is closed, all further method invocations on the
- * iterator throw {@link java.util.concurrent.ConcurrentModificationException}
- * with cause {@link ClosedDirectoryStreamException}.
+ * releases any resources associated with the stream. Once a directory stream
+ * is closed, all further method invocations on the iterator throw {@link
+ * java.util.concurrent.ConcurrentModificationException} with cause {@link
+ * ClosedDirectoryStreamException}.
*
* <p> A directory stream is not required to be <i>asynchronously closeable</i>.
* If a thread is blocked on the directory stream's iterator reading from the
@@ -79,7 +77,7 @@ import java.io.Closeable;
*
* <p> The iterator's {@link Iterator#remove() remove} method removes the
* directory entry for the last element returned by the iterator, as if by
- * invoking the {@link FileRef#delete delete} method. If an I/O error or
+ * invoking the {@link Path#delete delete} method. If an I/O error or
* security exception occurs then {@code ConcurrentModificationException} is
* thrown with the cause.
*
@@ -104,10 +102,6 @@ public interface DirectoryStream<T>
* newDirectoryStream} method 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
- * filters.
- *
* @param <T> the type of the directory entry
*
* @since 1.7
@@ -120,8 +114,11 @@ public interface DirectoryStream<T>
* the directory entry to be tested
*
* @return {@code true} if the directory entry should be accepted
+ *
+ * @throws IOException
+ * If an I/O error occurs
*/
- boolean accept(T entry);
+ boolean accept(T entry) throws IOException;
}
/**
--- a/src/share/classes/java/nio/file/FileRef.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/FileRef.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,225 +26,85 @@ package java.nio.file;
package java.nio.file;
import java.nio.file.attribute.*;
-import java.nio.channels.SeekableByteChannel;
+import java.util.Map;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.io.IOException;
/**
* A reference to a file.
*
* <p> A {@code FileRef} is an object that locates a file and defines methods to
- * access the file. The means by which the file is located depends on the
- * implementation. In many cases, a file is located by a {@link Path} but it may
- * be located by other means such as a file-system identifier.
- *
- * <p> This interface defines the following operations:
- * <ul>
- * <li><p> The {@link #newByteChannel newByteChannel} method
- * may be used to open a file and obtain a byte channel for reading or
- * writing. </p></li>
- * <li><p> The {@link #delete delete} method may be used to delete a file.
- * </p></li>
- * <li><p> The {@link #checkAccess checkAccess} method may be used to check
- * the existence or accessibility of a file. </p></li>
- * <li><p> The {@link #isSameFile isSameFile} method may be used to test if
- * two file references locate the same file. </p></li>
- * <li><p> The {@link #getFileStore getFileStore} method may be used to
- * obtain the {@link FileStore} representing the storage where a file is
- * located. </p></li>
- * </ul>
- *
- * <p> Access to associated metadata or file attributes requires an appropriate
- * {@link FileAttributeView FileAttributeView}. The {@link
- * #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,LinkOption[]) getFileAttributeView(String,LinkOption[])}
- * method may be used to obtain a file attribute view where dynamic access to
- * file attributes where required.
- *
- * <p> A {@code FileRef} is immutable and safe for use by multiple concurrent
- * threads.
+ * open the file for reading or writing. It also provides access to associated
+ * metadata or file attributes.
*
* @since 1.7
+ * @see java.io.Inputs
+ * @see java.io.Outputs
+ * @see java.nio.file.attribute.Attributes
+ * @see java.io.File#toPath
*/
public interface FileRef {
/**
- * Opens the file referenced by this object, returning a seekable byte
- * channel to access the file.
+ * Opens the file referenced by this object, returning an input stream to
+ * read from the file. The stream will not be buffered, and is not required
+ * to support the {@link InputStream#mark mark} or {@link InputStream#reset
+ * reset} methods. The stream will be safe for access by multiple concurrent
+ * threads. Reading commences at the beginning of the file.
*
* <p> The {@code options} parameter determines how the file is opened.
- * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE
- * WRITE} options determine if the file should be opened for reading and/or
- * writing. If neither option (or the {@link StandardOpenOption#APPEND APPEND}
- * option) is contained in the array then the file is opened for reading.
- * By default reading or writing commences at the beginning of the file.
- *
- * <p> In the addition to {@code READ} and {@code WRITE}, the following
- * options may be present:
- *
- * <table border=1 cellpadding=5 summary="">
- * <tr> <th>Option</th> <th>Description</th> </tr>
- * <tr>
- * <td> {@link StandardOpenOption#APPEND APPEND} </td>
- * <td> If this option is present then the file is opened for writing and
- * each invocation of the channel's {@code write} method first advances
- * the position to the end of the file and then writes the requested
- * data. Whether the advancement of the position and the writing of the
- * data are done in a single atomic operation is system-dependent and
- * therefore unspecified. This option may not be used in conjunction
- * with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
- * </tr>
- * <tr>
- * <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
- * <td> If this option is present then the existing file is truncated to
- * a size of 0 bytes. This option is ignored when the file is opened only
- * for reading. </td>
- * </tr>
- * <tr>
- * <td> {@link StandardOpenOption#SYNC SYNC} </td>
- * <td> Requires that every update to the file's content or metadata be
- * written synchronously to the underlying storage device. (see <a
- * href="package-summary.html#integrity"> Synchronized I/O file
- * integrity</a>). </td>
- * </tr>
- * <tr>
- * <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
- * <td> Requires that every update to the file's content be written
- * synchronously to the underlying storage device. (see <a
- * href="package-summary.html#integrity"> Synchronized I/O file
- * integrity</a>). </td>
- * </tr>
- * </table>
- *
- * <p> An implementation of this interface may support additional options
- * defined by the {@link StandardOpenOption} enumeration type or other
+ * If no options are present then it is equivalent to opening the file with
+ * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
+ * READ} option, an implementation may also support additional implementation
+ * specific options.
+ *
+ * @return an input stream to read bytes from the file
+ *
+ * @throws IllegalArgumentException
+ * if an invalid combination of options is specified
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @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#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ InputStream newInputStream(OpenOption... options) throws IOException;
+
+ /**
+ * Opens or creates the file located by this object for writing, returning
+ * an output stream to write bytes to the file.
+ *
+ * <p> The {@code options} parameter determines how the file is opened.
+ * If no options are present then this method creates a new file for writing
+ * or truncates an existing file. In addition to the {@link StandardOpenOption
+ * standard} options, an implementation may also support additional
* implementation specific options.
*
- * <p> The {@link java.nio.channels.Channels} utility classes defines methods
- * to construct input and output streams where inter-operation with the
- * {@link java.io} package is required.
- *
- * @param options
- * Options specifying how the file is opened
- *
- * @return a new seekable byte channel
+ * <p> The resulting stream will not be buffered. The stream will be safe
+ * for access by multiple concurrent threads.
+ *
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new output stream
*
* @throws IllegalArgumentException
- * If an invalid combination of options is specified
- * @throws UnsupportedOperationException
- * If an unsupported open option is specified
- * @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#checkRead(String) checkRead}
- * method is invoked to check read access to the path if the file is
- * opened for reading. The {@link SecurityManager#checkWrite(String)
- * checkWrite} method is invoked to check write access to the path
- * if the file is opened for writing.
- */
- SeekableByteChannel newByteChannel(OpenOption... options)
- throws IOException;
-
- /**
- * Returns the {@link FileStore} representing the file store where the file
- * referenced by this object is stored.
- *
- * <p> Once a reference to the {@code FileStore} is obtained it is
- * implementation specific if operations on the returned {@code FileStore},
- * or {@link FileStoreAttributeView} objects obtained from it, continue
- * to depend on the existence of the file. In particular the behavior is not
- * defined for the case that the file is deleted or moved to a different
- * file store.
- *
- * @return The file store where the file is stored
- *
- * @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#checkRead(String) checkRead}
- * method is invoked to check read access to the file, and in
- * addition it checks {@link RuntimePermission}<tt>
- * ("getFileStoreAttributes")</tt>
- */
- FileStore getFileStore() throws IOException;
-
- /**
- * Checks the existence and optionally the accessibility of the file
- * referenced by this object.
- *
- * <p> This method checks the existence of a file and that this Java virtual
- * machine has appropriate privileges that would allow it access the file
- * according to all of access modes specified in the {@code modes} parameter
- * as follows:
- *
- * <table border=1 cellpadding=5 summary="">
- * <tr> <th>Value</th> <th>Description</th> </tr>
- * <tr>
- * <td> {@link AccessMode#READ READ} </td>
- * <td> Checks that the file exists and that the Java virtual machine has
- * permission to read the file. </td>
- * </tr>
- * <tr>
- * <td> {@link AccessMode#WRITE WRITE} </td>
- * <td> Checks that the file exists and that the Java virtual machine has
- * permission to write to the file, </td>
- * </tr>
- * <tr>
- * <td> {@link AccessMode#EXECUTE EXECUTE} </td>
- * <td> Checks that the file exists and that the Java virtual machine has
- * permission to {@link Runtime#exec execute} the file. The semantics
- * may differ when checking access to a directory. For example, on UNIX
- * systems, checking for {@code EXECUTE} access checks that the Java
- * virtual machine has permission to search the directory in order to
- * access file or subdirectories. </td>
- * </tr>
- * </table>
- *
- * <p> If the {@code modes} parameter is of length zero, then the existence
- * of the file is checked.
- *
- * <p> This method follows symbolic links if the file referenced by this
- * object is a symbolic link. Depending on the implementation, this method
- * may require to read file permissions, access control lists, or other
- * file attributes in order to check the effective access to the file. To
- * determine the effective access to a file may require access to several
- * attributes and so in some implementations this method may not be atomic
- * with respect to other file system operations. Furthermore, as the result
- * of this method is immediately outdated, there is no guarantee that a
- * subsequence access will succeed (or even that it will access the same
- * file). Care should be taken when using this method in security sensitive
- * applications.
- *
- * @param modes
- * The access modes to check; may have zero elements
- *
- * @throws UnsupportedOperationException
- * An implementation is required to support checking for
- * {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
- * exception is specified to allow for the {@code Access} enum to
- * be extended in future releases.
- * @throws NoSuchFileException
- * If a file does not exist <i>(optional specific exception)</i>
- * @throws AccessDeniedException
- * The requested access would be denied or the access cannot be
- * determined because the Java virtual machine has insufficient
- * privileges or other reasons. <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#checkRead(String) checkRead}
- * is invoked when checking read access to the file or only the
- * existence of the file, the {@link SecurityManager#checkWrite(String)
- * checkWrite} is invoked when checking write access to the file,
- * and {@link SecurityManager#checkExec(String) checkExec} is invoked
- * when checking execute access.
- */
- void checkAccess(AccessMode... modes) throws IOException;
+ * if {@code options} contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @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#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ */
+ OutputStream newOutputStream(OpenOption... options) throws IOException;
/**
* Returns a file attribute view of a given type.
@@ -266,11 +126,11 @@ public interface FileRef {
* that do not support symbolic links.
*
* @param type
- * The {@code Class} object corresponding to the file attribute view
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return A file attribute view of the specified type, or {@code null} if
+ * the {@code Class} object corresponding to the file attribute view
+ * @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
@@ -280,145 +140,185 @@ public interface FileRef {
*
* @see Attributes#readBasicFileAttributes
*/
- <V extends FileAttributeView> V getFileAttributeView(Class<V> type, LinkOption... options);
-
- /**
- * Returns a file attribute view of the given name.
- *
- * <p> A file attribute view provides a read-only or updatable view of a
- * set of file attributes. This method is intended to be used where
- * <em>dynamic access</em> to the file attributes is required. The {@code
- * name} parameter specifies the {@link FileAttributeView#name name} of the
- * file attribute view and this method returns an instance of that view if
- * supported. The {@link BasicFileAttributeView} type supports access to the
- * basic attributes of a file and is name {@code "basic"}. Invoking this
- * method to select a file attribute view named {@code "basic"} will always
- * return an instance of that class.
+ <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
+ LinkOption... options);
+
+ /**
+ * Sets the value of a file attribute.
+ *
+ * <p> The {@code attribute} parameter identifies the attribute to be set
+ * and takes the form:
+ * <blockquote>
+ * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+ * </blockquote>
+ * where square brackets [...] delineate an optional component and the
+ * character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+ * FileAttributeView} that identifies a set of file attributes. If not
+ * specified then it defaults to {@code "basic"}, the name of the file
+ * 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
+ * within the set.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to set the DOS "hidden" attribute:
+ * <pre>
+ * file.setAttribute("dos:hidden", true);
+ * </pre>
+ *
+ * @param attribute
+ * the attribute to set
+ * @param value
+ * the attribute value
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available or it does not support
+ * updating the attribute
+ * @throws IllegalArgumentException
+ * if the attribute value is of the correct type but has an
+ * inappropriate value
+ * @throws ClassCastException
+ * If the attribute value is not of the expected type or is a
+ * collection containing elements that are not of the expected
+ * type
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file. If this method is invoked
+ * to set security sensitive attributes then the security manager
+ * may be invoked to check for additional permissions.
+ */
+ void setAttribute(String attribute, Object value, LinkOption... options)
+ throws IOException;
+
+ /**
+ * Reads the value of a file attribute.
+ *
+ * <p> The {@code attribute} parameter identifies the attribute to be read
+ * and takes the form:
+ * <blockquote>
+ * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+ * </blockquote>
+ * where square brackets [...] delineate an optional component and the
+ * character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+ * FileAttributeView} that identifies a set of file attributes. If not
+ * specified then it defaults to {@code "basic"}, the name of the file
+ * 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 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
+ * 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)file.getAttribute("unix:uid");
+ * </pre>
+ *
+ * @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
+ *
+ * reading the attribute
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and 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 security sensitive attributes then the security manager
+ * may be invoked to check for additional permissions.
+ */
+ Object getAttribute(String attribute, LinkOption... options) throws IOException;
+
+ /**
+ * Reads a set of file attributes as a bulk operation.
+ *
+ * <p> The {@code attributes} parameter identifies the attributes to be read
+ * and takes the form:
+ * <blockquote>
+ * [<i>view-name</i><b>:</b>]<i>attribute-list</i>
+ * </blockquote>
+ * where square brackets [...] delineate an optional component and the
+ * character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+ * FileAttributeView} that identifies a set of file attributes. If not
+ * specified then it defaults to {@code "basic"}, the name of the file
+ * attribute view that identifies the basic set of file attributes common to
+ * many file systems.
+ *
+ * <p> The <i>attribute-list</i> component is a comma separated list of
+ * zero or more names of attributes to read. If the list contains the value
+ * {@code "*"} then all attributes are read. Attributes that are not supported
+ * are ignored and will not be present in the returned map. It is
+ * implementation specific if all attributes are read as an atomic operation
+ * with respect to other file system operations.
+ *
+ * <p> The following examples demonstrate possible values for the {@code
+ * attributes} parameter:
+ *
+ * <blockquote>
+ * <table border="0">
+ * <tr>
+ * <td> {@code "*"} </td>
+ * <td> Read all {@link BasicFileAttributes basic-file-attributes}. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code "size,lastModifiedTime,lastAccessTime"} </td>
+ * <td> Reads the file size, last modified time, and last access time
+ * attributes. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code "posix:*"} </td>
+ * <td> Read all {@link PosixFileAttributes POSIX-file-attributes}.. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code "posix:permissions,owner,size"} </td>
+ * <td> Reads the POSX file permissions, owner, and file size. </td>
+ * </tr>
+ * </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 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.
+ *
+ * @param attributes
+ * The attributes to read
* @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, LinkOption... options);
-
- /**
- * Tests if the file referenced by this object is the same file referenced
- * by another object.
- *
- * <p> If this {@code FileRef} and the given {@code FileRef} are {@link
- * #equals(Object) equal} then this method returns {@code true} without checking
- * if the file exists. If the {@code FileRef} and the given {@code FileRef}
- * are associated with different providers, or the given {@code FileRef} is
- * {@code null} then this method returns {@code false}. Otherwise, this method
- * checks if both {@code FileRefs} locate the same file, and depending on the
- * implementation, may require to open or access both files.
- *
- * <p> If the file system and files remain static, then this method implements
- * an equivalence relation for non-null {@code FileRefs}.
- * <ul>
- * <li>It is <i>reflexive</i>: for a non-null {@code FileRef} {@code f},
- * {@code f.isSameFile(f)} should return {@code true}.
- * <li>It is <i>symmetric</i>: for two non-null {@code FileRefs}
- * {@code f} and {@code g}, {@code f.isSameFile(g)} will equal
- * {@code g.isSameFile(f)}.
- * <li>It is <i>transitive</i>: for three {@code FileRefs}
- * {@code f}, {@code g}, and {@code h}, if {@code f.isSameFile(g)} returns
- * {@code true} and {@code g.isSameFile(h)} returns {@code true}, then
- * {@code f.isSameFile(h)} will return return {@code true}.
- * </ul>
- *
- * @param other
- * The other file reference
- *
- * @return {@code true} if, and only if, this object and the given object
- * locate the same file
+ * @return A map of the attributes returned; may be empty. The map's keys
+ * are the attribute names, its values are the attribute values
*
* @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#checkRead(String) checkRead}
- * method is invoked to check read access to both files.
- *
- * @see java.nio.file.attribute.BasicFileAttributes#fileKey
- */
- boolean isSameFile(FileRef other) throws IOException;
-
- /**
- * Deletes the file referenced by this object.
- *
- * <p> An implementation may require to examine the file to determine if the
- * file is a directory. Consequently this method may not be atomic with respect
- * to other file system operations. If the file is a symbolic-link then the
- * link is deleted and not the final target of the link.
- *
- * <p> If the file is a directory then the directory must be empty. In some
- * implementations a directory has entries for special files or links that
- * are created when the directory is created. In such implementations a
- * directory is considered empty when only the special entries exist.
- *
- * <p> On some operating systems it may not be possible to remove a file when
- * it is open and in use by this Java virtual machine or other programs.
- *
- * @throws NoSuchFileException
- * If 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
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkDelete(String)} method
- * is invoked to check delete access to the file
- */
- void delete() throws IOException;
-
- /**
- * Tests this object for equality with another object.
- *
- * <p> If the given object is not a {@code FileRef} then this method
- * immediately returns {@code false}.
- *
- * <p> For two file references to be considered equal requires that they
- * are both the same type of {@code FileRef} and encapsulate components
- * to locate the same file. This method does not access the file system and
- * the file may not exist.
- *
- * <p> This method satisfies the general contract of the {@link
- * java.lang.Object#equals(Object) Object.equals} method. </p>
- *
- * @param ob The object to which this object is to be compared
- *
- * @return {@code true} if, and only if, the given object is a {@code FileRef}
- * that is identical to this {@code FileRef}
- *
- * @see #isSameFile
- */
- boolean equals(Object ob);
-
- /**
- * Returns the hash-code value for this object.
- *
- * <p> This method satisfies the general contract of the
- * {@link java.lang.Object#hashCode() Object.hashCode} method.
- */
- int hashCode();
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file. If this method is invoked
+ * to read security sensitive attributes then the security manager
+ * may be invoke to check for additional permissions.
+ */
+ Map<String,?> readAttributes(String attributes, LinkOption... options)
+ throws IOException;
}
--- a/src/share/classes/java/nio/file/FileStore.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/FileStore.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,12 +26,13 @@ package java.nio.file;
package java.nio.file;
import java.nio.file.attribute.*;
+import java.io.IOException;
/**
* Storage for files. A {@code FileStore} represents a storage pool, device,
* partition, volume, concrete file system or other implementation specific means
* of file storage. The {@code FileStore} for where a file is stored is obtained
- * by invoking the {@link FileRef#getFileStore getFileStore} method, or all file
+ * by invoking the {@link Path#getFileStore getFileStore} method, or all file
* stores can be enumerated by invoking the {@link FileSystem#getFileStores
* getFileStores} method.
*
@@ -146,24 +147,41 @@ public abstract class FileStore {
getFileStoreAttributeView(Class<V> type);
/**
- * Returns a {@code FileStoreAttributeView} of the given name.
+ * Reads the value of a file store attribute.
*
- * <p> This method is intended to be used where <em>dynamic access</em> to
- * file store attributes is required. The {@code name} parameter specifies
- * the {@link FileAttributeView#name name} of the file store attribute view
- * and this method returns an instance of that view if supported.
+ * <p> The {@code attribute} parameter identifies the attribute to be read
+ * and takes the form:
+ * <blockquote>
+ * <i>view-name</i><b>:</b><i>attribute-name</i>
+ * </blockquote>
+ * where the character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileStoreAttributeView#name name} of
+ * a {@link FileStore AttributeView} that identifies a set of file attributes.
+ * <i>attribute-name</i> is the name of the attribute.
*
* <p> For {@code FileStore} objects created by the default provider, then
* the file stores support the {@link FileStoreSpaceAttributeView} that
- * provides access to space attributes. In that case invoking this method
- * with a parameter value of {@code "space"} will always return an instance
- * of that class.
+ * provides access to space attributes.
*
- * @param name
- * the name of the attribute view
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to know if ZFS compression is enabled (assuming the "zfs"
+ * view is supported):
+ * <pre>
+ * boolean compression = (Boolean)fs.getAttribute("zfs:compression");
+ * </pre>
*
- * @return a file store attribute view of the given name, or {@code null}
- * if the attribute view is not available
+ * @param attribute
+ * the attribute to read
+
+ * @return the attribute value; {@code null} may be a valid valid for some
+ * attributes
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available or it does not support
+ * reading the attribute
+ * @throws IOException
+ * if an I/O error occurs
*/
- public abstract FileStoreAttributeView getFileStoreAttributeView(String name);
+ public abstract Object getAttribute(String attribute) throws IOException;
}
--- a/src/share/classes/java/nio/file/FileTreeWalker.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/FileTreeWalker.java Mon Jun 29 15:08:52 2009 +0100
@@ -50,8 +50,6 @@ class FileTreeWalker {
case FOLLOW_LINKS : fl = true; break;
case DETECT_CYCLES : dc = true; break;
default:
- if (option == null)
- throw new NullPointerException("Visit options contains 'null'");
throw new AssertionError("Should not get here");
}
}
@@ -239,13 +237,13 @@ class FileTreeWalker {
}
private static class AncestorDirectory {
- private final FileRef dir;
+ private final Path dir;
private final Object key;
- AncestorDirectory(FileRef dir, Object key) {
+ AncestorDirectory(Path dir, Object key) {
this.dir = dir;
this.key = key;
}
- FileRef file() {
+ Path file() {
return dir;
}
Object fileKey() {
--- a/src/share/classes/java/nio/file/FileVisitor.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/FileVisitor.java Mon Jun 29 15:08:52 2009 +0100
@@ -42,9 +42,9 @@ import java.io.IOException;
* @Override
* public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
* try {
- * file.delete(false);
+ * file.delete();
* } catch (IOException exc) {
- * // failed to delete
+ * // failed to delete, do error handling here
* }
* return FileVisitResult.CONTINUE;
* }
@@ -52,9 +52,9 @@ import java.io.IOException;
* public FileVisitResult postVisitDirectory(Path dir, IOException e) {
* if (e == null) {
* try {
- * dir.delete(false);
+ * dir.delete();
* } catch (IOException exc) {
- * // failed to delete
+ * // failed to delete, do error handling here
* }
* } else {
* // directory iteration failed
@@ -80,7 +80,8 @@ import java.io.IOException;
* } catch (FileAlreadyExistsException e) {
* // ignore
* } catch (IOException e) {
- * // copy failed, skip rest of directory and descendants
+ * // copy failed, do error handling here
+ * // skip rest of directory and descendants
* return SKIP_SUBTREE;
* }
* return CONTINUE;
@@ -90,7 +91,7 @@ import java.io.IOException;
* try {
* file.copyTo(target.resolve(source.relativize(file)));
* } catch (IOException e) {
- * // copy failed
+ * // copy failed, do error handling here
* }
* return CONTINUE;
* }
@@ -100,7 +101,7 @@ import java.io.IOException;
* @since 1.7
*/
-public interface FileVisitor<T extends FileRef> {
+public interface FileVisitor<T> {
/**
* Invoked for a directory before entries in the directory are visited.
--- a/src/share/classes/java/nio/file/Files.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/Files.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,13 +26,15 @@ package java.nio.file;
package java.nio.file;
import java.nio.file.spi.FileTypeDetector;
+import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
- * Utility methods for files and directories.
+ * This class consists exclusively of static methods that operate on files or
+ * directories.
*
* @since 1.7
*/
@@ -109,8 +111,6 @@ public final class Files {
* @throws SecurityException
* If a security manager is installed and it denies an unspecified
* permission required by a file type detector implementation.
- *
- * @see DirectoryStreamFilters#newContentTypeFilter
*/
public static String probeContentType(FileRef file)
throws IOException
@@ -125,158 +125,6 @@ public final class Files {
// fallback to default
return DefaultFileTypeDetectorHolder.defaultFileTypeDetector
.probeContentType(file);
- }
-
- /**
- * Invokes a {@link FileAction} for each entry in a directory accepted
- * by a given {@link java.nio.file.DirectoryStream.Filter filter}.
- *
- * <p> This method opens the given directory and invokes the file action's
- * {@link FileAction#invoke invoke} method for each entry accepted by the
- * filter. When iteration is completed then the directory is closed. If the
- * {@link DirectoryStream#close close} method throws an {@code IOException}
- * then it is silently ignored.
- *
- * <p> If the {@code FileAction}'s {@code invoke} method terminates due
- * to an uncaught {@link IOException}, {@code Error} or {@code RuntimeException}
- * then the exception is propagated by this method after closing the
- * directory.
- *
- * @param dir
- * The directory
- * @param filter
- * The filter
- * @param action
- * The {@code FileAction} to invoke for each accepted entry
- *
- * @throws NotDirectoryException
- * If the {@code dir} parameter is not a directory <i>(optional
- * specific exception)</i>
- * @throws IOException
- * If an I/O error occurs or the {@code invoke} method terminates
- * due to an uncaught {@code IOException}
- * @throws SecurityException
- * In the case of the default provider, the {@link
- * SecurityManager#checkRead(String) checkRead} method is invoked
- * to check read access to the directory.
- */
- public static void withDirectory(Path dir,
- DirectoryStream.Filter<? super Path> filter,
- FileAction<? super Path> action)
- throws IOException
- {
- // explicit null check required in case directory is empty
- if (action == null)
- throw new NullPointerException();
-
- DirectoryStream<Path> stream = dir.newDirectoryStream(filter);
- try {
- // set to true when invoking the action so as to distinguish a
- // CME thrown by the iteration from a CME thrown by the invoke
- boolean inAction = false;
- try {
- for (Path entry: stream) {
- inAction = true;
- action.invoke(entry);
- inAction = false;
- }
- } catch (ConcurrentModificationException cme) {
- if (!inAction) {
- Throwable cause = cme.getCause();
- if (cause instanceof IOException)
- throw (IOException)cause;
- }
- throw cme;
- }
- } finally {
- try {
- stream.close();
- } catch (IOException x) { }
- }
- }
-
- /**
- * Invokes a {@link FileAction} for each entry in a directory with a
- * file name that matches a given pattern.
- *
- * <p> This method opens the given directory and invokes the file action's
- * {@link FileAction#invoke invoke} method for each entry that matches the
- * given pattern. When iteration is completed then the directory is closed.
- * If the {@link DirectoryStream#close close} method throws an {@code
- * IOException} then it is silently ignored.
- *
- * <p> If the {@code FileAction}'s {@code invoke} method terminates due
- * to an uncaught {@link IOException}, {@code Error} or {@code RuntimeException}
- * then the exception is propagated by this method after closing the
- * directory.
- *
- * <p> The globbing pattern language supported by this method is as
- * specified by the {@link FileSystem#getPathMatcher getPathMatcher} method.
- *
- * @param dir
- * The directory
- * @param glob
- * The globbing pattern
- * @param action
- * The {@code FileAction} to invoke for each entry
- *
- * @throws NotDirectoryException
- * If the {@code dir} parameter is not a directory <i>(optional
- * specific exception)</i>
- * @throws IOException
- * If an I/O error occurs or the {@code invoke} method terminates
- * due to an uncaught {@code IOException}
- * @throws SecurityException
- * In the case of the default provider, the {@link
- * SecurityManager#checkRead(String) checkRead} method is invoked
- * to check read access to the directory.
- */
- public static void withDirectory(Path dir,
- String glob,
- FileAction<? super Path> action)
- throws IOException
- {
- if (glob == null)
- throw new NullPointerException("'glob' is null");
- final PathMatcher matcher = dir.getFileSystem().getPathMatcher("glob:" + glob);
- DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
- @Override
- public boolean accept(Path entry) {
- return matcher.matches(entry.getName());
- }
- };
- withDirectory(dir, filter, action);
- }
-
- /**
- * Invokes a {@link FileAction} for all entries in a directory.
- *
- * <p> This method works as if invoking it were equivalent to evaluating the
- * expression:
- * <blockquote><pre>
- * withDirectory(dir, "*", action)
- * </pre></blockquote>
- *
- * @param dir
- * The directory
- * @param action
- * The {@code FileAction} to invoke for each entry
- *
- * @throws NotDirectoryException
- * If the {@code dir} parameter is not a directory <i>(optional
- * specific exception)</i>
- * @throws IOException
- * If an I/O error occurs or the {@code invoke} method terminates
- * due to an uncaught {@code IOException}
- * @throws SecurityException
- * In the case of the default provider, the {@link
- * SecurityManager#checkRead(String) checkRead} method is invoked
- * to check read access to the directory.
- */
- public static void withDirectory(Path dir, FileAction<? super Path> action)
- throws IOException
- {
- withDirectory(dir, "*", action);
}
/**
@@ -328,7 +176,7 @@ public final class Files {
* arises when there is an entry in a directory that is an ancestor of the
* directory. Cycle detection is done by recording the {@link
* java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
- * or if file keys are not available, by invoking the {@link FileRef#isSameFile
+ * or if file keys are not available, by invoking the {@link Path#isSameFile
* isSameFile} method to test if a directory is the same file as an
* ancestor. When a cycle is detected the {@link FileVisitor#visitFile
* visitFile} is invoked with the attributes of the directory. The {@link
@@ -403,4 +251,108 @@ public final class Files {
Integer.MAX_VALUE,
visitor);
}
+
+ /**
+ * Creates a directory by creating all nonexistent parent directories first.
+ *
+ * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
+ * file-attributes} to set atomically when creating the nonexistent
+ * directories. Each file attribute is identified by its {@link
+ * FileAttribute#name name}. If more than one attribute of the same name is
+ * included in the array then all but the last occurrence is ignored.
+ *
+ * <p> If this method fails, then it may do so after creating some, but not
+ * all, of the parent directories.
+ *
+ * @param dir
+ * the directory to create
+ *
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws FileAlreadyExistsException
+ * if {@code dir} exists but is not a directory <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#checkWrite(String) checkWrite}
+ * method is invoked prior to attempting to create a directory and
+ * its {@link SecurityManager#checkRead(String) checkRead} is
+ * invoked for each parent directory that is checked. If {@code
+ * dir} is not an absolute path then its {@link Path#toAbsolutePath
+ * toAbsolutePath} may need to be invoked to get its absolute path.
+ * This may invoke the security manager's {@link
+ * SecurityManager#checkPropertyAccess(String) checkPropertyAccess}
+ * method to check access to the system property {@code user.dir}
+ *
+ */
+ public static void createDirectories(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ // attempt to create the directory
+ try {
+ createAndCheckIsDirectory(dir, attrs);
+ return;
+ } catch (FileAlreadyExistsException x) {
+ // file exists and is not a directory
+ throw x;
+ } catch (IOException x) {
+ // parent may not exist or other reason
+ }
+
+ // find existing parent (may require absolute path)
+ SecurityException se = null;
+ try {
+ dir = dir.toAbsolutePath();
+ } catch (SecurityException x) {
+ // don't have permission to get absolute path
+ se = x;
+ }
+ Path parent = dir.getParent();
+ while (parent != null) {
+ try {
+ parent.checkAccess();
+ break;
+ } catch (NoSuchFileException x) {
+ // does not exist
+ }
+ parent = parent.getParent();
+ }
+ if (parent == null) {
+ // unable to find existing parent
+ if (se != null)
+ throw se;
+ throw new IOException("Root directory does not exist");
+ }
+
+ // create directories
+ Path child = parent;
+ for (Path name: parent.relativize(dir)) {
+ child = child.resolve(name);
+ createAndCheckIsDirectory(child, attrs);
+ }
+ }
+
+ /**
+ * Attempts to create a directory. Does nothing if the directory already
+ * exists.
+ */
+ private static void createAndCheckIsDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ try {
+ dir.createDirectory(attrs);
+ } catch (FileAlreadyExistsException x) {
+ boolean isDirectory = Attributes
+ .readBasicFileAttributes(dir, LinkOption.NOFOLLOW_LINKS).isDirectory();
+ if (!isDirectory)
+ throw x;
+ }
+ }
}
--- a/src/share/classes/java/nio/file/LinkPermission.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/LinkPermission.java Mon Jun 29 15:08:52 2009 +0100
@@ -95,7 +95,7 @@ public final class LinkPermission extend
* {@code null}
*
* @throws IllegalArgumentException
- * if name is empty or invalid
+ * if name is empty or invalid, or actions is a non-empty string
*/
public LinkPermission(String name, String actions) {
super(name);
--- a/src/share/classes/java/nio/file/OpenOption.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/OpenOption.java Mon Jun 29 15:08:52 2009 +0100
@@ -30,7 +30,7 @@ package java.nio.file;
*
* <p> Objects of this type are used by methods such as {@link
* Path#newOutputStream(OpenOption[]) newOutputStream}, {@link
- * FileRef#newByteChannel newByteChannel}, {@link
+ * Path#newByteChannel newByteChannel}, {@link
* java.nio.channels.FileChannel#open FileChannel.open}, and {@link
* java.nio.channels.AsynchronousFileChannel#open AsynchronousFileChannel.open}
* when opening or creating a file.
--- a/src/share/classes/java/nio/file/Path.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/Path.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,10 +26,12 @@ package java.nio.file;
package java.nio.file;
import java.nio.file.attribute.*;
-import java.nio.channels.*;
-import java.io.*;
+import java.nio.channels.SeekableByteChannel;
+import java.io.IOException;
+import java.io.OutputStream;
import java.net.URI;
-import java.util.*;
+import java.util.Iterator;
+import java.util.Set;
/**
* A file reference that locates a file using a system dependent path. The file
@@ -70,19 +72,27 @@ import java.util.*;
* this class defines the following operations:
*
* <ul>
+ * <li><p> The {@link #newByteChannel newByteChannel} method
+ * may be used to open a file and obtain a byte channel for reading or
+ * writing. </p></li>
* <li><p> Files may be {@link #createFile(FileAttribute[]) created}, or
* directories may be {@link #createDirectory(FileAttribute[]) created}.
* </p></li>
+ * <li><p> The {@link #delete delete} method may be used to delete a file.
+ * </p></li>
+ * <li><p> The {@link #checkAccess checkAccess} method may be used to check
+ * the existence or accessibility of a file. </p></li>
+ * <li><p> The {@link #isSameFile isSameFile} method may be used to test if
+ * two file references locate the same file. </p></li>
+ * <li><p> The {@link #getFileStore getFileStore} method may be used to
+ * obtain the {@link FileStore} representing the storage where a file is
+ * located. </p></li>
* <li><p> Directories can be {@link #newDirectoryStream opened} so as to
* iterate over the entries in the directory. </p></li>
* <li><p> Files can be {@link #copyTo(Path,CopyOption[]) copied} or
* {@link #moveTo(Path,CopyOption[]) moved}. </p></li>
* <li><p> Symbolic-links may be {@link #createSymbolicLink created}, or the
* target of a link may be {@link #readSymbolicLink read}. </p></li>
- * <li><p> {@link #newInputStream InputStream} or {@link #newOutputStream
- * OutputStream} streams can be created to allow for interoperation with the
- * <a href="../../../java/io/package-summary.html">{@code java.io}</a> package
- * where required. </li></p>
* <li><p> The {@link #toRealPath real} path of an existing file may be
* obtained. </li></p>
* </ul>
@@ -93,13 +103,14 @@ import java.util.*;
*
* <h4>File attributes</h4>
*
- * The <a href="attribute/package-summary.html">{@code java.nio.file.attribute}</a>
- * package provides access to file attributes or <em>meta-data</em> associated
- * with files. The {@link Attributes Attributes} class defines methods that
- * operate on or return file attributes. For example, the file type, size,
- * timestamps, and other <em>basic</em> meta-data are obtained, in bulk, by
- * invoking the {@link Attributes#readBasicFileAttributes
- * Attributes.readBasicFileAttributes} method:
+ * In addition to the {@link #setAttribute setAttribute} and {@link #getAttribute
+ * getAttribute} methods, the <a href="attribute/package-summary.html">{@code
+ * java.nio.file.attribute}</a> package provides type-safe and efficient access
+ * to file attributes or <em>meta-data</em> associated with files. The {@link
+ * Attributes Attributes} class defines methods that operate on or return file
+ * attributes. For example, the file type, size, timestamps, and other
+ * <em>basic</em> meta-data are obtained, in bulk, by invoking the {@link
+ * Attributes#readBasicFileAttributes Attributes.readBasicFileAttributes} method:
* <pre>
* Path file = ...
* BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
@@ -417,12 +428,38 @@ public abstract class Path
/**
* Deletes the file located by this path.
*
- * <p> The {@code failIfNotExists} parameter determines how the method
- * behaves when the file does not exist. When {@code true}, and the file
- * does not exist, then the method fails. When {@code false} then the method
- * does not fail.
- *
- * <p> As with the {@link FileRef#delete delete()} method, an implementation
+ * <p> An implementation may require to examine the file to determine if the
+ * file is a directory. Consequently this method may not be atomic with respect
+ * to other file system operations. If the file is a symbolic-link then the
+ * link is deleted and not the final target of the link.
+ *
+ * <p> If the file is a directory then the directory must be empty. In some
+ * implementations a directory has entries for special files or links that
+ * are created when the directory is created. In such implementations a
+ * directory is considered empty when only the special entries exist.
+ *
+ * <p> On some operating systems it may not be possible to remove a file when
+ * it is open and in use by this Java virtual machine or other programs.
+ *
+ * @throws NoSuchFileException
+ * if 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
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file
+ */
+ public abstract void delete() throws IOException;
+
+ /**
+ * Deletes the file located by this path, if it exists.
+ *
+ * <p> As with the {@link #delete delete()} method, an implementation
* may require to examine the file to determine if the file is a directory.
* Consequently this method may not be atomic with respect to other file
* system operations. If the file is a symbolic-link then the link is
@@ -436,13 +473,6 @@ public abstract class Path
* <p> On some operating systems it may not be possible to remove a file when
* it is open and in use by this Java virtual machine or other programs.
*
- * @param failIfNotExists
- * {@code true} if the method should fail when the file does not
- * exist
- *
- * @throws NoSuchFileException
- * if the value of the {@code failIfNotExists} is {@code true} and
- * 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
@@ -454,7 +484,7 @@ public abstract class Path
* installed, the {@link SecurityManager#checkDelete(String)} method
* is invoked to check delete access to the file.
*/
- public abstract void delete(boolean failIfNotExists) throws IOException;
+ public abstract void deleteIfExists() throws IOException;
/**
* Creates a symbolic link to a target <i>(optional operation)</i>.
@@ -536,8 +566,6 @@ public abstract class Path
* or its {@link SecurityManager#checkWrite(String) checkWrite}
* method denies write access to both this path and the path of the
* existing file.
- *
- * @see BasicFileAttributes#linkCount
*/
public abstract Path createLink(Path existing) throws IOException;
@@ -608,7 +636,7 @@ public abstract class Path
*
* @return an absolute, hierarchical URI with a non-empty path component
*
- * @throws IOError
+ * @throws java.io.IOError
* if an I/O error occurs obtaining the absolute path, or where a
* file system is constructed to access the contents of a file as
* a file system, and the URI of the enclosing file system cannot be
@@ -636,8 +664,9 @@ public abstract class Path
* @throws IOError
* if an I/O error occurs
* @throws SecurityException
- * In the case of the default provider, and a security manager
- * is installed, its {@link SecurityManager#checkPropertyAccess(String)
+ * In the case of the default provider, a security manager
+ * is installed, and this path is not absolute, then the security
+ * manager's {@link SecurityManager#checkPropertyAccess(String)
* checkPropertyAccess} method is invoked to check access to the
* system property {@code user.dir}
*/
@@ -720,7 +749,9 @@ public abstract class Path
* the target file. The exact file attributes that are copied is platform
* and file system dependent and therefore unspecified. Minimally, the
* {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
- * copied to the target file. </td>
+ * copied to the target file if supported by both the source and target
+ * file store. Copying of file timestamps may result in precision
+ * loss. </td>
* </tr>
* <tr>
* <td> {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
@@ -867,10 +898,7 @@ public abstract class Path
*
* <p> The directory stream's {@code close} method should be invoked after
* iteration is completed so as to free any resources held for the open
- * directory. The {@link Files#withDirectory Files.withDirectory} utility
- * method is useful for cases where a task is performed on each accepted
- * entry in a directory. This method closes the directory when iteration is
- * complete (or an error occurs).
+ * directory.
*
* <p> When an implementation supports operations on entries in the
* directory that execute in a race-free manner then the returned directory
@@ -927,8 +955,6 @@ public abstract class Path
*
* @throws java.util.regex.PatternSyntaxException
* if the pattern is invalid
- * @throws UnsupportedOperationException
- * if the pattern syntax is not known to the implementation
* @throws NotDirectoryException
* if the file could not otherwise be opened because it is not
* a directory <i>(optional specific exception)</i>
@@ -950,19 +976,18 @@ public abstract class Path
* directory. The {@code Path} objects are obtained as if by {@link
* #resolve(Path) resolving} the name of the directory entry against this
* path. The entries returned by the iterator are filtered by the given
- * {@link DirectoryStream.Filter filter}. The {@link DirectoryStreamFilters}
- * class defines factory methods that create useful filters.
+ * {@link DirectoryStream.Filter filter}.
*
* <p> The directory stream's {@code close} method should be invoked after
* iteration is completed so as to free any resources held for the open
- * directory. The {@link Files#withDirectory Files.withDirectory} utility
- * method is useful for cases where a task is performed on each accepted
- * entry in a directory. This method closes the directory when iteration is
- * complete (or an error occurs).
+ * directory.
*
* <p> Where the filter terminates due to an uncaught error or runtime
- * exception then it propogated to the caller of the iterator's {@link
- * Iterator#hasNext() hasNext} or {@link Iterator#next() next} methods.
+ * exception then it is propogated to the iterator's {@link Iterator#hasNext()
+ * hasNext} or {@link Iterator#next() next} method. Where an {@code
+ * IOException} is thrown, it is propogated as a {@link
+ * java.util.concurrent.ConcurrentModificationException} with the {@code
+ * IOException} as the cause.
*
* <p> When an implementation supports operations on entries in the
* directory that execute in a race-free manner then the returned directory
@@ -973,14 +998,9 @@ public abstract class Path
* larger than 8K.
* <pre>
* DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
- * public boolean accept(Path file) {
- * try {
- * long size = Attributes.readBasicFileAttributes(file).size();
- * return (size > 8192L);
- * } catch (IOException e) {
- * // failed to get size
- * return false;
- * }
+ * public boolean accept(Path file) throws IOException {
+ * long size = Attributes.readBasicFileAttributes(file).size();
+ * return (size > 8192L);
* }
* };
* Path dir = ...
@@ -1071,6 +1091,8 @@ public abstract class Path
* In the case of the default provider, and a security manager is
* installed, the {@link SecurityManager#checkWrite(String) checkWrite}
* method is invoked to check write access to the new directory.
+ *
+ * @see Files#createDirectories
*/
public abstract Path createDirectory(FileAttribute<?>... attrs)
throws IOException;
@@ -1159,7 +1181,7 @@ public abstract class Path
* FileAttribute file-attributes} to set atomically when a new file is created.
*
* <p> In the case of the default provider, the returned seekable byte channel
- * is a {@link FileChannel}.
+ * is a {@link java.nio.channels.FileChannel}.
*
* <p> <b>Usage Examples:</b>
* <pre>
@@ -1212,12 +1234,9 @@ public abstract class Path
* Opens or creates a file, returning a seekable byte channel to access the
* file.
*
- * <p> This method extends the options defined by the {@code FileRef}
- * interface and to the options specified by the {@link
- * #newByteChannel(Set,FileAttribute[]) newByteChannel} method
- * except that the options are specified by an array. In the case of the
- * default provider, the returned seekable byte channel is a {@link
- * FileChannel}.
+ * <p> This method opens or creates a file in exactly the manner specified
+ * by the {@link Path#newByteChannel(Set,FileAttribute[]) newByteChannel}
+ * method.
*
* @param options
* options specifying how the file is opened
@@ -1232,108 +1251,40 @@ public abstract class Path
* if a file of that name already exists and the {@link
* StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
* <i>(optional specific exception)</i>
- * @throws IOException {@inheritDoc}
- * @throws SecurityException {@inheritDoc}
- */
- @Override
+ * @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#checkRead(String) checkRead}
+ * method is invoked to check read access to the path if the file is
+ * opened for reading. The {@link SecurityManager#checkWrite(String)
+ * checkWrite} method is invoked to check write access to the path
+ * if the file is opened for writing.
+ */
public abstract SeekableByteChannel newByteChannel(OpenOption... options)
throws IOException;
/**
- * Opens the file located by this path for reading, returning an input
- * stream to read bytes from the file. The stream will not be buffered, and
- * is not required to support the {@link InputStream#mark mark} or {@link
- * InputStream#reset reset} methods. The stream will be safe for access by
- * multiple concurrent threads. Reading commences at the beginning of the file.
- *
- * @return an input stream to read bytes from the file
- *
- * @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#checkRead(String) checkRead}
- * method is invoked to check read access to the file.
- */
- public abstract InputStream newInputStream() throws IOException;
-
- /**
- * Opens or creates the file located by this path for writing, returning an
- * output stream to write bytes to the file.
+ * Opens or creates the file located by this object for writing, returning
+ * an output stream to write bytes to the file.
*
* <p> This method opens or creates a file in exactly the manner specified
* by the {@link Path#newByteChannel(Set,FileAttribute[]) newByteChannel}
* method except that the {@link StandardOpenOption#READ READ} option may not
- * be present in the array of open options. If no open options are present
- * then this method creates a new file for writing or truncates an existing
- * file.
- *
- * <p> The resulting stream will not be buffered. The stream will be safe
- * for access by multiple concurrent threads.
- *
- * <p> <b>Usage Example:</b>
- * Suppose we wish to open a log file for writing so that we append to the
- * file if it already exists, or create it when it doesn't exist.
- * <pre>
- * Path logfile = ...
- * OutputStream out = new BufferedOutputStream(logfile.newOutputStream(CREATE, APPEND));
- * </pre>
+ * be present in the array of open options.
*
* @param options
* options specifying how the file is opened
*
- * @return a new seekable byte channel
- *
- * @throws IllegalArgumentException
- * if {@code options} contains an invalid combination of options
- * @throws UnsupportedOperationException
- * if an unsupported open option is specified
- * @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#checkWrite(String) checkWrite}
- * method is invoked to check write access to the file.
- */
+ * @return a new output stream
+ *
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ * @throws SecurityException {@inheritDoc}
+ */
+ @Override
public abstract OutputStream newOutputStream(OpenOption... options)
- throws IOException;
-
- /**
- * Opens or creates the file located by this path for writing, returning an
- * output stream to write bytes to the file.
- *
- * <p> This method opens or creates a file in exactly the manner specified
- * by the {@link Path#newByteChannel(Set,FileAttribute[]) newByteChannel}
- * method except that {@code options} parameter may not contain the {@link
- * StandardOpenOption#READ READ} option. If no open options are present
- * then this method creates a new file for writing or truncates an existing
- * file.
- *
- * <p> The resulting stream will not be buffered. The stream will be safe
- * for access by multiple concurrent threads.
- *
- * @param options
- * options specifying how the file is opened
- * @param attrs
- * an optional list of file attributes to set atomically when
- * creating the file
- *
- * @return a new output stream
- *
- * @throws IllegalArgumentException
- * if the set contains an invalid combination of options
- * @throws UnsupportedOperationException
- * if an unsupported open option is specified or the array contains
- * attributes that cannot be set atomically when creating the file
- * @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#checkWrite(String) checkWrite}
- * method is invoked to check write access to the file.
- */
- public abstract OutputStream newOutputStream(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
throws IOException;
/**
@@ -1357,6 +1308,80 @@ public abstract class Path
* method is invoked to check read access to the file.
*/
public abstract boolean isHidden() throws IOException;
+
+ /**
+ * Checks the existence and optionally the accessibility of the file
+ * located by this path.
+ *
+ * <p> This method checks the existence of a file and that this Java virtual
+ * machine has appropriate privileges that would allow it access the file
+ * according to all of access modes specified in the {@code modes} parameter
+ * as follows:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Value</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link AccessMode#READ READ} </td>
+ * <td> Checks that the file exists and that the Java virtual machine has
+ * permission to read the file. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link AccessMode#WRITE WRITE} </td>
+ * <td> Checks that the file exists and that the Java virtual machine has
+ * permission to write to the file, </td>
+ * </tr>
+ * <tr>
+ * <td> {@link AccessMode#EXECUTE EXECUTE} </td>
+ * <td> Checks that the file exists and that the Java virtual machine has
+ * permission to {@link Runtime#exec execute} the file. The semantics
+ * may differ when checking access to a directory. For example, on UNIX
+ * systems, checking for {@code EXECUTE} access checks that the Java
+ * virtual machine has permission to search the directory in order to
+ * access file or subdirectories. </td>
+ * </tr>
+ * </table>
+ *
+ * <p> If the {@code modes} parameter is of length zero, then the existence
+ * of the file is checked.
+ *
+ * <p> This method follows symbolic links if the file referenced by this
+ * object is a symbolic link. Depending on the implementation, this method
+ * may require to read file permissions, access control lists, or other
+ * file attributes in order to check the effective access to the file. To
+ * determine the effective access to a file may require access to several
+ * attributes and so in some implementations this method may not be atomic
+ * with respect to other file system operations. Furthermore, as the result
+ * of this method is immediately outdated, there is no guarantee that a
+ * subsequence access will succeed (or even that it will access the same
+ * file). Care should be taken when using this method in security sensitive
+ * applications.
+ *
+ * @param modes
+ * The access modes to check; may have zero elements
+ *
+ * @throws UnsupportedOperationException
+ * an implementation is required to support checking for
+ * {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
+ * exception is specified to allow for the {@code Access} enum to
+ * be extended in future releases.
+ * @throws NoSuchFileException
+ * if a file does not exist <i>(optional specific exception)</i>
+ * @throws AccessDeniedException
+ * the requested access would be denied or the access cannot be
+ * determined because the Java virtual machine has insufficient
+ * privileges or other reasons. <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#checkRead(String) checkRead}
+ * is invoked when checking read access to the file or only the
+ * existence of the file, the {@link SecurityManager#checkWrite(String)
+ * checkWrite} is invoked when checking write access to the file,
+ * and {@link SecurityManager#checkExec(String) checkExec} is invoked
+ * when checking execute access.
+ */
+ public abstract void checkAccess(AccessMode... modes) throws IOException;
/**
* Tests whether the file located by this path exists.
@@ -1413,6 +1438,30 @@ public abstract class Path
* read access to the file.
*/
public abstract boolean notExists();
+
+ /**
+ * Returns the {@link FileStore} representing the file store where an
+ * existing file, located by this path, is stored.
+ *
+ * <p> Once a reference to the {@code FileStore} is obtained it is
+ * implementation specific if operations on the returned {@code FileStore},
+ * or {@link FileStoreAttributeView} objects obtained from it, continue
+ * to depend on the existence of the file. In particular the behavior is not
+ * defined for the case that the file is deleted or moved to a different
+ * file store.
+ *
+ * @return the file store where the file is stored
+ *
+ * @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#checkRead(String) checkRead}
+ * method is invoked to check read access to the file, and in
+ * addition it checks {@link RuntimePermission}<tt>
+ * ("getFileStoreAttributes")</tt>
+ */
+ public abstract FileStore getFileStore() throws IOException;
// -- watchable --
@@ -1562,6 +1611,49 @@ public abstract class Path
public abstract int compareTo(Path other);
/**
+ * Tests if the file referenced by this object is the same file referenced
+ * by another object.
+ *
+ * <p> If this {@code FileRef} and the given {@code FileRef} are {@link
+ * #equals(Object) equal} then this method returns {@code true} without checking
+ * if the file exists. If the {@code FileRef} and the given {@code FileRef}
+ * are associated with different providers, or the given {@code FileRef} is
+ * {@code null} then this method returns {@code false}. Otherwise, this method
+ * checks if both {@code FileRefs} locate the same file, and depending on the
+ * implementation, may require to open or access both files.
+ *
+ * <p> If the file system and files remain static, then this method implements
+ * an equivalence relation for non-null {@code FileRefs}.
+ * <ul>
+ * <li>It is <i>reflexive</i>: for a non-null {@code FileRef} {@code f},
+ * {@code f.isSameFile(f)} should return {@code true}.
+ * <li>It is <i>symmetric</i>: for two non-null {@code FileRefs}
+ * {@code f} and {@code g}, {@code f.isSameFile(g)} will equal
+ * {@code g.isSameFile(f)}.
+ * <li>It is <i>transitive</i>: for three {@code FileRefs}
+ * {@code f}, {@code g}, and {@code h}, if {@code f.isSameFile(g)} returns
+ * {@code true} and {@code g.isSameFile(h)} returns {@code true}, then
+ * {@code f.isSameFile(h)} will return return {@code true}.
+ * </ul>
+ *
+ * @param other
+ * the other file reference
+ *
+ * @return {@code true} if, and only if, this object and the given object
+ * locate the same file
+ *
+ * @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#checkRead(String) checkRead}
+ * method is invoked to check read access to both files.
+ *
+ * @see java.nio.file.attribute.BasicFileAttributes#fileKey
+ */
+ public abstract boolean isSameFile(Path other) throws IOException;
+
+ /**
* Tests this path for equality with the given object.
*
* <p> If the given object is not a Path, or is a Path associated with a
--- a/src/share/classes/java/nio/file/Paths.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/Paths.java Mon Jun 29 15:08:52 2009 +0100
@@ -35,7 +35,7 @@ import java.net.URI;
* @since 1.7
*/
-public class Paths {
+public final class Paths {
private Paths() { }
/**
@@ -106,8 +106,9 @@ public class Paths {
* if preconditions on the {@code uri} parameter do not hold. The
* format of the URI is provider specific.
* @throws FileSystemNotFoundException
- * if the file system identified by the URI does not exist or the
- * provider identified by the URI's scheme component is not installed
+ * The file system, identified by the URI, does not exist and
+ * cannot be created automatically, or the provider identified by
+ * the URI's scheme component is not installed
* @throws SecurityException
* if a security manager is installed and it denies an unspecified
* permission to access the file system
--- a/src/share/classes/java/nio/file/SecureDirectoryStream.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/SecureDirectoryStream.java Mon Jun 29 15:08:52 2009 +0100
@@ -36,7 +36,7 @@ import java.io.IOException;
* traverse file trees or otherwise operate on directories in a race-free manner.
* Race conditions can arise when a sequence of file operations cannot be
* carried out in isolation. Each of the file operations defined by this
- * interface specify a relative {@link Path}. All access to the file is relative
+ * interface specify a relative path. All access to the file is relative
* to the open directory irrespective of if the directory is moved or replaced
* by an attacker while the directory is open. A {@code SecureDirectoryStream}
* may also be used as a virtual <em>working directory</em>.
@@ -65,8 +65,8 @@ import java.io.IOException;
* @since 1.7
*/
-public abstract class SecureDirectoryStream
- implements DirectoryStream<Path>
+public abstract class SecureDirectoryStream<T>
+ implements DirectoryStream<T>
{
/**
* Initialize a new instance of this class.
@@ -78,13 +78,12 @@ public abstract class SecureDirectoryStr
* SecureDirectoryStream} to iterate over the entries in the directory.
*
* <p> This method works in exactly the manner specified by the {@link
- * Path#newDirectoryStream newDirectoryStream} method for the case that
+ * Path#newDirectoryStream() newDirectoryStream} 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 directory to open is
- * relative to this open directory. The {@code followLinks} parameter
- * determines if links should be followed. If this parameter is {@code
- * false} and the file is a symbolic link then this method fails (by
- * throwing an I/O exception).
+ * relative to this open directory. The {@link
+ * LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
+ * ensure that this method fails if the file is a symbolic link.
*
* <p> The new directory stream, once created, is not dependent upon the
* directory stream used to create it. Closing this directory stream has no
@@ -92,10 +91,8 @@ public abstract class SecureDirectoryStr
*
* @param path
* the path to the directory to open
- * @param followLinks
- * {@code true} if the links should be followed
- * @param filter
- * the directory stream filter or {@code null}.
+ * @param options
+ * options indicating how symbolic links are handled
*
* @return a new and open {@code SecureDirectoryStream} object
*
@@ -111,9 +108,8 @@ public abstract class SecureDirectoryStr
* installed, the {@link SecurityManager#checkRead(String) checkRead}
* method is invoked to check read access to the directory.
*/
- public abstract SecureDirectoryStream newDirectoryStream(Path path,
- boolean followLinks,
- DirectoryStream.Filter<? super Path> filter)
+ public abstract SecureDirectoryStream<T> newDirectoryStream(T path,
+ LinkOption... options)
throws IOException;
/**
@@ -162,7 +158,7 @@ public abstract class SecureDirectoryStr
* checkWrite} method is invoked to check write access to the path
* if the file is opened for writing.
*/
- public abstract SeekableByteChannel newByteChannel(Path path,
+ public abstract SeekableByteChannel newByteChannel(T path,
Set<? extends OpenOption> options,
FileAttribute<?>... attrs)
throws IOException;
@@ -170,7 +166,7 @@ public abstract class SecureDirectoryStr
/**
* Deletes a file.
*
- * <p> Unlike the {@link FileRef#delete delete()} method, this method
+ * <p> Unlike the {@link Path#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
@@ -191,12 +187,12 @@ public abstract class SecureDirectoryStr
* installed, the {@link SecurityManager#checkDelete(String) checkDelete}
* method is invoked to check delete access to the file
*/
- public abstract void deleteFile(Path path) throws IOException;
+ public abstract void deleteFile(T path) throws IOException;
/**
* Deletes a directory.
*
- * <p> Unlike the {@link FileRef#delete delete()} method, this method
+ * <p> Unlike the {@link Path#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
@@ -219,7 +215,7 @@ public abstract class SecureDirectoryStr
* 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;
+ public abstract void deleteDirectory(T path) throws IOException;
/**
* Move a file from this directory to another directory.
@@ -259,7 +255,7 @@ public abstract class SecureDirectoryStr
* method is invoked to check write access to both the source and
* target file.
*/
- public abstract void move(Path srcpath, SecureDirectoryStream targetdir, Path targetpath)
+ public abstract void move(T srcpath, SecureDirectoryStream<T> targetdir, T targetpath)
throws IOException;
/**
@@ -318,7 +314,7 @@ public abstract class SecureDirectoryStr
* type is not available
*
*/
- public abstract <V extends FileAttributeView> V getFileAttributeView(Path path,
+ public abstract <V extends FileAttributeView> V getFileAttributeView(T path,
Class<V> type,
LinkOption... options);
}
--- a/src/share/classes/java/nio/file/SimpleFileVisitor.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/SimpleFileVisitor.java Mon Jun 29 15:08:52 2009 +0100
@@ -40,7 +40,7 @@ import java.io.IOError;
* @since 1.7
*/
-public class SimpleFileVisitor<T extends FileRef> implements FileVisitor<T> {
+public class SimpleFileVisitor<T> implements FileVisitor<T> {
/**
* Initializes a new instance of this class.
*/
--- a/src/share/classes/java/nio/file/StandardWatchEventKind.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/StandardWatchEventKind.java Mon Jun 29 15:08:52 2009 +0100
@@ -31,7 +31,7 @@ package java.nio.file;
* @since 1.7
*/
-public class StandardWatchEventKind {
+public final class StandardWatchEventKind {
private StandardWatchEventKind() { }
/**
--- a/src/share/classes/java/nio/file/WatchKey.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/WatchKey.java Mon Jun 29 15:08:52 2009 +0100
@@ -103,7 +103,7 @@ public abstract class WatchKey {
*
* <p> Note that this method does not wait if there are no events pending.
*
- * @return the list of the events retrieved
+ * @return the list of the events retrieved; may be empty
*/
public abstract List<WatchEvent<?>> pollEvents();
@@ -128,7 +128,7 @@ public abstract class WatchKey {
* will be invalid. If the watch key is enqueued, waiting to be retrieved
* from the watch service, then it will remain in the queue until it is
* removed. Pending events, if any, remain pending and may be retrieved by
- * invoking the {@link #pollEvents pollEvents} method event after the key is
+ * invoking the {@link #pollEvents pollEvents} method after the key is
* cancelled.
*
* <p> If this watch key has already been cancelled then invoking this
--- a/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -110,13 +110,13 @@ import java.io.IOException;
* </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.
+ * <p> The {@link FileRef#getAttribute getAttribute} method 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 FileRef#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>
*
--- a/src/share/classes/java/nio/file/attribute/AttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/AttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -25,20 +25,12 @@
package java.nio.file.attribute;
-import java.util.*;
-import java.io.IOException;
-
/**
* An object that provides a read-only or updatable <em>view</em> of non-opaque
* values associated with an object in a filesystem. This interface is extended
* or implemented by specific attribute views that define the attributes
* supported by the view. A specific attribute view will typically define
- * type-safe methods to read or update the attributes that it supports. It also
- * provides <em>dynamic access</em> where the {@link #readAttributes
- * readAttributes}, {@link #getAttribute getAttribute} and {@link #setAttribute
- * setAttributs} methods are used to access the attributes by names defined
- * by the attribute view. Implementations must ensure that the attribute names
- * do not contain the colon (':') or comma (',') characters.
+ * type-safe methods to read or update the attributes that it supports.
*
* @since 1.7
*/
@@ -48,71 +40,4 @@ public interface AttributeView {
* Returns the name of the attribute view.
*/
String name();
-
- /**
- * Reads the value of an attribute.
- *
- * @param attribute
- * the attribute name (case sensitive)
- *
- * @return the value of the attribute, or {@code null} if the attribute is
- * not supported
- *
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * if a security manager is set and it denies access
- */
- Object getAttribute(String attribute) throws IOException;
-
- /**
- * Sets/updates the value of an attribute.
- *
- * @param attribute
- * the attribute name (case sensitive)
- * @param value
- * the attribute value
- *
- * @throws UnsupportedOperationException
- * if the attribute is not supported or this attribute view does
- * not support updating the value of the attribute
- * @throws IllegalArgumentException
- * if the attribute value is of the correct type but has an
- * inappropriate value
- * @throws ClassCastException
- * if the attribute value is not of the expected type or is a
- * collection containing elements that are not of the expected
- * type
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * if a security manager is set and it denies access
- */
- void setAttribute(String attribute, Object value) throws IOException;
-
- /**
- * Reads all, or a subset, of the attributes supported by this file attribute
- * view.
- *
- * <p> The {@code first} and {@code rest} parameters are the names of the
- * attributes to read. If any of the parameters has the value {@code "*"}
- * then all attributes are read. Attributes that are not supported are
- * ignored and will not be present in the returned map. It is implementation
- * specific if all attributes are read as an atomic operation with respect
- * to other file system operations.
- *
- * @param first
- * the name of an attribute to read (case sensitive)
- * @param rest
- * the names of other attributes to read (case sensitive)
- *
- * @return an unmodifiable map of the attributes; may be empty. Its keys are
- * the attribute names, its values are the attribute values
- *
- * @throws IOException
- * if an I/O error occurs
- * @throws SecurityException
- * if a security manager is set and it denies access
- */
- Map<String,?> readAttributes(String first, String... rest) throws IOException;
}
--- a/src/share/classes/java/nio/file/attribute/Attributes.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/Attributes.java Mon Jun 29 15:08:52 2009 +0100
@@ -28,7 +28,6 @@ import java.nio.file.*;
import java.nio.file.*;
import java.io.IOException;
import java.util.*;
-import java.util.concurrent.TimeUnit;
/**
* This class consists exclusively of static methods that operate on or return
@@ -39,245 +38,7 @@ import java.util.concurrent.TimeUnit;
*/
public final class Attributes {
- private Attributes() {
- }
-
- /**
- * Splits the given attribute name into the name of an attribute view and
- * the attribute. If the attribute view is not identified then it assumed
- * to be "basic".
- */
- private static String[] split(String attribute) {
- String[] s = new String[2];
- int pos = attribute.indexOf(':');
- if (pos == -1) {
- s[0] = "basic";
- s[1] = attribute;
- } else {
- s[0] = attribute.substring(0, pos++);
- s[1] = (pos == attribute.length()) ? "" : attribute.substring(pos);
- }
- return s;
- }
-
- /**
- * Sets the value of a file attribute.
- *
- * <p> The {@code attribute} parameter identifies the attribute to be set
- * and takes the form:
- * <blockquote>
- * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
- * </blockquote>
- * where square brackets [...] delineate an optional component and the
- * character {@code ':'} stands for itself.
- *
- * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
- * FileAttributeView} that identifies a set of file attributes. If not
- * specified then it defaults to {@code "basic"}, the name of the file
- * 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
- * within the set.
- *
- * <p> <b>Usage Example:</b>
- * Suppose we want to set the DOS "hidden" attribute:
- * <pre>
- * Attributes.setAttribute(file, "dos:hidden", true);
- * </pre>
- *
- * @param file
- * A file reference that locates the file
- * @param attribute
- * The attribute to set
- * @param value
- * The attribute value
- *
- * @throws UnsupportedOperationException
- * If the attribute view is not available or it does not
- * support updating the attribute
- * @throws IllegalArgumentException
- * If the attribute value is of the correct type but has an
- * inappropriate value
- * @throws ClassCastException
- * If the attribute value is not of the expected type or is a
- * collection containing elements that are not of the expected
- * type
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file. If this method is invoked
- * to set security sensitive attributes then the security manager
- * may be invoked to check for additional permissions.
- */
- public static void setAttribute(FileRef file, String attribute, Object value)
- throws IOException
- {
- String[] s = split(attribute);
- FileAttributeView view = file.getFileAttributeView(s[0]);
- if (view == null)
- throw new UnsupportedOperationException("View '" + s[0] + "' not available");
- view.setAttribute(s[1], value);
- }
-
- /**
- * Reads the value of a file attribute.
- *
- * <p> The {@code attribute} parameter identifies the attribute to be read
- * and takes the form:
- * <blockquote>
- * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
- * </blockquote>
- * where square brackets [...] delineate an optional component and the
- * character {@code ':'} stands for itself.
- *
- * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
- * FileAttributeView} that identifies a set of file attributes. If not
- * specified then it defaults to {@code "basic"}, the name of the file
- * 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, "unix:uid");
- * </pre>
- *
- * @param file
- * A file reference that locates the file
- * @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
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and 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 security sensitive attributes then the security manager
- * may be invoked to check for additional permissions.
- */
- public static Object getAttribute(FileRef file,
- String attribute,
- LinkOption... options)
- throws IOException
- {
- String[] s = split(attribute);
- FileAttributeView view = file.getFileAttributeView(s[0], options);
- if (view != null)
- return view.getAttribute(s[1]);
- // view not available
- return null;
- }
-
- /**
- * Reads a set of file attributes as a bulk operation.
- *
- * <p> The {@code attributes} parameter identifies the attributes to be read
- * and takes the form:
- * <blockquote>
- * [<i>view-name</i><b>:</b>]<i>attribute-list</i>
- * </blockquote>
- * where square brackets [...] delineate an optional component and the
- * character {@code ':'} stands for itself.
- *
- * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
- * FileAttributeView} that identifies a set of file attributes. If not
- * specified then it defaults to {@code "basic"}, the name of the file
- * attribute view that identifies the basic set of file attributes common to
- * many file systems.
- *
- * <p> The <i>attribute-list</i> component is a comma separated list of
- * zero or more names of attributes to read. If the list contains the value
- * {@code "*"} then all attributes are read. Attributes that are not supported
- * are ignored and will not be present in the returned map. It is
- * implementation specific if all attributes are read as an atomic operation
- * with respect to other file system operations.
- *
- * <p> The following examples demonstrate possible values for the {@code
- * attributes} parameter:
- *
- * <blockquote>
- * <table border="0">
- * <tr>
- * <td> {@code "*"} </td>
- * <td> Read all {@link BasicFileAttributes basic-file-attributes}. </td>
- * </tr>
- * <tr>
- * <td> {@code "size,lastModifiedTime,lastAccessTime"} </td>
- * <td> Reads the file size, last modified time, and last access time
- * attributes. </td>
- * </tr>
- * <tr>
- * <td> {@code "posix:*"} </td>
- * <td> Read all {@link PosixFileAttributes POSIX-file-attributes}.. </td>
- * </tr>
- * <tr>
- * <td> {@code "posix:permissions,owner,size"} </td>
- * <td> Reads the POSX file permissions, owner, and file size. </td>
- * </tr>
- * </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 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
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and 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 security sensitive attributes then the security manager
- * may be invoke to check for additional permissions.
- */
- public static Map<String,?> readAttributes(FileRef file,
- String attributes,
- LinkOption... options)
- throws IOException
- {
- String[] s = split(attributes);
- FileAttributeView view = file.getFileAttributeView(s[0], options);
- if (view != null) {
- // further split attributes into the first and rest.
- String[] names = s[1].split(",");
- int rem = names.length-1;
- 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
- return Collections.emptyMap();
- }
+ private Attributes() { }
/**
* Reads the basic file attributes of a file.
@@ -551,29 +312,28 @@ public final class Attributes {
}
/**
- * Updates the value of a file's last modified time attribute.
- *
- * <p> The time value is measured since the epoch
- * (00:00:00 GMT, January 1, 1970) and is converted to the precision supported
- * by the file system. Converting from finer to coarser granularities result
- * in precision loss.
- *
- * <p> If the file system does not support a last modified time attribute then
- * this method has no effect.
- *
- * @param file
- * A file reference that locates the file
- *
+ * Updates a file's last modified time attribute. The file time is converted
+ * to the epoch and precision supported by the file system. Converting from
+ * finer to coarser granularities result in precision loss. The behavior of
+ * this method when attempting to set a timestamp to a value that is outside
+ * the range supported by the underlying file store is not defined. It may
+ * or not fail by throwing an {@code IOException}.
+ *
+ * <p> If the file system does not support a last modified time attribute
+ * then this method has no effect.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to set the last modified time to the current time:
+ * <pre>
+ * FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+ * Attributes.setLastModifiedTime(file, now);
+ * </pre>
+ *
+ * @param file
+ * A file reference that locates the file
* @param lastModifiedTime
- * The new last modified time, or {@code -1L} to update it to
- * the current time
- * @param unit
- * A {@code TimeUnit} determining how to interpret the
- * {@code lastModifiedTime} parameter
- *
- * @throws IllegalArgumentException
- * If the {@code lastModifiedime} parameter is a negative value other
- * than {@code -1L}
+ * The new last modified time
+ *
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
@@ -584,35 +344,31 @@ public final class Attributes {
* @see BasicFileAttributeView#setTimes
*/
public static void setLastModifiedTime(FileRef file,
- long lastModifiedTime,
- TimeUnit unit)
- throws IOException
- {
+ FileTime lastModifiedTime)
+ throws IOException
+ {
+ if (lastModifiedTime == null)
+ throw new NullPointerException("'lastModifiedTime' is null");
file.getFileAttributeView(BasicFileAttributeView.class)
- .setTimes(lastModifiedTime, null, null, unit);
- }
-
- /**
- * Updates the value of a file's last access time attribute.
- *
- * <p> The time value is measured since the epoch
- * (00:00:00 GMT, January 1, 1970) and is converted to the precision supported
- * by the file system. Converting from finer to coarser granularities result
- * in precision loss.
+ .setTimes(lastModifiedTime, null, null);
+ }
+
+ /**
+ * Updates a file's last access time attribute. The file time is converted
+ * to the epoch and precision supported by the file system. Converting from
+ * finer to coarser granularities result in precision loss. The behavior of
+ * this method when attempting to set a timestamp to a value that is outside
+ * the range supported by the underlying file store is not defined. It may
+ * or not fail by throwing an {@code IOException}.
*
* <p> If the file system does not support a last access time attribute then
* this method has no effect.
*
+ * @param file
+ * A file reference that locates the file
* @param lastAccessTime
- * The new last access time, or {@code -1L} to update it to
- * the current time
- * @param unit
- * A {@code TimeUnit} determining how to interpret the
- * {@code lastModifiedTime} parameter
- *
- * @throws IllegalArgumentException
- * If the {@code lastAccessTime} parameter is a negative value other
- * than {@code -1L}
+ * The new last access time
+ *
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
@@ -623,12 +379,13 @@ public final class Attributes {
* @see BasicFileAttributeView#setTimes
*/
public static void setLastAccessTime(FileRef file,
- long lastAccessTime,
- TimeUnit unit)
- throws IOException
- {
+ FileTime lastAccessTime)
+ throws IOException
+ {
+ if (lastAccessTime == null)
+ throw new NullPointerException("'lastAccessTime' is null");
file.getFileAttributeView(BasicFileAttributeView.class)
- .setTimes(null, lastAccessTime, null, unit);
+ .setTimes(null, lastAccessTime, null);
}
/**
--- a/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -25,7 +25,6 @@
package java.nio.file.attribute;
-import java.util.concurrent.TimeUnit;
import java.io.IOException;
/**
@@ -49,19 +48,15 @@ import java.io.IOException;
* </tr>
* <tr>
* <td> "lastModifiedTime" </td>
- * <td> {@link Long} </td>
+ * <td> {@link FileTime} </td>
* </tr>
* <tr>
* <td> "lastAccessTime" </td>
- * <td> {@link Long} </td>
+ * <td> {@link FileTime} </td>
* </tr>
* <tr>
* <td> "creationTime" </td>
- * <td> {@link Long} </td>
- * </tr>
- * <tr>
- * <td> "resolution" </td>
- * <td> {@link java.util.concurrent.TimeUnit} </td>
+ * <td> {@link FileTime} </td>
* </tr>
* <tr>
* <td> "size" </td>
@@ -84,26 +79,19 @@ import java.io.IOException;
* <td> {@link Boolean} </td>
* </tr>
* <tr>
- * <td> "linkCount" </td>
- * <td> {@link Integer} </td>
- * </tr>
- * <tr>
* <td> "fileKey" </td>
* <td> {@link Object} </td>
* </tr>
* </table>
* </blockquote>
*
- * <p> The {@link #getAttribute getAttribute} or {@link
- * #readAttributes(String,String[]) readAttributes(String,String[])} methods may
- * be used to read any of these attributes as if by invoking the {@link
+ * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} method 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.
+ * <p> The {@link java.nio.file.FileRef#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.
*
* @since 1.7
* @see Attributes
@@ -141,11 +129,11 @@ public interface BasicFileAttributeView
* and create time attributes.
*
* <p> This method updates the file's timestamp attributes. The values are
- * measured since the epoch (00:00:00 GMT, January 1, 1970) and converted to
- * the precision supported by the file system. Converting from finer to
- * coarser granularities result in precision loss. If a value is larger
- * than the maximum supported by the file system then the corresponding
- * timestamp is set to its maximum value.
+ * converted to the epoch and precision supported by the file system.
+ * Converting from finer to coarser granularities result in precision loss.
+ * The behavior of this method when attempting to set a timestamp to a value
+ * that is outside the range supported by the underlying file store is not
+ * defined. It may or not fail by throwing an {@code IOException}.
*
* <p> If any of the {@code lastModifiedTime}, {@code lastAccessTime},
* or {@code createTime} parameters has the value {@code null} then the
@@ -153,25 +141,19 @@ public interface BasicFileAttributeView
* read the existing values of the file attributes when only some, but not
* all, of the timestamp attributes are updated. Consequently, this method
* may not be an atomic operation with respect to other file system
- * operations. If all of the {@code lastModifiedTime}, {@code
+ * operations. Reading and re-writing existing values may also result in
+ * precision loss. If all of the {@code lastModifiedTime}, {@code
* lastAccessTime} and {@code createTime} parameters are {@code null} then
* this method has no effect.
*
* @param lastModifiedTime
- * the new last modified time, or {@code -1L} to update it to
- * the current time, or {@code null} to not change the attribute
+ * the new last modified time, or {@code null} to not change the
+ * value
* @param lastAccessTime
- * the last access time, or {@code -1L} to update it to
- * the current time, or {@code null} to not change the attribute.
+ * the last access time, or {@code null} to not change the value
* @param createTime
- * the file's create time, or {@code -1L} to update it to
- * the current time, or {@code null} to not change the attribute
- * @param unit
- * a {@code TimeUnit} determining how to interpret the time values
+ * the file's create time, or {@code null} to not change the value
*
- * @throws IllegalArgumentException
- * if any of the parameters is a negative value other than {@code
- * -1L}
* @throws IOException
* if an I/O error occurs
* @throws SecurityException
@@ -179,8 +161,7 @@ public interface BasicFileAttributeView
* installed, its {@link SecurityManager#checkWrite(String) checkWrite}
* method is invoked to check write access to the file
*/
- void setTimes(Long lastModifiedTime,
- Long lastAccessTime,
- Long createTime,
- TimeUnit unit) throws IOException;
+ void setTimes(FileTime lastModifiedTime,
+ FileTime lastAccessTime,
+ FileTime createTime) throws IOException;
}
--- a/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java Mon Jun 29 15:08:52 2009 +0100
@@ -25,8 +25,6 @@
package java.nio.file.attribute;
-import java.util.concurrent.TimeUnit;
-
/**
* Basic attributes associated with a file in a file system.
*
@@ -50,47 +48,27 @@ public interface BasicFileAttributes {
/**
* Returns the time of last modification.
*
- * <p> The {@link #resolution() resolution} method returns the {@link TimeUnit}
- * to interpret the return value of this method.
- *
- * @return a <code>long</code> value representing the time the file was
- * last modified since the epoch (00:00:00 GMT, January 1, 1970),
- * or {@code -1L} if the attribute is not supported.
+ * @return a {@code FileTime} representing the time the file was last
+ * modified or {@code null} if the attribute is not supported.
*/
- long lastModifiedTime();
+ FileTime lastModifiedTime();
/**
* Returns the time of last access if supported.
*
- * <p> The {@link #resolution() resolution} method returns the {@link TimeUnit}
- * to interpret the return value of this method.
- *
- * @return a <code>long</code> value representing the time of last access
- * since the epoch (00:00:00 GMT, January 1, 1970), or {@code -1L}
- * if the attribute is not supported.
+ * @return a {@code FileTime} representing the time of last access or
+ * {@code null} if the attribute is not supported.
*/
- long lastAccessTime();
+ FileTime lastAccessTime();
/**
* Returns the creation time if supported. The creation time is the time
* that the file was created.
*
- * <p> The {@link #resolution() resolution} method returns the {@link TimeUnit}
- * to interpret the return value of this method.
- *
- * @return a <code>long</code> value representing the time the file was
- * created since the epoch (00:00:00 GMT, January 1, 1970), or
- * {@code -1L} if the attribute is not supported.
+ * @return a {@code FileTime} representing the time the file was created
+ * or {@code null} if the attribute is not supported.
*/
- long creationTime();
-
- /**
- * Returns the {@link TimeUnit} required to interpret the time of last
- * modification, time of last access, and creation time.
- *
- * @return the {@code TimeUnit} required to interpret the file time stamps
- */
- TimeUnit resolution();
+ FileTime creationTime();
/**
* Tells whether the file is a regular file with opaque content.
@@ -125,18 +103,6 @@ public interface BasicFileAttributes {
long size();
/**
- * Returns the number of <em>links</em> to this file.
- *
- * <p> On file systems where the same file may be in several directories then
- * the link count is the number of directory entries for the file. The return
- * value is {@code 1} on file systems that only allow a file to have a
- * single name in a single directory.
- *
- * @see java.nio.file.Path#createLink
- */
- int linkCount();
-
- /**
* Returns an object that uniquely identifies the given file, or {@code
* null} if a file key is not available. On some platforms or file systems
* it is possible to use an identifier, or a combination of identifiers to
@@ -154,7 +120,7 @@ public interface BasicFileAttributes {
*
* <p> File keys returned by this method can be compared for equality and are
* suitable for use in collections. If the file system and files remain static,
- * and two files are the {@link java.nio.file.FileRef#isSameFile same} with
+ * and two files are the {@link java.nio.file.Path#isSameFile same} with
* non-{@code null} file keys, then their file keys are equal.
*
* @see java.nio.file.Files#walkFileTree
--- a/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -65,17 +65,17 @@ import java.io.IOException;
* </table>
* </blockquote>
*
- * <p> The {@link #getAttribute getAttribute} or {@link #readAttributes(String,String[])
- * 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 java.nio.file.FileRef#getAttribute getAttribute} method 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 DOS attributes as if by invoking the {@link #setReadOnly setReadOnly},
- * {@link #setHidden setHidden}, {@link #setSystem setSystem}, and {@link
- * #setArchive setArchive} methods respectively.
+ * <p> The {@link java.nio.file.FileRef#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 DOS 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/FileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/FileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -34,7 +34,6 @@ package java.nio.file.attribute;
* @since 1.7
*
* @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/FileOwnerAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -37,11 +37,11 @@ import java.io.IOException;
* <p> The {@link #getOwner getOwner} or {@link #setOwner setOwner} methods may
* be used to read or update the owner of the file.
*
- * <p> Where dynamic access to file attributes is required, the owner attribute
- * 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.
+ * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} and
+ * {@link java.nio.file.FileRef#setAttribute setAttribute} methods may also be
+ * used to read or update the owner. In that case, the owner attribute is
+ * identified by the name {@code "owner"}, and the value of the attribute is
+ * a {@link UserPrincipal}.
*
* @since 1.7
*/
--- a/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -52,10 +52,8 @@ import java.io.IOException;
* </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.
+ * <p> The {@link java.nio.file.FileStore#getAttribute getAttribute} method may
+ * be used to read any of these attributes.
*
* @since 1.7
*/
--- a/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -90,14 +90,13 @@ import java.io.IOException;
* </table>
* </blockquote>
*
- * <p> The {@link #getAttribute getAttribute} or {@link
- * #readAttributes(String,String[]) 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
+ * <p> The {@link FileRef#getAttribute getAttribute} method 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
+ * <p> The {@link FileRef#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
--- a/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java Mon Jun 29 15:08:52 2009 +0100
@@ -35,7 +35,7 @@ import java.util.*;
* @since 1.7
*/
-public class PosixFilePermissions {
+public final class PosixFilePermissions {
private PosixFilePermissions() { }
// Write string representation of permission bits to {@code sb}.
@@ -58,7 +58,9 @@ public class PosixFilePermissions {
}
/**
- * Returns the {@code String} representation of a set of permissions.
+ * Returns the {@code String} representation of a set of permissions. It
+ * is guaranteed that the returned {@code String} can be parsed by the
+ * {@link #fromString} method.
*
* <p> If the set contains {@code null} or elements that are not of type
* {@code PosixFilePermission} then these elements are ignored.
@@ -67,8 +69,6 @@ public class PosixFilePermissions {
* the set of permissions
*
* @return the string representation of the permission set
- *
- * @see #fromString
*/
public static String toString(Set<PosixFilePermission> perms) {
StringBuilder sb = new StringBuilder(9);
--- a/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -59,12 +59,11 @@ import java.io.IOException;
* attributes.
*
* <p> Where dynamic access to file attributes is required, the {@link
- * #getAttribute getAttribute} or {@link #readAttributes(String,String[])
- * readAttributes(String,String[])} methods may be used to read the attribute
- * value. The attribute value is returned as a byte array (byte[]). The {@link
- * #setAttribute setAttribute} method may be used to write the value of a
- * user-defined attribute from a buffer (as if by invoking the {@link #write
- * write} method), or byte array (byte[]).
+ * java.nio.file.FileRef#getAttribute getAttribute} method may be used to read
+ * the attribute value. The attribute value is returned as a byte array (byte[]).
+ * The {@link java.nio.file.FileRef#setAttribute setAttribute} method may be used
+ * to write the value of a user-defined attribute from a buffer (as if by
+ * invoking the {@link #write write} method), or byte array (byte[]).
*
* @since 1.7
*/
@@ -74,7 +73,7 @@ public interface UserDefinedFileAttribut
{
/**
* Returns the name of this attribute view. Attribute views of this type
- * have the name {@code "xattr"}.
+ * have the name {@code "user"}.
*/
@Override
String name();
--- a/src/share/classes/java/nio/file/attribute/UserPrincipalLookupService.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/attribute/UserPrincipalLookupService.java Mon Jun 29 15:08:52 2009 +0100
@@ -89,7 +89,7 @@ public abstract class UserPrincipalLooku
* @param group
* the string representation of the group to lookup
*
- * @return a user principal
+ * @return a group principal
*
* @throws UserPrincipalNotFoundException
* the principal does not exist or is not a group
--- a/src/share/classes/java/nio/file/spi/FileSystemProvider.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/nio/file/spi/FileSystemProvider.java Mon Jun 29 15:08:52 2009 +0100
@@ -270,7 +270,9 @@ public abstract class FileSystemProvider
public abstract FileSystem getFileSystem(URI uri);
/**
- * Return a {@code Path} object by converting the given {@link URI}.
+ * Return a {@code Path} object by converting the given {@link URI}. The
+ * resulting {@code Path} is associated with a {@link FileSystem} that
+ * already exists or is constructed automatically.
*
* <p> The exact form of the URI is file system provider dependent. In the
* case of the default provider, the URI scheme is {@code "file"} and the
@@ -290,7 +292,8 @@ public abstract class FileSystemProvider
* If the URI scheme does not identify this provider or other
* preconditions on the uri parameter do not hold
* @throws FileSystemNotFoundException
- * The file system, identified by the URI, does not exist
+ * The file system, identified by the URI, does not exist and
+ * cannot be created automatically
* @throws SecurityException
* If a security manager is installed and it denies an unspecified
* permission.
--- a/src/share/classes/java/util/Scanner.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/java/util/Scanner.java Mon Jun 29 15:08:52 2009 +0100
@@ -690,7 +690,7 @@ public final class Scanner implements It
public Scanner(FileRef source)
throws IOException
{
- this(source.newByteChannel());
+ this(source.newInputStream());
}
/**
@@ -713,7 +713,7 @@ public final class Scanner implements It
public Scanner(FileRef source, String charsetName)
throws IOException
{
- this(source.newByteChannel(), charsetName);
+ this(source.newInputStream(), charsetName);
}
/**
--- a/src/share/classes/sun/management/ManagementFactoryHelper.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/management/ManagementFactoryHelper.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,22 +26,15 @@ package sun.management;
package sun.management;
import java.lang.management.*;
-import java.util.logging.LogManager;
-
-import javax.management.DynamicMBean;
+
import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.MBeanInfo;
-import javax.management.NotificationEmitter;
import javax.management.ObjectName;
-import javax.management.ObjectInstance;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.NotCompliantMBeanException;
import javax.management.RuntimeOperationsException;
-import javax.management.StandardEmitterMBean;
-import javax.management.StandardMBean;
+import java.nio.BufferPoolMXBean;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
@@ -49,11 +42,6 @@ import sun.security.action.LoadLibraryAc
import java.util.ArrayList;
import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Iterator;
-import java.util.ListIterator;
import com.sun.management.OSMBeanFactory;
import com.sun.management.HotSpotDiagnosticMXBean;
@@ -68,7 +56,6 @@ public class ManagementFactoryHelper {
private static VMManagement jvm;
- private static boolean mbeansCreated = false;
private static ClassLoadingImpl classMBean = null;
private static MemoryImpl memoryMBean = null;
private static ThreadImpl threadMBean = null;
@@ -148,6 +135,58 @@ public class ManagementFactoryHelper {
return result;
}
+ public static List<BufferPoolMXBean> getBufferPoolMXBeans() {
+ List<BufferPoolMXBean> pools = new ArrayList<BufferPoolMXBean>(2);
+ pools.add(createBufferPoolMXBean(sun.misc.SharedSecrets.getJavaNioAccess()
+ .getDirectBufferPool()));
+ pools.add(createBufferPoolMXBean(sun.nio.ch.FileChannelImpl
+ .getMappedBufferPool()));
+ return pools;
+ }
+
+ private final static String BUFFER_POOL_MXBEAN_NAME = "java.nio:type=BufferPool";
+
+ /**
+ * Creates management interface for the given buffer pool.
+ */
+ private static BufferPoolMXBean
+ createBufferPoolMXBean(final sun.misc.JavaNioAccess.BufferPool pool)
+ {
+ return new BufferPoolMXBean() {
+ private volatile ObjectName objname; // created lazily
+ @Override
+ public ObjectName getObjectName() {
+ ObjectName result = objname;
+ if (result == null) {
+ synchronized (this) {
+ if (objname == null) {
+ result = ObjectName.valueOf(BUFFER_POOL_MXBEAN_NAME +
+ ",name=" + pool.getName());
+ objname = result;
+ }
+ }
+ }
+ return result;
+ }
+ @Override
+ public String getName() {
+ return pool.getName();
+ }
+ @Override
+ public long getCount() {
+ return pool.getCount();
+ }
+ @Override
+ public long getTotalCapacity() {
+ return pool.getTotalCapacity();
+ }
+ @Override
+ public long getMemoryUsed() {
+ return pool.getMemoryUsed();
+ }
+ };
+ }
+
private static HotSpotDiagnostic hsDiagMBean = null;
private static HotspotRuntime hsRuntimeMBean = null;
private static HotspotClassLoading hsClassMBean = null;
@@ -161,8 +200,6 @@ public class ManagementFactoryHelper {
}
return hsDiagMBean;
}
-
- /**
/**
* This method is for testing only.
--- a/src/share/classes/sun/misc/JavaNioAccess.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/misc/JavaNioAccess.java Mon Jun 29 15:08:52 2009 +0100
@@ -25,8 +25,15 @@
package sun.misc;
-import java.nio.BufferPoolMXBean;
-
public interface JavaNioAccess {
- BufferPoolMXBean getDirectBufferPoolMXBean();
+ /**
+ * Provides access to information on buffer usage.
+ */
+ interface BufferPool {
+ String getName();
+ long getCount();
+ long getTotalCapacity();
+ long getMemoryUsed();
+ }
+ BufferPool getDirectBufferPool();
}
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Jun 29 15:08:52 2009 +0100
@@ -237,6 +237,8 @@ public class HttpURLConnection extends j
/* try auth without calling Authenticator */
private boolean tryTransparentNTLMServer = NTLMAuthentication.supportsTransparentAuth();
private boolean tryTransparentNTLMProxy = NTLMAuthentication.supportsTransparentAuth();
+ /* Used by Windows specific code */
+ Object authObj;
/* Set if the user is manually setting the Authorization or Proxy-Authorization headers */
boolean isUserServerAuth;
@@ -1219,6 +1221,7 @@ public class HttpURLConnection extends j
disconnectInternal ();
throw new IOException ("Authentication failure");
}
+ authObj = null;
doingNTLMp2ndStage = false;
continue;
}
@@ -1295,6 +1298,7 @@ public class HttpURLConnection extends j
throw new IOException ("Authentication failure");
}
doingNTLM2ndStage = false;
+ authObj = null;
setCookieHeader();
continue;
}
@@ -1646,6 +1650,7 @@ public class HttpURLConnection extends j
disconnectInternal();
throw new IOException ("Authentication failure");
}
+ authObj = null;
doingNTLMp2ndStage = false;
continue;
}
--- a/src/share/classes/sun/nio/ch/FileChannelImpl.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java Mon Jun 29 15:08:52 2009 +0100
@@ -29,13 +29,10 @@ import java.io.IOException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
-import java.nio.BufferPoolMXBean;
import java.nio.channels.*;
import java.util.ArrayList;
import java.util.List;
import java.security.AccessController;
-import javax.management.ObjectName;
-import javax.management.MalformedObjectNameException;
import sun.misc.Cleaner;
import sun.security.action.GetPropertyAction;
@@ -805,47 +802,28 @@ public class FileChannelImpl
}
/**
- * Returns the management interface for mapped buffers
+ * Invoked by sun.management.ManagementFactoryHelper to create the management
+ * interface for mapped buffers.
*/
- public static BufferPoolMXBean getMappedBufferPoolMXBean() {
- return LazyInitialization.mappedBufferPoolMXBean;
- }
-
- // Lazy initialization of management interface
- private static class LazyInitialization {
- static final BufferPoolMXBean mappedBufferPoolMXBean = mappedBufferPoolMXBean();
-
- private static BufferPoolMXBean mappedBufferPoolMXBean() {
- final String pool = "mapped";
- final ObjectName obj;
- try {
- obj = new ObjectName("java.nio:type=BufferPool,name=" + pool);
- } catch (MalformedObjectNameException x) {
- throw new AssertionError(x);
- }
- return new BufferPoolMXBean() {
- @Override
- public ObjectName getObjectName() {
- return obj;
- }
- @Override
- public String getName() {
- return pool;
- }
- @Override
- public long getCount() {
- return Unmapper.count;
- }
- @Override
- public long getTotalCapacity() {
- return Unmapper.totalCapacity;
- }
- @Override
- public long getMemoryUsed() {
- return Unmapper.totalSize;
- }
- };
- }
+ public static sun.misc.JavaNioAccess.BufferPool getMappedBufferPool() {
+ return new sun.misc.JavaNioAccess.BufferPool() {
+ @Override
+ public String getName() {
+ return "mapped";
+ }
+ @Override
+ public long getCount() {
+ return Unmapper.count;
+ }
+ @Override
+ public long getTotalCapacity() {
+ return Unmapper.totalCapacity;
+ }
+ @Override
+ public long getMemoryUsed() {
+ return Unmapper.totalSize;
+ }
+ };
}
// -- Locks --
--- a/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,15 +26,15 @@ package sun.nio.fs;
package sun.nio.fs;
import java.nio.file.attribute.*;
+import java.util.*;
import java.io.IOException;
-import java.util.*;
/**
* Base implementation of AclFileAttributeView
*/
abstract class AbstractAclFileAttributeView
- implements AclFileAttributeView
+ implements AclFileAttributeView, DynamicFileAttributeView
{
private static final String OWNER_NAME = "owner";
private static final String ACL_NAME = "acl";
@@ -66,38 +66,29 @@ abstract class AbstractAclFileAttributeV
setAcl((List<AclEntry>)value);
return;
}
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException("'" + name() + ":" +
+ attribute + "' not supported");
}
@Override
- public final Map<String,?> readAttributes(String first, String[] rest)
+ public final Map<String,?> readAttributes(String[] attributes)
throws IOException
{
boolean acl = false;
boolean owner = false;
-
- if (first.equals(ACL_NAME)) acl = true;
- else if (first.equals(OWNER_NAME)) owner = true;
- else if (first.equals("*")) {
- owner = true;
- acl = true;
- }
-
- if (!acl || !owner) {
- for (String attribute: rest) {
- if (attribute.equals("*")) {
- owner = true;
- acl = true;
- break;
- }
- if (attribute.equals(ACL_NAME)) {
- acl = true;
- continue;
- }
- if (attribute.equals(OWNER_NAME)) {
- owner = true;
- continue;
- }
+ for (String attribute: attributes) {
+ if (attribute.equals("*")) {
+ owner = true;
+ acl = true;
+ continue;
+ }
+ if (attribute.equals(ACL_NAME)) {
+ acl = true;
+ continue;
+ }
+ if (attribute.equals(OWNER_NAME)) {
+ owner = true;
+ continue;
}
}
Map<String,Object> result = new HashMap<String,Object>(2);
--- a/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,24 +26,21 @@ package sun.nio.fs;
package sun.nio.fs;
import java.nio.file.attribute.*;
+import java.util.*;
import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
/**
* Base implementation of BasicFileAttributeView
*/
abstract class AbstractBasicFileAttributeView
- implements BasicFileAttributeView
+ implements BasicFileAttributeView, DynamicFileAttributeView
{
private static final String SIZE_NAME = "size";
private static final String CREATION_TIME_NAME = "creationTime";
private static final String LAST_ACCESS_TIME_NAME = "lastAccessTime";
private static final String LAST_MODIFIED_TIME_NAME = "lastModifiedTime";
- private static final String RESOLUTION_NAME = "resolution";
private static final String FILE_KEY_NAME = "fileKey";
- private static final String LINK_COUNT_NAME = "linkCount";
private static final String IS_DIRECTORY_NAME = "isDirectory";
private static final String IS_REGULAR_FILE_NAME = "isRegularFile";
private static final String IS_SYMBOLIC_LINK_NAME = "isSymbolicLink";
@@ -67,12 +64,8 @@ abstract class AbstractBasicFileAttribut
return attrs.lastAccessTime();
if (attribute.equals(LAST_MODIFIED_TIME_NAME))
return attrs.lastModifiedTime();
- if (attribute.equals(RESOLUTION_NAME))
- return attrs.resolution();
if (attribute.equals(FILE_KEY_NAME))
return attrs.fileKey();
- if (attribute.equals(LINK_COUNT_NAME))
- return attrs.linkCount();
if (attribute.equals(IS_DIRECTORY_NAME))
return attrs.isDirectory();
if (attribute.equals(IS_REGULAR_FILE_NAME))
@@ -84,29 +77,20 @@ abstract class AbstractBasicFileAttribut
return null;
}
- private Long toTimeValue(Object value) {
- if (value == null)
- throw new NullPointerException();
- Long time = (Long)value;
- if (time < 0L && time != -1L)
- throw new IllegalArgumentException("time value cannot be negative");
- return time;
- }
-
@Override
public void setAttribute(String attribute, Object value)
throws IOException
{
if (attribute.equals(LAST_MODIFIED_TIME_NAME)) {
- setTimes(toTimeValue(value), null, null, TimeUnit.MILLISECONDS);
+ setTimes((FileTime)value, null, null);
return;
}
if (attribute.equals(LAST_ACCESS_TIME_NAME)) {
- setTimes(null, toTimeValue(value), null, TimeUnit.MILLISECONDS);
+ setTimes(null, (FileTime)value, null);
return;
}
if (attribute.equals(CREATION_TIME_NAME)) {
- setTimes(null, null, toTimeValue(value), TimeUnit.MILLISECONDS);
+ setTimes(null, null, (FileTime)value);
return;
}
throw new UnsupportedOperationException("'" + attribute +
@@ -114,24 +98,18 @@ abstract class AbstractBasicFileAttribut
}
/**
- *
+ * Used to build a map of attribute name/values.
*/
static class AttributesBuilder {
private Set<String> set = new HashSet<String>();
private Map<String,Object> map = new HashMap<String,Object>();
private boolean copyAll;
- private AttributesBuilder(String first, String[] rest) {
- if (first.equals("*")) {
- copyAll = true;
- } else {
- set.add(first);
- // copy names into the given Set bailing out if "*" is found
- for (String attribute: rest) {
- if (attribute.equals("*")) {
- copyAll = true;
- break;
- }
+ private AttributesBuilder(String[] attributes) {
+ for (String attribute: attributes) {
+ if (attribute.equals("*")) {
+ copyAll = true;
+ } else {
set.add(attribute);
}
}
@@ -140,8 +118,8 @@ abstract class AbstractBasicFileAttribut
/**
* Creates builder to build up a map of the matching attributes
*/
- static AttributesBuilder create(String first, String[] rest) {
- return new AttributesBuilder(first, rest);
+ static AttributesBuilder create(String[] attributes) {
+ return new AttributesBuilder(attributes);
}
/**
@@ -181,12 +159,8 @@ abstract class AbstractBasicFileAttribut
builder.add(LAST_ACCESS_TIME_NAME, attrs.lastAccessTime());
if (builder.match(LAST_MODIFIED_TIME_NAME))
builder.add(LAST_MODIFIED_TIME_NAME, attrs.lastModifiedTime());
- if (builder.match(RESOLUTION_NAME))
- builder.add(RESOLUTION_NAME, attrs.resolution());
if (builder.match(FILE_KEY_NAME))
builder.add(FILE_KEY_NAME, attrs.fileKey());
- if (builder.match(LINK_COUNT_NAME))
- builder.add(LINK_COUNT_NAME, attrs.linkCount());
if (builder.match(IS_DIRECTORY_NAME))
builder.add(IS_DIRECTORY_NAME, attrs.isDirectory());
if (builder.match(IS_REGULAR_FILE_NAME))
@@ -198,10 +172,8 @@ abstract class AbstractBasicFileAttribut
}
@Override
- public Map<String,?> readAttributes(String first, String[] rest)
- throws IOException
- {
- AttributesBuilder builder = AttributesBuilder.create(first, rest);
+ public Map<String,?> readAttributes(String[] attributes) throws IOException {
+ AttributesBuilder builder = AttributesBuilder.create(attributes);
addBasicAttributesToBuilder(readAttributes(), builder);
return builder.unmodifiableMap();
}
--- a/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java Mon Jun 29 15:08:52 2009 +0100
@@ -27,8 +27,8 @@ package sun.nio.fs;
import java.nio.file.FileRef;
import java.nio.file.spi.FileTypeDetector;
+import java.util.Locale;
import java.io.IOException;
-import sun.nio.fs.MimeType;
/**
* Base implementation of FileTypeDetector
@@ -42,23 +42,15 @@ public abstract class AbstractFileTypeDe
}
/**
- * Invokes the implProbeContentType method to guess the file's content type,
- * and this validates that the content type's syntax is valid.
+ * Invokes the appropriate probe method to guess a file's content type,
+ * and checks that the content type's syntax is valid.
*/
@Override
public final String probeContentType(FileRef file) throws IOException {
if (file == null)
throw new NullPointerException("'file' is null");
String result = implProbeContentType(file);
- if (result != null) {
- // check the content type
- try {
- MimeType.parse(result);
- } catch (IllegalArgumentException ignore) {
- result = null;
- }
- }
- return result;
+ return (result == null) ? null : parse(result);
}
/**
@@ -66,4 +58,54 @@ public abstract class AbstractFileTypeDe
*/
protected abstract String implProbeContentType(FileRef file)
throws IOException;
+
+ /**
+ * Parses a candidate content type into its type and subtype, returning
+ * null if either token is invalid.
+ */
+ private static String parse(String s) {
+ int slash = s.indexOf('/');
+ int semicolon = s.indexOf(';');
+ if (slash < 0)
+ return null; // no subtype
+ String type = s.substring(0, slash).trim().toLowerCase(Locale.ENGLISH);
+ if (!isValidToken(type))
+ return null; // invalid type
+ String subtype = (semicolon < 0) ? s.substring(slash + 1) :
+ s.substring(slash + 1, semicolon);
+ subtype = subtype.trim().toLowerCase(Locale.ENGLISH);
+ if (!isValidToken(subtype))
+ return null; // invalid subtype
+ StringBuilder sb = new StringBuilder(type.length() + subtype.length() + 1);
+ sb.append(type);
+ sb.append('/');
+ sb.append(subtype);
+ return sb.toString();
+ }
+
+ /**
+ * Special characters
+ */
+ private static final String TSPECIALS = "()<>@,;:/[]?=\\\"";
+
+ /**
+ * Returns true if the character is a valid token character.
+ */
+ private static boolean isTokenChar(char c) {
+ return (c > 040) && (c < 0177) && (TSPECIALS.indexOf(c) < 0);
+ }
+
+ /**
+ * Returns true if the given string is a legal type or subtype.
+ */
+ private static boolean isValidToken(String s) {
+ int len = s.length();
+ if (len == 0)
+ return false;
+ for (int i = 0; i < len; i++) {
+ if (!isTokenChar(s.charAt(i)))
+ return false;
+ }
+ return true;
+ }
}
--- a/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -31,11 +31,11 @@ import java.util.*;
import java.util.*;
/**
- * Base implementation of NamedAttributeView
+ * Base implementation of UserDefinedAttributeView
*/
abstract class AbstractUserDefinedFileAttributeView
- implements UserDefinedFileAttributeView
+ implements UserDefinedFileAttributeView, DynamicFileAttributeView
{
protected AbstractUserDefinedFileAttributeView() { }
@@ -56,7 +56,7 @@ abstract class AbstractUserDefinedFileAt
@Override
public final String name() {
- return "xattr";
+ return "user";
}
@Override
@@ -70,6 +70,7 @@ abstract class AbstractUserDefinedFileAt
throw e;
return null;
}
+
byte[] buf = new byte[size];
int n = read(attribute, ByteBuffer.wrap(buf));
return (n == size) ? buf : Arrays.copyOf(buf, n);
@@ -89,27 +90,20 @@ abstract class AbstractUserDefinedFileAt
}
@Override
- public final Map<String,?> readAttributes(String first, String... rest)
+ public final Map<String,?> readAttributes(String[] attributes)
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) {
+ for (String name: attributes) {
if (name.equals("*")) {
- readAll = true;
+ names = list();
+ break;
} else {
names.add(name);
}
}
- if (readAll)
- names = list();
// read each value and return in map
Map<String,Object> result = new HashMap<String,Object>();
--- a/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java Mon Jun 29 15:08:52 2009 +0100
@@ -34,7 +34,9 @@ import java.io.IOException;
* PosixFileAttributeView or AclFileAttributeView object.
*/
-final class FileOwnerAttributeViewImpl implements FileOwnerAttributeView {
+final class FileOwnerAttributeViewImpl
+ implements FileOwnerAttributeView, DynamicFileAttributeView
+{
private static final String OWNER_NAME = "owner";
private final FileAttributeView view;
@@ -70,20 +72,16 @@ final class FileOwnerAttributeViewImpl i
setOwner((UserPrincipal)value);
return;
}
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException("'" + name() + ":" +
+ attribute + "' not supported");
}
@Override
- public Map<String,?> readAttributes(String first, String[] rest) throws IOException {
+ public Map<String,?> readAttributes(String[] attributes) throws IOException {
Map<String,Object> result = new HashMap<String,Object>();
- if (first.equals("*") || first.equals(OWNER_NAME)) {
- result.put(OWNER_NAME, getOwner());
- } else {
- for (String attribute: rest) {
- if (attribute.equals("*") || attribute.equals(OWNER_NAME)) {
- result.put(OWNER_NAME, getOwner());
- break;
- }
+ for (String attribute: attributes) {
+ if (attribute.equals("*") || attribute.equals(OWNER_NAME)) {
+ result.put(OWNER_NAME, getOwner());
}
}
return result;
--- a/src/share/classes/sun/nio/fs/PollingWatchService.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/classes/sun/nio/fs/PollingWatchService.java Mon Jun 29 15:08:52 2009 +0100
@@ -265,7 +265,7 @@ class PollingWatchService
// don't follow links
long lastModified = Attributes
.readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
- .lastModifiedTime();
+ .lastModifiedTime().toMillis();
entries.put(entry.getName(),
new CacheEntry(lastModified, tickCount));
}
@@ -357,7 +357,7 @@ class PollingWatchService
try {
lastModified = Attributes
.readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
- .lastModifiedTime();
+ .lastModifiedTime().toMillis();
} catch (IOException x) {
// unable to get attributes of entry. If file has just
// been deleted then we'll report it as deleted on the
--- a/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c Mon Jun 29 15:08:52 2009 +0100
@@ -2227,7 +2227,8 @@ inject_class(struct CrwClassImage *ci,
CrwCpoolIndex this_class;
CrwCpoolIndex super_class;
unsigned magic;
- unsigned classfileVersion;
+ unsigned classfileMajorVersion;
+ unsigned classfileMinorVersion;
unsigned interface_count;
CRW_ASSERT_CI(ci);
@@ -2258,10 +2259,12 @@ inject_class(struct CrwClassImage *ci,
}
/* minor version number not used */
- (void)copyU2(ci);
+ classfileMinorVersion = copyU2(ci);
/* major version number not used */
- classfileVersion = copyU2(ci);
- CRW_ASSERT(ci, classfileVersion <= 50); /* Mustang class files or less */
+ classfileMajorVersion = copyU2(ci);
+ CRW_ASSERT(ci, (classfileMajorVersion <= JVM_CLASSFILE_MAJOR_VERSION) ||
+ ((classfileMajorVersion == JVM_CLASSFILE_MAJOR_VERSION) &&
+ (classfileMinorVersion <= JVM_CLASSFILE_MINOR_VERSION)));
cpool_setup(ci);
--- a/src/share/javavm/export/classfile_constants.h Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/javavm/export/classfile_constants.h Mon Jun 29 15:08:52 2009 +0100
@@ -29,6 +29,10 @@
#ifdef __cplusplus
extern "C" {
#endif
+
+/* Classfile version number for this information */
+#define JVM_CLASSFILE_MAJOR_VERSION 51
+#define JVM_CLASSFILE_MINOR_VERSION 0
/* Flags */
--- a/src/share/sample/nio/file/Copy.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/sample/nio/file/Copy.java Mon Jun 29 15:08:52 2009 +0100
@@ -127,8 +127,7 @@ public class Copy {
Path newdir = target.resolve(source.relativize(dir));
try {
BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
- Attributes.setLastModifiedTime(newdir,
- attrs.lastModifiedTime(), attrs.resolution());
+ Attributes.setLastModifiedTime(newdir, attrs.lastModifiedTime());
} catch (IOException x) {
System.err.format("Unable to copy all attributes to: %s: %s%n", newdir, x);
}
--- a/src/share/sample/nio/file/Xdd.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/share/sample/nio/file/Xdd.java Mon Jun 29 15:08:52 2009 +0100
@@ -59,7 +59,7 @@ public class Xdd {
// check that user defined attributes are supported by the file system
FileStore store = file.getFileStore();
- if (!store.supportsFileAttributeView("xattr")) {
+ if (!store.supportsFileAttributeView("user")) {
System.err.format("UserDefinedFileAttributeView not supported on %s\n", store);
System.exit(-1);
--- a/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,6 +26,7 @@ package sun.nio.ch;
import java.net.InetAddress;
import java.net.SocketAddress;
+import java.net.SocketException;
import java.net.InetSocketAddress;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -122,6 +123,8 @@ public class SctpChannelImpl extends Sct
private Association association;
+ private Set<SocketAddress> remoteAddresses = Collections.EMPTY_SET;
+
/* -- End of fields protected by stateLock -- */
private SctpResultContainer commUpResultContainer; /* null */
@@ -142,18 +145,32 @@ public class SctpChannelImpl extends Sct
*/
public SctpChannelImpl(SelectorProvider provider, FileDescriptor fd)
throws IOException {
+ this(provider, fd, null);
+ }
+
+ /**
+ * Constructor for sockets obtained from branching
+ */
+ public SctpChannelImpl(SelectorProvider provider,
+ FileDescriptor fd,
+ Association association)
+ throws IOException {
super(provider);
this.fd = fd;
this.fdVal = IOUtil.fdVal(fd);
this.state = ChannelState.CONNECTED;
port = (Net.localAddress(fd)).getPort();
- /* Receive COMM_UP */
- ByteBuffer buf = Util.getTemporaryDirectBuffer(50);
- try {
- receive(buf, null, null, true);
- } finally {
- Util.releaseTemporaryDirectBuffer(buf);
+ if (association != null) { /* branched */
+ this.association = association;
+ } else { /* obtained from server channel */
+ /* Receive COMM_UP */
+ ByteBuffer buf = Util.getTemporaryDirectBuffer(50);
+ try {
+ receive(buf, null, null, true);
+ } finally {
+ Util.releaseTemporaryDirectBuffer(buf);
+ }
}
}
@@ -391,6 +408,12 @@ public class SctpChannelImpl extends Sct
} finally {
Util.releaseTemporaryDirectBuffer(buf);
}
+
+ /* cache remote addresses */
+ try {
+ remoteAddresses = getRemoteAddresses();
+ } catch (IOException unused) { /* swallow exception */ }
+
return true;
}
} else {
@@ -414,6 +437,7 @@ public class SctpChannelImpl extends Sct
int maxOutStreams,
int maxInStreams)
throws IOException {
+ ensureOpenAndUnconnected();
return setOption(SCTP_INIT_MAXSTREAMS, InitMaxStreams.
create(maxInStreams, maxOutStreams)).connect(endpoint);
@@ -512,6 +536,12 @@ public class SctpChannelImpl extends Sct
} finally {
Util.releaseTemporaryDirectBuffer(buf);
}
+
+ /* cache remote addresses */
+ try {
+ remoteAddresses = getRemoteAddresses();
+ } catch (IOException unused) { /* swallow exception */ }
+
return true;
}
}
@@ -966,7 +996,7 @@ public class SctpChannelImpl extends Sct
int pos = src.position();
int lim = src.limit();
- assert (pos <= lim && streamNumber > 0);
+ assert (pos <= lim && streamNumber >= 0);
int rem = (pos <= lim ? lim - pos : 0);
if (src instanceof DirectBuffer)
@@ -1043,10 +1073,15 @@ public class SctpChannelImpl extends Sct
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
- if (!isConnected())
+ if (!isConnected() || isShutdown)
return Collections.EMPTY_SET;
- return SctpNet.getRemoteAddresses(fdVal, 0/*unused*/);
+ try {
+ return SctpNet.getRemoteAddresses(fdVal, 0/*unused*/);
+ } catch (SocketException unused) {
+ /* an open connected channel should always have remote addresses */
+ return remoteAddresses;
+ }
}
}
--- a/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,6 +26,7 @@ package sun.nio.ch;
import java.net.InetAddress;
import java.net.SocketAddress;
+import java.net.SocketException;
import java.net.InetSocketAddress;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -398,8 +399,8 @@ public class SctpMultiChannelImpl extend
if (!isOpen())
throw new ClosedChannelException();
- SctpNet.setSocketOption(fdVal, name, value,
- association.associationID());
+ int assocId = association == null ? 0 : association.associationID();
+ SctpNet.setSocketOption(fdVal, name, value, assocId);
}
return this;
}
@@ -414,12 +415,15 @@ public class SctpMultiChannelImpl extend
throw new UnsupportedOperationException("'" + name + "' not supported");
synchronized (stateLock) {
- checkAssociation(association);
+ if (association != null && (name.equals(SCTP_PRIMARY_ADDR) ||
+ name.equals(SCTP_SET_PEER_PRIMARY_ADDR))) {
+ checkAssociation(association);
+ }
if (!isOpen())
throw new ClosedChannelException();
- return (T)SctpNet.getSocketOption(fdVal, name,
- association.associationID());
+ int assocId = association == null ? 0 : association.associationID();
+ return (T)SctpNet.getSocketOption(fdVal, name, assocId);
}
}
@@ -626,15 +630,19 @@ public class SctpMultiChannelImpl extend
case ASSOCIATION_CHANGED :
result = absHandler.handleNotification(
resultContainer.getAssociationChanged(), attachment);
+ break;
case PEER_ADDRESS_CHANGED :
result = absHandler.handleNotification(
resultContainer.getPeerAddressChanged(), attachment);
+ break;
case SEND_FAILED :
result = absHandler.handleNotification(
resultContainer.getSendFailed(), attachment);
+ break;
case SHUTDOWN :
result = absHandler.handleNotification(
resultContainer.getShutdown(), attachment);
+ break;
default :
/* implementation specific handlers */
result = absHandler.handleNotification(
@@ -836,7 +844,7 @@ public class SctpMultiChannelImpl extend
int ppid = messageInfo.payloadProtocolID();
int pos = src.position();
int lim = src.limit();
- assert (pos <= lim && streamNumber > 0);
+ assert (pos <= lim && streamNumber >= 0);
int rem = (pos <= lim ? lim - pos : 0);
if (src instanceof DirectBuffer)
@@ -914,7 +922,13 @@ public class SctpMultiChannelImpl extend
if (!isOpen())
throw new ClosedChannelException();
- return SctpNet.getRemoteAddresses(fdVal, association.associationID());
+ try {
+ return SctpNet.getRemoteAddresses(fdVal, association.associationID());
+ } catch (SocketException se) {
+ /* a valid association should always have remote addresses */
+ Set<SocketAddress> addrs = associationMap.get(association);
+ return addrs != null ? addrs : Collections.EMPTY_SET;
+ }
}
}
@@ -922,7 +936,16 @@ public class SctpMultiChannelImpl extend
public SctpChannel branch(Association association)
throws IOException {
synchronized (stateLock) {
- return null; //TODO: implement
+ checkAssociation(association);
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ FileDescriptor bFd = SctpNet.branch(fdVal,
+ association.associationID());
+ /* successfully branched, we can now remove it from assoc list */
+ removeAssociation(association);
+
+ return new SctpChannelImpl(provider(), bFd, association);
}
}
--- a/src/solaris/classes/sun/nio/ch/SctpNet.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/ch/SctpNet.java Mon Jun 29 15:08:52 2009 +0100
@@ -232,6 +232,11 @@ public class SctpNet {
shutdown0(fd, assocId);
}
+ static FileDescriptor branch(int fd, int assocId) throws IOException {
+ int nativefd = branch0(fd, assocId);
+ return IOUtil.newFD(nativefd);
+ }
+
/* Native Methods */
static native int socket0(boolean oneToOne) throws IOException;
@@ -248,6 +253,8 @@ public class SctpNet {
static native SocketAddress[] getRemoteAddresses0(int fd, int assocId)
throws IOException;
+ static native int branch0(int fd, int assocId) throws IOException;
+
static native void setPrimAddrOption0(int fd, int assocId, InetAddress ia,
int port) throws IOException;
--- a/src/solaris/classes/sun/nio/ch/SctpResultContainer.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/ch/SctpResultContainer.java Mon Jun 29 15:08:52 2009 +0100
@@ -121,6 +121,8 @@ public class SctpResultContainer {
case SHUTDOWN: sb.append("SHUTDOWN"); break;
default : sb.append("Unknown result type");
}
- return sb.append(", Value: ").append(value.toString()).toString();
+ sb.append(", Value: ");
+ sb.append((value == null) ? "null" : value.toString());
+ return sb.toString();
}
}
--- a/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java Mon Jun 29 15:08:52 2009 +0100
@@ -407,7 +407,7 @@ public class SctpServerChannelImpl exten
if (!isOpen())
throw new ClosedChannelException();
if (!isBound())
- return null;
+ return Collections.EMPTY_SET;
return SctpNet.getLocalAddresses(fdVal);
}
--- a/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -26,8 +26,7 @@ package sun.nio.fs;
package sun.nio.fs;
import java.nio.file.attribute.*;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
+import java.util.Map;
import java.io.IOException;
import sun.misc.Unsafe;
@@ -104,10 +103,10 @@ class LinuxDosFileAttributeView
}
@Override
- public Map<String,?> readAttributes(String first, String[] rest)
+ public Map<String,?> readAttributes(String[] attributes)
throws IOException
{
- AttributesBuilder builder = AttributesBuilder.create(first, rest);
+ AttributesBuilder builder = AttributesBuilder.create(attributes);
DosFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder);
if (builder.match(READONLY_NAME))
@@ -132,20 +131,16 @@ class LinuxDosFileAttributeView
return new DosFileAttributes() {
@Override
- public long lastModifiedTime() {
+ public FileTime lastModifiedTime() {
return attrs.lastModifiedTime();
}
@Override
- public long lastAccessTime() {
+ public FileTime lastAccessTime() {
return attrs.lastAccessTime();
}
@Override
- public long creationTime() {
+ public FileTime creationTime() {
return attrs.creationTime();
- }
- @Override
- public TimeUnit resolution() {
- return attrs.resolution();
}
@Override
public boolean isRegularFile() {
@@ -166,10 +161,6 @@ class LinuxDosFileAttributeView
@Override
public long size() {
return attrs.size();
- }
- @Override
- public int linkCount() {
- return attrs.linkCount();
}
@Override
public Object fileKey() {
--- a/src/solaris/classes/sun/nio/fs/LinuxFileStore.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/LinuxFileStore.java Mon Jun 29 15:08:52 2009 +0100
@@ -53,7 +53,7 @@ class LinuxFileStore
*/
@Override
UnixMountEntry findMountEntry() throws IOException {
- UnixFileSystem fs = file().getFileSystem();
+ LinuxFileSystem fs = (LinuxFileSystem)file().getFileSystem();
// step 1: get realpath
UnixPath path = null;
@@ -79,14 +79,15 @@ class LinuxFileStore
parent = parent.getParent();
}
- // step 3: lookup mounted file systems
+ // step 3: lookup mounted file systems (use /proc/mounts to ensure we
+ // find the file system even when not in /etc/mtab)
byte[] dir = path.asByteArray();
- for (UnixMountEntry entry: fs.getMountEntries()) {
+ for (UnixMountEntry entry: fs.getMountEntries("/proc/mounts")) {
if (Arrays.equals(dir, entry.dir()))
return entry;
}
- throw new IOException("Mount point not found in mtab");
+ throw new IOException("Mount point not found");
}
// returns true if extended attributes enabled on file system where given
@@ -113,9 +114,9 @@ class LinuxFileStore
@Override
public boolean supportsFileAttributeView(String name) {
- // support DosFileAttributeView and NamedAttributeView if extended
+ // support DosFileAttributeView and UserDefinedAttributeView if extended
// attributes enabled
- if (name.equals("dos") || name.equals("xattr")) {
+ if (name.equals("dos") || name.equals("user")) {
// lookup fstypes.properties
FeatureStatus status = checkIfFeaturePresent("user_xattr");
if (status == FeatureStatus.PRESENT)
--- a/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java Mon Jun 29 15:08:52 2009 +0100
@@ -39,7 +39,6 @@ import static sun.nio.fs.LinuxNativeDisp
class LinuxFileSystem extends UnixFileSystem {
private final boolean hasInotify;
- private final boolean hasAtSysCalls;
LinuxFileSystem(UnixFileSystemProvider provider, String dir) {
super(provider, dir);
@@ -47,14 +46,14 @@ class LinuxFileSystem extends UnixFileSy
// assume X.Y[-Z] format
String osversion = AccessController
.doPrivileged(new GetPropertyAction("os.version"));
- String[] vers = osversion.split("\\.", 0);
+ String[] vers = Util.split(osversion, '.');
assert vers.length >= 2;
int majorVersion = Integer.parseInt(vers[0]);
int minorVersion = Integer.parseInt(vers[1]);
int microVersion = 0;
if (vers.length > 2) {
- String[] microVers = vers[2].split("-", 0);
+ String[] microVers = Util.split(vers[2], '-');
microVersion = (microVers.length > 0) ?
Integer.parseInt(microVers[0]) : 0;
}
@@ -63,11 +62,6 @@ class LinuxFileSystem extends UnixFileSy
this.hasInotify = ((majorVersion > 2) ||
(majorVersion == 2 && minorVersion > 6) ||
((majorVersion == 2) && (minorVersion == 6) && (microVersion >= 13)));
-
- // openat etc. available since 2.6.16
- this.hasAtSysCalls = ((majorVersion > 2) ||
- (majorVersion == 2 && minorVersion > 6) ||
- ((majorVersion == 2) && (minorVersion == 6) && (microVersion >= 16)));
}
@Override
@@ -97,13 +91,13 @@ class LinuxFileSystem extends UnixFileSy
@Override
@SuppressWarnings("unchecked")
- public FileAttributeView newFileAttributeView(String name,
- UnixPath file,
- LinkOption... options)
+ public DynamicFileAttributeView newFileAttributeView(String name,
+ UnixPath file,
+ LinkOption... options)
{
if (name.equals("dos"))
return new LinuxDosFileAttributeView(file, followLinks(options));
- if (name.equals("xattr"))
+ if (name.equals("user"))
return new LinuxUserDefinedFileAttributeView(file, followLinks(options));
return super.newFileAttributeView(name, file, options);
}
@@ -117,7 +111,7 @@ class LinuxFileSystem extends UnixFileSy
result.addAll(UnixFileSystem.standardFileAttributeViews());
// additional Linux-specific views
result.add("dos");
- result.add("xattr");
+ result.add("user");
return Collections.unmodifiableSet(result);
}
}
@@ -132,19 +126,13 @@ class LinuxFileSystem extends UnixFileSy
LinuxUserDefinedFileAttributeView.copyExtendedAttributes(ofd, nfd);
}
- @Override
- boolean supportsSecureDirectoryStreams() {
- return hasAtSysCalls;
- }
-
/**
- * Returns object to iterate over entries in /etc/mtab
+ * Returns object to iterate over the mount entries in the given fstab file.
*/
- @Override
- Iterable<UnixMountEntry> getMountEntries() {
+ Iterable<UnixMountEntry> getMountEntries(String fstab) {
ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
try {
- long fp = setmntent("/etc/mtab".getBytes(), "r".getBytes());
+ long fp = setmntent(fstab.getBytes(), "r".getBytes());
try {
for (;;) {
UnixMountEntry entry = new UnixMountEntry();
@@ -163,6 +151,14 @@ class LinuxFileSystem extends UnixFileSy
return entries;
}
+ /**
+ * Returns object to iterate over the mount entries in /etc/mtab
+ */
+ @Override
+ Iterable<UnixMountEntry> getMountEntries() {
+ return getMountEntries("/etc/mtab");
+ }
+
@Override
FileStore getFileStore(UnixPath path) throws IOException {
return new LinuxFileStore(path);
--- a/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Mon Jun 29 15:08:52 2009 +0100
@@ -98,7 +98,7 @@ class SolarisAclFileAttributeView
// map UserPrincipal to uid and flags
UserPrincipal who = ace.principal();
- if (!(who instanceof UnixUserPrincipals))
+ if (!(who instanceof UnixUserPrincipals.User))
throw new ProviderMismatchException();
UnixUserPrincipals.User user = (UnixUserPrincipals.User)who;
int uid;
--- a/src/solaris/classes/sun/nio/fs/SolarisFileStore.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/SolarisFileStore.java Mon Jun 29 15:08:52 2009 +0100
@@ -83,7 +83,7 @@ class SolarisFileStore
// AclFileAttributeView available on ZFS
return (type().equals("zfs"));
}
- if (name.equals("xattr")) {
+ if (name.equals("user")) {
// lookup fstypes.properties
FeatureStatus status = checkIfFeaturePresent("xattr");
if (status == FeatureStatus.PRESENT)
--- a/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java Mon Jun 29 15:08:52 2009 +0100
@@ -46,7 +46,7 @@ class SolarisFileSystem extends UnixFile
// check os.version
String osversion = AccessController
.doPrivileged(new GetPropertyAction("os.version"));
- String[] vers = osversion.split("\\.", 0);
+ String[] vers = Util.split(osversion, '.');
assert vers.length >= 2;
int majorVersion = Integer.parseInt(vers[0]);
int minorVersion = Integer.parseInt(vers[1]);
@@ -85,13 +85,13 @@ class SolarisFileSystem extends UnixFile
}
@Override
- protected FileAttributeView newFileAttributeView(String name,
- UnixPath file,
- LinkOption... options)
+ protected DynamicFileAttributeView newFileAttributeView(String name,
+ UnixPath file,
+ LinkOption... options)
{
if (name.equals("acl"))
return new SolarisAclFileAttributeView(file, followLinks(options));
- if (name.equals("xattr"))
+ if (name.equals("user"))
return new SolarisUserDefinedFileAttributeView(file, followLinks(options));
return super.newFileAttributeView(name, file, options);
}
@@ -105,7 +105,7 @@ class SolarisFileSystem extends UnixFile
result.addAll(UnixFileSystem.standardFileAttributeViews());
// additional Solaris-specific views
result.add("acl");
- result.add("xattr");
+ result.add("user");
return Collections.unmodifiableSet(result);
}
}
@@ -119,11 +119,6 @@ class SolarisFileSystem extends UnixFile
void copyNonPosixAttributes(int ofd, int nfd) {
SolarisUserDefinedFileAttributeView.copyExtendedAttributes(ofd, nfd);
// TDB: copy ACL from source to target
- }
-
- @Override
- boolean supportsSecureDirectoryStreams() {
- return true;
}
/**
--- a/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java Mon Jun 29 15:08:52 2009 +0100
@@ -49,13 +49,13 @@ class UnixChannelFactory {
private static final JavaIOFileDescriptorAccess fdAccess =
SharedSecrets.getJavaIOFileDescriptorAccess();
- private UnixChannelFactory() {
+ protected UnixChannelFactory() {
}
/**
* Represents the flags from a user-supplied set of open options.
*/
- private static class Flags {
+ protected static class Flags {
boolean read;
boolean write;
boolean append;
@@ -179,11 +179,11 @@ class UnixChannelFactory {
* Opens file based on parameters and options, returning a FileDescriptor
* encapsulating the handle to the open file.
*/
- static FileDescriptor open(int dfd,
- UnixPath path,
- String pathForPermissionCheck,
- Flags flags,
- int mode)
+ protected static FileDescriptor open(int dfd,
+ UnixPath path,
+ String pathForPermissionCheck,
+ Flags flags,
+ int mode)
throws UnixException
{
// map to oflags
--- a/src/solaris/classes/sun/nio/fs/UnixCopyFile.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixCopyFile.java Mon Jun 29 15:08:52 2009 +0100
@@ -30,6 +30,7 @@ import java.security.AccessController;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
import com.sun.nio.file.ExtendedCopyOption;
import static sun.nio.fs.UnixNativeDispatcher.*;
@@ -189,11 +190,13 @@ class UnixCopyFile {
if (flags.copyBasicAttributes) {
try {
if (dfd >= 0) {
- futimes(dfd, attrs.lastAccessTime(),
- attrs.lastModifiedTime());
+ futimes(dfd,
+ attrs.lastAccessTime().to(TimeUnit.MICROSECONDS),
+ attrs.lastModifiedTime().to(TimeUnit.MICROSECONDS));
} else {
- utimes(target, attrs.lastAccessTime(),
- attrs.lastModifiedTime());
+ utimes(target,
+ attrs.lastAccessTime().to(TimeUnit.MICROSECONDS),
+ attrs.lastModifiedTime().to(TimeUnit.MICROSECONDS));
}
} catch (UnixException x) {
// unable to set times
@@ -266,7 +269,9 @@ class UnixCopyFile {
// copy time attributes
if (flags.copyBasicAttributes) {
try {
- futimes(fo, attrs.lastAccessTime(), attrs.lastModifiedTime());
+ futimes(fo,
+ attrs.lastAccessTime().to(TimeUnit.MICROSECONDS),
+ attrs.lastModifiedTime().to(TimeUnit.MICROSECONDS));
} catch (UnixException x) {
if (flags.failIfUnableToCopyBasic)
x.rethrowAsIOException(target);
@@ -341,7 +346,9 @@ class UnixCopyFile {
}
if (flags.copyBasicAttributes) {
try {
- utimes(target, attrs.lastAccessTime(), attrs.lastModifiedTime());
+ utimes(target,
+ attrs.lastAccessTime().to(TimeUnit.MICROSECONDS),
+ attrs.lastModifiedTime().to(TimeUnit.MICROSECONDS));
} catch (UnixException x) {
if (flags.failIfUnableToCopyBasic)
x.rethrowAsIOException(target);
--- a/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java Mon Jun 29 15:08:52 2009 +0100
@@ -194,8 +194,11 @@ class UnixDirectoryStream
Path entry = dir.resolve(nameAsBytes);
// return entry if no filter or filter accepts it
- if (filter.accept(entry)) {
- return entry;
+ try {
+ if (filter == null || filter.accept(entry))
+ return entry;
+ } catch (IOException ioe) {
+ throwAsConcurrentModificationException(ioe);
}
}
}
@@ -248,7 +251,7 @@ class UnixDirectoryStream
((UnixSecureDirectoryStream)stream)
.implDelete(entry.getName(), false, 0);
} else {
- entry.delete(true);
+ entry.delete();
}
} catch (IOException ioe) {
throwAsConcurrentModificationException(ioe);
--- a/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java Mon Jun 29 15:08:52 2009 +0100
@@ -56,11 +56,11 @@ class UnixFileAttributeViews {
return null; // keep compiler happy
}
}
- @Override
- public void setTimes(Long lastModifiedTime,
- Long lastAccessTime,
- Long createTime,
- TimeUnit unit) throws IOException
+
+ @Override
+ public void setTimes(FileTime lastModifiedTime,
+ FileTime lastAccessTime,
+ FileTime createTime) throws IOException
{
// null => don't change
if (lastModifiedTime == null && lastAccessTime == null) {
@@ -68,53 +68,49 @@ class UnixFileAttributeViews {
return;
}
+ // permission check
file.checkWrite();
int fd = file.openForAttributeAccess(followLinks);
try {
- UnixFileAttributes attrs = null;
-
// if not changing both attributes then need existing attributes
if (lastModifiedTime == null || lastAccessTime == null) {
try {
- attrs = UnixFileAttributes.get(fd);
+ UnixFileAttributes attrs = UnixFileAttributes.get(fd);
+ if (lastModifiedTime == null)
+ lastModifiedTime = attrs.lastModifiedTime();
+ if (lastAccessTime == null)
+ lastAccessTime = attrs.lastAccessTime();
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
}
- // modified time = existing, now, or new value
- long modTime;
- if (lastModifiedTime == null) {
- modTime = attrs.lastModifiedTime();
- } else {
- if (lastModifiedTime >= 0L) {
- modTime = TimeUnit.MILLISECONDS.convert(lastModifiedTime, unit);
+ // uptime times
+ long modValue = lastModifiedTime.to(TimeUnit.MICROSECONDS);
+ long accessValue= lastAccessTime.to(TimeUnit.MICROSECONDS);
+
+ boolean retry = false;
+ try {
+ futimes(fd, accessValue, modValue);
+ } catch (UnixException x) {
+ // if futimes fails with EINVAL and one/both of the times is
+ // negative then we adjust the value to the epoch and retry.
+ if (x.errno() == UnixConstants.EINVAL &&
+ (modValue < 0L || accessValue < 0L)) {
+ retry = true;
} else {
- if (lastModifiedTime != -1L)
- throw new IllegalArgumentException();
- modTime = System.currentTimeMillis();
- }
- }
-
- // access time = existing, now, or new value
- long accTime;
- if (lastAccessTime == null) {
- accTime = attrs.lastAccessTime();
- } else {
- if (lastAccessTime >= 0L) {
- accTime = TimeUnit.MILLISECONDS.convert(lastAccessTime, unit);
- } else {
- if (lastAccessTime != -1L)
- throw new IllegalArgumentException();
- accTime = System.currentTimeMillis();
- }
- }
-
- try {
- futimes(fd, accTime, modTime);
- } catch (UnixException x) {
- x.rethrowAsIOException(file);
+ x.rethrowAsIOException(file);
+ }
+ }
+ if (retry) {
+ if (modValue < 0L) modValue = 0L;
+ if (accessValue < 0L) accessValue= 0L;
+ try {
+ futimes(fd, accessValue, modValue);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(file);
+ }
}
} finally {
close(fd);
@@ -199,10 +195,10 @@ class UnixFileAttributeViews {
}
@Override
- public Map<String,?> readAttributes(String first, String[] rest)
- throws IOException
- {
- AttributesBuilder builder = AttributesBuilder.create(first, rest);
+ public Map<String,?> readAttributes(String[] attributes)
+ throws IOException
+ {
+ AttributesBuilder builder = AttributesBuilder.create(attributes);
PosixFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder);
addPosixAttributesToBuilder(attrs, builder);
@@ -297,6 +293,7 @@ class UnixFileAttributeViews {
private static final String INO_NAME = "ino";
private static final String DEV_NAME = "dev";
private static final String RDEV_NAME = "rdev";
+ private static final String NLINK_NAME = "nlink";
private static final String UID_NAME = "uid";
private static final String GID_NAME = "gid";
private static final String CTIME_NAME = "ctime";
@@ -320,6 +317,8 @@ class UnixFileAttributeViews {
return readAttributes().dev();
if (attribute.equals(RDEV_NAME))
return readAttributes().rdev();
+ if (attribute.equals(NLINK_NAME))
+ return readAttributes().nlink();
if (attribute.equals(UID_NAME))
return readAttributes().uid();
if (attribute.equals(GID_NAME))
@@ -349,10 +348,10 @@ class UnixFileAttributeViews {
}
@Override
- public Map<String,?> readAttributes(String first, String[] rest)
- throws IOException
- {
- AttributesBuilder builder = AttributesBuilder.create(first, rest);
+ public Map<String,?> readAttributes(String[] attributes)
+ throws IOException
+ {
+ AttributesBuilder builder = AttributesBuilder.create(attributes);
UnixFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder);
addPosixAttributesToBuilder(attrs, builder);
@@ -364,6 +363,8 @@ class UnixFileAttributeViews {
builder.add(DEV_NAME, attrs.dev());
if (builder.match(RDEV_NAME))
builder.add(RDEV_NAME, attrs.rdev());
+ if (builder.match(NLINK_NAME))
+ builder.add(NLINK_NAME, attrs.nlink());
if (builder.match(UID_NAME))
builder.add(UID_NAME, attrs.uid());
if (builder.match(GID_NAME))
@@ -374,19 +375,19 @@ class UnixFileAttributeViews {
}
}
- static BasicFileAttributeView createBasicView(UnixPath file, boolean followLinks) {
+ static Basic createBasicView(UnixPath file, boolean followLinks) {
return new Basic(file, followLinks);
}
- static PosixFileAttributeView createPosixView(UnixPath file, boolean followLinks) {
+ static Posix createPosixView(UnixPath file, boolean followLinks) {
return new Posix(file, followLinks);
}
- static PosixFileAttributeView createUnixView(UnixPath file, boolean followLinks) {
+ static Unix createUnixView(UnixPath file, boolean followLinks) {
return new Unix(file, followLinks);
}
- static FileOwnerAttributeView createOwnerView(UnixPath file, boolean followLinks) {
+ static FileOwnerAttributeViewImpl createOwnerView(UnixPath file, boolean followLinks) {
return new FileOwnerAttributeViewImpl(createPosixView(file, followLinks));
}
}
--- a/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java Mon Jun 29 15:08:52 2009 +0100
@@ -97,9 +97,13 @@ class UnixFileAttributes
long ino() { return st_ino; }
long dev() { return st_dev; }
long rdev() { return st_rdev; }
+ int nlink() { return st_nlink; }
int uid() { return st_uid; }
int gid() { return st_gid; }
- long ctime() { return st_ctime; }
+
+ FileTime ctime() {
+ return FileTime.from(st_ctime, TimeUnit.SECONDS);
+ }
boolean isDevice() {
int type = st_mode & UnixConstants.S_IFMT;
@@ -109,23 +113,18 @@ class UnixFileAttributes
}
@Override
- public long lastModifiedTime() {
- return st_mtime;
- }
-
- @Override
- public long lastAccessTime() {
- return st_atime;
- }
-
- @Override
- public long creationTime() {
- return -1L;
- }
-
- @Override
- public TimeUnit resolution() {
- return TimeUnit.MILLISECONDS;
+ public FileTime lastModifiedTime() {
+ return FileTime.from(st_mtime, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public FileTime lastAccessTime() {
+ return FileTime.from(st_atime, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public FileTime creationTime() {
+ return null;
}
@Override
@@ -154,11 +153,6 @@ class UnixFileAttributes
@Override
public long size() {
return st_size;
- }
-
- @Override
- public int linkCount() {
- return st_nlink;
}
@Override
@@ -260,20 +254,16 @@ class UnixFileAttributes
}
@Override
- public long lastModifiedTime() {
+ public FileTime lastModifiedTime() {
return attrs.lastModifiedTime();
}
@Override
- public long lastAccessTime() {
+ public FileTime lastAccessTime() {
return attrs.lastAccessTime();
}
@Override
- public long creationTime() {
+ public FileTime creationTime() {
return attrs.creationTime();
- }
- @Override
- public TimeUnit resolution() {
- return attrs.resolution();
}
@Override
public boolean isRegularFile() {
@@ -296,10 +286,6 @@ class UnixFileAttributes
return attrs.size();
}
@Override
- public int linkCount() {
- return attrs.linkCount();
- }
- @Override
public Object fileKey() {
return attrs.fileKey();
}
--- a/src/solaris/classes/sun/nio/fs/UnixFileKey.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixFileKey.java Mon Jun 29 15:08:52 2009 +0100
@@ -53,4 +53,15 @@ class UnixFileKey {
UnixFileKey other = (UnixFileKey)obj;
return (this.st_dev == other.st_dev) && (this.st_ino == other.st_ino);
}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(dev=")
+ .append(Long.toHexString(st_dev))
+ .append(",ino=")
+ .append(st_ino)
+ .append(')');
+ return sb.toString();
+ }
}
--- a/src/solaris/classes/sun/nio/fs/UnixFileModeAttribute.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixFileModeAttribute.java Mon Jun 29 15:08:52 2009 +0100
@@ -42,10 +42,7 @@ class UnixFileModeAttribute {
static final int TEMPFILE_PERMISSIONS =
UnixConstants.S_IRUSR | UnixConstants.S_IWUSR | UnixConstants.S_IXUSR;
- private Set<PosixFilePermission> perms;
-
- UnixFileModeAttribute() {
- perms = Collections.emptySet();
+ private UnixFileModeAttribute() {
}
static int toUnixMode(Set<PosixFilePermission> perms) {
--- a/src/solaris/classes/sun/nio/fs/UnixFileStore.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixFileStore.java Mon Jun 29 15:08:52 2009 +0100
@@ -78,7 +78,7 @@ abstract class UnixFileStore
/**
* Returns true if this file store represents a loopback file system that
- * will have the same device ID as undelrying file system.
+ * will have the same device ID as underlying file system.
*/
abstract boolean isLoopback();
@@ -111,22 +111,33 @@ abstract class UnixFileStore
@Override
@SuppressWarnings("unchecked")
- public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> viewType)
+ public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> view)
{
- if (viewType == FileStoreSpaceAttributeView.class)
+ if (view == null)
+ throw new NullPointerException();
+ if (view == FileStoreSpaceAttributeView.class)
return (V) new UnixFileStoreSpaceAttributeView(this);
return (V) null;
}
@Override
- public FileStoreAttributeView getFileStoreAttributeView(String name) {
- if (name.equals("space"))
- return new UnixFileStoreSpaceAttributeView(this);
- return null;
+ public Object getAttribute(String attribute) throws IOException {
+ if (attribute.equals("space:totalSpace"))
+ return new UnixFileStoreSpaceAttributeView(this)
+ .readAttributes().totalSpace();
+ if (attribute.equals("space:usableSpace"))
+ return new UnixFileStoreSpaceAttributeView(this)
+ .readAttributes().usableSpace();
+ if (attribute.equals("space:unallocatedSpace"))
+ return new UnixFileStoreSpaceAttributeView(this)
+ .readAttributes().unallocatedSpace();
+ throw new UnsupportedOperationException("'" + attribute + "' not recognized");
}
@Override
public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
+ if (type == null)
+ throw new NullPointerException();
if (type == BasicFileAttributeView.class)
return true;
if (type == PosixFileAttributeView.class ||
@@ -187,12 +198,17 @@ abstract class UnixFileStore
}
private static class UnixFileStoreSpaceAttributeView
- extends AbstractFileStoreSpaceAttributeView
+ implements FileStoreSpaceAttributeView
{
private final UnixFileStore fs;
UnixFileStoreSpaceAttributeView(UnixFileStore fs) {
this.fs = fs;
+ }
+
+ @Override
+ public String name() {
+ return "space";
}
@Override
@@ -275,7 +291,7 @@ abstract class UnixFileStore
private static Properties loadProperties() {
Properties result = new Properties();
String fstypes = System.getProperty("java.home") + "/lib/fstypes.properties";
- FileRef file = Paths.get(fstypes);
+ Path file = Paths.get(fstypes);
try {
ReadableByteChannel rbc = file.newByteChannel();
try {
--- a/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Mon Jun 29 15:08:52 2009 +0100
@@ -137,13 +137,9 @@ abstract class UnixFileSystem
* @param tfd
* Open file descriptor to target file
*/
- abstract void copyNonPosixAttributes(int sfd, int tfd);
-
- /**
- * Tells if directory relative system calls (openat, etc.) are available
- * on this operating system.
- */
- abstract boolean supportsSecureDirectoryStreams();
+ void copyNonPosixAttributes(int sfd, int tfd) {
+ // no-op by default
+ }
/**
* Unix systems only have a single root directory (/)
@@ -340,9 +336,9 @@ abstract class UnixFileSystem
return Arrays.asList("basic", "posix", "unix", "owner");
}
- protected FileAttributeView newFileAttributeView(String name,
- UnixPath file,
- LinkOption... options)
+ protected DynamicFileAttributeView newFileAttributeView(String name,
+ UnixPath file,
+ LinkOption... options)
{
boolean followLinks = followLinks(options);
if (name.equals("basic"))
--- a/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Mon Jun 29 15:08:52 2009 +0100
@@ -93,7 +93,7 @@ public abstract class UnixFileSystemProv
return UnixUriUtils.fromUri(theFileSystem, uri);
}
- private UnixPath checkPath(Path obj) {
+ protected UnixPath checkPath(Path obj) {
if (obj == null)
throw new NullPointerException();
if (!(obj instanceof UnixPath))
@@ -102,9 +102,9 @@ public abstract class UnixFileSystemProv
}
@Override
- public final FileChannel newFileChannel(Path obj,
- Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
+ public FileChannel newFileChannel(Path obj,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
throws IOException
{
UnixPath file = checkPath(obj);
@@ -119,10 +119,10 @@ public abstract class UnixFileSystemProv
}
@Override
- public final AsynchronousFileChannel newAsynchronousFileChannel(Path obj,
- Set<? extends OpenOption> options,
- ExecutorService executor,
- FileAttribute<?>... attrs) throws IOException
+ public AsynchronousFileChannel newAsynchronousFileChannel(Path obj,
+ Set<? extends OpenOption> options,
+ ExecutorService executor,
+ FileAttribute<?>... attrs) throws IOException
{
UnixPath file = checkPath(obj);
int mode = UnixFileModeAttribute
--- a/src/solaris/classes/sun/nio/fs/UnixMountEntry.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixMountEntry.java Mon Jun 29 15:08:52 2009 +0100
@@ -66,7 +66,7 @@ class UnixMountEntry {
boolean hasOption(String requested) {
if (optionsAsString == null)
optionsAsString = new String(opts);
- for (String opt: optionsAsString.split("\\,", 0)) {
+ for (String opt: Util.split(optionsAsString, ',')) {
if (opt.equals(requested))
return true;
}
--- a/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java Mon Jun 29 15:08:52 2009 +0100
@@ -542,8 +542,17 @@ class UnixNativeDispatcher {
*/
static native byte[] strerror(int errnum);
- // initialize field IDs
- private static native void initIDs();
+ // indicates if openat, unlinkat, etc. is supported
+ private static final boolean hasAtSysCalls;
+ static boolean supportsAtSysCalls() {
+ return hasAtSysCalls;
+ }
+
+ // initialize syscalls and fieldIDs
+ private static native int init();
+
+ // flags returned by init to indicate capabilities
+ private static final int HAS_AT_SYSCALLS = 0x1;
static {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@@ -551,6 +560,8 @@ class UnixNativeDispatcher {
System.loadLibrary("nio");
return null;
}});
- initIDs();
+ int flags = init();
+
+ hasAtSysCalls = (flags & HAS_AT_SYSCALLS) > 0;
}
}
--- a/src/solaris/classes/sun/nio/fs/UnixPath.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixPath.java Mon Jun 29 15:08:52 2009 +0100
@@ -28,7 +28,6 @@ import java.nio.*;
import java.nio.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
-import java.nio.file.spi.AbstractPath;
import java.nio.charset.*;
import java.nio.channels.*;
import java.security.AccessController;
@@ -88,15 +87,19 @@ class UnixPath
char prevChar = 0;
for (int i=0; i < n; i++) {
char c = input.charAt(i);
- if (c == '\u0000')
- throw new InvalidPathException(input, "Nul character not allowed");
if ((c == '/') && (prevChar == '/'))
return normalize(input, n, i - 1);
+ checkNotNul(input, c);
prevChar = c;
}
if (prevChar == '/')
return normalize(input, n, n - 1);
return input;
+ }
+
+ private static void checkNotNul(String input, char c) {
+ if (c == '\u0000')
+ throw new InvalidPathException(input, "Nul character not allowed");
}
private static String normalize(String input, int len, int off) {
@@ -114,6 +117,7 @@ class UnixPath
char c = input.charAt(i);
if ((c == '/') && (prevChar == '/'))
continue;
+ checkNotNul(input, c);
sb.append(c);
prevChar = c;
}
@@ -862,7 +866,7 @@ class UnixPath
}
@Override
- public void delete(boolean failIfNotExists) throws IOException {
+ void implDelete(boolean failIfNotExists) throws IOException {
checkDelete();
// need file attributes to know if file is directory
@@ -896,13 +900,14 @@ class UnixPath
throw new NullPointerException();
checkRead();
- // can't return SecureDirectoryStream on older kernels.
- if (!getFileSystem().supportsSecureDirectoryStreams()) {
+ // can't return SecureDirectoryStream on kernels that don't support
+ // openat, etc.
+ if (!supportsAtSysCalls()) {
try {
long ptr = opendir(this);
return new UnixDirectoryStream(this, ptr, filter);
} catch (UnixException x) {
- if (x.errno() == UnixConstants.ENOTDIR)
+ if (x.errno() == ENOTDIR)
throw new NotDirectoryException(getPathForExecptionMessage());
x.rethrowAsIOException(this);
}
@@ -959,7 +964,9 @@ class UnixPath
}
@Override
- public FileAttributeView getFileAttributeView(String name, LinkOption... options) {
+ public DynamicFileAttributeView getFileAttributeView(String name,
+ LinkOption... options)
+ {
return getFileSystem().newFileAttributeView(name, this, options);
}
@@ -980,20 +987,8 @@ class UnixPath
}
@Override
- public InputStream newInputStream()throws IOException {
- try {
- Set<OpenOption> options = Collections.emptySet();
- FileChannel fc = UnixChannelFactory.newFileChannel(this, options, 0);
- return Channels.newInputStream(fc);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- return null; // keep compiler happy
- }
- }
-
- @Override
public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
+ FileAttribute<?>... attrs)
throws IOException
{
int mode = UnixFileModeAttribute
@@ -1007,29 +1002,7 @@ class UnixPath
}
@Override
- public OutputStream newOutputStream(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- // need to copy options to add WRITE
- Set<OpenOption> opts = new HashSet<OpenOption>(options);
- if (opts.contains(StandardOpenOption.READ))
- throw new IllegalArgumentException("READ not allowed");
- opts.add(StandardOpenOption.WRITE);
-
- int mode = UnixFileModeAttribute
- .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
- try {
- FileChannel fc = UnixChannelFactory.newFileChannel(this, opts, mode);
- return Channels.newOutputStream(fc);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- return null; // keep compiler happy
- }
- }
-
- @Override
- public boolean isSameFile(FileRef obj) throws IOException {
+ public boolean isSameFile(Path obj) throws IOException {
if (this.equals(obj))
return true;
if (!(obj instanceof UnixPath)) // includes null check
@@ -1188,13 +1161,6 @@ class UnixPath
}
result = result.resolve(element);
}
-
- // finally check that file exists
- try {
- UnixFileAttributes.get(result, true);
- } catch (UnixException x) {
- x.rethrowAsIOException(result);
- }
return result;
}
--- a/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java Mon Jun 29 15:08:52 2009 +0100
@@ -40,7 +40,7 @@ import static sun.nio.fs.UnixConstants.*
*/
class UnixSecureDirectoryStream
- extends SecureDirectoryStream
+ extends SecureDirectoryStream<Path>
{
private final UnixDirectoryStream ds;
private final int dfd;
@@ -85,13 +85,13 @@ class UnixSecureDirectoryStream
* Opens sub-directory in this directory
*/
@Override
- public SecureDirectoryStream newDirectoryStream(Path obj,
- boolean followLinks,
- DirectoryStream.Filter<? super Path> filter)
+ public SecureDirectoryStream<Path> newDirectoryStream(Path obj,
+ LinkOption... options)
throws IOException
{
UnixPath file = getName(obj);
UnixPath child = ds.directory().resolve(file);
+ boolean followLinks = file.getFileSystem().followLinks(options);
// permission check using name resolved against original path of directory
SecurityManager sm = System.getSecurityManager();
@@ -124,7 +124,7 @@ class UnixSecureDirectoryStream
throw new NotDirectoryException(file.toString());
x.rethrowAsIOException(file);
}
- return new UnixSecureDirectoryStream(child, ptr, newdfd2, filter);
+ return new UnixSecureDirectoryStream(child, ptr, newdfd2, null);
} finally {
ds.readLock().unlock();
}
@@ -225,7 +225,7 @@ class UnixSecureDirectoryStream
* Rename/move file in this directory to another (open) directory
*/
@Override
- public void move(Path fromObj, SecureDirectoryStream dir, Path toObj)
+ public void move(Path fromObj, SecureDirectoryStream<Path> dir, Path toObj)
throws IOException
{
UnixPath from = getName(fromObj);
@@ -310,13 +310,10 @@ class UnixSecureDirectoryStream
* A BasicFileAttributeView implementation that using a dfd/name pair.
*/
private class BasicFileAttributeViewImpl
- extends AbstractBasicFileAttributeView
+ implements BasicFileAttributeView
{
final UnixPath file;
final boolean followLinks;
-
- // set to true when binding to another object
- volatile boolean forwarding;
BasicFileAttributeViewImpl(UnixPath file, boolean followLinks)
{
@@ -380,17 +377,11 @@ class UnixSecureDirectoryStream
}
@Override
- public void setTimes(Long lastModifiedTime,
- Long lastAccessTime,
- Long createTime, // ignore
- TimeUnit unit)
+ public void setTimes(FileTime lastModifiedTime,
+ FileTime lastAccessTime,
+ FileTime createTime) // ignore
throws IOException
{
- // no effect
- if (lastModifiedTime == null && lastAccessTime == null) {
- return;
- }
-
checkWriteAccess();
ds.readLock().lock();
@@ -400,47 +391,23 @@ class UnixSecureDirectoryStream
int fd = (file == null) ? dfd : open();
try {
- UnixFileAttributes attrs = null;
-
// if not changing both attributes then need existing attributes
if (lastModifiedTime == null || lastAccessTime == null) {
try {
- attrs = UnixFileAttributes.get(fd);
+ UnixFileAttributes attrs = UnixFileAttributes.get(fd);
+ if (lastModifiedTime == null)
+ lastModifiedTime = attrs.lastModifiedTime();
+ if (lastAccessTime == null)
+ lastAccessTime = attrs.lastAccessTime();
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
}
-
- // modified time = existing, now, or new value
- long modTime;
- if (lastModifiedTime == null) {
- modTime = attrs.lastModifiedTime();
- } else {
- if (lastModifiedTime >= 0L) {
- modTime = TimeUnit.MILLISECONDS.convert(lastModifiedTime, unit);
- } else {
- if (lastModifiedTime != -1L)
- throw new IllegalArgumentException();
- modTime = System.currentTimeMillis();
- }
- }
-
- // access time = existing, now, or new value
- long accTime;
- if (lastAccessTime == null) {
- accTime = attrs.lastAccessTime();
- } else {
- if (lastAccessTime >= 0L) {
- accTime = TimeUnit.MILLISECONDS.convert(lastAccessTime, unit);
- } else {
- if (lastAccessTime != -1L)
- throw new IllegalArgumentException();
- accTime = System.currentTimeMillis();
- }
- }
-
+ // update times
try {
- futimes(fd, accTime, modTime);
+ futimes(fd,
+ lastAccessTime.to(TimeUnit.MICROSECONDS),
+ lastModifiedTime.to(TimeUnit.MICROSECONDS));
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
@@ -460,10 +427,6 @@ class UnixSecureDirectoryStream
private class PosixFileAttributeViewImpl
extends BasicFileAttributeViewImpl implements PosixFileAttributeView
{
- private static final String PERMISSIONS_NAME = "permissions";
- private static final String OWNER_NAME = "owner";
- private static final String GROUP_NAME = "group";
-
PosixFileAttributeViewImpl(UnixPath file, boolean followLinks) {
super(file, followLinks);
}
@@ -479,59 +442,6 @@ class UnixSecureDirectoryStream
@Override
public String name() {
return "posix";
- }
-
- @Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(PERMISSIONS_NAME))
- return readAttributes().permissions();
- if (attribute.equals(OWNER_NAME))
- return readAttributes().owner();
- if (attribute.equals(GROUP_NAME))
- return readAttributes().group();
- return super.getAttribute(attribute);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public void setAttribute(String attribute, Object value)
- throws IOException
- {
- if (attribute.equals(PERMISSIONS_NAME)) {
- setPermissions((Set<PosixFilePermission>)value);
- return;
- }
- if (attribute.equals(OWNER_NAME)) {
- setOwner((UserPrincipal)value);
- return;
- }
- if (attribute.equals(GROUP_NAME)) {
- setGroup((GroupPrincipal)value);
- return;
- }
- super.setAttribute(attribute, value);
- }
-
- final void addPosixAttributesToBuilder(PosixFileAttributes attrs,
- AttributesBuilder builder)
- {
- if (builder.match(PERMISSIONS_NAME))
- builder.add(PERMISSIONS_NAME, attrs.permissions());
- if (builder.match(OWNER_NAME))
- builder.add(OWNER_NAME, attrs.owner());
- if (builder.match(GROUP_NAME))
- builder.add(GROUP_NAME, attrs.group());
- }
-
- @Override
- public Map<String,?> readAttributes(String first, String[] rest)
- throws IOException
- {
- AttributesBuilder builder = AttributesBuilder.create(first, rest);
- PosixFileAttributes attrs = readAttributes();
- addBasicAttributesToBuilder(attrs, builder);
- addPosixAttributesToBuilder(attrs, builder);
- return builder.unmodifiableMap();
}
@Override
--- a/src/solaris/classes/sun/nio/fs/UnixUserPrincipals.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixUserPrincipals.java Mon Jun 29 15:08:52 2009 +0100
@@ -147,8 +147,14 @@ class UnixUserPrincipals {
} catch (UnixException x) {
throw new IOException(name + ": " + x.errorString());
}
- if (id == -1)
- throw new UserPrincipalNotFoundException(name);
+ if (id == -1) {
+ // lookup failed, allow input to be uid or gid
+ try {
+ id = Integer.parseInt(name);
+ } catch (NumberFormatException ignore) {
+ throw new UserPrincipalNotFoundException(name);
+ }
+ }
return id;
}
--- a/src/solaris/native/sun/nio/ch/Sctp.h Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/native/sun/nio/ch/Sctp.h Mon Jun 29 15:08:52 2009 +0100
@@ -63,6 +63,8 @@ typedef int sctp_getpaddrs_func(int sock
typedef int sctp_getpaddrs_func(int sock, sctp_assoc_t id, void **addrs);
typedef int sctp_freepaddrs_func(void *addrs);
typedef int sctp_bindx_func(int sock, void *addrs, int addrcnt, int flags);
+typedef int sctp_peeloff_func(int sock, sctp_assoc_t id);
+
#else /* __linux__ */
@@ -315,6 +317,8 @@ typedef int sctp_getpaddrs_func(int sd,
typedef int sctp_getpaddrs_func(int sd, sctp_assoc_t id, struct sockaddr **addrs);
typedef int sctp_freepaddrs_func(struct sockaddr *addrs);
typedef int sctp_bindx_func(int sd, struct sockaddr *addrs, int addrcnt, int flags);
+typedef int sctp_peeloff_func(int sock, sctp_assoc_t id);
+
#endif /* __linux__ */
@@ -323,6 +327,7 @@ sctp_getpaddrs_func* nio_sctp_getpaddrs;
sctp_getpaddrs_func* nio_sctp_getpaddrs;
sctp_freepaddrs_func* nio_sctp_freepaddrs;
sctp_bindx_func* nio_sctp_bindx;
+sctp_peeloff_func* nio_sctp_peeloff;
jboolean loadSocketExtensionFuncs(JNIEnv* env);
--- a/src/solaris/native/sun/nio/ch/SctpChannelImpl.c Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/native/sun/nio/ch/SctpChannelImpl.c Mon Jun 29 15:08:52 2009 +0100
@@ -254,7 +254,6 @@ void handleSendFailed
if (remaining > 0) {
if ((rv = recvmsg(fd, msg, 0)) < 0) {
- fprintf(stdout, "\nNative: handleSFN: recvmsg failed: errno = %d ", errno);
handleSocketError(env, errno);
return;
}
@@ -269,7 +268,7 @@ void handleSendFailed
/* create SctpSendFailed */
resultObj = (*env)->NewObject(env, ssf_class, ssf_ctrID, ssf->ssf_assoc_id,
- sri->sinfo_stream, ssf->ssf_error, isaObj, bufferObj);
+ isaObj, bufferObj, ssf->ssf_error, sri->sinfo_stream);
CHECK_NULL(resultObj);
(*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
(*env)->SetIntField(env, resultContainerObj, src_typeID,
--- a/src/solaris/native/sun/nio/ch/SctpNet.c Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/native/sun/nio/ch/SctpNet.c Mon Jun 29 15:08:52 2009 +0100
@@ -96,6 +96,13 @@ jboolean loadSocketExtensionFuncs
return JNI_FALSE;
}
+ if ((nio_sctp_peeloff = (sctp_peeloff_func*)
+ dlsym(RTLD_DEFAULT, "sctp_peeloff")) == NULL) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ dlerror());
+ return JNI_FALSE;
+ }
+
funcsLoaded = JNI_TRUE;
return JNI_TRUE;
}
@@ -440,12 +447,10 @@ JNIEXPORT jobject JNICALL Java_sun_nio_c
JNIEXPORT jobject JNICALL Java_sun_nio_ch_SctpNet_getPrimAddrOption0
(JNIEnv *env, jclass klass, jint fd, jint assocId) {
struct sctp_setprim prim;
- struct sockaddr_storage ss;
- int ss_len = sizeof(ss);
unsigned int prim_len = sizeof(prim);
+ struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;
prim.ssp_assoc_id = assocId;
- prim.ssp_addr = ss;
if (getsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, &prim_len) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
@@ -453,7 +458,7 @@ JNIEXPORT jobject JNICALL Java_sun_nio_c
return NULL;
}
- return SockAddrToInetSocketAddress(env, (struct sockaddr*)&ss);
+ return SockAddrToInetSocketAddress(env, sap);
}
/*
@@ -464,16 +469,15 @@ JNIEXPORT void JNICALL Java_sun_nio_ch_S
JNIEXPORT void JNICALL Java_sun_nio_ch_SctpNet_setPrimAddrOption0
(JNIEnv *env, jclass klass, jint fd, jint assocId, jobject iaObj, jint port) {
struct sctp_setprim prim;
- struct sockaddr_storage ss;
- int ss_len = sizeof(ss);
-
- if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&ss,
- &ss_len, JNI_TRUE) != 0) {
+ struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;
+ int sap_len;
+
+ if (NET_InetAddressToSockaddr(env, iaObj, port, sap,
+ &sap_len, JNI_TRUE) != 0) {
return;
}
prim.ssp_assoc_id = assocId;
- prim.ssp_addr = ss;
if (setsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, sizeof(prim)) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
@@ -607,3 +611,17 @@ JNIEXPORT void JNICALL Java_sun_nio_ch_S
}
}
+/*
+ * Class: sun_nio_ch_SctpNet
+ * Method: branch
+ * Signature: (II)I
+ */
+JNIEXPORT int JNICALL Java_sun_nio_ch_SctpNet_branch0
+ (JNIEnv *env, jclass klass, jint fd, jint assocId) {
+ int newfd = 0;
+ if ((newfd = nio_sctp_peeloff(fd, assocId)) < 0) {
+ handleSocketError(env, errno);
+ }
+
+ return newfd;
+}
--- a/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Mon Jun 29 15:08:52 2009 +0100
@@ -92,14 +92,12 @@ typedef int unlinkat_func(int, const cha
typedef int unlinkat_func(int, const char*, int);
typedef int renameat_func(int, const char*, int, const char*);
typedef int futimesat_func(int, const char *, const struct timeval *);
-typedef DIR* fdopendir_func(int);
static openat64_func* my_openat64_func = NULL;
static fstatat64_func* my_fstatat64_func = NULL;
static unlinkat_func* my_unlinkat_func = NULL;
static renameat_func* my_renameat_func = NULL;
static futimesat_func* my_futimesat_func = NULL;
-static fdopendir_func* my_fdopendir_func = NULL;
/**
* fstatat missing from glibc on Linux. Temporary workaround
@@ -142,16 +140,17 @@ static void throwUnixException(JNIEnv* e
}
/**
- * Initialize jfieldIDs
+ * Initialization
*/
-JNIEXPORT void JNICALL
-Java_sun_nio_fs_UnixNativeDispatcher_initIDs(JNIEnv* env, jclass this)
-{
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
+{
+ jint flags = 0;
jclass clazz;
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileAttributes");
if (clazz == NULL) {
- return;
+ return 0;
}
attrs_st_mode = (*env)->GetFieldID(env, clazz, "st_mode", "I");
attrs_st_ino = (*env)->GetFieldID(env, clazz, "st_ino", "J");
@@ -167,7 +166,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_ini
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileStoreAttributes");
if (clazz == NULL) {
- return;
+ return 0;
}
attrs_f_frsize = (*env)->GetFieldID(env, clazz, "f_frsize", "J");
attrs_f_blocks = (*env)->GetFieldID(env, clazz, "f_blocks", "J");
@@ -176,7 +175,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_ini
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
if (clazz == NULL) {
- return;
+ return 0;
}
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
@@ -197,13 +196,21 @@ Java_sun_nio_fs_UnixNativeDispatcher_ini
my_unlinkat_func = (unlinkat_func*) dlsym(RTLD_DEFAULT, "unlinkat");
my_renameat_func = (renameat_func*) dlsym(RTLD_DEFAULT, "renameat");
my_futimesat_func = (futimesat_func*) dlsym(RTLD_DEFAULT, "futimesat");
- my_fdopendir_func = (fdopendir_func*) dlsym(RTLD_DEFAULT, "fdopendir");
#if defined(FSTATAT64_SYSCALL_AVAILABLE)
/* fstatat64 missing from glibc */
if (my_fstatat64_func == NULL)
my_fstatat64_func = (fstatat64_func*)&fstatat64_wrapper;
#endif
+
+ if (my_openat64_func != NULL && my_fstatat64_func != NULL &&
+ my_unlinkat_func != NULL && my_renameat_func != NULL &&
+ my_futimesat_func != NULL)
+ {
+ flags |= sun_nio_fs_UnixNativeDispatcher_HAS_AT_SYSCALLS;
+ }
+
+ return flags;
}
JNIEXPORT jbyteArray JNICALL
@@ -364,9 +371,9 @@ static void prepAttributes(JNIEnv* env,
(*env)->SetIntField(env, attrs, attrs_st_uid, (jint)buf->st_uid);
(*env)->SetIntField(env, attrs, attrs_st_gid, (jint)buf->st_gid);
(*env)->SetLongField(env, attrs, attrs_st_size, (jlong)buf->st_size);
- (*env)->SetLongField(env, attrs, attrs_st_atime, (jlong)buf->st_atime * 1000);
- (*env)->SetLongField(env, attrs, attrs_st_mtime, (jlong)buf->st_mtime * 1000);
- (*env)->SetLongField(env, attrs, attrs_st_ctime, (jlong)buf->st_ctime * 1000);
+ (*env)->SetLongField(env, attrs, attrs_st_atime, (jlong)buf->st_atime);
+ (*env)->SetLongField(env, attrs, attrs_st_mtime, (jlong)buf->st_mtime);
+ (*env)->SetLongField(env, attrs, attrs_st_ctime, (jlong)buf->st_ctime);
}
JNIEXPORT void JNICALL
@@ -506,11 +513,11 @@ Java_sun_nio_fs_UnixNativeDispatcher_uti
struct timeval times[2];
const char* path = (const char*)jlong_to_ptr(pathAddress);
- times[0].tv_sec = accessTime / 1000;
- times[0].tv_usec = (accessTime % 1000) * 1000;
-
- times[1].tv_sec = modificationTime / 1000;
- times[1].tv_usec = (modificationTime % 1000) * 1000;
+ times[0].tv_sec = accessTime / 1000000;
+ times[0].tv_usec = accessTime % 1000000;
+
+ times[1].tv_sec = modificationTime / 1000000;
+ times[1].tv_usec = modificationTime % 1000000;
RESTARTABLE(utimes(path, ×[0]), err);
if (err == -1) {
@@ -525,11 +532,11 @@ Java_sun_nio_fs_UnixNativeDispatcher_fut
struct timeval times[2];
int err = 0;
- times[0].tv_sec = accessTime / 1000;
- times[0].tv_usec = (accessTime % 1000) * 1000;
-
- times[1].tv_sec = modificationTime / 1000;
- times[1].tv_usec = (modificationTime % 1000) * 1000;
+ times[0].tv_sec = accessTime / 1000000;
+ times[0].tv_usec = accessTime % 1000000;
+
+ times[1].tv_sec = modificationTime / 1000000;
+ times[1].tv_usec = modificationTime % 1000000;
if (my_futimesat_func != NULL) {
RESTARTABLE((*my_futimesat_func)(filedes, NULL, ×[0]), err);
@@ -558,13 +565,8 @@ Java_sun_nio_fs_UnixNativeDispatcher_fdo
Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd) {
DIR* dir;
- if (my_fdopendir_func == NULL) {
- JNU_ThrowInternalError(env, "should not reach here");
- return (jlong)-1;
- }
-
- /* EINTR not listed as a possible error */
- dir = (*my_fdopendir_func)((int)dfd);
+ /* EINTR not listed as a possible error */
+ dir = fdopendir((int)dfd);
if (dir == NULL) {
throwUnixException(env, errno);
}
--- a/src/solaris/native/sun/nio/fs/genUnixConstants.c Mon Jun 29 15:05:15 2009 +0100
+++ b/src/solaris/native/sun/nio/fs/genUnixConstants.c Mon Jun 29 15:08:52 2009 +0100
@@ -66,16 +66,6 @@ int main(int argc, const char* argv[]) {
DEFX(O_DSYNC);
DEFX(O_NOFOLLOW);
- // flags used with openat/unlinkat/etc.
-#ifdef __solaris__
- DEFX(AT_SYMLINK_NOFOLLOW);
- DEFX(AT_REMOVEDIR);
-#endif
-#ifdef __linux__
- emitX("AT_SYMLINK_NOFOLLOW", 0x100); // since 2.6.16
- emitX("AT_REMOVEDIR", 0x200);
-#endif
-
// mode masks
emitX("S_IAMB",
(S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH));
@@ -119,6 +109,16 @@ int main(int argc, const char* argv[]) {
DEF(ENODATA);
DEF(ERANGE);
+ // flags used with openat/unlinkat/etc.
+#if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_REMOVEDIR)
+ DEFX(AT_SYMLINK_NOFOLLOW)
+ DEFX(AT_REMOVEDIR);
+#else
+ // not supported (dummy values will not be used at runtime).
+ emitX("AT_SYMLINK_NOFOLLOW", 0x0);
+ emitX("AT_REMOVEDIR", 0x0);
+#endif
+
out("} ");
return 0;
--- a/src/windows/classes/sun/nio/fs/WindowsConstants.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/windows/classes/sun/nio/fs/WindowsConstants.java Mon Jun 29 15:08:52 2009 +0100
@@ -93,6 +93,7 @@ class WindowsConstants {
public static final int ERROR_NOT_SAME_DEVICE = 17;
public static final int ERROR_NOT_READY = 21;
public static final int ERROR_FILE_EXISTS = 80;
+ public static final int ERROR_INVALID_PARAMATER = 87;
public static final int ERROR_DISK_FULL = 112;
public static final int ERROR_INSUFFICIENT_BUFFER = 122;
public static final int ERROR_INVALID_LEVEL = 124;
--- a/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java Mon Jun 29 15:08:52 2009 +0100
@@ -152,11 +152,13 @@ class WindowsDirectoryStream
}
Path entry = WindowsPath
.createFromNormalizedPath(dir.getFileSystem(), s, attrs);
- if (filter.accept(entry)) {
- return entry;
- } else {
- return null;
- }
+ try {
+ if (filter.accept(entry))
+ return entry;
+ } catch (IOException ioe) {
+ throwAsConcurrentModificationException(ioe);
+ }
+ return null;
}
// reads next directory entry
@@ -244,7 +246,7 @@ class WindowsDirectoryStream
prevEntry = null;
}
try {
- entry.delete(true);
+ entry.delete();
} catch (IOException ioe) {
throwAsConcurrentModificationException(ioe);
} catch (SecurityException se) {
--- a/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Mon Jun 29 15:08:52 2009 +0100
@@ -28,7 +28,6 @@ package sun.nio.fs;
import java.nio.file.attribute.*;
import java.util.*;
-import java.util.concurrent.TimeUnit;
import java.io.IOException;
import static sun.nio.fs.WindowsNativeDispatcher.*;
@@ -56,9 +55,24 @@ class WindowsFileAttributeViews {
}
/**
+ * Adjusts a Windows time for the FAT epoch.
+ */
+ private long adjustForFatEpoch(long time) {
+ // 1/1/1980 in Windows Time
+ final long FAT_EPOCH = 119600064000000000L;
+ if (time != -1L && time < FAT_EPOCH) {
+ return FAT_EPOCH;
+ } else {
+ return time;
+ }
+ }
+
+ /**
* Parameter values in Windows times.
*/
- void setFileTimes(long createTime, long lastAccessTime, long lastWriteTime)
+ void setFileTimes(long createTime,
+ long lastAccessTime,
+ long lastWriteTime)
throws IOException
{
long handle = -1L;
@@ -76,24 +90,43 @@ class WindowsFileAttributeViews {
x.rethrowAsIOException(file);
}
- // update attributes
- try {
- SetFileTime(handle, createTime, lastAccessTime, lastWriteTime);
- } catch (WindowsException x) {
- x.rethrowAsIOException(file);
+ // update times
+ try {
+ SetFileTime(handle,
+ createTime,
+ lastAccessTime,
+ lastWriteTime);
+ } catch (WindowsException x) {
+ // If ERROR_INVALID_PARAMATER is returned and the volume is
+ // FAT then adjust to the FAT epoch and retry.
+ if (followLinks && x.lastError() == ERROR_INVALID_PARAMATER) {
+ try {
+ if (WindowsFileStore.create(file).type().equals("FAT")) {
+ SetFileTime(handle,
+ adjustForFatEpoch(createTime),
+ adjustForFatEpoch(lastAccessTime),
+ adjustForFatEpoch(lastWriteTime));
+ // retry succeeded
+ x = null;
+ }
+ } catch (SecurityException ignore) {
+ } catch (WindowsException ignore) {
+ } catch (IOException ignore) {
+ // ignore exceptions to let original exception be thrown
+ }
+ }
+ if (x != null)
+ x.rethrowAsIOException(file);
} finally {
CloseHandle(handle);
}
}
@Override
- public void setTimes(Long lastModifiedTime,
- Long lastAccessTime,
- Long createTime,
- TimeUnit unit) throws IOException
- {
- file.checkWrite();
-
+ public void setTimes(FileTime lastModifiedTime,
+ FileTime lastAccessTime,
+ FileTime createTime) throws IOException
+ {
// if all null then do nothing
if (lastModifiedTime == null && lastAccessTime == null &&
createTime == null)
@@ -102,42 +135,17 @@ class WindowsFileAttributeViews {
return;
}
- // null => no change
- // -1 => change to current time
- long now = System.currentTimeMillis();
- long modTime = 0L, accTime = 0L, crTime = 0L;
- if (lastModifiedTime != null) {
- if (lastModifiedTime < 0L) {
- if (lastModifiedTime != -1L)
- throw new IllegalArgumentException();
- modTime = now;
- } else {
- modTime = TimeUnit.MILLISECONDS.convert(lastModifiedTime, unit);
- }
- modTime = WindowsFileAttributes.toWindowsTime(modTime);
- }
- if (lastAccessTime != null) {
- if (lastAccessTime < 0L) {
- if (lastAccessTime != -1L)
- throw new IllegalArgumentException();
- accTime = now;
- } else {
- accTime = TimeUnit.MILLISECONDS.convert(lastAccessTime, unit);
- }
- accTime = WindowsFileAttributes.toWindowsTime(accTime);
- }
- if (createTime != null) {
- if (createTime < 0L) {
- if (createTime != -1L)
- throw new IllegalArgumentException();
- crTime = now;
- } else {
- crTime = TimeUnit.MILLISECONDS.convert(createTime, unit);
- }
- crTime = WindowsFileAttributes.toWindowsTime(crTime);
- }
-
- setFileTimes(crTime, accTime, modTime);
+ // permission check
+ file.checkWrite();
+
+ // update times
+ long t1 = (createTime == null) ? -1L :
+ WindowsFileAttributes.toWindowsTime(createTime);
+ long t2 = (lastAccessTime == null) ? -1L :
+ WindowsFileAttributes.toWindowsTime(lastAccessTime);
+ long t3 = (lastModifiedTime == null) ? -1L :
+ WindowsFileAttributes.toWindowsTime(lastModifiedTime);
+ setFileTimes(t1, t2, t3);
}
}
@@ -197,10 +205,10 @@ class WindowsFileAttributeViews {
}
@Override
- public Map<String,?> readAttributes(String first, String[] rest)
- throws IOException
- {
- AttributesBuilder builder = AttributesBuilder.create(first, rest);
+ public Map<String,?> readAttributes(String[] attributes)
+ throws IOException
+ {
+ AttributesBuilder builder = AttributesBuilder.create(attributes);
WindowsFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder);
if (builder.match(READONLY_NAME))
@@ -286,11 +294,11 @@ class WindowsFileAttributeViews {
}
}
- static BasicFileAttributeView createBasicView(WindowsPath file, boolean followLinks) {
+ static Basic createBasicView(WindowsPath file, boolean followLinks) {
return new Basic(file, followLinks);
}
- static WindowsFileAttributeViews.Dos createDosView(WindowsPath file, boolean followLinks) {
+ static Dos createDosView(WindowsPath file, boolean followLinks) {
return new Dos(file, followLinks);
}
}
--- a/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java Mon Jun 29 15:05:15 2009 +0100
+++ b/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java Mon Jun 29 15:08:52 2009 +0100
@@ -65,7 +65,6 @@ class WindowsFileAttributes
private static final short OFFSETOF_FILE_INFORMATION_VOLSERIALNUM = 28;
private static final short OFFSETOF_FILE_INFORMATION_SIZEHIGH = 32;
private static final short OFFSETOF_FILE_INFORMATION_SIZELOW = 36;
- private static final short OFFSETOF_FILE_INFORMATION_NUMLINKS = 40;
private static final short OFFSETOF_FILE_INFORMATION_INDEXHIGH = 44;
private static final short OFFSETOF_FILE_INFORMATION_INDEXLOW = 48;
@@ -110,6 +109,9 @@ class WindowsFileAttributes
private static final short OFFSETOF_FIND_DATA_SIZELOW = 32;
private static final short OFFSETOF_FIND_DATA_RESERVED0 = 36;
+ // used to adjust values between Windows and java epoch
+ private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
+
// indicates if accurate metadata is required (interesting on NTFS only)
private static final boolean ensureAccurateMetadata;
static {
@@ -128,29 +130,33 @@ class WindowsFileAttributes
private final int reparseTag;
// additional attributes when using GetFileInformationByHandle
- private final int linkCount;
private final int volSerialNumber;
private final int fileIndexHigh;
private final int fileIndexLow;
/**
* Convert 64-bit value representing the number of 100-nanosecond intervals
- * since January 1, 1601 to java time.
- */
- private static long toJavaTime(long time) {
- time /= 10000L;
- time -= 11644473600000L;
- return time;
- }
-
- /**
- * Convert java time to 64-bit value representing the number of 100-nanosecond
+ * since January 1, 1601 to a FileTime.
+ */
+ static FileTime toFileTime(long time) {
+ // 100ns -> us
+ time /= 10L;
+ // adjust to java epoch
+ time += WINDOWS_EPOCH_IN_MICROSECONDS;
+ return FileTime.from(time, TimeUnit.MICROSECONDS);
+ }
+
+ /**
+ * Convert FileTime to 64-bit value representing the number of 100-nanosecond
* intervals since January 1, 1601.
*/
- static long toWindowsTime(long time) {
- time += 11644473600000L;
- time *= 10000L;
- return time;
+ static long toWindowsTime(FileTime time) {
+ long value = time.to(TimeUnit.MICROSECONDS);
+ // adjust to Windows epoch+= 11644473600000000L;
+ value -= WINDOWS_EPOCH_IN_MICROSECONDS;
+ // us -> 100ns
+ value *= 10L;
+ return value;
}
/**
@@ -162,7 +168,6 @@ class WindowsFileAttributes
long lastWriteTime,
long size,
int reparseTag,
- int linkCount,
int volSerialNumber,
int fileIndexHigh,
int fileIndexLow)
@@ -173,7 +178,6 @@ class WindowsFileAttributes
this.lastWriteTime = lastWriteTime;
this.size = size;
this.reparseTag = reparseTag;
- this.linkCount = linkCount;
this.volSerialNumber = volSerialNumber;
this.fileIndexHigh = fileIndexHigh;
this.fileIndexLow = fileIndexLow;
@@ -184,15 +188,11 @@ class WindowsFileAttributes
*/
private static WindowsFileAttributes fromFileInformation(long address, int reparseTag) {
int fileAttrs = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_ATTRIBUTES);
- long creationTime =
- toJavaTime(unsafe.getLong(address + OFFSETOF_FILE_INFORMATION_CREATETIME));
- long lastAccessTime =
- toJavaTime(unsafe.getLong(address + OFFSETOF_FILE_INFORMATION_LASTACCESSTIME));
- long lastWriteTime =