--- a/jdk/make/java/java/FILES_java.gmk Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/make/java/java/FILES_java.gmk Tue Feb 08 14:25:33 2011 -0800
@@ -443,7 +443,6 @@
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/jdk/make/java/nio/FILES_java.gmk Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/make/java/nio/FILES_java.gmk Tue Feb 08 14:25:33 2011 -0800
@@ -81,12 +81,12 @@
java/nio/file/ClosedDirectoryStreamException.java \
java/nio/file/ClosedFileSystemException.java \
java/nio/file/ClosedWatchServiceException.java \
+ java/nio/file/CopyMoveHelper.java \
java/nio/file/CopyOption.java \
java/nio/file/DirectoryIteratorException.java \
java/nio/file/DirectoryNotEmptyException.java \
java/nio/file/DirectoryStream.java \
java/nio/file/FileAlreadyExistsException.java \
- java/nio/file/FileRef.java \
java/nio/file/FileStore.java \
java/nio/file/FileSystem.java \
java/nio/file/FileSystemAlreadyExistsException.java \
@@ -116,6 +116,7 @@
java/nio/file/StandardCopyOption.java \
java/nio/file/StandardOpenOption.java \
java/nio/file/StandardWatchEventKind.java \
+ java/nio/file/TempFileHelper.java \
java/nio/file/WatchEvent.java \
java/nio/file/WatchKey.java \
java/nio/file/WatchService.java \
@@ -127,7 +128,6 @@
java/nio/file/attribute/AclEntryType.java \
java/nio/file/attribute/AclFileAttributeView.java \
java/nio/file/attribute/AttributeView.java \
- java/nio/file/attribute/Attributes.java \
java/nio/file/attribute/BasicFileAttributeView.java \
java/nio/file/attribute/BasicFileAttributes.java \
java/nio/file/attribute/DosFileAttributeView.java \
@@ -136,8 +136,6 @@
java/nio/file/attribute/FileAttributeView.java \
java/nio/file/attribute/FileOwnerAttributeView.java \
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 \
@@ -246,6 +244,7 @@
sun/nio/fs/AbstractAclFileAttributeView.java \
sun/nio/fs/AbstractBasicFileAttributeView.java \
sun/nio/fs/AbstractFileTypeDetector.java \
+ sun/nio/fs/AbstractFileSystemProvider.java \
sun/nio/fs/AbstractPath.java \
sun/nio/fs/AbstractPoller.java \
sun/nio/fs/AbstractUserDefinedFileAttributeView.java \
--- a/jdk/make/netbeans/common/java-data-native.ent Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/make/netbeans/common/java-data-native.ent Tue Feb 08 14:25:33 2011 -0800
@@ -31,7 +31,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
+<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
<compilation-unit>
<package-root>${root}/src/share/classes</package-root>
<package-root>${root}/src/windows/classes</package-root>
@@ -39,6 +39,6 @@
<classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
<built-to>${root}/build/${platform}-${arch}/classes</built-to>
<javadoc-built-to>${root}/build/javadoc/${name}</javadoc-built-to>
- <source-level>1.5</source-level>
+ <source-level>1.7</source-level>
</compilation-unit>
</java-data>
--- a/jdk/make/netbeans/common/java-data-no-native.ent Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/make/netbeans/common/java-data-no-native.ent Tue Feb 08 14:25:33 2011 -0800
@@ -31,12 +31,12 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
+<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
<compilation-unit>
<package-root>${root}/src/share/classes</package-root>
<classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
<built-to>${root}/build/${platform}-${arch}/classes</built-to>
<javadoc-built-to>${root}/build/javadoc/${name}</javadoc-built-to>
- <source-level>1.5</source-level>
+ <source-level>1.7</source-level>
</compilation-unit>
</java-data>
--- a/jdk/src/share/bin/java.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/bin/java.c Tue Feb 08 14:25:33 2011 -0800
@@ -244,6 +244,7 @@
for (i = 0; i < argc ; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
+ AddOption("-Dsun.java.launcher.diag=true", NULL);
}
CreateExecutionEnvironment(&argc, &argv,
@@ -1009,6 +1010,8 @@
} else if (JLI_StrCmp(arg, "-XshowSettings") == 0 ||
JLI_StrCCmp(arg, "-XshowSettings:") == 0) {
showSettings = arg;
+ } else if (JLI_StrCmp(arg, "-Xdiag") == 0) {
+ AddOption("-Dsun.java.launcher.diag=true", NULL);
/*
* The following case provide backward compatibility with old-style
* command line options.
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Tue Feb 08 14:25:33 2011 -0800
@@ -656,14 +656,17 @@
}
nparent = notifyParent;
}
- }
- if (nparent) {
- LdapRequest ldr = pendingRequests;
- while (ldr != null) {
- ldr.notify();
- ldr = ldr.next;
+ if (nparent) {
+ LdapRequest ldr = pendingRequests;
+ while (ldr != null) {
+
+ synchronized (ldr) {
+ ldr.notify();
+ ldr = ldr.next;
+ }
+ }
+ parent.processConnectionClosure();
}
- parent.processConnectionClosure();
}
}
--- a/jdk/src/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java Tue Feb 08 14:25:33 2011 -0800
@@ -143,7 +143,7 @@
e.setRemainingName(remainingName);
e.setResolvedObj(resolvedObj);
- if (starter == null)
+ if (starter == null || starter.isEmpty())
e.setResolvedName(null);
else if (remainingName == null)
e.setResolvedName(starter);
--- a/jdk/src/share/classes/java/io/BufferedReader.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/io/BufferedReader.java Tue Feb 08 14:25:33 2011 -0800
@@ -54,6 +54,7 @@
*
* @see FileReader
* @see InputStreamReader
+ * @see java.nio.file.Files#newBufferedReader
*
* @author Mark Reinhold
* @since JDK1.1
@@ -374,6 +375,8 @@
* stream has been reached
*
* @exception IOException If an I/O error occurs
+ *
+ * @see java.nio.file.Files#readAllLines
*/
public String readLine() throws IOException {
return readLine(false);
--- a/jdk/src/share/classes/java/io/BufferedWriter.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/io/BufferedWriter.java Tue Feb 08 14:25:33 2011 -0800
@@ -57,6 +57,7 @@
* @see PrintWriter
* @see FileWriter
* @see OutputStreamWriter
+ * @see java.nio.file.Files#newBufferedWriter
*
* @author Mark Reinhold
* @since JDK1.1
--- a/jdk/src/share/classes/java/io/File.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/io/File.java Tue Feb 08 14:25:33 2011 -0800
@@ -35,8 +35,7 @@
import java.security.AccessController;
import java.security.SecureRandom;
import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.FileAttribute;
+import java.nio.file.FileSystems;
import sun.security.action.GetPropertyAction;
/**
@@ -139,9 +138,10 @@
* many of the limitations of the {@code java.io.File} class.
* The {@link #toPath toPath} method may be used to obtain a {@link
* Path} that uses the abstract path represented by a {@code File} object to
- * locate a file. The resulting {@code Path} provides more efficient and
- * extensive access to file attributes, additional file operations, and I/O
- * exceptions to help diagnose errors when an operation on a file fails.
+ * locate a file. The resulting {@code Path} may be used with the {@link
+ * java.nio.file.Files} class to provide more efficient and extensive access to
+ * additional file operations, file attributes, and I/O exceptions to help
+ * diagnose errors when an operation on a file fails.
*
* @author unascribed
* @since JDK1.0
@@ -778,6 +778,12 @@
* Tests whether the file denoted by this abstract pathname is a
* directory.
*
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * that the file is not a directory, or where several attributes of the
+ * same file are required at the same time, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return <code>true</code> if and only if the file denoted by this
* abstract pathname exists <em>and</em> is a directory;
* <code>false</code> otherwise
@@ -786,8 +792,6 @@
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public boolean isDirectory() {
SecurityManager security = System.getSecurityManager();
@@ -804,6 +808,12 @@
* addition, satisfies other system-dependent criteria. Any non-directory
* file created by a Java application is guaranteed to be a normal file.
*
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * that the file is not a normal file, or where several attributes of the
+ * same file are required at the same time, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return <code>true</code> if and only if the file denoted by this
* abstract pathname exists <em>and</em> is a normal file;
* <code>false</code> otherwise
@@ -812,8 +822,6 @@
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public boolean isFile() {
SecurityManager security = System.getSecurityManager();
@@ -853,6 +861,13 @@
* Returns the time that the file denoted by this abstract pathname was
* last modified.
*
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * where {@code 0L} is returned, or where several attributes of the
+ * same file are required at the same time, or where the time of last
+ * access or the creation time are required, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return A <code>long</code> value representing the time the file was
* last modified, measured in milliseconds since the epoch
* (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
@@ -862,8 +877,6 @@
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public long lastModified() {
SecurityManager security = System.getSecurityManager();
@@ -877,6 +890,12 @@
* Returns the length of the file denoted by this abstract pathname.
* The return value is unspecified if this pathname denotes a directory.
*
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * that {@code 0L} is returned, or where several attributes of the same file
+ * are required at the same time, then the {@link
+ * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+ * Files.readAttributes} method may be used.
+ *
* @return The length, in bytes, of the file denoted by this abstract
* pathname, or <code>0L</code> if the file does not exist. Some
* operating systems may return <code>0L</code> for pathnames
@@ -886,8 +905,6 @@
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
- *
- * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
*/
public long length() {
SecurityManager security = System.getSecurityManager();
@@ -937,11 +954,10 @@
* this pathname denotes a directory, then the directory must be empty in
* order to be deleted.
*
- * <p> Note that the {@link Path} class defines the {@link Path#delete
- * delete} method to throw an {@link IOException} when a file cannot be
- * deleted. This is useful for error reporting and to diagnose why a file
- * cannot be deleted. The {@link #toPath toPath} method may be used to
- * obtain a {@code Path} representing this abstract pathname.
+ * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+ * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException}
+ * when a file cannot be deleted. This is useful for error reporting and to
+ * diagnose why a file cannot be deleted.
*
* @return <code>true</code> if and only if the file or directory is
* successfully deleted; <code>false</code> otherwise
@@ -1009,12 +1025,11 @@
* will appear in any specific order; they are not, in particular,
* guaranteed to appear in alphabetical order.
*
- * <p> Note that the {@link Path} class defines the {@link
- * Path#newDirectoryStream newDirectoryStream} method to open a directory
- * and iterate over the names of the files in the directory. This may use
- * less resources when working with very large directories. The {@link
- * #toPath toPath} method may be used to obtain a {@code Path} representing
- * this abstract pathname.
+ * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+ * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to
+ * open a directory and iterate over the names of the files in the directory.
+ * This may use less resources when working with very large directories, and
+ * may be more responsive when working with remote directories.
*
* @return An array of strings naming the files and directories in the
* directory denoted by this abstract pathname. The array will be
@@ -1061,6 +1076,8 @@
* If a security manager exists and its {@link
* SecurityManager#checkRead(String)} method denies read access to
* the directory
+ *
+ * @see java.nio.file.Files#newDirectoryStream(Path,String)
*/
public String[] list(FilenameFilter filter) {
String names[] = list();
@@ -1095,12 +1112,11 @@
* will appear in any specific order; they are not, in particular,
* guaranteed to appear in alphabetical order.
*
- * <p> Note that the {@link Path} class defines the {@link
- * Path#newDirectoryStream newDirectoryStream} method to open a directory
- * and iterate over the names of the files in the directory. This may use
- * less resources when working with very large directories. The {@link
- * #toPath toPath} method may be used to obtain a {@code Path} representing
- * this abstract pathname.
+ * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+ * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method
+ * to open a directory and iterate over the names of the files in the
+ * directory. This may use less resources when working with very large
+ * directories.
*
* @return An array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname.
@@ -1154,6 +1170,7 @@
* the directory
*
* @since 1.2
+ * @see java.nio.file.Files#newDirectoryStream(Path,String)
*/
public File[] listFiles(FilenameFilter filter) {
String ss[] = list();
@@ -1191,6 +1208,7 @@
* the directory
*
* @since 1.2
+ * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter)
*/
public File[] listFiles(FileFilter filter) {
String ss[] = list();
@@ -1207,12 +1225,6 @@
/**
* Creates the directory named by this abstract pathname.
*
- * <p> Note that the {@link Path} class defines the {@link Path#createDirectory
- * createDirectory} method to throw an {@link IOException} when a directory
- * cannot be created. This is useful for error reporting and to diagnose why
- * a directory cannot be created. The {@link #toPath toPath} method may be
- * used to obtain a {@code Path} representing this abstract pathname.
- *
* @return <code>true</code> if and only if the directory was
* created; <code>false</code> otherwise
*
@@ -1278,10 +1290,9 @@
* already exists. The return value should always be checked to make sure
* that the rename operation was successful.
*
- * <p> Note that the {@link Path} class defines the {@link Path#moveTo
- * moveTo} method to move or rename a file in a platform independent manner.
- * The {@link #toPath toPath} method may be used to obtain a {@code Path}
- * representing this abstract pathname.
+ * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+ * java.nio.file.Files#move move} method to move or rename a file in a
+ * platform independent manner.
*
* @param dest The new abstract pathname for the named file
*
@@ -1369,10 +1380,9 @@
* Sets the owner's or everybody's write permission for this abstract
* pathname.
*
- * <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.
+ * <p> The {@link java.nio.file.Files} 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
@@ -1437,10 +1447,9 @@
* Sets the owner's or everybody's read permission for this abstract
* pathname.
*
- * <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.
+ * <p> The {@link java.nio.file.Files} 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
@@ -1511,10 +1520,9 @@
* Sets the owner's or everybody's execute permission for this abstract
* pathname.
*
- * <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.
+ * <p> The {@link java.nio.file.Files} 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
@@ -1646,6 +1654,7 @@
* filesystem roots.
*
* @since 1.2
+ * @see java.nio.file.FileStore
*/
public static File[] listRoots() {
return fs.listRoots();
@@ -1753,7 +1762,7 @@
/* -- Temporary files -- */
- static class TempDirectory {
+ private static class TempDirectory {
private TempDirectory() { }
// temporary directory location
@@ -1880,11 +1889,12 @@
* 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.
+ * <p> The {@link
+ * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[])
+ * Files.createTempFile} 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
@@ -1907,6 +1917,7 @@
* method does not allow a file to be created
*
* @since 1.2
+ * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[])
*/
public static File createTempFile(String prefix, String suffix)
throws IOException
@@ -1914,61 +1925,6 @@
return createTempFile(prefix, suffix, null);
}
- /**
- * Creates an empty file in the default temporary-file directory, using
- * 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
- * name; must be at least three characters long
- * @param suffix
- * 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 attrs
- * An optional list of file attributes to set atomically when creating
- * the file
- *
- * @return An abstract pathname denoting a newly-created empty file
- *
- * @throws IllegalArgumentException
- * If the {@code prefix} argument contains fewer than three
- * characters
- * @throws UnsupportedOperationException
- * If the array contains an attribute that cannot be set atomically
- * when creating the file
- * @throws IOException
- * If a file could not be created
- * @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.
- *
- * @since 1.7
- */
- 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;
- return TempFileHelper.createFile(prefix, suffix, attrs);
- }
-
/* -- Basic infrastructure -- */
/**
@@ -2104,6 +2060,7 @@
* path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
*
* @since 1.7
+ * @see Path#toFile
*/
public Path toPath() {
Path result = filePath;
@@ -2111,12 +2068,7 @@
synchronized (this) {
result = filePath;
if (result == null) {
- if (path.length() == 0) {
- // assume default file system treats "." as current directory
- result = Paths.get(".");
- } else {
- result = Paths.get(path);
- }
+ result = FileSystems.getDefault().getPath(path);
filePath = result;
}
}
--- a/jdk/src/share/classes/java/io/FileInputStream.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/io/FileInputStream.java Tue Feb 08 14:25:33 2011 -0800
@@ -42,6 +42,7 @@
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileOutputStream
+ * @see java.nio.file.Files#newInputStream
* @since JDK1.0
*/
public
--- a/jdk/src/share/classes/java/io/FileOutputStream.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/io/FileOutputStream.java Tue Feb 08 14:25:33 2011 -0800
@@ -46,6 +46,7 @@
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileInputStream
+ * @see java.nio.file.Files#newOutputStream
* @since JDK1.0
*/
public
--- a/jdk/src/share/classes/java/io/FilePermission.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/io/FilePermission.java Tue Feb 08 14:25:33 2011 -0800
@@ -72,7 +72,7 @@
* <DT> readlink
* <DD> read link permission. Allows the target of a
* <a href="../nio/file/package-summary.html#links">symbolic link</a>
- * to be read by invoking the {@link java.nio.file.Path#readSymbolicLink
+ * to be read by invoking the {@link java.nio.file.Files#readSymbolicLink
* readSymbolicLink } method.
* </DL>
* <P>
--- a/jdk/src/share/classes/java/io/PrintStream.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/io/PrintStream.java Tue Feb 08 14:25:33 2011 -0800
@@ -70,11 +70,11 @@
private OutputStreamWriter charOut;
/**
- * nonNull is explicitly declared here so as not to create an extra
- * dependency on java.util.Objects.nonNull. PrintStream is loaded
+ * requireNonNull is explicitly declared here so as not to create an extra
+ * dependency on java.util.Objects.requireNonNull. PrintStream is loaded
* early during system initialization.
*/
- private static <T> T nonNull(T obj, String message) {
+ private static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
@@ -88,7 +88,7 @@
private static Charset toCharset(String csn)
throws UnsupportedEncodingException
{
- nonNull(csn, "charsetName");
+ requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
@@ -148,7 +148,7 @@
* @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
*/
public PrintStream(OutputStream out, boolean autoFlush) {
- this(autoFlush, nonNull(out, "Null output stream"));
+ this(autoFlush, requireNonNull(out, "Null output stream"));
}
/**
@@ -173,7 +173,7 @@
throws UnsupportedEncodingException
{
this(autoFlush,
- nonNull(out, "Null output stream"),
+ requireNonNull(out, "Null output stream"),
toCharset(encoding));
}
--- a/jdk/src/share/classes/java/io/PrintWriter.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/io/PrintWriter.java Tue Feb 08 14:25:33 2011 -0800
@@ -82,7 +82,7 @@
private static Charset toCharset(String csn)
throws UnsupportedEncodingException
{
- Objects.nonNull(csn, "charsetName");
+ Objects.requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
--- a/jdk/src/share/classes/java/io/SerialCallbackContext.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/io/SerialCallbackContext.java Tue Feb 08 14:25:33 2011 -0800
@@ -54,5 +54,3 @@
thread = null;
}
}
-
-
--- a/jdk/src/share/classes/java/io/TempFileHelper.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.io;
-
-import java.nio.file.FileSystems;
-import java.nio.file.InvalidPathException;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.file.attribute.PosixFilePermission;
-import java.nio.file.attribute.PosixFilePermissions;
-import static java.nio.file.attribute.PosixFilePermission.*;
-import java.util.Set;
-import java.util.EnumSet;
-
-/**
- * Helper class to support creation of temporary files and directory with
- * initial attributes.
- */
-
-class TempFileHelper {
- private TempFileHelper() { }
-
- // default file and directory permissions (lazily initialized)
- private static class PermissionsHolder {
- static final boolean hasPosixPermissions = FileSystems.getDefault()
- .supportedFileAttributeViews().contains("posix");
- static final FileAttribute<Set<PosixFilePermission>> filePermissions =
- PosixFilePermissions.asFileAttribute(EnumSet.of(OWNER_READ, OWNER_WRITE));
- static final FileAttribute<Set<PosixFilePermission>> directoryPermissions =
- PosixFilePermissions.asFileAttribute(EnumSet
- .of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE));
- }
-
- /**
- * Creates a file or directory in the temporary directory.
- */
- private static File create(String prefix,
- String suffix,
- FileAttribute[] attrs,
- boolean isDirectory)
- throws IOException
- {
- // in POSIX environments use default file and directory permissions
- // if initial permissions not given by caller.
- if (PermissionsHolder.hasPosixPermissions) {
- if (attrs.length == 0) {
- // no attributes so use default permissions
- attrs = new FileAttribute<?>[1];
- attrs[0] = (isDirectory) ? PermissionsHolder.directoryPermissions :
- PermissionsHolder.filePermissions;
- } 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] = (isDirectory) ?
- PermissionsHolder.directoryPermissions :
- PermissionsHolder.filePermissions;
- }
- }
- }
-
- // loop generating random names until file or directory can be created
- SecurityManager sm = System.getSecurityManager();
- for (;;) {
- File tmpdir = File.TempDirectory.location();
- File f = File.TempDirectory.generateFile(prefix, suffix, tmpdir);
- try {
- if (isDirectory) {
- f.toPath().createDirectory(attrs);
- } else {
- f.toPath().createFile(attrs);
- }
- 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
- }
- }
- }
-
- /**
- * Creates a file in the temporary directory.
- */
- static File createFile(String prefix, String suffix, FileAttribute[] attrs)
- throws IOException
- {
- return create(prefix, suffix, attrs, false);
- }
-
- /**
- * Creates a directory in the temporary directory.
- */
- static File createDirectory(String prefix, FileAttribute[] attrs)
- throws IOException
- {
- return create(prefix, "", attrs, true);
- }
-}
--- a/jdk/src/share/classes/java/lang/StackTraceElement.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/lang/StackTraceElement.java Tue Feb 08 14:25:33 2011 -0800
@@ -68,8 +68,8 @@
*/
public StackTraceElement(String declaringClass, String methodName,
String fileName, int lineNumber) {
- this.declaringClass = Objects.nonNull(declaringClass, "Declaring class is null");
- this.methodName = Objects.nonNull(methodName, "Method name is null");
+ this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
+ this.methodName = Objects.requireNonNull(methodName, "Method name is null");
this.fileName = fileName;
this.lineNumber = lineNumber;
}
--- a/jdk/src/share/classes/java/lang/SuppressWarnings.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/lang/SuppressWarnings.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,7 @@
* @since 1.5
* @author Josh Bloch
*/
-@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER})
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
/**
--- a/jdk/src/share/classes/java/lang/annotation/ElementType.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/lang/annotation/ElementType.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,12 +40,6 @@
/** 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/jdk/src/share/classes/java/math/BigDecimal.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/math/BigDecimal.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -121,8 +121,8 @@
* scale for each operation is listed in the table below.
*
* <table border>
- * <caption top><h3>Preferred Scales for Results of Arithmetic Operations
- * </h3></caption>
+ * <caption><b>Preferred Scales for Results of Arithmetic Operations
+ * </b></caption>
* <tr><th>Operation</th><th>Preferred Scale of Result</th></tr>
* <tr><td>Add</td><td>max(addend.scale(), augend.scale())</td>
* <tr><td>Subtract</td><td>max(minuend.scale(), subtrahend.scale())</td>
@@ -661,25 +661,25 @@
* <dd>{@code .} <i>FractionPart</i>
* <dd><i>IntegerPart</i>
* <p>
- * <dt><i>IntegerPart:
- * <dd>Digits</i>
+ * <dt><i>IntegerPart:</i>
+ * <dd><i>Digits</i>
* <p>
- * <dt><i>FractionPart:
- * <dd>Digits</i>
+ * <dt><i>FractionPart:</i>
+ * <dd><i>Digits</i>
* <p>
- * <dt><i>Exponent:
- * <dd>ExponentIndicator SignedInteger</i>
+ * <dt><i>Exponent:</i>
+ * <dd><i>ExponentIndicator SignedInteger</i>
* <p>
* <dt><i>ExponentIndicator:</i>
* <dd>{@code e}
* <dd>{@code E}
* <p>
- * <dt><i>SignedInteger:
- * <dd>Sign<sub>opt</sub> Digits</i>
+ * <dt><i>SignedInteger:</i>
+ * <dd><i>Sign<sub>opt</sub> Digits</i>
* <p>
- * <dt><i>Digits:
- * <dd>Digit
- * <dd>Digits Digit</i>
+ * <dt><i>Digits:</i>
+ * <dd><i>Digit</i>
+ * <dd><i>Digits Digit</i>
* <p>
* <dt><i>Digit:</i>
* <dd>any character for which {@link Character#isDigit}
--- a/jdk/src/share/classes/java/math/RoundingMode.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/math/RoundingMode.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,7 @@
*
*<p>
*<table border>
- * <caption top><h3>Summary of Rounding Operations Under Different Rounding Modes</h3></caption>
+ * <caption><b>Summary of Rounding Operations Under Different Rounding Modes</b></caption>
* <tr><th></th><th colspan=8>Result of rounding input to one digit with the given
* rounding mode</th>
* <tr valign=top>
--- a/jdk/src/share/classes/java/nio/channels/FileChannel.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/channels/FileChannel.java Tue Feb 08 14:25:33 2011 -0800
@@ -248,7 +248,7 @@
* FileSystemProvider#newFileChannel newFileChannel} method on the
* provider that created the {@code Path}.
*
- * @param file
+ * @param path
* The path of the file to open or create
* @param options
* Options specifying how the file is opened
@@ -261,7 +261,7 @@
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
* @throws UnsupportedOperationException
- * If the {@code file} is associated with a provider that does not
+ * If the {@code path} is associated with a provider that does not
* support creating file channels, or an unsupported open option is
* specified, or the array contains an attribute that cannot be set
* atomically when creating the file
@@ -278,13 +278,13 @@
*
* @since 1.7
*/
- public static FileChannel open(Path file,
+ public static FileChannel open(Path path,
Set<? extends OpenOption> options,
FileAttribute<?>... attrs)
throws IOException
{
- FileSystemProvider provider = file.getFileSystem().provider();
- return provider.newFileChannel(file, options, attrs);
+ FileSystemProvider provider = path.getFileSystem().provider();
+ return provider.newFileChannel(path, options, attrs);
}
private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
@@ -295,10 +295,12 @@
* <p> An invocation of this method behaves in exactly the same way as the
* invocation
* <pre>
- * fc.{@link #open(Path,Set,FileAttribute[]) open}(file, options, new FileAttribute<?>[0]);
+ * fc.{@link #open(Path,Set,FileAttribute[]) open}(file, opts, new FileAttribute<?>[0]);
* </pre>
+ * where {@code opts} is a set of the options specified in the {@code
+ * options} array.
*
- * @param file
+ * @param path
* The path of the file to open or create
* @param options
* Options specifying how the file is opened
@@ -308,7 +310,7 @@
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
* @throws UnsupportedOperationException
- * If the {@code file} is associated with a provider that does not
+ * If the {@code path} is associated with a provider that does not
* support creating file channels, or an unsupported open option is
* specified
* @throws IOException
@@ -324,12 +326,12 @@
*
* @since 1.7
*/
- public static FileChannel open(Path file, OpenOption... options)
+ public static FileChannel open(Path path, OpenOption... options)
throws IOException
{
Set<OpenOption> set = new HashSet<OpenOption>(options.length);
Collections.addAll(set, options);
- return open(file, set, NO_ATTRIBUTES);
+ return open(path, set, NO_ATTRIBUTES);
}
// -- Channel operations --
--- a/jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java Tue Feb 08 14:25:33 2011 -0800
@@ -47,7 +47,7 @@
* so that method invocations on the implementation class can be chained.
*
* @since 1.7
- * @see java.nio.file.Path#newByteChannel
+ * @see java.nio.file.Files#newByteChannel
*/
public interface SeekableByteChannel
--- a/jdk/src/share/classes/java/nio/file/AccessMode.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/AccessMode.java Tue Feb 08 14:25:33 2011 -0800
@@ -29,8 +29,6 @@
* Defines access modes used to test the accessibility of a file.
*
* @since 1.7
- *
- * @see Path#checkAccess
*/
public enum AccessMode {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/CopyMoveHelper.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Helper class to support copying or moving files when the source and target
+ * are associated with different providers.
+ */
+
+class CopyMoveHelper {
+ private CopyMoveHelper() { }
+
+ /**
+ * Parses the arguments for a file copy operation.
+ */
+ private static class CopyOptions {
+ boolean replaceExisting = false;
+ boolean copyAttributes = false;
+ boolean followLinks = true;
+
+ private CopyOptions() { }
+
+ static CopyOptions parse(CopyOption... options) {
+ CopyOptions result = new CopyOptions();
+ for (CopyOption option: options) {
+ if (option == StandardCopyOption.REPLACE_EXISTING) {
+ result.replaceExisting = true;
+ continue;
+ }
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ result.followLinks = false;
+ continue;
+ }
+ if (option == StandardCopyOption.COPY_ATTRIBUTES) {
+ result.copyAttributes = true;
+ continue;
+ }
+ if (option == null)
+ throw new NullPointerException();
+ throw new UnsupportedOperationException("'" + option +
+ "' is not a recognized copy option");
+ }
+ return result;
+ }
+ }
+
+ /**
+ * Converts the given array of options for moving a file to options suitable
+ * for copying the file when a move is implemented as copy + delete.
+ */
+ private static CopyOption[] convertMoveToCopyOptions(CopyOption... options)
+ throws AtomicMoveNotSupportedException
+ {
+ int len = options.length;
+ CopyOption[] newOptions = new CopyOption[len+2];
+ for (int i=0; i<len; i++) {
+ CopyOption option = options[i];
+ if (option == StandardCopyOption.ATOMIC_MOVE) {
+ throw new AtomicMoveNotSupportedException(null, null,
+ "Atomic move between providers is not supported");
+ }
+ newOptions[i] = option;
+ }
+ newOptions[len] = LinkOption.NOFOLLOW_LINKS;
+ newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
+ return newOptions;
+ }
+
+ /**
+ * Simple copy for use when source and target are associated with different
+ * providers
+ */
+ static void copyToForeignTarget(Path source, Path target,
+ CopyOption... options)
+ throws IOException
+ {
+ CopyOptions opts = CopyOptions.parse(options);
+ LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
+ new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
+
+ // attributes of source file
+ BasicFileAttributes attrs = Files.readAttributes(source,
+ BasicFileAttributes.class,
+ linkOptions);
+ if (attrs.isSymbolicLink())
+ throw new IOException("Copying of symbolic links not supported");
+
+ // delete target if it exists and REPLACE_EXISTING is specified
+ if (opts.replaceExisting) {
+ Files.deleteIfExists(target);
+ } else if (Files.exists(target))
+ throw new FileAlreadyExistsException(target.toString());
+
+ // create directory or copy file
+ if (attrs.isDirectory()) {
+ Files.createDirectory(target);
+ } else {
+ try (InputStream in = Files.newInputStream(source)) {
+ Files.copy(in, target);
+ }
+ }
+
+ // copy basic attributes to target
+ if (opts.copyAttributes) {
+ BasicFileAttributeView view =
+ Files.getFileAttributeView(target, BasicFileAttributeView.class, linkOptions);
+ try {
+ view.setTimes(attrs.lastModifiedTime(),
+ attrs.lastAccessTime(),
+ attrs.creationTime());
+ } catch (IOException x) {
+ // rollback
+ try {
+ Files.delete(target);
+ } catch (IOException ignore) { }
+ throw x;
+ }
+ }
+ }
+
+ /**
+ * Simple move implements as copy+delete for use when source and target are
+ * associated with different providers
+ */
+ static void moveToForeignTarget(Path source, Path target,
+ CopyOption... options) throws IOException
+ {
+ copyToForeignTarget(source, target, convertMoveToCopyOptions(options));
+ Files.delete(source);
+ }
+}
--- a/jdk/src/share/classes/java/nio/file/CopyOption.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/CopyOption.java Tue Feb 08 14:25:33 2011 -0800
@@ -28,8 +28,12 @@
/**
* An object that configures how to copy or move a file.
*
- * <p> Objects of this type may be used with the {@link Path#copyTo copyTo} and
- * {@link Path#moveTo moveTo} methods to configure how a file is copied or moved.
+ * <p> Objects of this type may be used with the {@link
+ * Files#copy(Path,Path,CopyOption[]) Files.copy(Path,Path,CopyOption...)},
+ * {@link Files#copy(java.io.InputStream,Path,CopyOption[])
+ * Files.copy(InputStream,Path,CopyOption...)} and {@link Files#move
+ * Files.move(Path,Path,CopyOption...)} methods to configure how a file is
+ * copied or moved.
*
* <p> The {@link StandardCopyOption} enumeration type defines the
* <i>standard</i> options.
--- a/jdk/src/share/classes/java/nio/file/DirectoryIteratorException.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/DirectoryIteratorException.java Tue Feb 08 14:25:33 2011 -0800
@@ -56,7 +56,7 @@
* if the cause is {@code null}
*/
public DirectoryIteratorException(IOException cause) {
- super(Objects.nonNull(cause));
+ super(Objects.requireNonNull(cause));
}
/**
--- a/jdk/src/share/classes/java/nio/file/DirectoryStream.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/DirectoryStream.java Tue Feb 08 14:25:33 2011 -0800
@@ -54,7 +54,7 @@
* construct to ensure that the stream is closed:
* <pre>
* Path dir = ...
- * try (DirectoryStream<Path> stream = dir.newDirectoryStream()) {
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
* for (Path entry: stream) {
* ...
* }
@@ -97,8 +97,8 @@
* both the for-each and try-with-resources constructs.
* <pre>
* List<Path> listSourceFiles(Path dir) throws IOException {
- * List<Path> result = new ArrayList<Path>();
- * try (DirectoryStream<Path> stream = dir.newDirectoryStream("*.{c,h,cpp,hpp,java}")) {
+ * List<Path> result = new ArrayList<>();
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
* for (Path entry: stream) {
* result.add(entry);
* }
@@ -113,7 +113,7 @@
*
* @since 1.7
*
- * @see Path#newDirectoryStream
+ * @see Files#newDirectoryStream(Path)
*/
public interface DirectoryStream<T>
@@ -122,9 +122,9 @@
/**
* An interface that is implemented by objects that decide if a directory
* entry should be accepted or filtered. A {@code Filter} is passed as the
- * parameter to the {@link Path#newDirectoryStream(DirectoryStream.Filter)
- * newDirectoryStream} method when opening a directory to iterate over the
- * entries in the directory.
+ * parameter to the {@link Files#newDirectoryStream(Path,DirectoryStream.Filter)}
+ * method when opening a directory to iterate over the entries in the
+ * directory.
*
* @param <T> the type of the directory entry
*
--- a/jdk/src/share/classes/java/nio/file/FileRef.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file;
-
-import java.nio.file.attribute.*;
-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
- * open the file for reading or writing. It also provides access to associated
- * metadata or file attributes.
- *
- * @since 1.7
- * @see java.nio.file.attribute.Attributes
- * @see java.io.File#toPath
- */
-
-public interface FileRef {
-
- /**
- * 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.
- * 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 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 {@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.
- *
- * <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 the file
- * attribute view defines type-safe methods to read or update the file
- * attributes. The {@code type} parameter is the type of the attribute view
- * required and the method returns an instance of that type if supported.
- * The {@link BasicFileAttributeView} type supports access to the basic
- * attributes of a file. Invoking this method to select a file attribute
- * view of that type will always return an instance of that class.
- *
- * <p> The {@code options} array may be used to indicate how symbolic links
- * are handled by the resulting file attribute view for the case that the
- * file is a symbolic link. By default, symbolic links are followed. If the
- * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
- * symbolic links are not followed. This option is ignored by implementations
- * that do not support symbolic links.
- *
- * @param type
- * the {@code Class} object corresponding to the file attribute view
- * @param options
- * options indicating how symbolic links are handled
- *
- * @return a file attribute view of the specified type, or {@code null} if
- * the attribute view type is not available
- *
- * @throws UnsupportedOperationException
- * If options contains an unsupported option. This exception is
- * specified to allow the {@code LinkOption} enum be extended
- * in future releases.
- *
- * @see Attributes#readBasicFileAttributes
- */
- <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
- 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 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 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.
- */
- Map<String,?> readAttributes(String attributes, LinkOption... options)
- throws IOException;
-}
--- a/jdk/src/share/classes/java/nio/file/FileStore.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileStore.java Tue Feb 08 14:25:33 2011 -0800
@@ -32,16 +32,13 @@
* 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 Path#getFileStore getFileStore} method, or all file
+ * by invoking the {@link Files#getFileStore getFileStore} method, or all file
* stores can be enumerated by invoking the {@link FileSystem#getFileStores
* getFileStores} method.
*
* <p> In addition to the methods defined by this class, a file store may support
* one or more {@link FileStoreAttributeView FileStoreAttributeView} classes
* that provide a read-only or updatable view of a set of file store attributes.
- * File stores associated with the default provider support the {@link
- * FileStoreSpaceAttributeView} to read the space related attributes of the
- * file store.
*
* @since 1.7
*/
@@ -87,6 +84,51 @@
public abstract boolean isReadOnly();
/**
+ * Returns the size, in bytes, of the file store.
+ *
+ * @return the size of the file store, in bytes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getTotalSpace() throws IOException;
+
+ /**
+ * Returns the number of bytes available to this Java virtual machine on the
+ * file store.
+ *
+ * <p> The returned number of available bytes is a hint, but not a
+ * guarantee, that it is possible to use most or any of these bytes. The
+ * number of usable bytes is most likely to be accurate immediately
+ * after the space attributes are obtained. It is likely to be made inaccurate
+ * by any external I/O operations including those made on the system outside
+ * of this Java virtual machine.
+ *
+ * @return the number of bytes available
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getUsableSpace() throws IOException;
+
+ /**
+ * Returns the number of unallocated bytes in the file store.
+ *
+ * <p> The returned number of unallocated bytes is a hint, but not a
+ * guarantee, that it is possible to use most or any of these bytes. The
+ * number of unallocated bytes is most likely to be accurate immediately
+ * after the space attributes are obtained. It is likely to be
+ * made inaccurate by any external I/O operations including those made on
+ * the system outside of this virtual machine.
+ *
+ * @return the number of unallocated bytes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getUnallocatedSpace() throws IOException;
+
+ /**
* Tells whether or not this file store supports the file attributes
* identified by the given file attribute view.
*
@@ -131,12 +173,6 @@
* The {@code type} parameter is the type of the attribute view required and
* the method returns an instance of that type if supported.
*
- * <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 FileStoreSpaceAttributeView.class} will
- * always return an instance of that class.
- *
* @param type
* the {@code Class} object corresponding to the attribute view
*
@@ -160,10 +196,6 @@
* 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.
- *
* <p> <b>Usage Example:</b>
* Suppose we want to know if ZFS compression is enabled (assuming the "zfs"
* view is supported):
--- a/jdk/src/share/classes/java/nio/file/FileSystem.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileSystem.java Tue Feb 08 14:25:33 2011 -0800
@@ -38,8 +38,8 @@
* <p> The default file system, obtained by invoking the {@link FileSystems#getDefault
* FileSystems.getDefault} method, provides access to the file system that is
* accessible to the Java virtual machine. The {@link FileSystems} class defines
- * methods to create file systems that provide access to other types of file
- * systems.
+ * methods to create file systems that provide access to other types of (custom)
+ * file systems.
*
* <p> A file system is the factory for several types of objects:
*
@@ -214,10 +214,9 @@
* Suppose we want to print the space usage for all file stores:
* <pre>
* for (FileStore store: FileSystems.getDefault().getFileStores()) {
- * FileStoreSpaceAttributes attrs = Attributes.readFileStoreSpaceAttributes(store);
- * long total = attrs.totalSpace() / 1024;
- * long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / 1024;
- * long avail = attrs.usableSpace() / 1024;
+ * long total = store.getTotalSpace() / 1024;
+ * long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024;
+ * long avail = store.getUsableSpace() / 1024;
* System.out.format("%-20s %12d %12d %12d%n", store, total, used, avail);
* }
* </pre>
@@ -244,7 +243,20 @@
public abstract Set<String> supportedFileAttributeViews();
/**
- * Converts a path string to a {@code Path}.
+ * Converts a path string, or a sequence of strings that when joined form
+ * a path string, to a {@code Path}. If {@code more} does not specify any
+ * elements then the value of the {@code first} parameter is the path string
+ * to convert. If {@code more} specifies one or more elements then each
+ * non-empty string, including {@code first}, is considered to be a sequence
+ * of name elements (see {@link Path}) and is joined to form a path string.
+ * The details as to how the Strings are joined is provider specific but
+ * typically they will be joined using the {@link #getSeparator
+ * name-separator} as the separator. For example, if the name separator is
+ * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+ * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+ * A {@code Path} representing an empty path is returned if {@code first}
+ * is the empty string and {@code more} does not contain any non-empty
+ * strings.
*
* <p> The parsing and conversion to a path object is inherently
* implementation dependent. In the simplest case, the path string is rejected,
@@ -270,18 +282,17 @@
* index} value indicating the first position in the {@code path} parameter
* that caused the path string to be rejected.
*
- * <p> Invoking this method with an empty path string throws
- * {@code InvalidPathException}.
+ * @param first
+ * the path string or initial part of the path string
+ * @param more
+ * additional strings to be joined to form the path string
*
- * @param path
- * The path string
- *
- * @return A {@code Path} object
+ * @return the resulting {@code Path}
*
* @throws InvalidPathException
* If the path string cannot be converted
*/
- public abstract Path getPath(String path);
+ public abstract Path getPath(String first, String... more);
/**
* Returns a {@code PathMatcher} that performs match operations on the
@@ -290,9 +301,9 @@
*
* The {@code syntaxAndPattern} parameter identifies the syntax and the
* pattern and takes the form:
- * <blockquote>
+ * <blockquote><pre>
* <i>syntax</i><b>:</b><i>pattern</i>
- * </blockquote>
+ * </pre></blockquote>
* where {@code ':'} stands for itself.
*
* <p> A {@code FileSystem} implementation supports the "{@code glob}" and
@@ -409,7 +420,7 @@
* @throws UnsupportedOperationException
* If the pattern syntax is not known to the implementation
*
- * @see Path#newDirectoryStream(String)
+ * @see Files#newDirectoryStream(Path,String)
*/
public abstract PathMatcher getPathMatcher(String syntaxAndPattern);
@@ -421,10 +432,8 @@
* <p> <b>Usage Example:</b>
* Suppose we want to make "joe" the owner of a file:
* <pre>
- * Path file = ...
- * UserPrincipal joe = file.getFileSystem().getUserPrincipalLookupService()
- * .lookupPrincipalByName("joe");
- * Attributes.setOwner(file, joe);
+ * UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
+ * Files.setOwner(path, lookupService.lookupPrincipalByName("joe"));
* </pre>
*
* @throws UnsupportedOperationException
--- a/jdk/src/share/classes/java/nio/file/FileSystems.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileSystems.java Tue Feb 08 14:25:33 2011 -0800
@@ -164,8 +164,8 @@
* to the first provider instance. The third provider class is instantiated
* by invoking it with a reference to the second instance, and so on. The
* last provider to be instantiated becomes the default provider; its {@code
- * getFileSystem} method is invoked with the URI {@code "file:///"} to create
- * the default file system.
+ * getFileSystem} method is invoked with the URI {@code "file:///"} to
+ * get a reference to the default file system.
*
* <p> Subsequent invocations of this method return the file system that was
* returned by the first invocation.
@@ -238,7 +238,7 @@
* Suppose there is a provider identified by the scheme {@code "memory"}
* installed:
* <pre>
- * Map<String,String> env = new HashMap<String,String>();
+ * Map<String,String> env = new HashMap<>();
* env.put("capacity", "16G");
* env.put("blockSize", "4k");
* FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
@@ -343,33 +343,25 @@
*
* <p> This method makes use of specialized providers that create pseudo file
* systems where the contents of one or more files is treated as a file
- * system. The {@code file} parameter is a reference to an existing file
- * and the {@code env} parameter is a map of provider specific properties to
- * configure the file system.
+ * system.
*
* <p> This method iterates over the {@link FileSystemProvider#installedProviders()
* installed} providers. It invokes, in turn, each provider's {@link
- * FileSystemProvider#newFileSystem(FileRef,Map) newFileSystem(FileRef,Map)} method.
- * If a provider returns a file system then the iteration terminates
- * and the file system is returned. If none of the installed providers return
- * a {@code FileSystem} then an attempt is made to locate the provider using
- * the given class loader. If a provider returns a file system then the lookup
- * terminates and the file system is returned.
+ * FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)} method
+ * with an empty map. If a provider returns a file system then the iteration
+ * terminates and the file system is returned. If none of the installed
+ * providers return a {@code FileSystem} then an attempt is made to locate
+ * the provider using the given class loader. If a provider returns a file
+ * system then the lookup terminates and the file system is returned.
*
- * @param file
- * a reference to a file
- * @param env
- * a map of provider specific properties to configure the file system;
- * may be empty
+ * @param path
+ * the path to the file
* @param loader
* the class loader to locate the provider or {@code null} to only
* attempt to locate an installed provider
*
* @return a new file system
*
- * @throws IllegalArgumentException
- * if the {@code env} parameter does not contain properties required
- * by the provider, or a property value is invalid
* @throws ProviderNotFoundException
* if a provider supporting this file type cannot be located
* @throws ServiceConfigurationError
@@ -380,18 +372,18 @@
* if a security manager is installed and it denies an unspecified
* permission
*/
- public static FileSystem newFileSystem(FileRef file,
- Map<String,?> env,
+ public static FileSystem newFileSystem(Path path,
ClassLoader loader)
throws IOException
{
- if (file == null)
+ if (path == null)
throw new NullPointerException();
+ Map<String,?> env = Collections.emptyMap();
// check installed providers
for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
try {
- return provider.newFileSystem(file, env);
+ return provider.newFileSystem(path, env);
} catch (UnsupportedOperationException uoe) {
}
}
@@ -402,7 +394,7 @@
.load(FileSystemProvider.class, loader);
for (FileSystemProvider provider: sl) {
try {
- return provider.newFileSystem(file, env);
+ return provider.newFileSystem(path, env);
} catch (UnsupportedOperationException uoe) {
}
}
--- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Tue Feb 08 14:25:33 2011 -0800
@@ -69,7 +69,7 @@
FileVisitResult result = walk(start,
0,
new ArrayList<AncestorDirectory>());
- Objects.nonNull(result, "FileVisitor returned null");
+ Objects.requireNonNull(result, "FileVisitor returned null");
}
/**
@@ -102,12 +102,13 @@
if (attrs == null) {
try {
try {
- attrs = Attributes.readBasicFileAttributes(file, linkOptions);
+ attrs = Files.readAttributes(file, BasicFileAttributes.class, linkOptions);
} catch (IOException x1) {
if (followLinks) {
try {
- attrs = Attributes
- .readBasicFileAttributes(file, LinkOption.NOFOLLOW_LINKS);
+ attrs = Files.readAttributes(file,
+ BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS);
} catch (IOException x2) {
exc = x2;
}
@@ -151,7 +152,7 @@
} else {
boolean isSameFile = false;
try {
- isSameFile = file.isSameFile(ancestor.file());
+ isSameFile = Files.isSameFile(file, ancestor.file());
} catch (IOException x) {
// ignore
} catch (SecurityException x) {
@@ -175,7 +176,7 @@
// open the directory
try {
- stream = file.newDirectoryStream();
+ stream = Files.newDirectoryStream(file);
} catch (IOException x) {
return visitor.visitFileFailed(file, x);
} catch (SecurityException x) {
@@ -212,7 +213,11 @@
} finally {
try {
stream.close();
- } catch (IOException x) { }
+ } catch (IOException e) {
+ // IOException will be notified to postVisitDirectory
+ if (ioe == null)
+ ioe = e;
+ }
}
// invoke postVisitDirectory last
--- a/jdk/src/share/classes/java/nio/file/FileVisitor.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileVisitor.java Tue Feb 08 14:25:33 2011 -0800
@@ -30,8 +30,8 @@
/**
* A visitor of files. An implementation of this interface is provided to the
- * {@link Files#walkFileTree walkFileTree} utility method to visit each file
- * in a tree.
+ * {@link Files#walkFileTree Files.walkFileTree} methods to visit each file in
+ * a file tree.
*
* <p> <b>Usage Examples:</b>
* Suppose we want to delete a file tree. In that case, each directory should
@@ -43,19 +43,20 @@
* public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
* throws IOException
* {
- * file.delete();
+ * Files.delete(file);
* return FileVisitResult.CONTINUE;
* }
* @Override
* public FileVisitResult postVisitDirectory(Path dir, IOException e)
* throws IOException
* {
- * if (e != null) {
+ * if (e == null) {
+ * Files.delete(dir);
+ * return FileVisitResult.CONTINUE;
+ * } else {
* // directory iteration failed
* throw e;
* }
- * dir.delete();
- * return FileVisitResult.CONTINUE;
* }
* });
* </pre>
@@ -72,10 +73,12 @@
* public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
* throws IOException
* {
+ * Path targetdir = target.resolve(source.relativize(dir));
* try {
- * dir.copyTo(target.resolve(source.relativize(dir)));
+ * Files.copy(dir, targetdir);
* } catch (FileAlreadyExistsException e) {
- * // ignore
+ * if (!Files.isDirectory(targetdir))
+ * throw e;
* }
* return CONTINUE;
* }
@@ -83,7 +86,7 @@
* public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
* throws IOException
* {
- * file.copyTo(target.resolve(source.relativize(file)));
+ * Files.copy(file, target.resolve(source.relativize(file)));
* return CONTINUE;
* }
* });
--- a/jdk/src/share/classes/java/nio/file/Files.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/Files.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,16 +25,32 @@
package java.nio.file;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
import java.nio.file.spi.FileTypeDetector;
-import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
/**
- * This class consists exclusively of static methods that operate on files or
- * directories.
+ * This class consists exclusively of static methods that operate on files,
+ * directories, or other types of files.
+ *
+ * <p> In most cases, the methods defined here will delegate to the associated
+ * file system provider to perform the file operations.
*
* @since 1.7
*/
@@ -42,8 +58,1422 @@
public final class Files {
private Files() { }
+ /**
+ * Returns the {@code FileSystemProvider} to delegate to.
+ */
+ private static FileSystemProvider provider(Path path) {
+ return path.getFileSystem().provider();
+ }
+
+ // -- File contents --
+
+ /**
+ * Opens a file, 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. Whether the returned stream is
+ * <i>asynchronously closeable</i> and/or <i>interruptible</i> is highly
+ * file system provider specific and therefore not specified.
+ *
+ * <p> The {@code options} parameter determines how the file is opened.
+ * 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.
+ *
+ * @param path
+ * the path to the file to open
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new input stream
+ *
+ * @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.
+ */
+ public static InputStream newInputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return provider(path).newInputStream(path, options);
+ }
+
+ /**
+ * Opens or creates a file, returning an output stream that may be used to
+ * write bytes to the file. The resulting stream will not be buffered. The
+ * stream will be safe for access by multiple concurrent threads. Whether
+ * the returned stream is <i>asynchronously closeable</i> and/or
+ * <i>interruptible</i> is highly file system provider specific and
+ * therefore not specified.
+ *
+ * <p> This method opens or creates a file in exactly the manner specified
+ * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+ * method with the exception that the {@link StandardOpenOption#READ READ}
+ * option may not be present in the array of options. If no options are
+ * present then this method works as if the {@link StandardOpenOption#CREATE
+ * CREATE}, {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING},
+ * and {@link StandardOpenOption#WRITE WRITE} options are present. In other
+ * words, it opens the file for writing, creating the file if it doesn't
+ * exist, or initially truncating an existing {@link #isRegularFile
+ * regular-file} to a size of {@code 0} if it exists.
+ *
+ * <p> <b>Usage Examples:</b>
+ * <pre>
+ * Path path = ...
+ *
+ * // replace an existing file or create the file if it doesn't initially exist
+ * OutputStream out = Files.newOutputStream(path);
+ *
+ * // append to an existing file, fail if the file does not exist
+ * out = Files.newOutputStream(path, APPEND);
+ *
+ * // append to an existing file, create file if it doesn't initially exist
+ * out = Files.newOutputStream(CREATE, APPEND);
+ *
+ * // always create new file, failing if it already exists
+ * out = Files.newOutputStream(CREATE_NEW);
+ * </pre>
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new output stream
+ *
+ * @throws IllegalArgumentException
+ * 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. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public static OutputStream newOutputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return provider(path).newOutputStream(path, options);
+ }
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access 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 present then the file is
+ * opened for reading. By default reading or writing commence 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#CREATE_NEW CREATE_NEW} </td>
+ * <td> If this option is present then a new file is created, failing if
+ * the file already exists or is a symbolic link. When creating a file the
+ * check for the existence of the file and the creation of the file if it
+ * does not exist is atomic with respect to other file system operations.
+ * This option is ignored when the file is opened only for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#CREATE CREATE} </td>
+ * <td> If this option is present then an existing file is opened if it
+ * exists, otherwise a new file is created. This option is ignored if the
+ * {@code CREATE_NEW} option is also present or the file is opened only
+ * for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
+ * <td> When this option is present then the implementation makes a
+ * <em>best effort</em> attempt to delete the file when closed by the
+ * {@link SeekableByteChannel#close close} method. If the {@code close}
+ * method is not invoked then a <em>best effort</em> attempt is made to
+ * delete the file when the Java virtual machine terminates. </td>
+ * </tr>
+ * <tr>
+ * <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
+ * <td> When creating a new file this option is a <em>hint</em> that the
+ * new file will be sparse. This option is ignored when not creating
+ * a new file. </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 may also support additional implementation specific
+ * options.
+ *
+ * <p> The {@code attrs} parameter is optional {@link 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 java.nio.channels.FileChannel}.
+ *
+ * <p> <b>Usage Examples:</b>
+ * <pre>
+ * Path path = ...
+ *
+ * // open file for reading
+ * ReadableByteChannel rbc = Files.newByteChannel(path, EnumSet.of(READ)));
+ *
+ * // open file for writing to the end of an existing file, creating
+ * // the file if it doesn't already exist
+ * WritableByteChannel wbc = Files.newByteChannel(path, EnumSet.of(CREATE,APPEND));
+ *
+ * // create file with initial permissions, opening it for both reading and writing
+ * {@code FileAttribute<<SetPosixFilePermission>> perms = ...}
+ * SeekableByteChannel sbc = Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms);
+ * </pre>
+ *
+ * @param path
+ * the path to the file to open or create
+ * @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 seekable byte channel
+ *
+ * @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 FileAlreadyExistsException
+ * 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
+ * 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. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ *
+ * @see java.nio.channels.FileChannel#open(Path,Set,FileAttribute[])
+ */
+ public static SeekableByteChannel newByteChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return provider(path).newByteChannel(path, options, attrs);
+ }
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access the
+ * file.
+ *
+ * <p> This method opens or creates a file in exactly the manner specified
+ * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+ * method.
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new seekable byte channel
+ *
+ * @throws IllegalArgumentException
+ * if the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported open option is specified
+ * @throws FileAlreadyExistsException
+ * 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
+ * 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. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ *
+ * @see java.nio.channels.FileChannel#open(Path,OpenOption[])
+ */
+ public static SeekableByteChannel newByteChannel(Path path, OpenOption... options)
+ throws IOException
+ {
+ Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+ Collections.addAll(set, options);
+ return newByteChannel(path, set);
+ }
+
+ // -- Directories --
+
+ /**
+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
+ * all entries in the directory. The elements returned by the directory
+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+ * Path}, each one representing an entry in the directory. The {@code Path}
+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+ * name of the directory entry against {@code dir}.
+ *
+ * <p> When not using the try-with-resources construct, then directory
+ * stream's {@code close} method should be invoked after iteration is
+ * completed so as to free any resources held for the open directory.
+ *
+ * <p> When an implementation supports operations on entries in the
+ * directory that execute in a race-free manner then the returned directory
+ * stream is a {@link SecureDirectoryStream}.
+ *
+ * @param dir
+ * the path to the directory
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it 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#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ public static DirectoryStream<Path> newDirectoryStream(Path dir)
+ throws IOException
+ {
+ return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
+ @Override
+ public boolean accept(Path entry) {
+ return true;
+ }
+ });
+ }
+
+ /**
+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
+ * the entries in the directory. The elements returned by the directory
+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+ * Path}, each one representing an entry in the directory. The {@code Path}
+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+ * name of the directory entry against {@code dir}. The entries returned by
+ * the iterator are filtered by matching the {@code String} representation
+ * of their file names against the given <em>globbing</em> pattern.
+ *
+ * <p> For example, suppose we want to iterate over the files ending with
+ * ".java" in a directory:
+ * <pre>
+ * Path dir = ...
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.java")) {
+ * :
+ * }
+ * </pre>
+ *
+ * <p> The globbing pattern is specified by the {@link
+ * FileSystem#getPathMatcher getPathMatcher} method.
+ *
+ * <p> When not using the try-with-resources construct, then directory
+ * stream's {@code close} method should be invoked after iteration is
+ * completed so as to free any resources held for the open directory.
+ *
+ * <p> When an implementation supports operations on entries in the
+ * directory that execute in a race-free manner then the returned directory
+ * stream is a {@link SecureDirectoryStream}.
+ *
+ * @param dir
+ * the path to the directory
+ * @param glob
+ * the glob pattern
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws java.util.regex.PatternSyntaxException
+ * if the pattern is invalid
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it 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#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ public static DirectoryStream<Path> newDirectoryStream(Path dir, String glob)
+ throws IOException
+ {
+ // avoid creating a matcher if all entries are required.
+ if (glob.equals("*"))
+ return newDirectoryStream(dir);
+
+ // create a matcher and return a filter that uses it.
+ FileSystem fs = dir.getFileSystem();
+ final PathMatcher matcher = fs.getPathMatcher("glob:" + glob);
+ DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ @Override
+ public boolean accept(Path entry) {
+ return matcher.matches(entry.getFileName());
+ }
+ };
+ return fs.provider().newDirectoryStream(dir, filter);
+ }
+
+ /**
+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
+ * the entries in the directory. The elements returned by the directory
+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+ * Path}, each one representing an entry in the directory. The {@code Path}
+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+ * name of the directory entry against {@code dir}. The entries returned by
+ * the iterator are filtered by the given {@link DirectoryStream.Filter
+ * filter}.
+ *
+ * <p> When not using the try-with-resources construct, then directory
+ * stream's {@code close} method should be invoked after iteration is
+ * completed so as to free any resources held for the open directory.
+ *
+ * <p> Where the filter terminates due to an uncaught error or runtime
+ * exception then it is propagated to the {@link Iterator#hasNext()
+ * hasNext} or {@link Iterator#next() next} method. Where an {@code
+ * IOException} is thrown, it results in the {@code hasNext} or {@code
+ * next} method throwing a {@link DirectoryIteratorException} 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
+ * stream is a {@link SecureDirectoryStream}.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to iterate over the files in a directory that are
+ * larger than 8K.
+ * <pre>
+ * DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ * public boolean accept(Path file) throws IOException {
+ * return (Files.size(file) > 8192L);
+ * }
+ * };
+ * Path dir = ...
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
+ * :
+ * }
+ * </pre>
+ *
+ * @param dir
+ * the path to the directory
+ * @param filter
+ * the directory stream filter
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it 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#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ public static DirectoryStream<Path> newDirectoryStream(Path dir,
+ DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ return provider(dir).newDirectoryStream(dir, filter);
+ }
+
+ // -- Creation and deletion --
+
+ /**
+ * Creates a new and empty file, failing if the file already exists. The
+ * check for the existence of the file and the creation of the new file if
+ * it does not exist are a single operation that is atomic with respect to
+ * all other filesystem activities that might affect the directory.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-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.
+ *
+ * @param path
+ * the path to the file to create
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return the file
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the file
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs or the parent directory does not exist
+ * @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 new file.
+ */
+ public static Path createFile(Path path, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ EnumSet<StandardOpenOption> options =
+ EnumSet.<StandardOpenOption>of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
+ newByteChannel(path, options, attrs).close();
+ return path;
+ }
+
+ /**
+ * Creates a new directory. The check for the existence of the file and the
+ * creation of the directory if it does not exist are a single operation
+ * that is atomic with respect to all other filesystem activities that might
+ * affect the directory. The {@link #createDirectories createDirectories}
+ * method should be used where it is required to create all nonexistent
+ * parent directories first.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the directory. 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.
+ *
+ * @param dir
+ * the directory to create
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the directory
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws FileAlreadyExistsException
+ * if a directory could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs or the parent directory does not exist
+ * @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 new directory.
+ */
+ public static Path createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ provider(dir).createDirectory(dir, attrs);
+ return dir;
+ }
+
+ /**
+ * Creates a directory by creating all nonexistent parent directories first.
+ * Unlike the {@link #createDirectory createDirectory} method, an exception
+ * is not thrown if the directory could not be created because it already
+ * exists.
+ *
+ * <p> The {@code attrs} parameter is optional {@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
+ *
+ * @return 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 Path createDirectories(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ // attempt to create the directory
+ try {
+ createAndCheckIsDirectory(dir, attrs);
+ return dir;
+ } catch (FileAlreadyExistsException x) {
+ // file exists and is not a directory
+ throw x;
+ } catch (IOException x) {
+ // parent may not exist or other reason
+ }
+ SecurityException se = null;
+ try {
+ dir = dir.toAbsolutePath();
+ } catch (SecurityException x) {
+ // don't have permission to get absolute path
+ se = x;
+ }
+ // find a decendent that exists
+ Path parent = dir.getParent();
+ while (parent != null) {
+ try {
+ provider(parent).checkAccess(parent);
+ 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);
+ }
+ return dir;
+ }
+
+ /**
+ * Used by createDirectories to attempt to create a directory. A no-op
+ * if the directory already exists.
+ */
+ private static void createAndCheckIsDirectory(Path dir,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ try {
+ createDirectory(dir, attrs);
+ } catch (FileAlreadyExistsException x) {
+ if (!isDirectory(dir, LinkOption.NOFOLLOW_LINKS))
+ throw x;
+ }
+ }
+
+ /**
+ * Creates a new empty file in the specified directory, using the given
+ * prefix and suffix strings to generate its name. The resulting
+ * {@code Path} is associated with the same {@code FileSystem} as the given
+ * directory.
+ *
+ * <p> The details as to how the name of the file is constructed is
+ * implementation dependent and therefore not specified. Where possible
+ * the {@code prefix} and {@code suffix} are used to construct candidate
+ * names in the same manner as the {@link
+ * java.io.File#createTempFile(String,String,File)} method.
+ *
+ * <p> As with the {@code File.createTempFile} methods, this method is only
+ * part of a temporary-file facility. Where used as a <em>work files</em>,
+ * the resulting file may be opened using the {@link
+ * StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} option so that the
+ * file is deleted when the appropriate {@code close} method is invoked.
+ * Alternatively, a {@link Runtime#addShutdownHook shutdown-hook}, or the
+ * {@link java.io.File#deleteOnExit} mechanism may be used to delete the
+ * file automatically.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-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. When no file attributes are specified, then the
+ * resulting file may have more restrictive access permissions to files
+ * created by the {@link java.io.File#createTempFile(String,String,File)}
+ * method.
+ *
+ * @param dir
+ * the path to directory in which to create the file
+ * @param prefix
+ * the prefix string to be used in generating the file's name;
+ * may be {@code null}
+ * @param suffix
+ * the suffix string to be used in generating the file's name;
+ * may be {@code null}, in which case "{@code .tmp}" is used
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return the path to the newly created file that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix or suffix parameters cannot be used to generate
+ * a candidate file name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or {@code dir} does not exist
+ * @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 static Path createTempFile(Path dir,
+ String prefix,
+ String suffix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempFile(dir, prefix, suffix, attrs);
+ }
+
+ /**
+ * Creates an empty file in the default temporary-file directory, using
+ * the given prefix and suffix to generate its name. The resulting {@code
+ * Path} is associated with the default {@code FileSystem}.
+ *
+ * <p> This method works in exactly the manner specified by the
+ * {@link #createTempFile(Path,String,String,FileAttribute[])} method for
+ * the case that the {@code dir} parameter is the temporary-file directory.
+ *
+ * @param prefix
+ * the prefix string to be used in generating the file's name;
+ * may be {@code null}
+ * @param suffix
+ * the suffix string to be used in generating the file's name;
+ * may be {@code null}, in which case "{@code .tmp}" is used
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return the path to the newly created file that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix or suffix parameters cannot be used to generate
+ * a candidate file name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or the temporary-file directory does not
+ * exist
+ * @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 static Path createTempFile(String prefix,
+ String suffix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempFile(null, prefix, suffix, attrs);
+ }
+
+ /**
+ * Creates a new directory in the specified directory, using the given
+ * prefix to generate its name. The resulting {@code Path} is associated
+ * with the same {@code FileSystem} as the given directory.
+ *
+ * <p> The details as to how the name of the directory is constructed is
+ * implementation dependent and therefore not specified. Where possible
+ * the {@code prefix} is used to construct candidate names.
+ *
+ * <p> As with the {@code createTempFile} methods, this method is only
+ * part of a temporary-file facility. A {@link Runtime#addShutdownHook
+ * shutdown-hook}, or the {@link java.io.File#deleteOnExit} mechanism may be
+ * used to delete the directory automatically.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the directory. 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.
+ *
+ * @param dir
+ * the path to directory in which to create the directory
+ * @param prefix
+ * the prefix string to be used in generating the directory's name;
+ * may be {@code null}
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the path to the newly created directory that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix cannot be used to generate a candidate directory name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or {@code dir} does not exist
+ * @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 when creating the
+ * directory.
+ */
+ public static Path createTempDirectory(Path dir,
+ String prefix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempDirectory(dir, prefix, attrs);
+ }
+
+ /**
+ * Creates a new directory in the default temporary-file directory, using
+ * the given prefix and suffix to generate its name. The resulting {@code
+ * Path} is associated with the default {@code FileSystem}.
+ *
+ * <p> This method works in exactly the manner specified by {@link
+ * #createTempDirectory(Path,String,FileAttribute[])} method for the case
+ * that the {@code dir} parameter is the temporary-file directory.
+ *
+ * @param prefix
+ * the prefix string to be used in generating the directory's name;
+ * may be {@code null}
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the path to the newly created directory that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix cannot be used to generate a candidate directory name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or the temporary-file directory does not
+ * exist
+ * @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 when creating the
+ * directory.
+ */
+ public static Path createTempDirectory(String prefix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempDirectory(null, prefix, attrs);
+ }
+
+ /**
+ * Creates a symbolic link to a target <i>(optional operation)</i>.
+ *
+ * <p> The {@code target} parameter is the target of the link. It may be an
+ * {@link Path#isAbsolute absolute} or relative path and may not exist. When
+ * the target is a relative path then file system operations on the resulting
+ * link are relative to the path of the link.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * attributes} to set atomically when creating the link. 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 symbolic links are supported, but the underlying {@link FileStore}
+ * does not support symbolic links, then this may fail with an {@link
+ * IOException}. Additionally, some operating systems may require that the
+ * Java virtual machine be started with implementation specific privileges to
+ * create symbolic links, in which case this method may throw {@code IOException}.
+ *
+ * @param link
+ * the path of the symbolic link to create
+ * @param target
+ * the target of the symbolic link
+ * @param attrs
+ * the array of attributes to set atomically when creating the
+ * symbolic link
+ *
+ * @return the path to the symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links or the
+ * array contains an attribute that cannot be set atomically when
+ * creating the symbolic link
+ * @throws FileAlreadyExistsException
+ * if a file with the name already exists <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, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the path of the symbolic link.
+ */
+ public static Path createSymbolicLink(Path link, Path target,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ provider(link).createSymbolicLink(link, target, attrs);
+ return link;
+ }
+
+ /**
+ * Creates a new link (directory entry) for an existing file <i>(optional
+ * operation)</i>.
+ *
+ * <p> The {@code link} parameter locates the directory entry to create.
+ * The {@code existing} parameter is the path to an existing file. This
+ * method creates a new directory entry for the file so that it can be
+ * accessed using {@code link} as the path. On some file systems this is
+ * known as creating a "hard link". Whether the file attributes are
+ * maintained for the file or for each directory entry is file system
+ * specific and therefore not specified. Typically, a file system requires
+ * that all links (directory entries) for a file be on the same file system.
+ * Furthermore, on some platforms, the Java virtual machine may require to
+ * be started with implementation specific privileges to create hard links
+ * or to create links to directories.
+ *
+ * @param link
+ * the link (directory entry) to create
+ * @param existing
+ * a path to an existing file
+ *
+ * @return the path to the link (directory entry)
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support adding an existing file
+ * to a directory
+ * @throws FileAlreadyExistsException
+ * if the entry could not otherwise be created because a file of
+ * that name already exists <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, it denies {@link LinkPermission}<tt>("hard")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to either the link or the
+ * existing file.
+ */
+ public static Path createLink(Path link, Path existing) throws IOException {
+ provider(link).createLink(link, existing);
+ return link;
+ }
+
+ /**
+ * Deletes a file.
+ *
+ * <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
+ * symbolic link itself, not the final target of the link, is deleted.
+ *
+ * <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.
+ * This method can be used with the {@link #walkFileTree walkFileTree}
+ * method to delete a directory and all entries in the directory, or an
+ * entire <i>file-tree</i> where required.
+ *
+ * <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 path
+ * the path to the file to delete
+ *
+ * @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 static void delete(Path path) throws IOException {
+ provider(path).delete(path);
+ }
+
+ /**
+ * Deletes a file if it exists.
+ *
+ * <p> As with the {@link #delete(Path) delete(Path)} method, an
+ * implementation may need 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
+ * symbolic link itself, not the final target of the link, is deleted.
+ *
+ * <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.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @return {@code true} if the file was deleted by this method; {@code
+ * false} if the file could not be deleted because it did not
+ * exist
+ *
+ * @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 static boolean deleteIfExists(Path path) throws IOException {
+ return provider(path).deleteIfExists(path);
+ }
+
+ // -- Copying and moving files --
+
+ /**
+ * Copy a file to a target file.
+ *
+ * <p> This method copies a file to the target file with the {@code
+ * options} parameter specifying how the copy is performed. By default, the
+ * copy fails if the target file already exists or is a symbolic link,
+ * except if the source and target are the {@link #isSameFile same} file, in
+ * which case the method completes without copying the file. File attributes
+ * are not required to be copied to the target file. If symbolic links are
+ * supported, and the file is a symbolic link, then the final target of the
+ * link is copied. If the file is a directory then it creates an empty
+ * directory in the target location (entries in the directory are not
+ * copied). This method can be used with the {@link #walkFileTree
+ * walkFileTree} method to copy a directory and all entries in the directory,
+ * or an entire <i>file-tree</i> where required.
+ *
+ * <p> The {@code options} parameter may include any of the following:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+ * <td> If the target file exists, then the target file is replaced if it
+ * is not a non-empty directory. If the target file exists and is a
+ * symbolic link, then the symbolic link itself, not the target of
+ * the link, is replaced. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} </td>
+ * <td> Attempts to copy the file attributes associated with this file to
+ * 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 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>
+ * <td> Symbolic links are not followed. If the file is a symbolic link,
+ * then the symbolic link itself, not the target of the link, is copied.
+ * It is implementation specific if file attributes can be copied to the
+ * new link. In other words, the {@code COPY_ATTRIBUTES} option may be
+ * ignored when copying a symbolic link. </td>
+ * </tr>
+ * </table>
+ *
+ * <p> An implementation of this interface may support additional
+ * implementation specific options.
+ *
+ * <p> Copying a file is not an atomic operation. If an {@link IOException}
+ * is thrown then it possible that the target file is incomplete or some of
+ * its file attributes have not been copied from the source file. When the
+ * {@code REPLACE_EXISTING} option is specified and the target file exists,
+ * then the target file is replaced. The check for the existence of the file
+ * and the creation of the new file may not be atomic with respect to other
+ * file system activities.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to copy a file into a directory, giving it the same file
+ * name as the source file:
+ * <pre>
+ * Path source = ...
+ * Path newdir = ...
+ * Files.copy(source, newdir.resolve(source.getFileName());
+ * </pre>
+ *
+ * @param source
+ * the path to the file to copy
+ * @param target
+ * the path to the target file (may be associated with a different
+ * provider to the source path)
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @return the path to the target file
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty 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#checkRead(String) checkRead}
+ * method is invoked to check read access to the source file, the
+ * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+ * to check write access to the target file. If a symbolic link is
+ * copied the security manager is invoked to check {@link
+ * LinkPermission}{@code ("symbolic")}.
+ */
+ public static Path copy(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ FileSystemProvider provider = provider(source);
+ if (provider(target) == provider) {
+ // same provider
+ provider.copy(source, target, options);
+ } else {
+ // different providers
+ CopyMoveHelper.copyToForeignTarget(source, target, options);
+ }
+ return target;
+ }
+
+ /**
+ * Move or rename a file to a target file.
+ *
+ * <p> By default, this method attempts to move the file to the target
+ * file, failing if the target file exists except if the source and
+ * target are the {@link #isSameFile same} file, in which case this method
+ * has no effect. If the file is a symbolic link then the symbolic link
+ * itself, not the target of the link, is moved. This method may be
+ * invoked to move an empty directory. 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. When invoked to move a
+ * directory that is not empty then the directory is moved if it does not
+ * require moving the entries in the directory. For example, renaming a
+ * directory on the same {@link FileStore} will usually not require moving
+ * the entries in the directory. When moving a directory requires that its
+ * entries be moved then this method fails (by throwing an {@code
+ * IOException}). To move a <i>file tree</i> may involve copying rather
+ * than moving directories and this can be done using the {@link
+ * #copy copy} method in conjunction with the {@link
+ * #walkFileTree Files.walkFileTree} utility method.
+ *
+ * <p> The {@code options} parameter may include any of the following:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+ * <td> If the target file exists, then the target file is replaced if it
+ * is not a non-empty directory. If the target file exists and is a
+ * symbolic link, then the symbolic link itself, not the target of
+ * the link, is replaced. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} </td>
+ * <td> The move is performed as an atomic file system operation and all
+ * other options are ignored. If the target file exists then it is
+ * implementation specific if the existing file is replaced or this method
+ * fails by throwing an {@link IOException}. If the move cannot be
+ * performed as an atomic file system operation then {@link
+ * AtomicMoveNotSupportedException} is thrown. This can arise, for
+ * example, when the target location is on a different {@code FileStore}
+ * and would require that the file be copied, or target location is
+ * associated with a different provider to this object. </td>
+ * </table>
+ *
+ * <p> An implementation of this interface may support additional
+ * implementation specific options.
+ *
+ * <p> Where the move requires that the file be copied then the {@link
+ * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the
+ * new file. An implementation may also attempt to copy other file
+ * attributes but is not required to fail if the file attributes cannot be
+ * copied. When the move is performed as a non-atomic operation, and a {@code
+ * IOException} is thrown, then the state of the files is not defined. The
+ * original file and the target file may both exist, the target file may be
+ * incomplete or some of its file attributes may not been copied from the
+ * original file.
+ *
+ * <p> <b>Usage Examples:</b>
+ * Suppose we want to rename a file to "newname", keeping the file in the
+ * same directory:
+ * <pre>
+ * Path source = ...
+ * Files.move(source, source.resolveSibling("newname"));
+ * </pre>
+ * Alternatively, suppose we want to move a file to new directory, keeping
+ * the same file name, and replacing any existing file of that name in the
+ * directory:
+ * <pre>
+ * Path source = ...
+ * Path newdir = ...
+ * Files.move(source, newdir.resolve(source.getFileName()), REPLACE_EXISTING);
+ * </pre>
+ *
+ * @param source
+ * the path to the file to move
+ * @param target
+ * the path to the target file (may be associated with a different
+ * provider to the source path)
+ * @param options
+ * options specifying how the move should be done
+ *
+ * @return the path to the target file
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws AtomicMoveNotSupportedException
+ * if the options array contains the {@code ATOMIC_MOVE} option but
+ * the file cannot be moved as an atomic file system operation.
+ * @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 both the source and
+ * target file.
+ */
+ public static Path move(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ FileSystemProvider provider = provider(source);
+ if (provider(target) == provider) {
+ // same provider
+ provider.move(source, target, options);
+ } else {
+ // different providers
+ CopyMoveHelper.moveToForeignTarget(source, target, options);
+ }
+ return target;
+ }
+
+ // -- Miscellenous --
+
+ /**
+ * Reads the target of a symbolic link <i>(optional operation)</i>.
+ *
+ * <p> If the file system supports <a href="package-summary.html#links">symbolic
+ * links</a> then this method is used to read the target of the link, failing
+ * if the file is not a symbolic link. The target of the link need not exist.
+ * The returned {@code Path} object will be associated with the same file
+ * system as {@code link}.
+ *
+ * @param link
+ * the path to the symbolic link
+ *
+ * @return a {@code Path} object representing the target of the link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links
+ * @throws NotLinkException
+ * if the target could otherwise not be read because the file
+ * is not a symbolic link <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, it checks that {@code FilePermission} has been
+ * granted with the "{@code readlink}" action to read the link.
+ */
+ public static Path readSymbolicLink(Path link) throws IOException {
+ return provider(link).readSymbolicLink(link);
+ }
+
+ /**
+ * Returns the {@link FileStore} representing the file store where a file
+ * is located.
+ *
+ * <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.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @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 static FileStore getFileStore(Path path) throws IOException {
+ return provider(path).getFileStore(path);
+ }
+
+ /**
+ * Tests if two paths locate the same file.
+ *
+ * <p> If both {@code Path} objects are {@link Path#equals(Object) equal}
+ * then this method returns {@code true} without checking if the file exists.
+ * If the two {@code Path} objects are associated with different providers
+ * then this method returns {@code false}. Otherwise, this method checks if
+ * both {@code Path} objects 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 Paths}.
+ * <ul>
+ * <li>It is <i>reflexive</i>: for {@code Path} {@code f},
+ * {@code isSameFile(f,f)} should return {@code true}.
+ * <li>It is <i>symmetric</i>: for two {@code Paths} {@code f} and {@code g},
+ * {@code isSameFile(f,g)} will equal {@code isSameFile(g,f)}.
+ * <li>It is <i>transitive</i>: for three {@code Paths}
+ * {@code f}, {@code g}, and {@code h}, if {@code isSameFile(f,g)} returns
+ * {@code true} and {@code isSameFile(g,h)} returns {@code true}, then
+ * {@code isSameFile(g,h)} will return return {@code true}.
+ * </ul>
+ *
+ * @param path
+ * one path to the file
+ * @param path2
+ * the other path
+ *
+ * @return {@code true} if, and only if, the two paths 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 static boolean isSameFile(Path path, Path path2) throws IOException {
+ return provider(path).isSameFile(path, path2);
+ }
+
+ /**
+ * Tells whether or not a file is considered <em>hidden</em>. The exact
+ * definition of hidden is platform or provider dependent. On UNIX for
+ * example a file is considered to be hidden if its name begins with a
+ * period character ('.'). On Windows a file is considered hidden if it
+ * isn't a directory and the DOS {@link DosFileAttributes#isHidden hidden}
+ * attribute is set.
+ *
+ * <p> Depending on the implementation this method may require to access
+ * the file system to determine if the file is considered hidden.
+ *
+ * @param path
+ * the path to the file to test
+ *
+ * @return {@code true} if the file is considered hidden
+ *
+ * @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 static boolean isHidden(Path path) throws IOException {
+ return provider(path).isHidden(path);
+ }
+
// lazy loading of default and installed file type detectors
- private static class DefaultFileTypeDetectorHolder {
+ private static class FileTypeDetectors{
static final FileTypeDetector defaultFileTypeDetector =
sun.nio.fs.DefaultFileTypeDetector.create();
static final List<FileTypeDetector> installeDetectors =
@@ -54,7 +1484,7 @@
return AccessController
.doPrivileged(new PrivilegedAction<List<FileTypeDetector>>() {
@Override public List<FileTypeDetector> run() {
- List<FileTypeDetector> list = new ArrayList<FileTypeDetector>();
+ List<FileTypeDetector> list = new ArrayList<>();
ServiceLoader<FileTypeDetector> loader = ServiceLoader
.load(FileTypeDetector.class, ClassLoader.getSystemClassLoader());
for (FileTypeDetector detector: loader) {
@@ -100,34 +1530,949 @@
* Message Bodies</i></a>. The string is guaranteed to be parsable according
* to the grammar in the RFC.
*
- * @param file
- * The file reference
+ * @param path
+ * the path to the file to probe
*
* @return The content type of the file, or {@code null} if the content
* type cannot be determined
*
* @throws IOException
- * If an I/O error occurs
+ * if an I/O error occurs
* @throws SecurityException
* If a security manager is installed and it denies an unspecified
* permission required by a file type detector implementation.
*/
- public static String probeContentType(FileRef file)
+ public static String probeContentType(Path path)
throws IOException
{
// try installed file type detectors
- for (FileTypeDetector detector: DefaultFileTypeDetectorHolder.installeDetectors) {
- String result = detector.probeContentType(file);
+ for (FileTypeDetector detector: FileTypeDetectors.installeDetectors) {
+ String result = detector.probeContentType(path);
if (result != null)
return result;
}
// fallback to default
- return DefaultFileTypeDetectorHolder.defaultFileTypeDetector
- .probeContentType(file);
+ return FileTypeDetectors.defaultFileTypeDetector.probeContentType(path);
+ }
+
+ // -- File Attributes --
+
+ /**
+ * Returns a file attribute view of a given type.
+ *
+ * <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 the file
+ * attribute view defines type-safe methods to read or update the file
+ * attributes. The {@code type} parameter is the type of the attribute view
+ * required and the method returns an instance of that type if supported.
+ * The {@link BasicFileAttributeView} type supports access to the basic
+ * attributes of a file. Invoking this method to select a file attribute
+ * view of that type will always return an instance of that class.
+ *
+ * <p> The {@code 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.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want read or set a file's ACL, if supported:
+ * <pre>
+ * Path path = ...
+ * AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
+ * if (view != null) {
+ * List<AclEntry> acl = view.getAcl();
+ * :
+ * }
+ * </pre>
+ *
+ *
+ * @param path
+ * the path to the file
+ * @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 attribute view type is not available
+ */
+ public static <V extends FileAttributeView> V getFileAttributeView(Path path,
+ Class<V> type,
+ LinkOption... options)
+ {
+ return provider(path).getFileAttributeView(path, type, options);
+ }
+
+ /**
+ * Reads a file's attributes as a bulk operation.
+ *
+ * <p> The {@code type} parameter is the type of the attributes required
+ * and this method returns an instance of that type if supported. All
+ * implementations support a basic set of file attributes and so invoking
+ * this method with a {@code type} parameter of {@code
+ * BasicFileAttributes.class} will not throw {@code
+ * UnsupportedOperationException}.
+ *
+ * <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.
+ *
+ * <p> It is implementation specific if all file attributes are read as an
+ * atomic operation with respect to other file system operations.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to read a file's attributes in bulk:
+ * <pre>
+ * Path path = ...
+ * BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
+ * </pre>
+ * Alternatively, suppose we want to read file's POSIX attributes without
+ * following symbolic links:
+ * <pre>
+ * PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} of the file attributes required
+ * to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the file attributes
+ *
+ * @throws UnsupportedOperationException
+ * if an attributes of the given type are not supported
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file. If this
+ * method is invoked to read security sensitive attributes then the
+ * security manager may be invoke to check for additional permissions.
+ */
+ public static <A extends BasicFileAttributes> A readAttributes(Path path,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ return provider(path).readAttributes(path, type, 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> 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 set. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to set the DOS "hidden" attribute:
+ * <pre>
+ * Path path = ...
+ * Files.setAttribute(path, "dos:hidden", true);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param attribute
+ * the attribute to set
+ * @param value
+ * the attribute value
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the {@code path} parameter
+ *
+ * @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 Path setAttribute(Path path, String attribute, Object value,
+ LinkOption... options)
+ throws IOException
+ {
+ provider(path).setAttribute(path, attribute, value, options);
+ return path;
+ }
+
+ /**
+ * 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.
+ *
+ * <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>
+ * Path path = ...
+ * int uid = (Integer)Files.getAttribute(path, "unix:uid");
+ * </pre>
+ *
+ * @param path
+ * the path to 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(Path path, String attribute,
+ LinkOption... options)
+ throws IOException
+ {
+ // only one attribute should be read
+ if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0)
+ return null;
+ Map<String,Object> map = readAttributes(path, attribute, options);
+ String name;
+ int pos = attribute.indexOf(':');
+ if (pos == -1) {
+ name = attribute;
+ } else {
+ name = (pos == attribute.length()) ? "" : attribute.substring(pos+1);
+ }
+ return map.get(name);
+ }
+
+ /**
+ * 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.
+ *
+ * @param path
+ * the path to 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,Object> readAttributes(Path path, String attributes,
+ LinkOption... options)
+ throws IOException
+ {
+ return provider(path).readAttributes(path, attributes, options);
+ }
+
+ /**
+ * Returns a file's POSIX file permissions.
+ *
+ * <p> The {@code path} parameter is associated with a {@code FileSystem}
+ * that supports the {@link PosixFileAttributeView}. This attribute view
+ * provides access to file attributes commonly associated with files on file
+ * systems used by operating systems that implement the Portable Operating
+ * System Interface (POSIX) family of standards.
+ *
+ * <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.
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the file permissions
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * PosixFileAttributeView}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ public static Set<PosixFilePermission> getPosixFilePermissions(Path path,
+ LinkOption... options)
+ throws IOException
+ {
+ return readAttributes(path, PosixFileAttributes.class, options).permissions();
+ }
+
+ /**
+ * Sets a file's POSIX permissions.
+ *
+ * <p> The {@code path} parameter is associated with a {@code FileSystem}
+ * that supports the {@link PosixFileAttributeView}. This attribute view
+ * provides access to file attributes commonly associated with files on file
+ * systems used by operating systems that implement the Portable Operating
+ * System Interface (POSIX) family of standards.
+ *
+ * @param path
+ * A file reference that locates the file
+ * @param perms
+ * The new set of permissions
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * PosixFileAttributeView}
+ * @throws ClassCastException
+ * if the sets contains elements that are not of type {@code
+ * PosixFilePermission}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ */
+ public static Path setPosixFilePermissions(Path path,
+ Set<PosixFilePermission> perms)
+ throws IOException
+ {
+ PosixFileAttributeView view =
+ getFileAttributeView(path, PosixFileAttributeView.class);
+ if (view == null)
+ throw new UnsupportedOperationException();
+ view.setPermissions(perms);
+ return path;
+ }
+
+ /**
+ * Returns the owner of a file.
+ *
+ * <p> The {@code path} parameter is associated with a file system that
+ * supports {@link FileOwnerAttributeView}. This file attribute view provides
+ * access to a file attribute that is the owner of the file.
+ *
+ * @param path
+ * A file reference that locates the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return A user principal representing the owner of the file
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * FileOwnerAttributeView}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ public static UserPrincipal getOwner(Path path, LinkOption... options) throws IOException {
+ FileOwnerAttributeView view =
+ getFileAttributeView(path, FileOwnerAttributeView.class, options);
+ if (view == null)
+ throw new UnsupportedOperationException();
+ return view.getOwner();
}
/**
+ * Updates the file owner.
+ *
+ * <p> The {@code path} parameter is associated with a file system that
+ * supports {@link FileOwnerAttributeView}. This file attribute view provides
+ * access to a file attribute that is the owner of the file.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to make "joe" the owner of a file:
+ * <pre>
+ * Path path = ...
+ * UserPrincipalLookupService lookupService =
+ * provider(path).getUserPrincipalLookupService();
+ * UserPrincipal joe = lookupService.lookupPrincipalByName("joe");
+ * Files.setOwner(path, joe);
+ * </pre>
+ *
+ * @param path
+ * A file reference that locates the file
+ * @param owner
+ * The new file owner
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * FileOwnerAttributeView}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ *
+ * @see FileSystem#getUserPrincipalLookupService
+ * @see java.nio.file.attribute.UserPrincipalLookupService
+ */
+ public static Path setOwner(Path path, UserPrincipal owner)
+ throws IOException
+ {
+ FileOwnerAttributeView view =
+ getFileAttributeView(path, FileOwnerAttributeView.class);
+ if (view == null)
+ throw new UnsupportedOperationException();
+ view.setOwner(owner);
+ return path;
+ }
+
+ /**
+ * Tests whether a file is a symbolic link.
+ *
+ * <p> Where is it required to distinguish an I/O exception from the case
+ * that the file is not a symbolic link then the file attributes can be
+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
+ * readAttributes} method and the file type tested with the {@link
+ * BasicFileAttributes#isSymbolicLink} method.
+ *
+ * @return {@code true} if the file is a symbolic link; {@code false} if
+ * the file does not exist, is not a symbolic link, or it cannot
+ * be determined if the file is symbolic link or not.
+ *
+ * @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.
+ */
+ public static boolean isSymbolicLink(Path path) {
+ try {
+ return readAttributes(path,
+ BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS).isSymbolicLink();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether a file is a directory.
+ *
+ * <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.
+ *
+ * <p> Where is it required to distinguish an I/O exception from the case
+ * that the file is not a directory then the file attributes can be
+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
+ * readAttributes} method and the file type tested with the {@link
+ * BasicFileAttributes#isDirectory} method.
+ *
+ * @param path
+ * the path to the file to test
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return {@code true} if the file is a directory; {@code false} if
+ * the file does not exist, is not a directory, or it cannot
+ * be determined if the file is directory or not.
+ *
+ * @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.
+ */
+ public static boolean isDirectory(Path path, LinkOption... options) {
+ try {
+ return readAttributes(path, BasicFileAttributes.class, options).isDirectory();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether a file is a regular file with opaque content.
+ *
+ * <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.
+ *
+ * <p> Where is it required to distinguish an I/O exception from the case
+ * that the file is not a regular file then the file attributes can be
+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
+ * readAttributes} method and the file type tested with the {@link
+ * BasicFileAttributes#isRegularFile} method.
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return {@code true} if the file is a regular file; {@code false} if
+ * the file does not exist, is not a direcregular filetory, or it
+ * cannot be determined if the file is regular file or not.
+ *
+ * @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.
+ */
+ public static boolean isRegularFile(Path path, LinkOption... options) {
+ try {
+ return readAttributes(path, BasicFileAttributes.class, options).isRegularFile();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns a file's last modified time.
+ *
+ * <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.
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a {@code FileTime} representing the time the file was last
+ * modified, or an implementation specific default when a time
+ * stamp to indicate the time of last modification is not supported
+ * by the file system
+ *
+ * @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.
+ *
+ * @see BasicFileAttributes#lastModifiedTime
+ */
+ public static FileTime getLastModifiedTime(Path path, LinkOption... options)
+ throws IOException
+ {
+ return readAttributes(path, BasicFileAttributes.class, options).lastModifiedTime();
+ }
+
+ /**
+ * 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 the last modified time when it is not
+ * supported by the file system or is outside the range supported by the
+ * underlying file store is not defined. It may or not fail by throwing an
+ * {@code IOException}.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to set the last modified time to the current time:
+ * <pre>
+ * Path path = ...
+ * FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+ * Files.setLastModifiedTime(path, now);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param time
+ * the new last modified time
+ *
+ * @return the file
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, the security manager's {@link
+ * SecurityManager#checkWrite(String) checkWrite} method is invoked
+ * to check write access to file
+ *
+ * @see BasicFileAttributeView#setTimes
+ */
+ public static Path setLastModifiedTime(Path path, FileTime time)
+ throws IOException
+ {
+ getFileAttributeView(path, BasicFileAttributeView.class)
+ .setTimes(time, null, null);
+ return path;
+ }
+
+ /**
+ * Returns the size of a file (in bytes). The size may differ from the
+ * actual size on the file system due to compression, support for sparse
+ * files, or other reasons. The size of files that are not {@link
+ * #isRegularFile regular} files is implementation specific and
+ * therefore unspecified.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the file size, in bytes
+ *
+ * @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.
+ *
+ * @see BasicFileAttributes#size
+ */
+ public static long size(Path path) throws IOException {
+ return readAttributes(path, BasicFileAttributes.class).size();
+ }
+
+ // -- Accessibility --
+
+ /**
+ * Returns {@code false} if NOFOLLOW_LINKS is present.
+ */
+ private static boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption opt: options) {
+ if (opt == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ continue;
+ }
+ if (opt == null)
+ throw new NullPointerException();
+ throw new AssertionError("Should not get here");
+ }
+ return followLinks;
+ }
+
+ /**
+ * Tests whether a file exists.
+ *
+ * <p> The {@code options} parameter 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. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Note that the result of this method is immediately outdated. If this
+ * method indicates the file exists then there is no guarantee that a
+ * subsequence access will succeed. Care should be taken when using this
+ * method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to test
+ * @param options
+ * options indicating how symbolic links are handled
+ * .
+ * @return {@code true} if the file exists; {@code false} if the file does
+ * not exist or its existence cannot be determined.
+ *
+ * @throws SecurityException
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} is invoked to check
+ * read access to the file.
+ *
+ * @see #notExists
+ */
+ public static boolean exists(Path path, LinkOption... options) {
+ try {
+ if (followLinks(options)) {
+ provider(path).checkAccess(path);
+ } else {
+ // attempt to read attributes without following links
+ readAttributes(path, BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS);
+ }
+ // file exists
+ return true;
+ } catch (IOException x) {
+ // does not exist or unable to determine if file exists
+ return false;
+ }
+
+ }
+
+ /**
+ * Tests whether the file located by this path does not exist. This method
+ * is intended for cases where it is required to take action when it can be
+ * confirmed that a file does not exist.
+ *
+ * <p> The {@code options} parameter 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. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Note that this method is not the complement of the {@link #exists
+ * exists} method. Where it is not possible to determine if a file exists
+ * or not then both methods return {@code false}. As with the {@code exists}
+ * method, the result of this method is immediately outdated. If this
+ * method indicates the file does exist then there is no guarantee that a
+ * subsequence attempt to create the file will succeed. Care should be taken
+ * when using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to test
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return {@code true} if the file does not exist; {@code false} if the
+ * file exists or its existence cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} is invoked to check
+ * read access to the file.
+ */
+ public static boolean notExists(Path path, LinkOption... options) {
+ try {
+ if (followLinks(options)) {
+ provider(path).checkAccess(path);
+ } else {
+ // attempt to read attributes without following links
+ readAttributes(path, BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS);
+ }
+ // file exists
+ return false;
+ } catch (NoSuchFileException x) {
+ // file confirmed not to exist
+ return true;
+ } catch (IOException x) {
+ return false;
+ }
+ }
+
+ /**
+ * Used by isReadbale, isWritable, isExecutable to test access to a file.
+ */
+ private static boolean isAccessible(Path path, AccessMode... modes) {
+ try {
+ provider(path).checkAccess(path, modes);
+ return true;
+ } catch (IOException x) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether a file is readable. This method checks that a file exists
+ * and that this Java virtual machine has appropriate privileges that would
+ * allow it open the file for reading. 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.
+ * Consequently, this method may not be atomic with respect to other file
+ * system operations.
+ *
+ * <p> Note that the result of this method is immediately outdated, there is
+ * no guarantee that a subsequent attempt to open the file for reading will
+ * succeed (or even that it will access the same file). Care should be taken
+ * when using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to check
+ *
+ * @return {@code true} if the file exists and is readable; {@code false}
+ * if the file does not exist, read access would be denied because
+ * the Java virtual machine has insufficient privileges, or access
+ * cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * is invoked to check read access to the file.
+ */
+ public static boolean isReadable(Path path) {
+ return isAccessible(path, AccessMode.READ);
+ }
+
+ /**
+ * Tests whether a file is writable. This method checks that a file exists
+ * and that this Java virtual machine has appropriate privileges that would
+ * allow it open the file for writing. 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.
+ * Consequently, this method may not be atomic with respect to other file
+ * system operations.
+ *
+ * <p> Note that result of this method is immediately outdated, there is no
+ * guarantee that a subsequent attempt to open the file for writing will
+ * succeed (or even that it will access the same file). Care should be taken
+ * when using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to check
+ *
+ * @return {@code true} if the file exists and is writable; {@code false}
+ * if the file does not exist, write access would be denied because
+ * the Java virtual machine has insufficient privileges, or access
+ * cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * is invoked to check write access to the file.
+ */
+ public static boolean isWritable(Path path) {
+ return isAccessible(path, AccessMode.WRITE);
+ }
+
+ /**
+ * Tests whether a file is executable. This method checks that a file exists
+ * and that this Java virtual machine has appropriate privileges to {@link
+ * Runtime#exec execute} the file. The semantics may differ when checking
+ * access to a directory. For example, on UNIX systems, checking for
+ * execute access checks that the Java virtual machine has permission to
+ * search the directory in order to access file or subdirectories.
+ *
+ * <p> 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. Consequently, this method may not
+ * be atomic with respect to other file system operations.
+ *
+ * <p> Note that the result of this method is immediately outdated, there is
+ * no guarantee that a subsequent attempt to execute the file will succeed
+ * (or even that it will access the same file). Care should be taken when
+ * using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to check
+ *
+ * @return {@code true} if the file exists and is executable; {@code false}
+ * if the file does not exist, execute access would be denied because
+ * the Java virtual machine has insufficient privileges, or access
+ * cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkExec(String)
+ * checkExec} is invoked to check execute access to the file.
+ */
+ public static boolean isExecutable(Path path) {
+ return isAccessible(path, AccessMode.EXECUTE);
+ }
+
+ // -- Recursive operations --
+
+ /**
* Walks a file tree.
*
* <p> This method walks a file tree rooted at a given starting file. The
@@ -139,7 +2484,7 @@
* an uncaught error, or runtime exception, then the traversal is terminated
* and the error or exception is propagated to the caller of this method.
*
- * <p> For each file encountered this method attempts to gets its {@link
+ * <p> For each file encountered this method attempts to read its {@link
* java.nio.file.attribute.BasicFileAttributes}. If the file is not a
* directory then the {@link FileVisitor#visitFile visitFile} method is
* invoked with the file attributes. If the file attributes cannot be read,
@@ -174,7 +2519,7 @@
* arises when there is an entry in a directory that is an ancestor of the
* directory. Cycle detection is done by recording the {@link
* java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
- * or if file keys are not available, by invoking the {@link Path#isSameFile
+ * or if file keys are not available, by invoking the {@link #isSameFile
* isSameFile} method to test if a directory is the same file as an
* ancestor. When a cycle is detected it is treated as an I/O error, and the
* {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
@@ -197,25 +2542,27 @@
* that file (or directory).
*
* @param start
- * The starting file
+ * the starting file
* @param options
- * Options to configure the traversal
+ * options to configure the traversal
* @param maxDepth
- * The maximum number of directory levels to visit
+ * the maximum number of directory levels to visit
* @param visitor
- * The file visitor to invoke for each file
+ * the file visitor to invoke for each file
+ *
+ * @return the starting file
*
* @throws IllegalArgumentException
- * If the {@code maxDepth} parameter is negative
+ * if the {@code maxDepth} parameter is negative
* @throws SecurityException
* If the security manager denies access to the starting file.
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String) checkRead} method is invoked
* to check read access to the directory.
* @throws IOException
- * If an I/O error is thrown by a visitor method
+ * if an I/O error is thrown by a visitor method
*/
- public static void walkFileTree(Path start,
+ public static Path walkFileTree(Path start,
Set<FileVisitOption> options,
int maxDepth,
FileVisitor<? super Path> visitor)
@@ -224,6 +2571,7 @@
if (maxDepth < 0)
throw new IllegalArgumentException("'maxDepth' is negative");
new FileTreeWalker(options, visitor, maxDepth).walk(start);
+ return start;
}
/**
@@ -234,11 +2582,15 @@
* <blockquote><pre>
* walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor)
* </pre></blockquote>
+ * In other words, it does not follow symbolic links, and visits all levels
+ * of the file level.
*
* @param start
- * The starting file
+ * the starting file
* @param visitor
- * The file visitor to invoke for each file
+ * the file visitor to invoke for each file
+ *
+ * @return the starting file
*
* @throws SecurityException
* If the security manager denies access to the starting file.
@@ -246,118 +2598,511 @@
* SecurityManager#checkRead(String) checkRead} method is invoked
* to check read access to the directory.
* @throws IOException
- * If an I/O error is thrown by a visitor method
+ * if an I/O error is thrown by a visitor method
*/
- public static void walkFileTree(Path start, FileVisitor<? super Path> visitor)
+ public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
+ throws IOException
+ {
+ return walkFileTree(start,
+ EnumSet.noneOf(FileVisitOption.class),
+ Integer.MAX_VALUE,
+ visitor);
+ }
+
+
+ // -- Utility methods for simple usages --
+
+ // buffer size used for reading and writing
+ private static final int BUFFER_SIZE = 8192;
+
+ /**
+ * Opens a file for reading, returning a {@code BufferedReader} that may be
+ * used to read text from the file in an efficient manner. Bytes from the
+ * file are decoded into characters using the specified charset. Reading
+ * commences at the beginning of the file.
+ *
+ * <p> The {@code Reader} methods that read from the file throw {@code
+ * IOException} if a malformed or unmappable byte sequence is read.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for decoding
+ *
+ * @return a new buffered reader, with default buffer size, to read text
+ * from the file
+ *
+ * @throws IOException
+ * if an I/O error occurs opening the file
+ * @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.
+ *
+ * @see #readAllLines
+ */
+ public static BufferedReader newBufferedReader(Path path, Charset cs)
throws IOException
{
- walkFileTree(start,
- EnumSet.noneOf(FileVisitOption.class),
- Integer.MAX_VALUE,
- visitor);
+ CharsetDecoder decoder = cs.newDecoder();
+ Reader reader = new InputStreamReader(newInputStream(path), decoder);
+ return new BufferedReader(reader);
+ }
+
+ /**
+ * Opens or creates a file for writing, returning a {@code BufferedWriter}
+ * that may be used to write text to the file in an efficient manner.
+ * The {@code options} parameter specifies how the the file is created or
+ * opened. If no options are present then this method works as if the {@link
+ * StandardOpenOption#CREATE CREATE}, {@link
+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+ * opens the file for writing, creating the file if it doesn't exist, or
+ * initially truncating an existing {@link #isRegularFile regular-file} to
+ * a size of {@code 0} if it exists.
+ *
+ * <p> The {@code Writer} methods to write text throw {@code IOException}
+ * if the text cannot be encoded using the specified charset.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for encoding
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new buffered writer, with default buffer size, to write text
+ * to the file
+ *
+ * @throws IOException
+ * if an I/O error occurs opening or creating the file
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @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.
+ *
+ * @see #write(Path,Iterable,Charset,OpenOption[])
+ */
+ public static BufferedWriter newBufferedWriter(Path path, Charset cs,
+ OpenOption... options)
+ throws IOException
+ {
+ CharsetEncoder encoder = cs.newEncoder();
+ Writer writer = new OutputStreamWriter(newOutputStream(path, options), encoder);
+ return new BufferedWriter(writer);
+ }
+
+ /**
+ * Reads all bytes from an input stream and writes them to an output stream.
+ */
+ private static long copy(InputStream source, OutputStream sink)
+ throws IOException
+ {
+ long nread = 0L;
+ byte[] buf = new byte[BUFFER_SIZE];
+ int n;
+ while ((n = source.read(buf)) > 0) {
+ sink.write(buf, 0, n);
+ nread += n;
+ }
+ return nread;
}
/**
- * Creates a directory by creating all nonexistent parent directories first.
+ * Copies all bytes from an input stream to a file. On return, the input
+ * stream will be at end of stream.
+ *
+ * <p> By default, the copy fails if the target file already exists or is a
+ * symbolic link. If the {@link StandardCopyOption#REPLACE_EXISTING
+ * REPLACE_EXISTING} option is specified, and the target file already exists,
+ * then it is replaced if it is not a non-empty directory. If the target
+ * file exists and is a symbolic link, then the symbolic link is replaced.
+ * In this release, the {@code REPLACE_EXISTING} option is the only option
+ * required to be supported by this method. Additional options may be
+ * supported in future releases.
*
- * <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 an I/O error occurs reading from the input stream or writing to
+ * the file, then it may do so after the target file has been created and
+ * after some bytes have been read or written. Consequently the input
+ * stream may not be at end of stream and may be in an inconsistent state.
+ * It is strongly recommended that the input stream be promptly closed if an
+ * I/O error occurs.
+ *
+ * <p> This method may block indefinitely reading from the input stream (or
+ * writing to the file). The behavior for the case that the input stream is
+ * <i>asynchronously closed</i> or the thread interrupted during the copy is
+ * highly input stream and file system provider specific and therefore not
+ * specified.
*
- * <p> If this method fails, then it may do so after creating some, but not
- * all, of the parent directories.
+ * <p> <b>Usage example</b>: Suppose we want to capture a web page and save
+ * it to a file:
+ * <pre>
+ * Path path = ...
+ * URI u = URI.create("http://java.sun.com/");
+ * try (InputStream in = u.toURL().openStream()) {
+ * Files.copy(in, path);
+ * }
+ * </pre>
*
- * @param dir
- * the directory to create
+ * @param in
+ * the input stream to read from
+ * @param target
+ * the path to the file
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @return the number of bytes read or written
*
- * @param attrs
- * an optional list of file attributes to set atomically when
- * creating the directory
- *
+ * @throws IOException
+ * if an I/O error occurs when reading or writing
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i> *
* @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
+ * if {@code options} contains a copy option that is not supported
* @throws SecurityException
- * in the case of the default provider, and a security manager is
+ * 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}
- *
+ * method is invoked to check write access to the file. Where the
+ * {@code REPLACE_EXISTING} option is specified, the security
+ * manager's {@link SecurityManager#checkDelete(String) checkDelete}
+ * method is invoked to check that an existing file can be deleted.
*/
- public static void createDirectories(Path dir, FileAttribute<?>... attrs)
+ public static long copy(InputStream in, Path target, CopyOption... options)
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
+ // ensure not null before opening file
+ Objects.requireNonNull(in);
+
+ // check for REPLACE_EXISTING
+ boolean replaceExisting = false;
+ for (CopyOption opt: options) {
+ if (opt == StandardCopyOption.REPLACE_EXISTING) {
+ replaceExisting = true;
+ } else {
+ if (opt == null) {
+ throw new NullPointerException("options contains 'null'");
+ } else {
+ throw new UnsupportedOperationException(opt + " not supported");
+ }
+ }
}
- // find existing parent (may require absolute path)
+ // attempt to delete an existing file
SecurityException se = null;
- try {
- dir = dir.toAbsolutePath();
- } catch (SecurityException x) {
- // don't have permission to get absolute path
- se = x;
+ if (replaceExisting) {
+ try {
+ deleteIfExists(target);
+ } catch (SecurityException x) {
+ 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
+
+ // attempt to create target file. If it fails with
+ // FileAlreadyExistsException then it may be because the security
+ // manager prevented us from deleting the file, in which case we just
+ // throw the SecurityException.
+ OutputStream ostream;
+ try {
+ ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW,
+ StandardOpenOption.WRITE);
+ } catch (FileAlreadyExistsException x) {
if (se != null)
throw se;
- throw new IOException("Root directory does not exist");
+ // someone else won the race and created the file
+ throw x;
}
- // create directories
- Path child = parent;
- for (Path name: parent.relativize(dir)) {
- child = child.resolve(name);
- createAndCheckIsDirectory(child, attrs);
+ // do the copy
+ try (OutputStream out = ostream) {
+ return copy(in, out);
}
}
/**
- * Attempts to create a directory. Does nothing if the directory already
- * exists.
+ * Copies all bytes from a file to an output stream.
+ *
+ * <p> If an I/O error occurs reading from the file or writing to the output
+ * stream, then it may do so after some bytes have been read or written.
+ * Consequently the output stream may be in an inconsistent state. It is
+ * strongly recommended that the output stream be promptly closed if an I/O
+ * error occurs.
+ *
+ * <p> This method may block indefinitely writing to the output stream (or
+ * reading from the file). The behavior for the case that the output stream
+ * is <i>asynchronously closed</i> or the thread interrupted during the copy
+ * is highly output stream and file system provider specific and therefore
+ * not specified.
+ *
+ * <p> Note that if the given output stream is {@link java.io.Flushable}
+ * then its {@link java.io.Flushable#flush flush} method may need to invoked
+ * after this method completes so as to flush any buffered output.
+ *
+ * @param source
+ * the path to the file
+ * @param out
+ * the output stream to write to
+ *
+ * @return the number of bytes read or written
+ *
+ * @throws IOException
+ * if an I/O error occurs when reading or writing
+ * @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.
*/
- private static void createAndCheckIsDirectory(Path dir, FileAttribute<?>... attrs)
+ public static long copy(Path source, OutputStream out) throws IOException {
+ // ensure not null before opening file
+ Objects.requireNonNull(out);
+
+ try (InputStream in = newInputStream(source)) {
+ return copy(in, out);
+ }
+ }
+
+ /**
+ * Read all the bytes from an input stream. The {@code initialSize}
+ * parameter indicates the initial size of the byte[] to allocate.
+ */
+ private static byte[] read(InputStream source, int initialSize)
throws IOException
{
- try {
- dir.createDirectory(attrs);
- } catch (FileAlreadyExistsException x) {
- boolean isDirectory = Attributes
- .readBasicFileAttributes(dir, LinkOption.NOFOLLOW_LINKS).isDirectory();
- if (!isDirectory)
- throw x;
+ int capacity = initialSize;
+ byte[] buf = new byte[capacity];
+ int nread = 0;
+ int rem = buf.length;
+ int n;
+ // read to EOF which may read more or less than initialSize (eg: file
+ // is truncated while we are reading)
+ while ((n = source.read(buf, nread, rem)) > 0) {
+ nread += n;
+ rem -= n;
+ assert rem >= 0;
+ if (rem == 0) {
+ // need larger buffer
+ int newCapacity = capacity << 1;
+ if (newCapacity < 0) {
+ if (capacity == Integer.MAX_VALUE)
+ throw new OutOfMemoryError("Required array size too large");
+ newCapacity = Integer.MAX_VALUE;
+ }
+ rem = newCapacity - capacity;
+ buf = Arrays.copyOf(buf, newCapacity);
+ capacity = newCapacity;
+ }
+ }
+ return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
+ }
+
+ /**
+ * Read all the bytes from a file. The method ensures that the file is
+ * closed when all bytes have been read or an I/O error, or other runtime
+ * exception, is thrown.
+ *
+ * <p> Note that this method is intended for simple cases where it is
+ * convenient to read all bytes into a byte array. It is not intended for
+ * reading in large files.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return a byte array containing the bytes read from the file
+ *
+ * @throws IOException
+ * if an I/O error occurs reading from the stream
+ * @throws OutOfMemoryError
+ * if an array of the required size cannot be allocated, for
+ * example the file is larger that {@code 2GB}
+ * @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 static byte[] readAllBytes(Path path) throws IOException {
+ long size = size(path);
+ if (size > (long)Integer.MAX_VALUE)
+ throw new OutOfMemoryError("Required array size too large");
+
+ try (InputStream in = newInputStream(path)) {
+ return read(in, (int)size);
+ }
+ }
+
+ /**
+ * Read all lines from a file. This method ensures that the file is
+ * closed when all bytes have been read or an I/O error, or other runtime
+ * exception, is thrown. Bytes from the file are decoded into characters
+ * using the specified charset.
+ *
+ * <p> This method recognizes the following as line terminators:
+ * <ul>
+ * <li> <code>\u000D</code> followed by <code>\u000A</code>,
+ * CARRIAGE RETURN followed by LINE FEED </li>
+ * <li> <code>\u000A</code>, LINE FEED </li>
+ * <li> <code>\u000D</code>, CARRIAGE RETURN </li>
+ * </ul>
+ * <p> Additional Unicode line terminators may be recognized in future
+ * releases.
+ *
+ * <p> Note that this method is intended for simple cases where it is
+ * convenient to read all lines in a single operation. It is not intended
+ * for reading in large files.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for decoding
+ *
+ * @return the lines from the file as a {@code List}; whether the {@code
+ * List} is modifiable or not is implementation dependent and
+ * therefore not specified
+ *
+ * @throws IOException
+ * if an I/O error occurs reading from the file or a malformed or
+ * unmappable byte sequence is read
+ * @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.
+ *
+ * @see #newBufferedReader
+ */
+ public static List<String> readAllLines(Path path, Charset cs)
+ throws IOException
+ {
+ try (BufferedReader reader = newBufferedReader(path, cs)) {
+ List<String> result = new ArrayList<>();
+ for (;;) {
+ String line = reader.readLine();
+ if (line == null)
+ break;
+ result.add(line);
+ }
+ return result;
}
}
+
+ /**
+ * Writes bytes to a file. The {@code options} parameter specifies how the
+ * the file is created or opened. If no options are present then this method
+ * works as if the {@link StandardOpenOption#CREATE CREATE}, {@link
+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+ * opens the file for writing, creating the file if it doesn't exist, or
+ * initially truncating an existing {@link #isRegularFile regular-file} to
+ * a size of {@code 0}. All bytes in the byte array are written to the file.
+ * The method ensures that the file is closed when all bytes have been
+ * written (or an I/O error or other runtime exception is thrown). If an I/O
+ * error occurs then it may do so after the file has created or truncated,
+ * or after some bytes have been written to the file.
+ *
+ * <p> <b>Usage example</b>: By default the method creates a new file or
+ * overrides an existing file. Suppose you instead want to append bytes
+ * to an existing file:
+ * <pre>
+ * Path path = ...
+ * byte[] bytes = ...
+ * Files.write(path, bytes, StandardOpenOption.APPEND);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param bytes
+ * the byte array with the bytes to write
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return the path
+ *
+ * @throws IOException
+ * if an I/O error occurs writing to or creating the file
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @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 static Path write(Path path, byte[] bytes, OpenOption... options)
+ throws IOException
+ {
+ // ensure bytes is not null before opening file
+ Objects.requireNonNull(bytes);
+
+ try (OutputStream out = Files.newOutputStream(path, options)) {
+ int len = bytes.length;
+ int rem = len;
+ while (rem > 0) {
+ int n = Math.min(rem, BUFFER_SIZE);
+ out.write(bytes, (len-rem), n);
+ rem -= n;
+ }
+ }
+ return path;
+ }
+
+ /**
+ * Write lines of text to a file. Each line is a char sequence and is
+ * written to the file in sequence with each line terminated by the
+ * platform's line separator, as defined by the system property {@code
+ * line.separator}. Characters are encoded into bytes using the specified
+ * charset.
+ *
+ * <p> The {@code options} parameter specifies how the the file is created
+ * or opened. If no options are present then this method works as if the
+ * {@link StandardOpenOption#CREATE CREATE}, {@link
+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+ * opens the file for writing, creating the file if it doesn't exist, or
+ * initially truncating an existing {@link #isRegularFile regular-file} to
+ * a size of {@code 0}. The method ensures that the file is closed when all
+ * lines have been written (or an I/O error or other runtime exception is
+ * thrown). If an I/O error occurs then it may do so after the file has
+ * created or truncated, or after some bytes have been written to the file.
+ *
+ * @param path
+ * the path to the file
+ * @param lines
+ * an object to iterate over the char sequences
+ * @param cs
+ * the charset to use for encoding
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return the path
+ *
+ * @throws IOException
+ * if an I/O error occurs writing to or creating the file, or the
+ * text cannot be encoded using the specified charset
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @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 static Path write(Path path, Iterable<? extends CharSequence> lines,
+ Charset cs, OpenOption... options)
+ throws IOException
+ {
+ // ensure lines is not null before opening file
+ Objects.requireNonNull(lines);
+ CharsetEncoder encoder = cs.newEncoder();
+ OutputStream out = newOutputStream(path, options);
+ try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
+ for (CharSequence line: lines) {
+ writer.append(line);
+ writer.newLine();
+ }
+ }
+ return path;
+ }
}
--- a/jdk/src/share/classes/java/nio/file/LinkOption.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/LinkOption.java Tue Feb 08 14:25:33 2011 -0800
@@ -35,8 +35,8 @@
/**
* Do not follow symbolic links.
*
- * @see FileRef#getFileAttributeView(Class,LinkOption[])
- * @see Path#copyTo
+ * @see Files#getFileAttributeView(Path,Class,LinkOption[])
+ * @see Files#copy
* @see SecureDirectoryStream#newByteChannel
*/
NOFOLLOW_LINKS;
--- a/jdk/src/share/classes/java/nio/file/LinkPermission.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/LinkPermission.java Tue Feb 08 14:25:33 2011 -0800
@@ -59,8 +59,8 @@
*
* @since 1.7
*
- * @see Path#createLink
- * @see Path#createSymbolicLink
+ * @see Files#createLink
+ * @see Files#createSymbolicLink
*/
public final class LinkPermission extends BasicPermission {
static final long serialVersionUID = -1441492453772213220L;
--- a/jdk/src/share/classes/java/nio/file/OpenOption.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/OpenOption.java Tue Feb 08 14:25:33 2011 -0800
@@ -29,8 +29,8 @@
* An object that configures how to open or create a file.
*
* <p> Objects of this type are used by methods such as {@link
- * Path#newOutputStream(OpenOption[]) newOutputStream}, {@link
- * Path#newByteChannel newByteChannel}, {@link
+ * Files#newOutputStream(Path,OpenOption[]) newOutputStream}, {@link
+ * Files#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/jdk/src/share/classes/java/nio/file/Path.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/Path.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,147 +25,95 @@
package java.nio.file;
-import java.nio.file.attribute.*;
-import java.nio.channels.SeekableByteChannel;
+import java.io.File;
import java.io.IOException;
-import java.io.OutputStream;
import java.net.URI;
import java.util.Iterator;
-import java.util.Set;
/**
- * A file reference that locates a file using a system dependent path. The file
- * is not required to exist.
- *
- * <p> On many platforms a <em>path</em> is the means to locate and access files
- * in a file system. A path is hierarchical and composed of a sequence of
- * directory and file name elements separated by a special separator or
- * delimiter.
- *
- * <h4>Path operations</h4>
+ * An object that may be used to locate a file in a file system. It will
+ * typically represent a system dependent file path.
*
- * <p> A system dependent path represented by this class is conceptually a
- * sequence of name elements and optionally a <em>root component</em>. The name
- * that is <em>farthest</em> from the root of the directory hierarchy is the
- * name of a file or directory. The other elements are directory names. The root
- * component typically identifies a file system hierarchy. A {@code Path} can
- * represent a root, a root and a sequence of names, or simply one or more name
- * elements. It defines the {@link #getName() getName}, {@link #getParent
- * getParent}, {@link #getRoot getRoot}, and {@link #subpath subpath} methods
- * to access the components or a subsequence of its name elements.
+ * <p> A {@code Path} represents a path that is hierarchical and composed of a
+ * sequence of directory and file name elements separated by a special separator
+ * or delimiter. A <em>root component</em>, that identifies a file system
+ * hierarchy, may also be present. The name element that is <em>farthest</em>
+ * from the root of the directory hierarchy is the name of a file or directory.
+ * The other name elements are directory names. A {@code Path} can represent a
+ * root, a root and a sequence of names, or simply one or more name elements.
+ * A {@code Path} is considered to be an <i>empty path</i> if it consists
+ * solely of one name element that is empty. Accessing a file using an
+ * <i>empty path</i> is equivalent to accessing the default directory of the
+ * file system. {@code Path} defines the {@link #getFileName() getFileName},
+ * {@link #getParent getParent}, {@link #getRoot getRoot}, and {@link #subpath
+ * subpath} methods to access the path components or a subsequence of its name
+ * elements.
*
* <p> In addition to accessing the components of a path, a {@code Path} also
- * defines {@link #resolve(Path) resolve} and {@link #relativize relativize}
- * operations. Paths can also be {@link #compareTo compared}, and tested
- * against each other using using the {@link #startsWith startsWith} and {@link
- * #endsWith endWith} methods.
- *
- * <h4>File operations</h4>
+ * defines the {@link #resolve(Path) resolve} and {@link #resolveSibling(Path)
+ * resolveSibling} methods to combine paths. The {@link #relativize relativize}
+ * method that can be used to construct a relative path between two paths.
+ * Paths can be {@link #compareTo compared}, and tested against each other using
+ * the {@link #startsWith startsWith} and {@link #endsWith endWith} methods.
*
- * <p> A {@code Path} is either <em>absolute</em> or <em>relative</em>. An
- * absolute path is complete in that does not need to be combined with another
- * path in order to locate a file. All operations on relative paths are first
- * resolved against a file system's default directory as if by invoking the
- * {@link #toAbsolutePath toAbsolutePath} method.
- *
- * <p> In addition to the operations defined by the {@link FileRef} interface,
- * this class defines the following operations:
+ * <p> This interface extends {@link Watchable} interface so that a directory
+ * located by a path can be {@link #register registered} with a {@link
+ * WatchService} and entries in the directory watched. </p>
*
- * <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 symbolic link may be {@link #readSymbolicLink read}. </p></li>
- * <li><p> The {@link #toRealPath real} path of an existing file may be
- * obtained. </li></p>
- * </ul>
+ * <p> <b>WARNING:</b> This interface is only intended to be implemented by
+ * those developing custom file system implementations. Methods may be added to
+ * this interface in future releases. </p>
*
- * <p> This class implements {@link Watchable} interface so that a directory
- * located by a path can be {@link #register registered} with a {@link WatchService}.
- * and entries in the directory watched.
- *
- * <h4>File attributes</h4>
- *
- * 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:
+ * <a name="interop"><h4>Accessing Files</h4></a>
+ * <p> Paths may be used with the {@link Files} class to operate on files,
+ * directories, and other types of files. For example, suppose we want a {@link
+ * java.io.BufferedReader} to read text from a file "{@code access.log}". The
+ * file is located in a directory "{@code logs}" relative to the current working
+ * directory and is UTF-8 encoded.
* <pre>
- * Path file = ...
- * BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ * Path path = FileSystems.getDefault().getPath("logs", "access.log");
+ * BufferReader reader = Files.newBufferedReader(path, Charset.forName("UTF-8"));
* </pre>
*
* <a name="interop"><h4>Interoperability</h4></a>
- *
- * <p> Paths created by file systems associated with the default {@link
+ * <p> Paths associated with the default {@link
* java.nio.file.spi.FileSystemProvider provider} are generally interoperable
* with the {@link java.io.File java.io.File} class. Paths created by other
* providers are unlikely to be interoperable with the abstract path names
- * represented by {@code java.io.File}. The {@link java.io.File#toPath
- * File.toPath} method may be used to obtain a {@code Path} from the abstract
- * path name represented by a {@code java.io.File java.io.File} object. The
- * resulting {@code Path} can be used to operate on the same file as the {@code
- * java.io.File} object.
- *
- * <p> Path objects created by file systems associated with the default
- * provider are interoperable with objects created by other file systems created
- * by the same provider. Path objects created by file systems associated with
- * other providers may not be interoperable with other file systems created by
- * the same provider. The reasons for this are provider specific.
+ * represented by {@code java.io.File}. The {@link java.io.File#toPath toPath}
+ * method may be used to obtain a {@code Path} from the abstract path name
+ * represented by a {@code java.io.File} object. The resulting {@code Path} can
+ * be used to operate on the same file as the {@code java.io.File} object. In
+ * addition, the {@link #toFile toFile} method is useful to construct a {@code
+ * File} from the {@code String} representation of a {@code Path}.
*
* <h4>Concurrency</h4></a>
- *
- * <p> Instances of this class are immutable and safe for use by multiple concurrent
- * threads.
+ * <p> Implementations of this interface are immutable and safe for use by
+ * multiple concurrent threads.
*
* @since 1.7
+ * @see Paths
*/
-public abstract class Path
- implements FileRef, Comparable<Path>, Iterable<Path>, Watchable
+public interface Path
+ extends Comparable<Path>, Iterable<Path>, Watchable
{
/**
- * Initializes a new instance of this class.
- */
- protected Path() { }
-
- /**
* Returns the file system that created this object.
*
* @return the file system that created this object
*/
- public abstract FileSystem getFileSystem();
+ FileSystem getFileSystem();
/**
* Tells whether or not this path is absolute.
*
- * <p> An absolute path is complete in that it doesn't need to be
- * combined with other path information in order to locate a file.
+ * <p> An absolute path is complete in that it doesn't need to be combined
+ * with other path information in order to locate a file.
*
* @return {@code true} if, and only if, this path is absolute
*/
- public abstract boolean isAbsolute();
+ boolean isAbsolute();
/**
* Returns the root component of this path as a {@code Path} object,
@@ -174,17 +122,17 @@
* @return a path representing the root component of this path,
* or {@code null}
*/
- public abstract Path getRoot();
+ Path getRoot();
/**
- * Returns the name of the file or directory denoted by this path. The
- * file name is the <em>farthest</em> element from the root in the directory
- * hierarchy.
+ * Returns the name of the file or directory denoted by this path as a
+ * {@code Path} object. The file name is the <em>farthest</em> element from
+ * the root in the directory hierarchy.
*
* @return a path representing the name of the file or directory, or
* {@code null} if this path has zero elements
*/
- public abstract Path getName();
+ Path getFileName();
/**
* Returns the <em>parent path</em>, or {@code null} if this path does not
@@ -209,7 +157,7 @@
*
* @return a path representing the path's parent
*/
- public abstract Path getParent();
+ Path getParent();
/**
* Returns the number of name elements in the path.
@@ -217,10 +165,10 @@
* @return the number of elements in the path, or {@code 0} if this path
* only represents a root component
*/
- public abstract int getNameCount();
+ int getNameCount();
- /**
- * Returns a name element of this path.
+ /**
+ * Returns a name element of this path as a {@code Path} object.
*
* <p> The {@code index} parameter is the index of the name element to return.
* The element that is <em>closest</em> to the root in the directory hierarchy
@@ -237,7 +185,7 @@
* equal to the number of elements, or this path has zero name
* elements
*/
- public abstract Path getName(int index);
+ Path getName(int index);
/**
* Returns a relative {@code Path} that is a subsequence of the name
@@ -264,7 +212,7 @@
* the number of elements. If {@code endIndex} is less than or
* equal to {@code beginIndex}, or larger than the number of elements.
*/
- public abstract Path subpath(int beginIndex, int endIndex);
+ Path subpath(int beginIndex, int endIndex);
/**
* Tests if this path starts with the given path.
@@ -286,7 +234,25 @@
* @return {@code true} if this path starts with the given path; otherwise
* {@code false}
*/
- public abstract boolean startsWith(Path other);
+ boolean startsWith(Path other);
+
+ /**
+ * Tests if this path starts with a {@code Path}, constructed by converting
+ * the given path string, in exactly the manner specified by the {@link
+ * #startsWith(Path) startsWith(Path)} method. On UNIX for example, the path
+ * "{@code foo/bar}" starts with "{@code foo}" and "{@code foo/bar}". It
+ * does not start with "{@code f}" or "{@code fo}".
+ *
+ * @param other
+ * the given path string
+ *
+ * @return {@code true} if this path starts with the given path; otherwise
+ * {@code false}
+ *
+ * @throws InvalidPathException
+ * If the path string cannot be converted to a Path.
+ */
+ boolean startsWith(String other);
/**
* Tests if this path ends with the given path.
@@ -310,7 +276,25 @@
* @return {@code true} if this path ends with the given path; otherwise
* {@code false}
*/
- public abstract boolean endsWith(Path other);
+ boolean endsWith(Path other);
+
+ /**
+ * Tests if this path ends with a {@code Path}, constructed by converting
+ * the given path string, in exactly the manner specified by the {@link
+ * #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path
+ * "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does
+ * not end with "{@code r}" or "{@code /bar}".
+ *
+ * @param other
+ * the given path string
+ *
+ * @return {@code true} if this path starts with the given path; otherwise
+ * {@code false}
+ *
+ * @throws InvalidPathException
+ * If the path string cannot be converted to a Path.
+ */
+ boolean endsWith(String other);
/**
* Returns a path that is this path with redundant name elements eliminated.
@@ -330,14 +314,14 @@
* path may result in the path that locates a different file than the original
* path. This can arise when the preceding name is a symbolic link.
*
- * @return the resulting path, or this path if it does not contain
- * redundant name elements, or {@code null} if this path does not
- * have a root component and all name elements are redundant
+ * @return the resulting path or this path if it does not contain
+ * redundant name elements; an empty path is returned if this path
+ * does have a root component and all name elements are redundant
*
* @see #getParent
* @see #toRealPath
*/
- public abstract Path normalize();
+ Path normalize();
// -- resolution and relativization --
@@ -346,28 +330,31 @@
*
* <p> If the {@code other} parameter is an {@link #isAbsolute() absolute}
* path then this method trivially returns {@code other}. If {@code other}
- * is {@code null} then this path is returned. Otherwise this method
- * considers this path to be a directory and resolves the given path
- * against this path. In the simplest case, the given path does not have
- * a {@link #getRoot root} component, in which case this method <em>joins</em>
- * the given path to this path and returns a resulting path that {@link
- * #endsWith ends} with the given path. Where the given path has a root
- * component then resolution is highly implementation dependent and therefore
- * unspecified.
+ * is an <i>empty path</i> then this method trivially returns this path.
+ * Otherwise this method considers this path to be a directory and resolves
+ * the given path against this path. In the simplest case, the given path
+ * does not have a {@link #getRoot root} component, in which case this method
+ * <em>joins</em> the given path to this path and returns a resulting path
+ * that {@link #endsWith ends} with the given path. Where the given path has
+ * a root component then resolution is highly implementation dependent and
+ * therefore unspecified.
*
* @param other
- * the path to resolve against this path; can be {@code null}
+ * the path to resolve against this path
*
* @return the resulting path
*
* @see #relativize
*/
- public abstract Path resolve(Path other);
+ Path resolve(Path other);
/**
* Converts a given path string to a {@code Path} and resolves it against
* this {@code Path} in exactly the manner specified by the {@link
- * #resolve(Path) resolve} method.
+ * #resolve(Path) resolve} method. For example, suppose that the name
+ * separator is "{@code /}" and a path represents "{@code foo/bar}", then
+ * invoking this method with the path string "{@code gus}" will result in
+ * the {@code Path} "{@code foo/bar/gus}".
*
* @param other
* the path string to resolve against this path
@@ -375,11 +362,49 @@
* @return the resulting path
*
* @throws InvalidPathException
- * If the path string cannot be converted to a Path.
+ * if the path string cannot be converted to a Path.
*
* @see FileSystem#getPath
*/
- public abstract Path resolve(String other);
+ Path resolve(String other);
+
+ /**
+ * Resolves the given path against this path's {@link #getParent parent}
+ * path. This is useful where a file name needs to be <i>replaced</i> with
+ * another file name. For example, suppose that the name separator is
+ * "{@code /}" and a path represents "{@code dir1/dir2/foo}", then invoking
+ * this method with the {@code Path} "{@code bar}" will result in the {@code
+ * Path} "{@code dir1/dir2/bar}". If this path does not have a parent path,
+ * or {@code other} is {@link #isAbsolute() absolute}, then this method
+ * returns {@code other}. If {@code other} is an empty path then this method
+ * returns this path's parent, or where this path doesn't have a parent, the
+ * empty path.
+ *
+ * @param other
+ * the path to resolve against this path's parent
+ *
+ * @return the resulting path
+ *
+ * @see #resolve(Path)
+ */
+ Path resolveSibling(Path other);
+
+ /**
+ * Converts a given path string to a {@code Path} and resolves it against
+ * this path's {@link #getParent parent} path in exactly the manner
+ * specified by the {@link #resolveSibling(Path) resolveSibling} method.
+ *
+ * @param other
+ * the path string to resolve against this path's parent
+ *
+ * @return the resulting path
+ *
+ * @throws InvalidPathException
+ * if the path string cannot be converted to a Path.
+ *
+ * @see FileSystem#getPath
+ */
+ Path resolveSibling(String other);
/**
* Constructs a relative path between this path and a given path.
@@ -395,17 +420,17 @@
* constructed if only one of the paths have a root component. Where both
* paths have a root component then it is implementation dependent if a
* relative path can be constructed. If this path and the given path are
- * {@link #equals equal} then {@code null} is returned.
+ * {@link #equals equal} then an <i>empty path</i> is returned.
*
- * <p> For any two paths <i>p</i> and <i>q</i>, where <i>q</i> does not have
- * a root component,
+ * <p> For any two {@link #normalize normalized} paths <i>p</i> and
+ * <i>q</i>, where <i>q</i> does not have a root component,
* <blockquote>
* <i>p</i><tt>.relativize(</tt><i>p</i><tt>.resolve(</tt><i>q</i><tt>)).equals(</tt><i>q</i><tt>)</tt>
* </blockquote>
*
* <p> When symbolic links are supported, then whether the resulting path,
* when resolved against this path, yields a path that can be used to locate
- * the {@link #isSameFile same} file as {@code other} is implementation
+ * the {@link Files#isSameFile same} file as {@code other} is implementation
* dependent. For example, if this path is {@code "/a/b"} and the given
* path is {@code "/a/x"} then the resulting relative path may be {@code
* "../x"}. If {@code "b"} is a symbolic link then is implementation
@@ -414,185 +439,14 @@
* @param other
* the path to relativize against this path
*
- * @return the resulting relative path, or {@code null} if both paths are
+ * @return the resulting relative path, or an empty path if both paths are
* equal
*
* @throws IllegalArgumentException
* if {@code other} is not a {@code Path} that can be relativized
* against this path
*/
- public abstract Path relativize(Path other);
-
- // -- file operations --
-
- /**
- * Deletes the file located by this path.
- *
- * <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
- * symbolic link itself, not the final target of the link, is deleted.
- *
- * <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
- * need 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 symbolic
- * link itself, not the final target of the link, is deleted.
- *
- * <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 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 deleteIfExists() throws IOException;
-
- /**
- * Creates a symbolic link to a target <i>(optional operation)</i>.
- *
- * <p> The {@code target} parameter is the target of the link. It may be an
- * {@link Path#isAbsolute absolute} or relative path and may not exist. When
- * the target is a relative path then file system operations on the resulting
- * link are relative to the path of the link.
- *
- * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
- * attributes} to set atomically when creating the link. 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 symbolic links are supported, but the underlying {@link FileStore}
- * does not support symbolic links, then this may fail with an {@link
- * IOException}. Additionally, some operating systems may require that the
- * Java virtual machine be started with implementation specific privileges to
- * create symbolic links, in which case this method may throw {@code IOException}.
- *
- * @param target
- * the target of the symbolic link
- * @param attrs
- * the array of attributes to set atomically when creating the
- * symbolic link
- *
- * @return this path
- *
- * @throws UnsupportedOperationException
- * if the implementation does not support symbolic links or the
- * array contains an attribute that cannot be set atomically when
- * creating the symbolic link
- * @throws FileAlreadyExistsException
- * if a file with the name already exists <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, it denies {@link LinkPermission}<tt>("symbolic")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the path of the symbolic link.
- */
- public abstract Path createSymbolicLink(Path target, FileAttribute<?>... attrs)
- throws IOException;
-
- /**
- * Creates a new link (directory entry) for an existing file <i>(optional
- * operation)</i>.
- *
- * <p> This path locates the directory entry to create. The {@code existing}
- * parameter is the path to an existing file. This method creates a new
- * directory entry for the file so that it can be accessed using this path.
- * On some file systems this is known as creating a "hard link". Whether the
- * file attributes are maintained for the file or for each directory entry
- * is file system specific and therefore not specified. Typically, a file
- * system requires that all links (directory entries) for a file be on the
- * same file system. Furthermore, on some platforms, the Java virtual machine
- * may require to be started with implementation specific privileges to
- * create hard links or to create links to directories.
- *
- * @param existing
- * a reference to an existing file
- *
- * @return this path
- *
- * @throws UnsupportedOperationException
- * if the implementation does not support adding an existing file
- * to a directory
- * @throws FileAlreadyExistsException
- * if the entry could not otherwise be created because a file of
- * that name already exists <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, it denies {@link LinkPermission}<tt>("hard")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to both this path and the path of the
- * existing file.
- */
- public abstract Path createLink(Path existing) throws IOException;
-
- /**
- * Reads the target of a symbolic link <i>(optional operation)</i>.
- *
- * <p> If the file system supports <a href="package-summary.html#links">symbolic
- * links</a> then this method is used to read the target of the link, failing
- * if the file is not a symbolic link. The target of the link need not exist.
- * The returned {@code Path} object will be associated with the same file
- * system as this {@code Path}.
- *
- * @return a {@code Path} object representing the target of the link
- *
- * @throws UnsupportedOperationException
- * if the implementation does not support symbolic links
- * @throws NotLinkException
- * if the target could otherwise not be read because the file
- * is not a symbolic link <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, it checks that {@code FilePermission} has been
- * granted with the "{@code readlink}" action to read the link.
- */
- public abstract Path readSymbolicLink() throws IOException;
+ Path relativize(Path other);
/**
* Returns a URI to represent this path.
@@ -647,7 +501,7 @@
* is installed, the {@link #toAbsolutePath toAbsolutePath} method
* throws a security exception.
*/
- public abstract URI toUri();
+ URI toUri();
/**
* Returns a {@code Path} object representing the absolute path of this
@@ -670,14 +524,14 @@
* checkPropertyAccess} method is invoked to check access to the
* system property {@code user.dir}
*/
- public abstract Path toAbsolutePath();
+ Path toAbsolutePath();
/**
* Returns the <em>real</em> path of an existing file.
*
* <p> The precise definition of this method is implementation dependent but
* in general it derives from this path, an {@link #isAbsolute absolute}
- * path that locates the {@link #isSameFile same} file as this path, but
+ * path that locates the {@link Files#isSameFile same} file as this path, but
* with name elements that represent the actual name of the directories
* and the file. For example, where filename comparisons on a file system
* are case insensitive then the name elements represent the names in their
@@ -713,756 +567,25 @@
* checkPropertyAccess} method is invoked to check access to the
* system property {@code user.dir}
*/
- public abstract Path toRealPath(boolean resolveLinks) throws IOException;
-
- /**
- * Copy the file located by this path to a target location.
- *
- * <p> This method copies the file located by this {@code Path} to the
- * target location with the {@code options} parameter specifying how the
- * copy is performed. By default, the copy fails if the target file already
- * exists, except if the source and target are the {@link #isSameFile same}
- * file, in which case this method has no effect. File attributes are not
- * required to be copied to the target file. If symbolic links are supported,
- * and the file is a symbolic link, then the final target of the link is copied.
- * If the file is a directory then it creates an empty directory in the target
- * location (entries in the directory are not copied). This method can be
- * used with the {@link Files#walkFileTree Files.walkFileTree} utility
- * method to copy a directory and all entries in the directory, or an entire
- * <i>file-tree</i> where required.
- *
- * <p> The {@code options} parameter is an array of options and may contain
- * any of the following:
- *
- * <table border=1 cellpadding=5 summary="">
- * <tr> <th>Option</th> <th>Description</th> </tr>
- * <tr>
- * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
- * <td> If the target file exists, then the target file is replaced if it
- * is not a non-empty directory. If the target file exists and is a
- * symbolic link, then the symbolic link itself, not the target of
- * the link, is replaced. </td>
- * </tr>
- * <tr>
- * <td> {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} </td>
- * <td> Attempts to copy the file attributes associated with this file to
- * 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 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>
- * <td> Symbolic links are not followed. If the file, located by this path,
- * is a symbolic link, then the symbolic link itself, not the target of
- * the link, is copied. It is implementation specific if file attributes
- * can be copied to the new link. In other words, the {@code
- * COPY_ATTRIBUTES} option may be ignored when copying a symbolic link. </td>
- * </tr>
- * </table>
- *
- * <p> An implementation of this interface may support additional
- * implementation specific options.
- *
- * <p> Copying a file is not an atomic operation. If an {@link IOException}
- * is thrown then it possible that the target file is incomplete or some of
- * its file attributes have not been copied from the source file. When the
- * {@code REPLACE_EXISTING} option is specified and the target file exists,
- * then the target file is replaced. The check for the existence of the file
- * and the creation of the new file may not be atomic with respect to other
- * file system activities.
- *
- * @param target
- * the target location
- * @param options
- * options specifying how the copy should be done
- *
- * @return the target
- *
- * @throws UnsupportedOperationException
- * if the array contains a copy option that is not supported
- * @throws FileAlreadyExistsException
- * if the target file exists and cannot be replaced because the
- * {@code REPLACE_EXISTING} option is not specified, or the target
- * file is a non-empty 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#checkRead(String) checkRead}
- * method is invoked to check read access to the source file, the
- * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
- * to check write access to the target file. If a symbolic link is
- * copied the security manager is invoked to check {@link
- * LinkPermission}{@code ("symbolic")}.
- */
- public abstract Path copyTo(Path target, CopyOption... options)
- throws IOException;
-
- /**
- * Move or rename the file located by this path to a target location.
- *
- * <p> By default, this method attempts to move the file to the target
- * location, failing if the target file exists except if the source and
- * target are the {@link #isSameFile same} file, in which case this method
- * has no effect. If the file is a symbolic link then the symbolic link
- * itself, not the target of the link, is moved. This method may be
- * invoked to move an empty directory. 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. When invoked to move a
- * directory that is not empty then the directory is moved if it does not
- * require moving the entries in the directory. For example, renaming a
- * directory on the same {@link FileStore} will usually not require moving
- * the entries in the directory. When moving a directory requires that its
- * entries be moved then this method fails (by throwing an {@code
- * IOException}). To move a <i>file tree</i> may involve copying rather
- * than moving directories and this can be done using the {@link
- * #copyTo copyTo} method in conjunction with the {@link
- * Files#walkFileTree Files.walkFileTree} utility method.
- *
- * <p> The {@code options} parameter is an array of options and may contain
- * any of the following:
- *
- * <table border=1 cellpadding=5 summary="">
- * <tr> <th>Option</th> <th>Description</th> </tr>
- * <tr>
- * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
- * <td> If the target file exists, then the target file is replaced if it
- * is not a non-empty directory. If the target file exists and is a
- * symbolic link, then the symbolic link itself, not the target of
- * the link, is replaced. </td>
- * </tr>
- * <tr>
- * <td> {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} </td>
- * <td> The move is performed as an atomic file system operation and all
- * other options are ignored. If the target file exists then it is
- * implementation specific if the existing file is replaced or this method
- * fails by throwing an {@link IOException}. If the move cannot be
- * performed as an atomic file system operation then {@link
- * AtomicMoveNotSupportedException} is thrown. This can arise, for
- * example, when the target location is on a different {@code FileStore}
- * and would require that the file be copied, or target location is
- * associated with a different provider to this object. </td>
- * </table>
- *
- * <p> An implementation of this interface may support additional
- * implementation specific options.
- *
- * <p> Where the move requires that the file be copied then the {@link
- * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the
- * new file. An implementation may also attempt to copy other file
- * attributes but is not required to fail if the file attributes cannot be
- * copied. When the move is performed as a non-atomic operation, and a {@code
- * IOException} is thrown, then the state of the files is not defined. The
- * original file and the target file may both exist, the target file may be
- * incomplete or some of its file attributes may not been copied from the
- * original file.
- *
- * @param target
- * the target location
- * @param options
- * options specifying how the move should be done
- *
- * @return the target
- *
- * @throws UnsupportedOperationException
- * if the array contains a copy option that is not supported
- * @throws FileAlreadyExistsException
- * if the target file exists and cannot be replaced because the
- * {@code REPLACE_EXISTING} option is not specified, or the target
- * file is a non-empty directory
- * @throws AtomicMoveNotSupportedException
- * if the options array contains the {@code ATOMIC_MOVE} option but
- * the file cannot be moved as an atomic file system operation.
- * @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 both the source and
- * target file.
- */
- public abstract Path moveTo(Path target, CopyOption... options)
- throws IOException;
+ Path toRealPath(boolean resolveLinks) throws IOException;
/**
- * Opens the directory referenced by this object, returning a {@code
- * DirectoryStream} to iterate over all entries in the directory. The
- * elements returned by the directory stream's {@link DirectoryStream#iterator
- * iterator} are of type {@code Path}, each one representing an entry in the
- * directory. The {@code Path} objects are obtained as if by {@link
- * #resolve(Path) resolving} the name of the directory entry against this
- * 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.
- *
- * <p> When an implementation supports operations on entries in the
- * directory that execute in a race-free manner then the returned directory
- * stream is a {@link SecureDirectoryStream}.
- *
- * @return a new and open {@code DirectoryStream} object
- *
- * @throws NotDirectoryException
- * if the file could not otherwise be opened because it 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#checkRead(String) checkRead}
- * method is invoked to check read access to the directory.
- */
- public abstract DirectoryStream<Path> newDirectoryStream()
- throws IOException;
-
- /**
- * Opens the directory referenced by this object, returning a {@code
- * DirectoryStream} to iterate over the entries in the directory. The
- * elements returned by the directory stream's {@link DirectoryStream#iterator
- * iterator} are of type {@code Path}, each one representing an entry in the
- * 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 matching the
- * {@code String} representation of their file names against the given
- * <em>globbing</em> pattern.
- *
- * <p> For example, suppose we want to iterate over the files ending with
- * ".java" in a directory:
- * <pre>
- * Path dir = ...
- * DirectoryStream<Path> stream = dir.newDirectoryStream("*.java");
- * </pre>
- *
- * <p> The globbing pattern is specified by the {@link
- * FileSystem#getPathMatcher getPathMatcher} method.
- *
- * <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.
- *
- * <p> When an implementation supports operations on entries in the
- * directory that execute in a race-free manner then the returned directory
- * stream is a {@link SecureDirectoryStream}.
- *
- * @param glob
- * the glob pattern
- *
- * @return a new and open {@code DirectoryStream} object
- *
- * @throws java.util.regex.PatternSyntaxException
- * if the pattern is invalid
- * @throws NotDirectoryException
- * if the file could not otherwise be opened because it 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#checkRead(String) checkRead}
- * method is invoked to check read access to the directory.
- */
- public abstract DirectoryStream<Path> newDirectoryStream(String glob)
- throws IOException;
-
- /**
- * Opens the directory referenced by this object, returning a {@code
- * DirectoryStream} to iterate over the entries in the directory. The
- * elements returned by the directory stream's {@link DirectoryStream#iterator
- * iterator} are of type {@code Path}, each one representing an entry in the
- * 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}.
- *
- * <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.
+ * Returns a {@link File} object representing this path. Where this {@code
+ * Path} is associated with the default provider, then this method is
+ * equivalent to returning a {@code File} object constructed with the
+ * {@code String} representation of this path.
*
- * <p> Where the filter terminates due to an uncaught error or runtime
- * exception then it is propagated to the {@link Iterator#hasNext()
- * hasNext} or {@link Iterator#next() next} method. Where an {@code
- * IOException} is thrown, it results in the {@code hasNext} or {@code
- * next} method throwing a {@link DirectoryIteratorException} 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
- * stream is a {@link SecureDirectoryStream}.
- *
- * <p> <b>Usage Example:</b>
- * Suppose we want to iterate over the files in a directory that are
- * larger than 8K.
- * <pre>
- * DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
- * public boolean accept(Path file) throws IOException {
- * long size = Attributes.readBasicFileAttributes(file).size();
- * return (size > 8192L);
- * }
- * };
- * Path dir = ...
- * DirectoryStream<Path> stream = dir.newDirectoryStream(filter);
- * </pre>
- * @param filter
- * the directory stream filter
- *
- * @return a new and open {@code DirectoryStream} object
- *
- * @throws NotDirectoryException
- * if the file could not otherwise be opened because it 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#checkRead(String) checkRead}
- * method is invoked to check read access to the directory.
- */
- public abstract DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
- throws IOException;
-
- /**
- * Creates a new and empty file, failing if the file already exists.
+ * <p> If this path was created by invoking the {@code File} {@link
+ * File#toPath toPath} method then there is no guarantee that the {@code
+ * File} object returned by this method is {@link #equals equal} to the
+ * original {@code File}.
*
- * <p> This {@code Path} locates the file to create. The check for the
- * existence of the file and the creation of the new file if it does not
- * exist are a single operation that is atomic with respect to all other
- * filesystem activities that might affect the directory.
- *
- * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
- * file-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.
- *
- * @param attrs
- * an optional list of file attributes to set atomically when
- * creating the file
- *
- * @return this path
- *
- * @throws UnsupportedOperationException
- * if the array contains an attribute that cannot be set atomically
- * when creating the file
- * @throws FileAlreadyExistsException
- * if a file of that name already exists
- * <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 to check write access to the new file.
- */
- public abstract Path createFile(FileAttribute<?>... attrs) throws IOException;
-
- /**
- * Creates a new directory.
- *
- * <p> This {@code Path} locates the directory to create. The check for the
- * existence of the file and the creation of the directory if it does not
- * exist are a single operation that is atomic with respect to all other
- * filesystem activities that might affect the directory.
- *
- * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
- * file-attributes} to set atomically when creating the directory. 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.
- *
- * @param attrs
- * an optional list of file attributes to set atomically when
- * creating the directory
- *
- * @return this path
+ * @return a {@code File} object representing this path
*
* @throws UnsupportedOperationException
- * if the array contains an attribute that cannot be set atomically
- * when creating the directory
- * @throws FileAlreadyExistsException
- * if a directory could not otherwise be created because a file of
- * that name already exists <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 to check write access to the new directory.
- *
- * @see Files#createDirectories
- */
- public abstract Path createDirectory(FileAttribute<?>... attrs)
- throws IOException;
-
- /**
- * Opens or creates a file, returning a seekable byte channel to access 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#CREATE_NEW CREATE_NEW} </td>
- * <td> If this option is present then a new file is created, failing if
- * the file already exists or is a symbolic link. When creating a file the
- * check for the existence of the file and the creation of the file if it
- * does not exist is atomic with respect to other file system operations.
- * This option is ignored when the file is opened only for reading. </td>
- * </tr>
- * <tr>
- * <td > {@link StandardOpenOption#CREATE CREATE} </td>
- * <td> If this option is present then an existing file is opened if it
- * exists, otherwise a new file is created. This option is ignored if the
- * {@code CREATE_NEW} option is also present or the file is opened only
- * for reading. </td>
- * </tr>
- * <tr>
- * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
- * <td> When this option is present then the implementation makes a
- * <em>best effort</em> attempt to delete the file when closed by the
- * {@link SeekableByteChannel#close close} method. If the {@code close}
- * method is not invoked then a <em>best effort</em> attempt is made to
- * delete the file when the Java virtual machine terminates. </td>
- * </tr>
- * <tr>
- * <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
- * <td> When creating a new file this option is a <em>hint</em> that the
- * new file will be sparse. This option is ignored when not creating
- * a new file. </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 may also support additional implementation specific
- * options.
- *
- * <p> The {@code attrs} parameter is an optional array of file {@link
- * 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 java.nio.channels.FileChannel}.
- *
- * <p> <b>Usage Examples:</b>
- * <pre>
- * Path file = ...
- *
- * // open file for reading
- * ReadableByteChannel rbc = file.newByteChannel(EnumSet.of(READ)));
- *
- * // open file for writing to the end of an existing file, creating
- * // the file if it doesn't already exist
- * WritableByteChannel wbc = file.newByteChannel(EnumSet.of(CREATE,APPEND));
- *
- * // create file with initial permissions, opening it for both reading and writing
- * FileAttribute<Set<PosixFilePermission>> perms = ...
- * SeekableByteChannel sbc = file.newByteChannel(EnumSet.of(CREATE_NEW,READ,WRITE), perms);
- * </pre>
- *
- * @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 seekable byte channel
- *
- * @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 FileAlreadyExistsException
- * 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
- * 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(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException;
-
- /**
- * Opens or creates a file, returning a seekable byte channel to access the
- * file.
- *
- * <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
- *
- * @return a new seekable byte channel
- *
- * @throws IllegalArgumentException
- * if the set contains an invalid combination of options
- * @throws UnsupportedOperationException
- * if an unsupported open option is specified
- * @throws FileAlreadyExistsException
- * 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
- * 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.
+ * if this {@code Path} is not associated with the default provider
*/
- public abstract SeekableByteChannel newByteChannel(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> 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.
- *
- * @param options
- * options specifying how the file is opened
- *
- * @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;
-
- /**
- * Tells whether or not the file located by this object is considered
- * <em>hidden</em>. The exact definition of hidden is platform or provider
- * dependent. On UNIX for example a file is considered to be hidden if its
- * name begins with a period character ('.'). On Windows a file is
- * considered hidden if it isn't a directory and the DOS {@link
- * DosFileAttributes#isHidden hidden} attribute is set.
- *
- * <p> Depending on the implementation this method may require to access
- * the file system to determine if the file is considered hidden.
- *
- * @return {@code true} if the file is considered hidden
- *
- * @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 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.
- *
- * <p> This convenience method is intended for cases where it is required to
- * take action when it can be confirmed that a file exists. This method simply
- * invokes the {@link #checkAccess checkAccess} method to check if the file
- * exists. If the {@code checkAccess} method succeeds then this method returns
- * {@code true}, otherwise if an {@code IOException} is thrown (because the
- * file doesn't exist or cannot be accessed by this Java virtual machine)
- * then {@code false} is returned.
- *
- * <p> Note that the result of this method is immediately outdated. If this
- * method indicates the file exists then there is no guarantee that a
- * subsequence access will succeed. Care should be taken when using this
- * method in security sensitive applications.
- *
- * @return {@code true} if the file exists; {@code false} if the file does
- * not exist or its existence cannot be determined.
- *
- * @throws SecurityException
- * In the case of the default provider, the {@link
- * SecurityManager#checkRead(String)} is invoked to check
- * read access to the file.
- *
- * @see #notExists
- */
- public abstract boolean exists();
-
- /**
- * Tests whether the file located by this path does not exist.
- *
- * <p> This convenience method is intended for cases where it is required to
- * take action when it can be confirmed that a file does not exist. This
- * method invokes the {@link #checkAccess checkAccess} method to check if the
- * file exists. If the file does not exist then {@code true} is returned,
- * otherwise the file exists or cannot be accessed by this Java virtual
- * machine and {@code false} is returned.
- *
- * <p> Note that this method is not the complement of the {@link #exists
- * exists} method. Where it is not possible to determine if a file exists
- * or not then both methods return {@code false}. As with the {@code exists}
- * method, the result of this method is immediately outdated. If this
- * method indicates the file does exist then there is no guarantee that a
- * subsequence attempt to create the file will succeed. Care should be taken
- * when using this method in security sensitive applications.
- *
- * @return {@code true} if the file does not exist; {@code false} if the
- * file exists or its existence cannot be determined.
- *
- * @throws SecurityException
- * In the case of the default provider, the {@link
- * SecurityManager#checkRead(String)} is invoked to check
- * 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;
+ File toFile();
// -- watchable --
@@ -1471,8 +594,8 @@
*
* <p> In this release, this path locates a directory that exists. The
* directory is registered with the watch service so that entries in the
- * directory can be watched. The {@code events} parameter is an array of
- * events to register and may contain the following events:
+ * directory can be watched. The {@code events} parameter is the events to
+ * register and may contain the following events:
* <ul>
* <li>{@link StandardWatchEventKind#ENTRY_CREATE ENTRY_CREATE} -
* entry created or moved into the directory</li>
@@ -1489,10 +612,10 @@
* <p> The set of events may include additional implementation specific
* event that are not defined by the enum {@link StandardWatchEventKind}
*
- * <p> The {@code modifiers} parameter is an array of <em>modifiers</em>
- * that qualify how the directory is registered. This release does not
- * define any <em>standard</em> modifiers. The array may contain
- * implementation specific modifiers.
+ * <p> The {@code modifiers} parameter specifies <em>modifiers</em> that
+ * qualify how the directory is registered. This release does not define any
+ * <em>standard</em> modifiers. It may contain implementation specific
+ * modifiers.
*
* <p> Where a file is registered with a watch service by means of a symbolic
* link then it is implementation specific if the watch continues to depend
@@ -1525,9 +648,9 @@
* method is invoked to check read access to the file.
*/
@Override
- public abstract WatchKey register(WatchService watcher,
- WatchEvent.Kind<?>[] events,
- WatchEvent.Modifier... modifiers)
+ WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>[] events,
+ WatchEvent.Modifier... modifiers)
throws IOException;
/**
@@ -1573,8 +696,8 @@
* method is invoked to check read access to the file.
*/
@Override
- public abstract WatchKey register(WatchService watcher,
- WatchEvent.Kind<?>... events)
+ WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>... events)
throws IOException;
// -- Iterable --
@@ -1591,7 +714,7 @@
* @return an iterator over the name elements of this path.
*/
@Override
- public abstract Iterator<Path> iterator();
+ Iterator<Path> iterator();
// -- compareTo/equals/hashCode --
@@ -1609,50 +732,7 @@
* lexicographically greater than the argument
*/
@Override
- 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 Path} and the given {@code Path} are {@link
- * #equals(Object) equal} then this method returns {@code true} without checking
- * if the file exists. If the {@code Path} and the given {@code Path}
- * are associated with different providers, or the given {@code Path} is
- * {@code null} then this method returns {@code false}. Otherwise, this method
- * checks if both {@code Paths} 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 Paths}.
- * <ul>
- * <li>It is <i>reflexive</i>: for a non-null {@code Path} {@code f},
- * {@code f.isSameFile(f)} should return {@code true}.
- * <li>It is <i>symmetric</i>: for two non-null {@code Path}
- * {@code f} and {@code g}, {@code f.isSameFile(g)} will equal
- * {@code g.isSameFile(f)}.
- * <li>It is <i>transitive</i>: for three {@code Paths}
- * {@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;
+ int compareTo(Path other);
/**
* Tests this path for equality with the given object.
@@ -1663,7 +743,9 @@
* <p> Whether or not two path are equal depends on the file system
* implementation. In some cases the paths are compared without regard
* to case, and others are case sensitive. This method does not access the
- * file system and the file is not required to exist.
+ * file system and the file is not required to exist. Where required, the
+ * {@link Files#isSameFile isSameFile} method may be used to check if two
+ * paths locate the same file.
*
* <p> This method satisfies the general contract of the {@link
* java.lang.Object#equals(Object) Object.equals} method. </p>
@@ -1674,8 +756,7 @@
* @return {@code true} if, and only if, the given object is a {@code Path}
* that is identical to this {@code Path}
*/
- @Override
- public abstract boolean equals(Object other);
+ boolean equals(Object other);
/**
* Computes a hash code for this path.
@@ -1686,8 +767,7 @@
*
* @return the hash-code value for this path
*/
- @Override
- public abstract int hashCode();
+ int hashCode();
/**
* Returns the string representation of this path.
@@ -1701,6 +781,5 @@
*
* @return the string representation of this path
*/
- @Override
- public abstract String toString();
+ String toString();
}
--- a/jdk/src/share/classes/java/nio/file/PathMatcher.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/PathMatcher.java Tue Feb 08 14:25:33 2011 -0800
@@ -32,7 +32,7 @@
* @since 1.7
*
* @see FileSystem#getPathMatcher
- * @see Path#newDirectoryStream(String)
+ * @see Files#newDirectoryStream(Path,String)
*/
public interface PathMatcher {
--- a/jdk/src/share/classes/java/nio/file/Paths.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/Paths.java Tue Feb 08 14:25:33 2011 -0800
@@ -39,14 +39,27 @@
private Paths() { }
/**
- * Constructs a {@code Path} by converting the given path string.
+ * Converts a path string, or a sequence of strings that when joined form
+ * a path string, to a {@code Path}. If {@code more} does not specify any
+ * elements then the value of the {@code first} parameter is the path string
+ * to convert. If {@code more} specifies one or more elements then each
+ * non-empty string, including {@code first}, is considered to be a sequence
+ * of name elements (see {@link Path}) and is joined to form a path string.
+ * The details as to how the Strings are joined is provider specific but
+ * typically they will be joined using the {@link FileSystem#getSeparator
+ * name-separator} as the separator. For example, if the name separator is
+ * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+ * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+ * A {@code Path} representing an empty path is returned if {@code first}
+ * is the empty string and {@code more} does not contain any non-empty
+ * strings.
*
* <p> The {@code Path} is obtained by invoking the {@link FileSystem#getPath
* getPath} method of the {@link FileSystems#getDefault default} {@link
* FileSystem}.
*
- * <p> Note that while this method is very convenient, using it will
- * imply an assumed reference to the default FileSystem and limit the
+ * <p> Note that while this method is very convenient, using it will imply
+ * an assumed reference to the default {@code FileSystem} and limit the
* utility of the calling code. Hence it should not be used in library code
* intended for flexible reuse. A more flexible alternative is to use an
* existing {@code Path} instance as an anchor, such as:
@@ -55,8 +68,10 @@
* Path path = dir.resolve("file");
* </pre>
*
- * @param path
- * the path string to convert
+ * @param first
+ * the path string or initial part of the path string
+ * @param more
+ * additional strings to be joined to form the path string
*
* @return the resulting {@code Path}
*
@@ -65,8 +80,8 @@
*
* @see FileSystem#getPath
*/
- public static Path get(String path) {
- return FileSystems.getDefault().getPath(path);
+ public static Path get(String first, String... more) {
+ return FileSystems.getDefault().getPath(first, more);
}
/**
--- a/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java Tue Feb 08 14:25:33 2011 -0800
@@ -43,7 +43,7 @@
*
* <p> A {@code SecureDirectoryStream} requires corresponding support from the
* underlying operating system. Where an implementation supports this features
- * then the {@code DirectoryStream} returned by the {@link Path#newDirectoryStream
+ * then the {@code DirectoryStream} returned by the {@link Files#newDirectoryStream
* newDirectoryStream} method will be a {@code SecureDirectoryStream} and must
* be cast to that type in order to invoke the methods defined by this interface.
*
@@ -56,20 +56,15 @@
* @since 1.7
*/
-public abstract class SecureDirectoryStream<T>
- implements DirectoryStream<T>
+public interface SecureDirectoryStream<T>
+ extends DirectoryStream<T>
{
/**
- * Initialize a new instance of this class.
- */
- protected SecureDirectoryStream() { }
-
- /**
* Opens the directory identified by the given path, returning a {@code
* 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
+ * Files#newDirectoryStream(Path) 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 {@link
@@ -99,8 +94,7 @@
* installed, the {@link SecurityManager#checkRead(String) checkRead}
* method is invoked to check read access to the directory.
*/
- public abstract SecureDirectoryStream<T> newDirectoryStream(T path,
- LinkOption... options)
+ SecureDirectoryStream<T> newDirectoryStream(T path, LinkOption... options)
throws IOException;
/**
@@ -108,11 +102,11 @@
* channel to access the file.
*
* <p> This method works in exactly the manner specified by the {@link
- * Path#newByteChannel Path.newByteChannel} method for the
+ * Files#newByteChannel Files.newByteChannel} method for the
* case that the {@code path} parameter is an {@link Path#isAbsolute absolute}
* path. When the parameter is a relative path then the file to open or
* create is relative to this open directory. In addition to the options
- * defined by the {@code Path.newByteChannel} method, the {@link
+ * defined by the {@code Files.newByteChannel} method, the {@link
* LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
* ensure that this method fails if the file is a symbolic link.
*
@@ -149,15 +143,15 @@
* checkWrite} method is invoked to check write access to the path
* if the file is opened for writing.
*/
- public abstract SeekableByteChannel newByteChannel(T path,
- Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
+ SeekableByteChannel newByteChannel(T path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
throws IOException;
/**
* Deletes a file.
*
- * <p> Unlike the {@link Path#delete delete()} method, this method does
+ * <p> Unlike the {@link Files#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
@@ -179,12 +173,12 @@
* installed, the {@link SecurityManager#checkDelete(String) checkDelete}
* method is invoked to check delete access to the file
*/
- public abstract void deleteFile(T path) throws IOException;
+ void deleteFile(T path) throws IOException;
/**
* Deletes a directory.
*
- * <p> Unlike the {@link Path#delete delete()} method, this method
+ * <p> Unlike the {@link Files#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
@@ -207,12 +201,12 @@
* installed, the {@link SecurityManager#checkDelete(String) checkDelete}
* method is invoked to check delete access to the directory
*/
- public abstract void deleteDirectory(T path) throws IOException;
+ void deleteDirectory(T path) throws IOException;
/**
* Move a file from this directory to another directory.
*
- * <p> This method works in a similar manner to {@link Path#moveTo moveTo}
+ * <p> This method works in a similar manner to {@link Files#move move}
* method when the {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} option
* is specified. That is, this method moves a file as an atomic file system
* operation. If the {@code srcpath} parameter is an {@link Path#isAbsolute
@@ -247,7 +241,7 @@
* method is invoked to check write access to both the source and
* target file.
*/
- public abstract void move(T srcpath, SecureDirectoryStream<T> targetdir, T targetpath)
+ void move(T srcpath, SecureDirectoryStream<T> targetdir, T targetpath)
throws IOException;
/**
@@ -273,7 +267,7 @@
* this directory stream, or {@code null} if the attribute view
* type is not available
*/
- public abstract <V extends FileAttributeView> V getFileAttributeView(Class<V> type);
+ <V extends FileAttributeView> V getFileAttributeView(Class<V> type);
/**
* Returns a new file attribute view to access the file attributes of a file
@@ -306,7 +300,7 @@
* type is not available
*
*/
- public abstract <V extends FileAttributeView> V getFileAttributeView(T path,
- Class<V> type,
- LinkOption... options);
+ <V extends FileAttributeView> V getFileAttributeView(T path,
+ Class<V> type,
+ LinkOption... options);
}
--- a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,8 @@
public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
throws IOException
{
- Objects.nonNull(dir);
- Objects.nonNull(attrs);
+ Objects.requireNonNull(dir);
+ Objects.requireNonNull(attrs);
return FileVisitResult.CONTINUE;
}
@@ -72,8 +72,8 @@
public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
throws IOException
{
- Objects.nonNull(file);
- Objects.nonNull(attrs);
+ Objects.requireNonNull(file);
+ Objects.requireNonNull(attrs);
return FileVisitResult.CONTINUE;
}
@@ -87,7 +87,7 @@
public FileVisitResult visitFileFailed(T file, IOException exc)
throws IOException
{
- Objects.nonNull(file);
+ Objects.requireNonNull(file);
throw exc;
}
@@ -104,7 +104,7 @@
public FileVisitResult postVisitDirectory(T dir, IOException exc)
throws IOException
{
- Objects.nonNull(dir);
+ Objects.requireNonNull(dir);
if (exc != null)
throw exc;
return FileVisitResult.CONTINUE;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/TempFileHelper.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.util.Set;
+import java.util.EnumSet;
+import java.security.SecureRandom;
+import static java.security.AccessController.*;
+import java.io.IOException;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import static java.nio.file.attribute.PosixFilePermission.*;
+import sun.security.action.GetPropertyAction;
+
+
+/**
+ * Helper class to support creation of temporary files and directories with
+ * initial attributes.
+ */
+
+class TempFileHelper {
+ private TempFileHelper() { }
+
+ // temporary directory location
+ private static final Path tmpdir =
+ Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+
+ private static final boolean isPosix =
+ FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
+
+ // file name generation, same as java.io.File for now
+ private static final SecureRandom random = new SecureRandom();
+ private static Path generatePath(String prefix, String suffix, Path dir) {
+ long n = random.nextLong();
+ n = (n == Long.MIN_VALUE) ? 0 : Math.abs(n);
+ Path name = dir.getFileSystem().getPath(prefix + Long.toString(n) + suffix);
+ // the generated name should be a simple file name
+ if (name.getParent() != null)
+ throw new IllegalArgumentException("Invalid prefix or suffix");
+ return dir.resolve(name);
+ }
+
+ // default file and directory permissions (lazily initialized)
+ private static class PosixPermissions {
+ static final FileAttribute<Set<PosixFilePermission>> filePermissions =
+ PosixFilePermissions.asFileAttribute(EnumSet.of(OWNER_READ, OWNER_WRITE));
+ static final FileAttribute<Set<PosixFilePermission>> dirPermissions =
+ PosixFilePermissions.asFileAttribute(EnumSet
+ .of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE));
+ }
+
+ /**
+ * Creates a file or directory in in the given given directory (or in the
+ * temporary directory if dir is {@code null}).
+ */
+ private static Path create(Path dir,
+ String prefix,
+ String suffix,
+ boolean createDirectory,
+ FileAttribute[] attrs)
+ throws IOException
+ {
+ if (prefix == null)
+ prefix = "";
+ if (suffix == null)
+ suffix = (createDirectory) ? "" : ".tmp";
+ if (dir == null)
+ dir = tmpdir;
+
+ // in POSIX environments use default file and directory permissions
+ // if initial permissions not given by caller.
+ if (isPosix && (dir.getFileSystem() == FileSystems.getDefault())) {
+ if (attrs.length == 0) {
+ // no attributes so use default permissions
+ attrs = new FileAttribute<?>[1];
+ attrs[0] = (createDirectory) ? PosixPermissions.dirPermissions :
+ PosixPermissions.filePermissions;
+ } 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] = (createDirectory) ?
+ PosixPermissions.dirPermissions :
+ PosixPermissions.filePermissions;
+ }
+ }
+ }
+
+ // loop generating random names until file or directory can be created
+ SecurityManager sm = System.getSecurityManager();
+ for (;;) {
+ Path f;
+ try {
+ f = generatePath(prefix, suffix, dir);
+ } catch (InvalidPathException e) {
+ // don't reveal temporary directory location
+ if (sm != null)
+ throw new IllegalArgumentException("Invalid prefix or suffix");
+ throw e;
+ }
+ try {
+ if (createDirectory) {
+ return Files.createDirectory(f, attrs);
+ } else {
+ return Files.createFile(f, attrs);
+ }
+ } catch (SecurityException e) {
+ // don't reveal temporary directory location
+ if (dir == tmpdir && sm != null)
+ throw new SecurityException("Unable to create temporary file or directory");
+ throw e;
+ } catch (FileAlreadyExistsException e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Creates a temporary file in the given directory, or in in the
+ * temporary directory if dir is {@code null}.
+ */
+ static Path createTempFile(Path dir,
+ String prefix,
+ String suffix,
+ FileAttribute[] attrs)
+ throws IOException
+ {
+ return create(dir, prefix, suffix, false, attrs);
+ }
+
+ /**
+ * Creates a temporary directory in the given directory, or in in the
+ * temporary directory if dir is {@code null}.
+ */
+ static Path createTempDirectory(Path dir,
+ String prefix,
+ FileAttribute[] attrs)
+ throws IOException
+ {
+ return create(dir, prefix, null, true, attrs);
+ }
+}
--- a/jdk/src/share/classes/java/nio/file/WatchEvent.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/WatchEvent.java Tue Feb 08 14:25:33 2011 -0800
@@ -44,7 +44,7 @@
* @since 1.7
*/
-public abstract class WatchEvent<T> {
+public interface WatchEvent<T> {
/**
* An event kind, for the purposes of identification.
@@ -65,11 +65,6 @@
}
/**
- * Initializes a new instance of this class.
- */
- protected WatchEvent() { }
-
- /**
* An event modifier that qualifies how a {@link Watchable} is registered
* with a {@link WatchService}.
*
@@ -90,7 +85,7 @@
*
* @return the event kind
*/
- public abstract Kind<T> kind();
+ Kind<T> kind();
/**
* Returns the event count. If the event count is greater than {@code 1}
@@ -98,7 +93,7 @@
*
* @return the event count
*/
- public abstract int count();
+ int count();
/**
* Returns the context for the event.
@@ -112,5 +107,5 @@
*
* @return the event context; may be {@code null}
*/
- public abstract T context();
+ T context();
}
--- a/jdk/src/share/classes/java/nio/file/WatchKey.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/WatchKey.java Tue Feb 08 14:25:33 2011 -0800
@@ -81,11 +81,7 @@
* @since 1.7
*/
-public abstract class WatchKey {
- /**
- * Initializes a new instance of this class.
- */
- protected WatchKey() { }
+public interface WatchKey {
/**
* Tells whether or not this watch key is valid.
@@ -95,7 +91,7 @@
*
* @return {@code true} if, and only if, this watch key is valid
*/
- public abstract boolean isValid();
+ boolean isValid();
/**
* Retrieves and removes all pending events for this watch key, returning
@@ -105,7 +101,7 @@
*
* @return the list of the events retrieved; may be empty
*/
- public abstract List<WatchEvent<?>> pollEvents();
+ List<WatchEvent<?>> pollEvents();
/**
* Resets this watch key.
@@ -121,7 +117,7 @@
* {@code false} if the watch key could not be reset because it is
* no longer {@link #isValid valid}
*/
- public abstract boolean reset();
+ boolean reset();
/**
* Cancels the registration with the watch service. Upon return the watch key
@@ -134,5 +130,21 @@
* <p> If this watch key has already been cancelled then invoking this
* method has no effect. Once cancelled, a watch key remains forever invalid.
*/
- public abstract void cancel();
+ void cancel();
+
+ /**
+ * Returns the object for which this watch key was created. This method will
+ * continue to return the object even after the key is cancelled.
+ *
+ * <p> As the {@code WatchService} is intended to map directly on to the
+ * native file event notification facility (where available) then many of
+ * details on how registered objects are watched is highly implementation
+ * specific. When watching a directory for changes for example, and the
+ * directory is moved or renamed in the file system, there is no guarantee
+ * that the watch key will be cancelled and so the object returned by this
+ * method may no longer be a valid path to the directory.
+ *
+ * @return the object for which this watch key was created
+ */
+ //T watchable();
}
--- a/jdk/src/share/classes/java/nio/file/WatchService.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/WatchService.java Tue Feb 08 14:25:33 2011 -0800
@@ -103,13 +103,9 @@
* @see FileSystem#newWatchService
*/
-public abstract class WatchService
- implements Closeable
+public interface WatchService
+ extends Closeable
{
- /**
- * Initializes a new instance of this class.
- */
- protected WatchService() { }
/**
* Closes this watch service.
@@ -129,7 +125,7 @@
* if an I/O error occurs
*/
@Override
- public abstract void close() throws IOException;
+ void close() throws IOException;
/**
* Retrieves and removes the next watch key, or {@code null} if none are
@@ -140,7 +136,7 @@
* @throws ClosedWatchServiceException
* if this watch service is closed
*/
- public abstract WatchKey poll();
+ WatchKey poll();
/**
* Retrieves and removes the next watch key, waiting if necessary up to the
@@ -160,7 +156,7 @@
* @throws InterruptedException
* if interrupted while waiting
*/
- public abstract WatchKey poll(long timeout, TimeUnit unit)
+ WatchKey poll(long timeout, TimeUnit unit)
throws InterruptedException;
/**
@@ -174,5 +170,5 @@
* @throws InterruptedException
* if interrupted while waiting
*/
- public abstract WatchKey take() throws InterruptedException;
+ WatchKey take() throws InterruptedException;
}
--- a/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java Tue Feb 08 14:25:33 2011 -0800
@@ -176,7 +176,7 @@
*/
public Builder setPermissions(Set<AclEntryPermission> perms) {
// copy and check for erroneous elements
- perms = new HashSet<AclEntryPermission>(perms);
+ perms = EnumSet.copyOf(perms);
checkSet(perms, AclEntryPermission.class);
this.perms = perms;
return this;
@@ -190,8 +190,7 @@
* @return this builder
*/
public Builder setPermissions(AclEntryPermission... perms) {
- Set<AclEntryPermission> set =
- new HashSet<AclEntryPermission>(perms.length);
+ Set<AclEntryPermission> set = EnumSet.noneOf(AclEntryPermission.class);
// copy and check for null elements
for (AclEntryPermission p: perms) {
if (p == null)
@@ -214,7 +213,7 @@
*/
public Builder setFlags(Set<AclEntryFlag> flags) {
// copy and check for erroneous elements
- flags = new HashSet<AclEntryFlag>(flags);
+ flags = EnumSet.copyOf(flags);
checkSet(flags, AclEntryFlag.class);
this.flags = flags;
return this;
@@ -228,7 +227,7 @@
* @return this builder
*/
public Builder setFlags(AclEntryFlag... flags) {
- Set<AclEntryFlag> set = new HashSet<AclEntryFlag>(flags.length);
+ Set<AclEntryFlag> set = EnumSet.noneOf(AclEntryFlag.class);
// copy and check for null elements
for (AclEntryFlag f: flags) {
if (f == null)
--- a/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -65,7 +65,7 @@
* UserPrincipalLookupService} may be used to obtain a {@link UserPrincipal}
* to represent these special identities by invoking the {@link
* UserPrincipalLookupService#lookupPrincipalByName lookupPrincipalByName}
- * method.
+ * method. </p>
*
* <p> <b>Usage Example:</b>
* Suppose we wish to add an entry to an existing ACL to grant "joe" access:
@@ -75,7 +75,7 @@
* .lookupPrincipalByName("joe");
*
* // get view
- * AclFileAttributeView view = file.getFileAttributeView(AclFileAttributeView.class);
+ * AclFileAttributeView view = Files.getFileAttributeView(file, AclFileAttributeView.class);
*
* // create ACE to give "joe" read access
* AclEntry entry = AclEntry.newBuilder()
@@ -110,11 +110,11 @@
* </table>
* </blockquote>
*
- * <p> The {@link FileRef#getAttribute getAttribute} method may be used to read
+ * <p> The {@link Files#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
+ * <p> The {@link Files#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.
*
@@ -122,8 +122,8 @@
*
* <p> Implementations supporting this attribute view may also support setting
* the initial ACL when creating a file or directory. The initial ACL
- * may be provided to methods such as {@link Path#createFile createFile} or {@link
- * Path#createDirectory createDirectory} as an {@link FileAttribute} with {@link
+ * may be provided to methods such as {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} as an {@link FileAttribute} with {@link
* FileAttribute#name name} {@code "acl:acl"} and a {@link FileAttribute#value
* value} that is the list of {@code AclEntry} objects.
*
@@ -135,8 +135,6 @@
* translation.
*
* @since 1.7
- * @see Attributes#getAcl
- * @see Attributes#setAcl
*/
public interface AclFileAttributeView
--- a/jdk/src/share/classes/java/nio/file/attribute/Attributes.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,460 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-import java.nio.file.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * This class consists exclusively of static methods that operate on or return
- * the attributes of files or file stores. These methods provide for convenient
- * use of the {@link AttributeView attribute-views} defined in this package.
- *
- * @since 1.7
- */
-
-public final class Attributes {
- private Attributes() { }
-
- /**
- * Reads the basic file attributes of a file.
- *
- * <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 itself.
- * This option should be used where there is a need to determine if a
- * file is a symbolic link:
- * <pre>
- * boolean isSymbolicLink = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS).isSymbolicLink();
- * </pre>
- *
- * <p> It is implementation specific if all file attributes are read as an
- * atomic operation with respect to other file system operations.
- *
- * @param file
- * A file reference that locates the file
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return The basic file attributes
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkRead(String) checkRead} method is invoked
- * to check read access to file
- *
- * @see BasicFileAttributeView#readAttributes
- */
- public static BasicFileAttributes readBasicFileAttributes(FileRef file,
- LinkOption... options)
- throws IOException
- {
- return file.getFileAttributeView(BasicFileAttributeView.class, options)
- .readAttributes();
- }
-
- /**
- * Reads the POSIX file attributes of a file.
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * PosixFileAttributeView}. This file attribute view provides access to a
- * subset of the file attributes commonly associated with files on file
- * systems used by operating systems that implement the Portable Operating
- * System Interface (POSIX) family of standards. It is implementation
- * specific if all file attributes are read as an atomic operation with
- * respect to other file system operations.
- *
- * <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 itself.
- *
- * @param file
- * A file reference that locates the file
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return The POSIX file attributes
- *
- * @throws UnsupportedOperationException
- * If the {@code PosixFileAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkRead(String) checkRead} method
- * denies read access to the file.
- *
- * @see PosixFileAttributeView#readAttributes
- */
- public static PosixFileAttributes readPosixFileAttributes(FileRef file,
- LinkOption... options)
- throws IOException
- {
- PosixFileAttributeView view =
- file.getFileAttributeView(PosixFileAttributeView.class, options);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.readAttributes();
- }
-
- /**
- * Reads the DOS file attributes of a file.
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * DosFileAttributeView}. This file attribute view provides access to
- * legacy "DOS" attributes supported by the file systems such as File
- * Allocation Table (FAT), commonly used in <em>consumer devices</em>. It is
- * implementation specific if all file attributes are read as an atomic
- * operation with respect to other file system operations.
- *
- * <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 itself.
- *
- * @param file
- * A file reference that locates the file
- * @param options
- * Options indicating how symbolic links are handled
- *
- * @return The DOS file attributes
- *
- * @throws UnsupportedOperationException
- * If the {@code DosFileAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkRead(String) checkRead} method is invoked
- * to check read access to file
- *
- * @see DosFileAttributeView#readAttributes
- */
- public static DosFileAttributes readDosFileAttributes(FileRef file,
- LinkOption... options)
- throws IOException
- {
- DosFileAttributeView view =
- file.getFileAttributeView(DosFileAttributeView.class, options);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.readAttributes();
- }
-
- /**
- * Returns the owner of a file.
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * FileOwnerAttributeView}. This file attribute view provides access to
- * a file attribute that is the owner of the file.
- *
- * @param file
- * A file reference that locates the file
- *
- * @return A user principal representing the owner of the file
- *
- * @throws UnsupportedOperationException
- * If the {@code FileOwnerAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkRead(String) checkRead} method
- * denies read access to the file.
- *
- * @see FileOwnerAttributeView#getOwner
- */
- public static UserPrincipal getOwner(FileRef file) throws IOException {
- FileOwnerAttributeView view =
- file.getFileAttributeView(FileOwnerAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.getOwner();
- }
-
- /**
- * Updates the file owner.
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * FileOwnerAttributeView}. This file attribute view provides access to
- * a file attribute that is the owner of the file.
- *
- * @param file
- * A file reference that locates the file
- * @param owner
- * The new file owner
- *
- * @throws UnsupportedOperationException
- * If the {@code FileOwnerAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file.
- *
- * @see FileOwnerAttributeView#setOwner
- */
- public static void setOwner(FileRef file, UserPrincipal owner)
- throws IOException
- {
- FileOwnerAttributeView view =
- file.getFileAttributeView(FileOwnerAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- view.setOwner(owner);
- }
-
- /**
- * Reads a file's Access Control List (ACL).
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * AclFileAttributeView}. This file attribute view provides access to ACLs
- * based on the ACL model specified in
- * <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC 3530</i></a>.
- *
- * @param file
- * A file reference that locates the file
- *
- * @return An ordered list of {@link AclEntry entries} representing the
- * ACL. The returned list is modifiable.
- *
- * @throws UnsupportedOperationException
- * If the {@code AclAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkRead(String) checkRead} method
- * denies read access to the file.
- *
- * @see AclFileAttributeView#getAcl
- */
- public static List<AclEntry> getAcl(FileRef file) throws IOException {
- AclFileAttributeView view =
- file.getFileAttributeView(AclFileAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.getAcl();
- }
-
- /**
- * Updates a file's Access Control List (ACL).
- *
- * <p> The {@code file} parameter locates a file that supports the {@link
- * AclFileAttributeView}. This file attribute view provides access to ACLs
- * based on the ACL model specified in
- * <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC 3530</i></a>.
- *
- * @param file
- * A file reference that locates the file
- * @param acl
- * The new file ACL
- *
- * @throws UnsupportedOperationException
- * If the {@code AclFileAttributeView} is not available
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file.
- *
- * @see AclFileAttributeView#setAcl
- */
- public static void setAcl(FileRef file, List<AclEntry> acl)
- throws IOException
- {
- AclFileAttributeView view =
- file.getFileAttributeView(AclFileAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- view.setAcl(acl);
- }
-
- /**
- * 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
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkWrite(String) checkWrite} method is invoked
- * to check write access to file
- *
- * @see BasicFileAttributeView#setTimes
- */
- public static void setLastModifiedTime(FileRef file,
- FileTime lastModifiedTime)
- throws IOException
- {
- if (lastModifiedTime == null)
- throw new NullPointerException("'lastModifiedTime' is null");
- file.getFileAttributeView(BasicFileAttributeView.class)
- .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
- *
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, the security manager's {@link
- * SecurityManager#checkWrite(String) checkWrite} method is invoked
- * to check write access to file
- *
- * @see BasicFileAttributeView#setTimes
- */
- public static void setLastAccessTime(FileRef file,
- FileTime lastAccessTime)
- throws IOException
- {
- if (lastAccessTime == null)
- throw new NullPointerException("'lastAccessTime' is null");
- file.getFileAttributeView(BasicFileAttributeView.class)
- .setTimes(null, lastAccessTime, null);
- }
-
- /**
- * Sets a file's POSIX permissions.
- *
- * <p> The {@code file} parameter is a reference to an existing file. It
- * supports the {@link PosixFileAttributeView} that provides access to file
- * attributes commonly associated with files on file systems used by
- * operating systems that implement the Portable Operating System Interface
- * (POSIX) family of standards.
- *
- * @param file
- * A file reference that locates the file
- * @param perms
- * The new set of permissions
- *
- * @throws UnsupportedOperationException
- * If {@code PosixFileAttributeView} is not available
- * @throws ClassCastException
- * If the sets contains elements that are not of type {@code
- * PosixFilePermission}
- * @throws IOException
- * If an I/O error occurs
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
- * or its {@link SecurityManager#checkWrite(String) checkWrite}
- * method denies write access to the file.
- *
- * @see PosixFileAttributeView#setPermissions
- */
- public static void setPosixFilePermissions(FileRef file,
- Set<PosixFilePermission> perms)
- throws IOException
- {
- PosixFileAttributeView view =
- file.getFileAttributeView(PosixFileAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- view.setPermissions(perms);
- }
-
- /**
- * Reads the space attributes of a file store.
- *
- * <p> The {@code store} parameter is a file store that supports the
- * {@link FileStoreSpaceAttributeView} providing access to the space related
- * attributes of the file store. It is implementation specific if all attributes
- * are read as an atomic operation with respect to other file system operations.
- *
- * @param store
- * The file store
- *
- * @return The file store space attributes
- *
- * @throws UnsupportedOperationException
- * If the file store space attribute view is not supported
- * @throws IOException
- * If an I/O error occurs
- *
- * @see FileStoreSpaceAttributeView#readAttributes()
- */
- public static FileStoreSpaceAttributes readFileStoreSpaceAttributes(FileStore store)
- throws IOException
- {
- FileStoreSpaceAttributeView view =
- store.getFileStoreAttributeView(FileStoreSpaceAttributeView.class);
- if (view == null)
- throw new UnsupportedOperationException();
- return view.readAttributes();
- }
-}
--- a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -85,16 +85,15 @@
* </table>
* </blockquote>
*
- * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} method may be
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} method may be
* used to read any of these attributes as if by invoking the {@link
* #readAttributes() readAttributes()} method.
*
- * <p> The {@link java.nio.file.FileRef#setAttribute setAttribute} method may be
+ * <p> The {@link java.nio.file.Files#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
*/
public interface BasicFileAttributeView
@@ -131,9 +130,10 @@
* <p> This method updates the file's timestamp attributes. The values are
* 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}.
+ * The behavior of this method when attempting to set a timestamp that is
+ * not supported or 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
@@ -146,6 +146,14 @@
* lastAccessTime} and {@code createTime} parameters are {@code null} then
* this method has no effect.
*
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to change a file's creation time.
+ * <pre>
+ * Path path = ...
+ * FileTime time = ...
+ * Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(null, null, time);
+ * </pre>
+ *
* @param lastModifiedTime
* the new last modified time, or {@code null} to not change the
* value
@@ -160,6 +168,8 @@
* In the case of the default provider, a security manager is
* installed, its {@link SecurityManager#checkWrite(String) checkWrite}
* method is invoked to check write access to the file
+ *
+ * @see java.nio.file.Files#setLastModifiedTime
*/
void setTimes(FileTime lastModifiedTime,
FileTime lastAccessTime,
--- a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java Tue Feb 08 14:25:33 2011 -0800
@@ -34,8 +34,8 @@
*
* <p> <b>Usage Example:</b>
* <pre>
- * FileRef file = ...
- * BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ * Path file = ...
+ * BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
* </pre>
*
* @since 1.7
@@ -48,25 +48,40 @@
/**
* Returns the time of last modification.
*
+ * <p> If the file system implementation does not support a time stamp
+ * to indicate the time of last modification then this method returns an
+ * implementation specific default value, typically a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
* @return a {@code FileTime} representing the time the file was last
- * modified or {@code null} if the attribute is not supported.
+ * modified
*/
FileTime lastModifiedTime();
/**
- * Returns the time of last access if supported.
+ * Returns the time of last access.
*
- * @return a {@code FileTime} representing the time of last access or
- * {@code null} if the attribute is not supported.
+ * <p> If the file system implementation does not support a time stamp
+ * to indicate the time of last access then this method returns
+ * an implementation specific default value, typically the {@link
+ * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
+ * @return a {@code FileTime} representing the time of last access
*/
FileTime lastAccessTime();
/**
- * Returns the creation time if supported. The creation time is the time
- * that the file was created.
+ * Returns the creation time. The creation time is the time that the file
+ * was created.
*
- * @return a {@code FileTime} representing the time the file was created
- * or {@code null} if the attribute is not supported.
+ * <p> If the file system implementation does not support a time stamp
+ * to indicate the time when the file was created then this method returns
+ * an implementation specific default value, typically the {@link
+ * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
+ * @return a {@code FileTime} representing the time the file was created
*/
FileTime creationTime();
@@ -120,7 +135,7 @@
*
* <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.Path#isSameFile same} with
+ * and two files are the {@link java.nio.file.Files#isSameFile same} with
* non-{@code null} file keys, then their file keys are equal.
*
* @see java.nio.file.Files#walkFileTree
--- a/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -65,12 +65,12 @@
* </table>
* </blockquote>
*
- * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} method may
+ * <p> The {@link java.nio.file.Files#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 java.nio.file.FileRef#setAttribute setAttribute} method may
+ * <p> The {@link java.nio.file.Files#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
--- a/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java Tue Feb 08 14:25:33 2011 -0800
@@ -29,13 +29,13 @@
* File attributes associated with a file in a file system that supports
* legacy "DOS" attributes.
*
- * <p> The DOS attributes of a file are retrieved using a {@link
- * DosFileAttributeView} by invoking its {@link DosFileAttributeView#readAttributes
- * readAttributes} method.
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ * Path file = ...
+ * DosFileAttributes attrs = Files.readAttributes(file, DosFileAttributes.class);
+ * </pre>
*
* @since 1.7
- *
- * @see Attributes#readDosFileAttributes
*/
public interface DosFileAttributes
--- a/jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java Tue Feb 08 14:25:33 2011 -0800
@@ -28,8 +28,8 @@
/**
* An object that encapsulates the value of a file attribute that can be set
* atomically when creating a new file or directory by invoking the {@link
- * java.nio.file.Path#createFile createFile} or {@link
- * java.nio.file.Path#createDirectory createDirectory} methods.
+ * java.nio.file.Files#createFile createFile} or {@link
+ * java.nio.file.Files#createDirectory createDirectory} methods.
*
* @param <T> The type of the file attribute value
*
--- a/jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -33,7 +33,7 @@
*
* @since 1.7
*
- * @see java.nio.file.FileRef#getFileAttributeView(Class,java.nio.file.LinkOption[])
+ * @see java.nio.file.Files#getFileAttributeView(Path,Class,java.nio.file.LinkOption[])
*/
public interface FileAttributeView
--- a/jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -37,8 +37,8 @@
* <p> The {@link #getOwner getOwner} or {@link #setOwner setOwner} methods may
* be used to read or update the owner of the file.
*
- * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} and
- * {@link java.nio.file.FileRef#setAttribute setAttribute} methods may also be
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} and
+ * {@link java.nio.file.Files#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}.
--- a/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-import java.io.IOException;
-
-/**
- * A file store attribute view that supports reading of space attributes.
- *
- * <p> Where dynamic access to file attributes is required, the attributes
- * supported by this attribute view have the following names and types:
- * <blockquote>
- * <table border="1" cellpadding="8">
- * <tr>
- * <th> Name </th>
- * <th> Type </th>
- * </tr>
- * <tr>
- * <td> "totalSpace" </td>
- * <td> {@link Long} </td>
- * </tr>
- * <tr>
- * <td> "usableSpace" </td>
- * <td> {@link Long} </td>
- * </tr>
- * <tr>
- * <td> "unallocatedSpace" </td>
- * <td> {@link Long} </td>
- * </tr>
- * </table>
- * </blockquote>
- * <p> The {@link java.nio.file.FileStore#getAttribute getAttribute} method may
- * be used to read any of these attributes.
- *
- * @since 1.7
- */
-
-public interface FileStoreSpaceAttributeView
- extends FileStoreAttributeView
-{
- /**
- * Returns the name of the attribute view. Attribute views of this type
- * have the name {@code "space"}.
- */
- @Override
- String name();
-
- /**
- * Reads the disk space attributes as a bulk operation.
- *
- * <p> It is file system specific if all attributes are read as an
- * atomic operation with respect to other file system operations.
- *
- * @return The disk space attributes
- *
- * @throws IOException
- * If an I/O error occurs
- */
- FileStoreSpaceAttributes readAttributes() throws IOException;
-}
--- a/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-/**
- * Space related attributes of a file store.
- *
- * @since 1.7
- *
- * @see Attributes#readFileStoreSpaceAttributes
- */
-
-public interface FileStoreSpaceAttributes {
- /**
- * Returns the size, in bytes, of the file store.
- */
- long totalSpace();
-
- /**
- * Returns the number of bytes available to this Java virtual machine on the
- * file store.
- *
- * <p> The returned number of available bytes is a hint, but not a
- * guarantee, that it is possible to use most or any of these bytes. The
- * number of usable bytes is most likely to be accurate immediately
- * after the space attributes are obtained. It is likely to be made inaccurate
- * by any external I/O operations including those made on the system outside
- * of this Java virtual machine.
- */
- long usableSpace();
-
- /**
- * Returns the number of unallocated bytes in the file store.
- *
- * <p> The returned number of unallocated bytes is a hint, but not a
- * guarantee, that it is possible to use most or any of these bytes. The
- * number of unallocated bytes is most likely to be accurate immediately
- * after the space attributes are obtained. It is likely to be
- * made inaccurate by any external I/O operations including those made on
- * the system outside of this virtual machine.
- */
- long unallocatedSpace();
-}
--- a/jdk/src/share/classes/java/nio/file/attribute/FileTime.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileTime.java Tue Feb 08 14:25:33 2011 -0800
@@ -35,20 +35,53 @@
/**
* Represents the value of a file's time stamp attribute. For example, it may
- * represent the time that the file was last modified, accessed, or created.
+ * represent the time that the file was last
+ * {@link BasicFileAttributes#lastModifiedTime() modified},
+ * {@link BasicFileAttributes#lastAccessTime() accessed},
+ * or {@link BasicFileAttributes#creationTime() created}.
*
* <p> Instances of this class are immutable.
*
* @since 1.7
- * @see BasicFileAttributes
- * @see Attributes#setLastModifiedTime
+ * @see java.nio.file.Files#setLastModifiedTime
+ * @see java.nio.file.Files#getLastModifiedTime
*/
-public final class FileTime implements Comparable<FileTime> {
+public final class FileTime
+ implements Comparable<FileTime>
+{
+ /**
+ * The value since the epoch; can be negative.
+ */
private final long value;
+
+ /**
+ * The unit of granularity to interpret the value.
+ */
private final TimeUnit unit;
- private String valueAsString; // created lazily
+
+ /**
+ * The value return by toString (created lazily)
+ */
+ private String valueAsString;
+
+ /**
+ * The value in days and excess nanos (created lazily)
+ */
+ private DaysAndNanos daysAndNanos;
+ /**
+ * Returns a DaysAndNanos object representing the value.
+ */
+ private DaysAndNanos asDaysAndNanos() {
+ if (daysAndNanos == null)
+ daysAndNanos = new DaysAndNanos(value, unit);
+ return daysAndNanos;
+ }
+
+ /**
+ * Initializes a new instance of this class.
+ */
private FileTime(long value, TimeUnit unit) {
if (unit == null)
throw new NullPointerException();
@@ -143,9 +176,8 @@
*/
@Override
public int hashCode() {
- // hash value for fixed granularity to satisfy contract with equals
- long ms = toMillis();
- return (int)(ms ^ (ms >>> 32));
+ // hashcode of days/nanos representation to satisfy contract with equals
+ return asDaysAndNanos().hashCode();
}
/**
@@ -162,46 +194,12 @@
@Override
public int compareTo(FileTime other) {
// same granularity
- if (unit == other.unit)
+ if (unit == other.unit) {
return (value < other.value) ? -1 : (value == other.value ? 0 : 1);
-
- // compare in days
- long thisValueInDays = unit.toDays(value);
- long otherValueInDays = other.unit.toDays(other.value);
- if (thisValueInDays != otherValueInDays)
- return (thisValueInDays < otherValueInDays) ? -1 : 1;
-
- // compare remainder in nanoseconds
- long thisRemainder = remainderInNanos(thisValueInDays);
- long otherRemainder = other.remainderInNanos(otherValueInDays);
- return (thisRemainder < otherRemainder) ? -1 :
- (thisRemainder == otherRemainder) ? 0 : 1;
- }
-
- private long remainderInNanos(long days) {
- // constants for conversion
- final long C0 = 1L;
- final long C1 = C0 * 24L;
- final long C2 = C1 * 60L;
- final long C3 = C2 * 60L;
- final long C4 = C3 * 1000L;
- final long C5 = C4 * 1000L;
- final long C6 = C5 * 1000L;
-
- long scale;
- switch (unit) {
- case DAYS : scale = C0; break;
- case HOURS : scale = C1; break;
- case MINUTES : scale = C2; break;
- case SECONDS : scale = C3; break;
- case MILLISECONDS : scale = C4; break;
- case MICROSECONDS : scale = C5; break;
- case NANOSECONDS : scale = C6; break;
- default:
- throw new AssertionError("Unit not handled");
+ } else {
+ // compare using days/nanos representation when unit differs
+ return asDaysAndNanos().compareTo(other.asDaysAndNanos());
}
- long rem = value - (days * scale);
- return unit.toNanos(rem);
}
/**
@@ -239,26 +237,12 @@
// nothing to do when seconds/minutes/hours/days
String fractionAsString = "";
if (unit.compareTo(TimeUnit.SECONDS) < 0) {
- // constants for conversion
- final long C0 = 1L;
- final long C1 = C0 * 1000L;
- final long C2 = C1 * 1000L;
- final long C3 = C2 * 1000L;
-
- long scale;
- int width;
- switch (unit) {
- case MILLISECONDS : scale = C1; width = 3; break;
- case MICROSECONDS : scale = C2; width = 6; break;
- case NANOSECONDS : scale = C3; width = 9; break;
- default:
- throw new AssertionError("Unit not handled");
- }
- long fraction = value % scale;
+ long fraction = asDaysAndNanos().fractionOfSecondInNanos();
if (fraction != 0L) {
// fraction must be positive
if (fraction < 0L) {
- fraction += scale;
+ final long MAX_FRACTION_PLUS_1 = 1000L * 1000L * 1000L;
+ fraction += MAX_FRACTION_PLUS_1;
if (ms != Long.MIN_VALUE) ms--;
}
@@ -266,7 +250,7 @@
// stripping any trailing zeros
String s = Long.toString(fraction);
int len = s.length();
- width -= len;
+ int width = 9 - len;
StringBuilder sb = new StringBuilder(".");
while (width-- > 0) {
sb.append('0');
@@ -302,4 +286,76 @@
}
return v;
}
+
+ /**
+ * Represents a FileTime's value as two longs: the number of days since
+ * the epoch, and the excess (in nanoseconds). This is used for comparing
+ * values with different units of granularity.
+ */
+ private static class DaysAndNanos implements Comparable<DaysAndNanos> {
+ // constants for conversion
+ private static final long C0 = 1L;
+ private static final long C1 = C0 * 24L;
+ private static final long C2 = C1 * 60L;
+ private static final long C3 = C2 * 60L;
+ private static final long C4 = C3 * 1000L;
+ private static final long C5 = C4 * 1000L;
+ private static final long C6 = C5 * 1000L;
+
+ /**
+ * The value (in days) since the epoch; can be negative.
+ */
+ private final long days;
+
+ /**
+ * The excess (in nanoseconds); can be negative if days <= 0.
+ */
+ private final long excessNanos;
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ DaysAndNanos(long value, TimeUnit unit) {
+ long scale;
+ switch (unit) {
+ case DAYS : scale = C0; break;
+ case HOURS : scale = C1; break;
+ case MINUTES : scale = C2; break;
+ case SECONDS : scale = C3; break;
+ case MILLISECONDS : scale = C4; break;
+ case MICROSECONDS : scale = C5; break;
+ case NANOSECONDS : scale = C6; break;
+ default : throw new AssertionError("Unit not handled");
+ }
+ this.days = unit.toDays(value);
+ this.excessNanos = unit.toNanos(value - (this.days * scale));
+ }
+
+ /**
+ * Returns the fraction of a second, in nanoseconds.
+ */
+ long fractionOfSecondInNanos() {
+ return excessNanos % (1000L * 1000L * 1000L);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof DaysAndNanos) ?
+ compareTo((DaysAndNanos)obj) == 0 : false;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int)(days ^ (days >>> 32) ^
+ excessNanos ^ (excessNanos >>> 32));
+ }
+
+ @Override
+ public int compareTo(DaysAndNanos other) {
+ if (this.days != other.days)
+ return (this.days < other.days) ? -1 : 1;
+ return (this.excessNanos < other.excessNanos) ? -1 :
+ (this.excessNanos == other.excessNanos) ? 0 : 1;
+ }
+ }
}
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -60,8 +60,8 @@
* <p> <b>Usage Example:</b>
* Suppose we need to print out the owner and access permissions of a file:
* <pre>
- * FileRef file = ...
- * PosixFileAttributes attrs = file.getFileAttributeView(PosixFileAttributeView.class)
+ * Path file = ...
+ * PosixFileAttributes attrs = Files.getFileAttributeView(file, PosixFileAttributeView.class)
* .readAttributes();
* System.out.format("%s %s%n",
* attrs.owner().getName(),
@@ -90,12 +90,12 @@
* </table>
* </blockquote>
*
- * <p> The {@link FileRef#getAttribute getAttribute} method may be used to read
+ * <p> The {@link Files#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 FileRef#setAttribute setAttribute} method may be used to update
+ * <p> The {@link Files#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
@@ -105,8 +105,8 @@
* <h4> Setting Initial Permissions </h4>
* <p> Implementations supporting this attribute view may also support setting
* the initial permissions when creating a file or directory. The
- * initial permissions are provided to the {@link Path#createFile createFile}
- * or {@link Path#createDirectory createDirectory} methods as a {@link
+ * initial permissions are provided to the {@link Files#createFile createFile}
+ * or {@link Files#createDirectory createDirectory} methods as a {@link
* FileAttribute} with {@link FileAttribute#name name} {@code "posix:permissions"}
* and a {@link FileAttribute#value value} that is the set of permissions. The
* following example uses the {@link PosixFilePermissions#asFileAttribute
@@ -117,7 +117,7 @@
* Path path = ...
* Set<PosixFilePermission> perms =
* EnumSet.of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ);
- * path.createFile(PosixFilePermissions.asFileAttribute(perms));
+ * Files.createFile(path, PosixFilePermissions.asFileAttribute(perms));
* </pre>
*
* <p> When the access permissions are set at file creation time then the actual
@@ -128,13 +128,11 @@
* the access permissions, and the underlying file system supports access
* permissions, then it is required that the value of the actual access
* permissions will be equal or less than the value of the attribute
- * provided to the {@link java.nio.file.Path#createFile createFile} or
- * {@link java.nio.file.Path#createDirectory createDirectory} methods. In
- * other words, the file may be more secure than requested.
+ * provided to the {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} methods. In other words, the file may
+ * be more secure than requested.
*
* @since 1.7
- *
- * @see Attributes#readPosixFileAttributes
*/
public interface PosixFileAttributeView
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java Tue Feb 08 14:25:33 2011 -0800
@@ -37,8 +37,6 @@
* PosixFileAttributeView#readAttributes readAttributes} method.
*
* @since 1.7
- *
- * @see Attributes#readPosixFileAttributes
*/
public interface PosixFileAttributes
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,14 +25,12 @@
package java.nio.file.attribute;
-import java.util.*;
-
/**
* Defines the bits for use with the {@link PosixFileAttributes#permissions()
* permissions} attribute.
*
- * <p> The {@link PosixFileAttributes} class defines method methods for
- * manipulating {@link Set sets} of permissions.
+ * <p> The {@link PosixFilePermissions} class defines methods for manipulating
+ * set of permissions.
*
* @since 1.7
*/
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java Tue Feb 08 14:25:33 2011 -0800
@@ -126,7 +126,7 @@
public static Set<PosixFilePermission> fromString(String perms) {
if (perms.length() != 9)
throw new IllegalArgumentException("Invalid mode");
- Set<PosixFilePermission> result = new HashSet<PosixFilePermission>();
+ Set<PosixFilePermission> result = EnumSet.noneOf(PosixFilePermission.class);
if (isR(perms.charAt(0))) result.add(OWNER_READ);
if (isW(perms.charAt(1))) result.add(OWNER_WRITE);
if (isX(perms.charAt(2))) result.add(OWNER_EXECUTE);
@@ -141,8 +141,8 @@
/**
* Creates a {@link FileAttribute}, encapsulating a copy of the given file
- * permissions, suitable for passing to the {@link java.nio.file.Path#createFile
- * createFile} or {@link java.nio.file.Path#createDirectory createDirectory}
+ * permissions, suitable for passing to the {@link java.nio.file.Files#createFile
+ * createFile} or {@link java.nio.file.Files#createDirectory createDirectory}
* methods.
*
* @param perms
--- a/jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -59,9 +59,9 @@
* attributes.
*
* <p> Where dynamic access to file attributes is required, the {@link
- * java.nio.file.FileRef#getAttribute getAttribute} method may be used to read
+ * java.nio.file.Files#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
+ * The {@link java.nio.file.Files#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[]).
*
@@ -132,8 +132,8 @@
* Suppose we want to read a file's MIME type that is stored as a user-defined
* attribute with the name "{@code user.mimetype}".
* <pre>
- * UserDefinedFileAttributeView view = file
- * .getFileAttributeView(UserDefinedFileAttributeView.class);
+ * UserDefinedFileAttributeView view =
+ * Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
* String name = "user.mimetype";
* ByteBuffer buf = ByteBuffer.allocate(view.size(name));
* view.read(name, buf);
@@ -189,8 +189,8 @@
* <p> <b>Usage Example:</b>
* Suppose we want to write a file's MIME type as a user-defined attribute:
* <pre>
- * UserDefinedFileAttributeView view = file
- * .getFileAttributeView(UserDefinedFileAttributeView.class);
+ * UserDefinedFileAttributeView view =
+ * FIles.getFileAttributeView(path, UserDefinedFileAttributeView.class);
* view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
* </pre>
*
--- a/jdk/src/share/classes/java/nio/file/attribute/package-info.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/package-info.java Tue Feb 08 14:25:33 2011 -0800
@@ -46,8 +46,6 @@
* <td>Can read or update user-defined file attributes</td></tr>
* <tr><td valign=top><tt> <i>{@link java.nio.file.attribute.FileStoreAttributeView}</i></tt></td>
* <td>Can read or update file system attributes</td></tr>
- * <tr><td valign=top><tt> <i>{@link java.nio.file.attribute.FileStoreSpaceAttributeView} </i></tt></td>
- * <td>Can read file system <em>space usage</em> related attributes</td></tr>
* </table></blockquote>
*
* <p> An attribute view provides a read-only or updatable view of the non-opaque
@@ -55,7 +53,7 @@
* The {@link java.nio.file.attribute.FileAttributeView} interface is
* extended by several other interfaces that that views to specific sets of file
* attributes. {@code FileAttributeViews} are selected by invoking the {@link
- * java.nio.file.FileRef#getFileAttributeView} method with a
+ * java.nio.file.Files#getFileAttributeView} method with a
* <em>type-token</em> to identify the required view. Views can also be identified
* by name. The {@link java.nio.file.attribute.FileStoreAttributeView} interface
* provides access to file store attributes. A {@code FileStoreAttributeView} of
@@ -83,13 +81,6 @@
* on the model defined by <a href="http://www.ietf.org/rfc/rfc3530.txt">
* <i>RFC 3530: Network File System (NFS) version 4 Protocol</i></a>.
*
- * <p> The {@link java.nio.file.attribute.FileStoreSpaceAttributeView} class
- * defines methods to read file system space usage related attributes of a file system.
- *
- * <p> The {@link java.nio.file.attribute.Attributes} utility class defines
- * static methods to access file or file system attribute using the above
- * attribute views.
- *
* <p> In addition to attribute views, this package also defines classes and
* interfaces that are used when accessing attributes:
*
--- a/jdk/src/share/classes/java/nio/file/package-info.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/package-info.java Tue Feb 08 14:25:33 2011 -0800
@@ -31,7 +31,7 @@
* systems. The API to access file and file system attributes is defined in the
* {@link java.nio.file.attribute} package. The {@link java.nio.file.spi}
* package is used by service provider implementors wishing to extend the
- * platform default provider, or to construct other provider implementations.
+ * platform default provider, or to construct other provider implementations. </p>
*
* <a name="links"><h3>Symbolic Links</h3></a>
* Many operating systems and file systems support for <em>symbolic links</em>.
@@ -43,7 +43,7 @@
* target of the link. This package includes support for symbolic links where
* implementations provide these semantics. File systems may support other types
* that are semantically close but support for these other types of links is
- * not included in this package.
+ * not included in this package. </p>
*
* <a name="interop"><h3>Interoperability</h3></a>
* The {@link java.io.File} class defines the {@link java.io.File#toPath
@@ -52,7 +52,7 @@
* {@code Path} can be used to operate on the same file as the {@code File}
* object. The {@code Path} specification provides further information
* on the <a href="Path.html#interop">interoperability</a> between {@code Path}
- * and {@code java.io.File} objects.
+ * and {@code java.io.File} objects. </p>
*
* <h3>Visibility</h3>
* The view of the files and file system provided by classes in this package are
@@ -63,7 +63,7 @@
* network-filesystem protocols. This is true regardless of the language in which
* these other programs are written, and whether they are running on the same machine
* or on some other machine. The exact nature of any such inconsistencies are
- * system-dependent and are therefore unspecified.
+ * system-dependent and are therefore unspecified. </p>
*
* <a name="integrity"><h3>Synchronized I/O File Integrity</h3></a>
* The {@link java.nio.file.StandardOpenOption#SYNC SYNC} and {@link
@@ -80,14 +80,14 @@
* crash. If the file does not reside on a local device then no such guarantee
* is made. Whether this guarantee is possible with other {@link
* java.nio.file.spi.FileSystemProvider provider} implementations is provider
- * specific.
+ * specific. </p>
*
* <h3>General Exceptions</h3>
* Unless otherwise noted, passing a {@code null} argument to a constructor
* or method of any class or interface in this package will cause a {@link
* java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
* invoking a method with a collection containing a {@code null} element will
- * cause a {@code NullPointerException}, unless otherwise specified.
+ * cause a {@code NullPointerException}, unless otherwise specified. </p>
*
* <p> Unless otherwise noted, methods that attempt to access the file system
* will throw {@link java.nio.file.ClosedFileSystemException} when invoked on
@@ -95,12 +95,13 @@
* {@link java.nio.file.FileSystem#close closed}. Additionally, any methods
* that attempt write access to a file system will throw {@link
* java.nio.file.ReadOnlyFileSystemException} when invoked on an object associated
- * with a {@link java.nio.file.FileSystem} that only provides read-only access.
+ * with a {@link java.nio.file.FileSystem} that only provides read-only
+ * access. </p>
*
* <p> Unless otherwise noted, invoking a method of any class or interface in
* this package created by one {@link java.nio.file.spi.FileSystemProvider
* provider} with a parameter that is an object created by another provider,
- * will throw {@link java.nio.file.ProviderMismatchException}.
+ * will throw {@link java.nio.file.ProviderMismatchException}. </p>
*
* <h3>Optional Specific Exceptions</h3>
* Most of the methods defined by classes in this package that access the
--- a/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java Tue Feb 08 14:25:33 2011 -0800
@@ -26,17 +26,21 @@
package java.nio.file.spi;
import java.nio.file.*;
-import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.*;
import java.nio.channels.*;
import java.net.URI;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.io.IOException;
/**
- * Service-provider class for file systems.
+ * Service-provider class for file systems. The methods defined by the {@link
+ * java.nio.file.Files} class will typically delegate to an instance of this
+ * class.
*
* <p> A file system provider is a concrete implementation of this class that
* implements the abstract methods defined by this class. A provider is
@@ -64,13 +68,6 @@
* the {@code newFileSystem} method is invoked. In the case of the default
* provider, the {@code FileSystem} is created when the provider is initialized.
*
- * <p> In addition to file systems, a provider is also a factory for {@link
- * FileChannel} and {@link AsynchronousFileChannel} channels. The {@link
- * #newFileChannel newFileChannel} and {@link #newAsynchronousFileChannel
- * AsynchronousFileChannel} methods are defined to open or create files, returning
- * a channel to access the file. These methods are invoked by static factory
- * methods defined in the {@link java.nio.channels} package.
- *
* <p> All of the methods in this class are safe for use by multiple concurrent
* threads.
*
@@ -202,9 +199,10 @@
*
* <p> This method throws {@link FileSystemAlreadyExistsException} if the
* file system already exists because it was previously created by an
- * invocation of this method. Once a file system is {@link FileSystem#close
- * closed} it is provider-dependent if the provider allows a new file system
- * to be created with the same URI as a file system it previously created.
+ * invocation of this method. Once a file system is {@link
+ * java.nio.file.FileSystem#close closed} it is provider-dependent if the
+ * provider allows a new file system to be created with the same URI as a
+ * file system it previously created.
*
* @param uri
* URI reference
@@ -234,20 +232,21 @@
*
* <p> This method returns a reference to a {@code FileSystem} that was
* created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
- * method. File systems created the {@link #newFileSystem(FileRef,Map)
- * newFileSystem(FileRef,Map)} method are not returned by this method.
+ * method. File systems created the {@link #newFileSystem(Path,Map)
+ * newFileSystem(Path,Map)} method are not returned by this method.
* The file system is identified by its {@code URI}. Its exact form
* is highly provider dependent. In the case of the default provider the URI's
* path component is {@code "/"} and the authority, query and fragment components
* are undefined (Undefined components are represented by {@code null}).
*
- * <p> Once a file system created by this provider is {@link FileSystem#close
- * closed} it is provider-dependent if this method returns a reference to
- * the closed file system or throws {@link FileSystemNotFoundException}.
- * If the provider allows a new file system to be created with the same URI
- * as a file system it previously created then this method throws the
- * exception if invoked after the file system is closed (and before a new
- * instance is created by the {@link #newFileSystem newFileSystem} method).
+ * <p> Once a file system created by this provider is {@link
+ * java.nio.file.FileSystem#close closed} it is provider-dependent if this
+ * method returns a reference to the closed file system or throws {@link
+ * FileSystemNotFoundException}. If the provider allows a new file system to
+ * be created with the same URI as a file system it previously created then
+ * this method throws the exception if invoked after the file system is
+ * closed (and before a new instance is created by the {@link #newFileSystem
+ * newFileSystem} method).
*
* <p> If a security manager is installed then a provider implementation
* may require to check a permission before returning a reference to an
@@ -306,17 +305,16 @@
*
* <p> This method is intended for specialized providers of pseudo file
* systems where the contents of one or more files is treated as a file
- * system. The {@code file} parameter is a reference to an existing file
- * and the {@code env} parameter is a map of provider specific properties to
- * configure the file system.
+ * system. The {@code env} parameter is a map of provider specific properties
+ * to configure the file system.
*
* <p> If this provider does not support the creation of such file systems
* or if the provider does not recognize the file type of the given file then
* it throws {@code UnsupportedOperationException}. The default implementation
* of this method throws {@code UnsupportedOperationException}.
*
- * @param file
- * The file
+ * @param path
+ * The path to the file
* @param env
* A map of provider specific properties to configure the file system;
* may be empty
@@ -336,32 +334,121 @@
* If a security manager is installed and it denies an unspecified
* permission.
*/
- public FileSystem newFileSystem(FileRef file, Map<String,?> env)
+ public FileSystem newFileSystem(Path path, Map<String,?> env)
throws IOException
{
throw new UnsupportedOperationException();
}
/**
- * Opens or creates a file for reading and/or writing, returning a file
- * channel to access the file.
+ * Opens a file, returning an input stream to read from the file. This
+ * method works in exactly the manner specified by the {@link
+ * Files#newInputStream} method.
+ *
+ * <p> The default implementation of this method opens a channel to the file
+ * as if by invoking the {@link #newByteChannel} method and constructs a
+ * stream that reads bytes from the channel. This method should be overridden
+ * where appropriate.
+ *
+ * @param path
+ * the path to the file to open
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new input stream
*
- * <p> This method is invoked by the {@link FileChannel#open(Path,Set,FileAttribute[])
- * FileChannel.open} method to open a file channel. A provider that does not
- * support all the features required to construct a file channel throws
- * {@code UnsupportedOperationException}. The default provider is required
- * to support the creation of file channels. When not overridden, the
- * default implementation throws {@code UnsupportedOperationException}.
+ * @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.
+ */
+ public InputStream newInputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ if (options.length > 0) {
+ for (OpenOption opt: options) {
+ if (opt != StandardOpenOption.READ)
+ throw new UnsupportedOperationException("'" + opt + "' not allowed");
+ }
+ }
+ return Channels.newInputStream(Files.newByteChannel(path));
+ }
+
+ /**
+ * Opens or creates a file, returning an output stream that may be used to
+ * write bytes to the file. This method works in exactly the manner
+ * specified by the {@link Files#newOutputStream} method.
+ *
+ * <p> The default implementation of this method opens a channel to the file
+ * as if by invoking the {@link #newByteChannel} method and constructs a
+ * stream that writes bytes to the channel. This method should be overridden
+ * where appropriate.
*
* @param path
- * The path of the file to open or create
+ * the path to the file to open or create
* @param options
- * Options specifying how the file is opened
+ * options specifying how the file is opened
+ *
+ * @return a new output stream
+ *
+ * @throws IllegalArgumentException
+ * 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. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public OutputStream newOutputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ int len = options.length;
+ Set<OpenOption> opts = new HashSet<OpenOption>(len + 3);
+ if (len == 0) {
+ opts.add(StandardOpenOption.CREATE);
+ opts.add(StandardOpenOption.TRUNCATE_EXISTING);
+ } else {
+ for (OpenOption opt: options) {
+ if (opt == StandardOpenOption.READ)
+ throw new IllegalArgumentException("READ not allowed");
+ opts.add(opt);
+ }
+ }
+ opts.add(StandardOpenOption.WRITE);
+ return Channels.newOutputStream(newByteChannel(path, opts));
+ }
+
+ /**
+ * Opens or creates a file for reading and/or writing, returning a file
+ * channel to access the file. This method works in exactly the manner
+ * specified by the {@link FileChannel#open(Path,Set,FileAttribute[])
+ * FileChannel.open} method. A provider that does not support all the
+ * features required to construct a file channel throws {@code
+ * UnsupportedOperationException}. The default provider is required to
+ * support the creation of file channels. When not overridden, the default
+ * implementation throws {@code UnsupportedOperationException}.
+ *
+ * @param path
+ * the path of the file to open or create
+ * @param options
+ * options specifying how the file is opened
* @param attrs
- * An optional list of file attributes to set atomically when
+ * an optional list of file attributes to set atomically when
* creating the file
*
- * @return A new file channel
+ * @return a new file channel
*
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
@@ -387,11 +474,10 @@
/**
* Opens or creates a file for reading and/or writing, returning an
- * asynchronous file channel to access the file.
- *
- * <p> This method is invoked by the {@link
+ * asynchronous file channel to access the file. This method works in
+ * exactly the manner specified by the {@link
* AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
- * AsynchronousFileChannel.open} method to open an asynchronous file channel.
+ * AsynchronousFileChannel.open} method.
* A provider that does not support all the features required to construct
* an asynchronous file channel throws {@code UnsupportedOperationException}.
* The default provider is required to support the creation of asynchronous
@@ -399,17 +485,17 @@
* method throws {@code UnsupportedOperationException}.
*
* @param path
- * The path of the file to open or create
+ * the path of the file to open or create
* @param options
- * Options specifying how the file is opened
+ * options specifying how the file is opened
* @param executor
- * The thread pool or {@code null} to associate the channel with
+ * the thread pool or {@code null} to associate the channel with
* the default thread pool
* @param attrs
- * An optional list of file attributes to set atomically when
+ * an optional list of file attributes to set atomically when
* creating the file
*
- * @return A new asynchronous file channel
+ * @return a new asynchronous file channel
*
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
@@ -434,4 +520,569 @@
{
throw new UnsupportedOperationException();
}
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access the
+ * file. This method works in exactly the manner specified by the {@link
+ * Files#newByteChannel(Path,Set,FileAttribute[])} method.
+ *
+ * @param path
+ * the path to the file to open or create
+ * @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 seekable byte channel
+ *
+ * @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 FileAlreadyExistsException
+ * 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
+ * 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. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public abstract SeekableByteChannel newByteChannel(Path path,
+ Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException;
+
+ /**
+ * Opens a directory, returning a {@code DirectoryStream} to iterate over
+ * the entries in the directory. This method works in exactly the manner
+ * specified by the {@link
+ * Files#newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter)}
+ * method.
+ *
+ * @param dir
+ * the path to the directory
+ * @param filter
+ * the directory stream filter
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it 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#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ public abstract DirectoryStream<Path> newDirectoryStream(Path dir,
+ DirectoryStream.Filter<? super Path> filter) throws IOException;
+
+ /**
+ * Creates a new directory. This method works in exactly the manner
+ * specified by the {@link Files#createDirectory} method.
+ *
+ * @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 a directory could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs or the parent directory does not exist
+ * @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 new directory.
+ */
+ public abstract void createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException;
+
+ /**
+ * Creates a symbolic link to a target. This method works in exactly the
+ * manner specified by the {@link Files#createSymbolicLink} method.
+ *
+ * <p> The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the path of the symbolic link to create
+ * @param target
+ * the target of the symbolic link
+ * @param attrs
+ * the array of attributes to set atomically when creating the
+ * symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links or the
+ * array contains an attribute that cannot be set atomically when
+ * creating the symbolic link
+ * @throws FileAlreadyExistsException
+ * if a file with the name already exists <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, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the path of the symbolic link.
+ */
+ public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a new link (directory entry) for an existing file. This method
+ * works in exactly the manner specified by the {@link Files#createLink}
+ * method.
+ *
+ * <p> The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the link (directory entry) to create
+ * @param existing
+ * a path to an existing file
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support adding an existing file
+ * to a directory
+ * @throws FileAlreadyExistsException
+ * if the entry could not otherwise be created because a file of
+ * that name already exists <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, it denies {@link LinkPermission}<tt>("hard")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to either the link or the
+ * existing file.
+ */
+ public void createLink(Path link, Path existing) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Deletes a file. This method works in exactly the manner specified by the
+ * {@link Files#delete} method.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @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(Path path) throws IOException;
+
+ /**
+ * Deletes a file if it exists. This method works in exactly the manner
+ * specified by the {@link Files#deleteIfExists} method.
+ *
+ * <p> The default implementation of this method simply invokes {@link
+ * #delete} ignoring the {@code NoSuchFileException} when the file does not
+ * exist. It may be overridden where appropriate.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @return {@code true} if the file was deleted by this method; {@code
+ * false} if the file could not be deleted because it did not
+ * exist
+ *
+ * @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 boolean deleteIfExists(Path path) throws IOException {
+ try {
+ delete(path);
+ return true;
+ } catch (NoSuchFileException ignore) {
+ return false;
+ }
+ }
+
+ /**
+ * Reads the target of a symbolic link. This method works in exactly the
+ * manner specified by the {@link Files#readSymbolicLink} method.
+ *
+ * <p> The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the path to the symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links
+ * @throws NotLinkException
+ * if the target could otherwise not be read because the file
+ * is not a symbolic link <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, it checks that {@code FilePermission} has been
+ * granted with the "{@code readlink}" action to read the link.
+ */
+ public Path readSymbolicLink(Path link) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Copy a file to a target file. This method works in exactly the manner
+ * specified by the {@link Files#copy(Path,Path,CopyOption[])} method
+ * except that both the source and target paths must be associated with
+ * this provider.
+ *
+ * @param source
+ * the path to the file to copy
+ * @param target
+ * the path to the target file
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty 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#checkRead(String) checkRead}
+ * method is invoked to check read access to the source file, the
+ * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+ * to check write access to the target file. If a symbolic link is
+ * copied the security manager is invoked to check {@link
+ * LinkPermission}{@code ("symbolic")}.
+ */
+ public abstract void copy(Path source, Path target, CopyOption... options)
+ throws IOException;
+
+ /**
+ * Move or rename a file to a target file. This method works in exactly the
+ * manner specified by the {@link Files#move} method except that both the
+ * source and target paths must be associated with this provider.
+ *
+ * @param source
+ * the path to the file to move
+ * @param target
+ * the path to the target file
+ * @param options
+ * options specifying how the move should be done
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws AtomicMoveNotSupportedException
+ * if the options array contains the {@code ATOMIC_MOVE} option but
+ * the file cannot be moved as an atomic file system operation.
+ * @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 both the source and
+ * target file.
+ */
+ public abstract void move(Path source, Path target, CopyOption... options)
+ throws IOException;
+
+ /**
+ * Tests if two paths locate the same file. This method works in exactly the
+ * manner specified by the {@link Files#isSameFile} method.
+ *
+ * @param path
+ * one path to the file
+ * @param path2
+ * the other path
+ *
+ * @return {@code true} if, and only if, the two paths 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.
+ */
+ public abstract boolean isSameFile(Path path, Path path2)
+ throws IOException;
+
+ /**
+ * Tells whether or not a file is considered <em>hidden</em>. This method
+ * works in exactly the manner specified by the {@link Files#isHidden}
+ * method.
+ *
+ * <p> This method is invoked by the {@link Files#isHidden isHidden} method.
+ *
+ * @param path
+ * the path to the file to test
+ *
+ * @return {@code true} if the file is considered hidden
+ *
+ * @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 boolean isHidden(Path path) throws IOException;
+
+ /**
+ * Returns the {@link FileStore} representing the file store where a file
+ * is located. This method works in exactly the manner specified by the
+ * {@link Files#getFileStore} method.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @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(Path path) throws IOException;
+
+ /**
+ * Checks the existence, and optionally the accessibility, of a file.
+ *
+ * <p> This method may be used by the {@link Files#isReadable isReadable},
+ * {@link Files#isWritable isWritable} and {@link Files#isExecutable
+ * isExecutable} methods to check the accessibility of a file.
+ *
+ * <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.
+ *
+ * @param path
+ * the path to the file to check
+ * @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(Path path, AccessMode... modes)
+ throws IOException;
+
+ /**
+ * Returns a file attribute view of a given type. This method works in
+ * exactly the manner specified by the {@link Files#getFileAttributeView}
+ * method.
+ *
+ * @param path
+ * the path to the file
+ * @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 attribute view type is not available
+ */
+ public abstract <V extends FileAttributeView> V
+ getFileAttributeView(Path path, Class<V> type, LinkOption... options);
+
+ /**
+ * Reads a file's attributes as a bulk operation. This method works in
+ * exactly the manner specified by the {@link
+ * Files#readAttributes(Path,Class,LinkOption[])} method.
+ *
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} of the file attributes required
+ * to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the file attributes
+ *
+ * @throws UnsupportedOperationException
+ * if an attributes of the given type are not supported
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file
+ */
+ public abstract <A extends BasicFileAttributes> A
+ readAttributes(Path path, Class<A> type, LinkOption... options) throws IOException;
+
+ /**
+ * Reads a set of file attributes as a bulk operation. This method works in
+ * exactly the manner specified by the {@link
+ * Files#readAttributes(Path,String,LinkOption[])} method.
+ *
+ * @param path
+ * the path to 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 abstract Map<String,Object> readAttributes(Path path, String attributes,
+ LinkOption... options)
+ throws IOException;
+
+ /**
+ * Sets the value of a file attribute. This method works in exactly the
+ * manner specified by the {@link Files#setAttribute} method.
+ *
+ * @param path
+ * the path to the file
+ * @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.
+ */
+ public abstract void setAttribute(Path path, String attribute,
+ Object value, LinkOption... options)
+ throws IOException;
}
--- a/jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,7 +25,7 @@
package java.nio.file.spi;
-import java.nio.file.FileRef;
+import java.nio.file.Path;
import java.io.IOException;
/**
@@ -42,7 +42,7 @@
* href="../attribute/package-summary.html"> attribute</a> or the bytes in a
* file may be examined to guess its file type.
*
- * @see java.nio.file.Files#probeContentType(FileRef)
+ * @see java.nio.file.Files#probeContentType(Path)
*
* @since 1.7
*/
@@ -83,8 +83,8 @@
* Message Bodies</i></a>. The string must be parsable according to the
* grammar in the RFC 2045.
*
- * @param file
- * The file to probe
+ * @param path
+ * the path to the file to probe
*
* @return The content type or {@code null} if the file type is not
* recognized
@@ -101,6 +101,6 @@
*
* @see java.nio.file.Files#probeContentType
*/
- public abstract String probeContentType(FileRef file)
+ public abstract String probeContentType(Path path)
throws IOException;
}
--- a/jdk/src/share/classes/java/security/AlgorithmParameterGenerator.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/AlgorithmParameterGenerator.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,6 +66,20 @@
* default modulus prime size of 1024 bits for the generation of DSA
* parameters.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>AlgorithmParameterGenerator</code> algorithms and
+ * keysizes in parentheses:
+ * <ul>
+ * <li><tt>DiffieHellman</tt> (1024)</li>
+ * <li><tt>DSA</tt> (1024)</li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * AlgorithmParameterGenerator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
*
@@ -126,9 +140,9 @@
*
* @param algorithm the name of the algorithm this
* parameter generator is associated with.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameterGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new AlgorithmParameterGenerator object.
@@ -168,9 +182,9 @@
*
* @param algorithm the name of the algorithm this
* parameter generator is associated with.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameterGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the string name of the Provider.
@@ -214,9 +228,9 @@
*
* @param algorithm the string name of the algorithm this
* parameter generator is associated with.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameterGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the Provider object.
--- a/jdk/src/share/classes/java/security/AlgorithmParameters.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/AlgorithmParameters.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,22 @@
* <code>getParameterSpec</code>, and a byte encoding of the parameters is
* obtained via a call to <code>getEncoded</code>.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>AlgorithmParameters</code> algorithms:
+ * <ul>
+ * <li><tt>AES</tt></li>
+ * <li><tt>DES</tt></li>
+ * <li><tt>DESede</tt></li>
+ * <li><tt>DiffieHellman</tt></li>
+ * <li><tt>DSA</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * AlgorithmParameters section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
*
@@ -111,9 +127,9 @@
* parameter encoding.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameters section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new parameter object.
@@ -153,9 +169,9 @@
* parameter encoding.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameters section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -200,9 +216,9 @@
* parameter encoding.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the AlgorithmParameters section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
--- a/jdk/src/share/classes/java/security/KeyFactory.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/KeyFactory.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,9 +67,22 @@
* sig.verify(signature);
* </pre>
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>KeyFactory</code> algorithms:
+ * <ul>
+ * <li><tt>DiffieHellman</tt></li>
+ * <li><tt>DSA</tt></li>
+ * <li><tt>RSA</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyFactory">
+ * KeyFactory section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
- *
* @see Key
* @see PublicKey
* @see PrivateKey
@@ -141,9 +154,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested key algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new KeyFactory object.
@@ -172,9 +185,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested key algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -211,9 +224,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the name of the requested key algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/KeyPairGenerator.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/KeyPairGenerator.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -105,9 +105,23 @@
* the superclass are intended for cryptographic service providers who wish to
* supply their own implementations of key pair generators.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>KeyPairGenerator</code> algorithms and keysizes in
+ * parentheses:
+ * <ul>
+ * <li><tt>DiffieHellman</tt> (1024)</li>
+ * <li><tt>DSA</tt> (1024)</li>
+ * <li><tt>RSA</tt> (1024, 2048)</li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * KeyPairGenerator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Benjamin Renaud
*
- *
* @see java.security.spec.AlgorithmParameterSpec
*/
@@ -122,9 +136,9 @@
* Creates a KeyPairGenerator object for the specified algorithm.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*/
protected KeyPairGenerator(String algorithm) {
@@ -133,9 +147,9 @@
/**
* Returns the standard name of the algorithm for this key pair generator.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the standard string name of the algorithm.
@@ -171,9 +185,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new KeyPairGenerator object.
@@ -227,9 +241,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the string name of the provider.
@@ -266,9 +280,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyPairGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/KeyStore.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/KeyStore.java Tue Feb 08 14:25:33 2011 -0800
@@ -164,9 +164,20 @@
* different passwords or other protection parameters
* may also be used.
*
+ * <p> Every implementation of the Java platform is required to support
+ * the following standard <code>KeyStore</code> type:
+ * <ul>
+ * <li><tt>PKCS12</tt></li>
+ * </ul>
+ * This type is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
+ * KeyStore section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other types are supported.
+ *
* @author Jan Luehe
*
- *
* @see java.security.PrivateKey
* @see javax.crypto.SecretKey
* @see java.security.cert.Certificate
@@ -582,9 +593,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param type the type of keystore.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard keystore types.
*
* @return a keystore object of the specified type.
@@ -620,9 +631,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param type the type of keystore.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard keystore types.
*
* @param provider the name of the provider.
@@ -663,9 +674,9 @@
* does not have to be registered in the provider list.
*
* @param type the type of keystore.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the KeyStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard keystore types.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/MessageDigest.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/MessageDigest.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
/**
* This MessageDigest class provides applications the functionality of a
- * message digest algorithm, such as MD5 or SHA.
+ * message digest algorithm, such as SHA-1 or SHA-256.
* Message digests are secure one-way hash functions that take arbitrary-sized
* data and output a fixed-length hash value.
*
@@ -81,9 +81,22 @@
* the superclass are intended for cryptographic service providers who wish to
* supply their own implementations of message digest algorithms.
*
+ * <p> Every implementation of the Java platform is required to support
+ * the following standard <code>MessageDigest</code> algorithms:
+ * <ul>
+ * <li><tt>MD5</tt></li>
+ * <li><tt>SHA-1</tt></li>
+ * <li><tt>SHA-256</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * MessageDigest section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Benjamin Renaud
*
- *
* @see DigestInputStream
* @see DigestOutputStream
*/
@@ -104,9 +117,9 @@
* Creates a message digest with the specified algorithm name.
*
* @param algorithm the standard name of the digest algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*/
protected MessageDigest(String algorithm) {
@@ -127,9 +140,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return a Message Digest object that implements the specified algorithm.
@@ -173,9 +186,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -222,9 +235,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
@@ -439,9 +452,9 @@
* Returns a string that identifies the algorithm, independent of
* implementation details. The name should be a standard
* Java Security name (such as "SHA", "MD5", and so on).
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the MessageDigest section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the name of the algorithm
--- a/jdk/src/share/classes/java/security/Policy.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/Policy.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,9 +67,6 @@
* implementation. In addition, an instance of a Policy object can be
* constructed by invoking one of the <code>getInstance</code> factory methods
* with a standard type. The default policy type is "JavaPolicy".
- * See Appendix A in the <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for a list of standard Policy types.
*
* <p> Once a Policy instance has been installed (either by default, or by
* calling <code>setPolicy</code>),
@@ -133,7 +130,7 @@
* This method first calls
* <code>SecurityManager.checkPermission</code> with a
* <code>SecurityPermission("getPolicy")</code> permission
- * to ensure it's ok to get the Policy object..
+ * to ensure it's ok to get the Policy object.
*
* @return the installed Policy.
*
@@ -340,9 +337,10 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * @param type the specified Policy type. See Appendix A in the
- * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * @param type the specified Policy type. See the Policy section in the
+ * <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Policy">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for a list of standard Policy types.
*
* @param params parameters for the Policy, which may be null.
@@ -393,9 +391,10 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * @param type the specified Policy type. See Appendix A in the
- * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * @param type the specified Policy type. See the Policy section in the
+ * <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Policy">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for a list of standard Policy types.
*
* @param params parameters for the Policy, which may be null.
@@ -456,9 +455,10 @@
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
- * @param type the specified Policy type. See Appendix A in the
- * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * @param type the specified Policy type. See the Policy section in the
+ * <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Policy">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for a list of standard Policy types.
*
* @param params parameters for the Policy, which may be null.
--- a/jdk/src/share/classes/java/security/SecureRandom.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/SecureRandom.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -133,9 +133,9 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * <p> See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * <p> See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* <p> The returned SecureRandom object has not been seeded. To seed the
@@ -171,9 +171,9 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * <p> See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * <p> See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* @param seed the seed.
@@ -256,9 +256,9 @@
* previously called.
*
* @param algorithm the name of the RNG algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* @return the new SecureRandom object.
@@ -299,9 +299,9 @@
* previously called.
*
* @param algorithm the name of the RNG algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* @param provider the name of the provider.
@@ -347,9 +347,9 @@
* previously called.
*
* @param algorithm the name of the RNG algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the SecureRandom section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard RNG algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/Security.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/Security.java Tue Feb 08 14:25:33 2011 -0800
@@ -277,10 +277,11 @@
/**
* Gets a specified property for an algorithm. The algorithm name
- * should be a standard name. See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * should be a standard name. See the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
+ *
* One possible use is by specialized algorithm parsers, which may map
* classes to algorithms which they understand (much like Key parsers
* do).
@@ -513,9 +514,9 @@
*
* </ul>
*
- * <p> See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * <p> See the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard cryptographic service names, standard
* algorithm names and standard attribute names.
*
@@ -581,9 +582,9 @@
* constraint expressed by the specified attribute name/value pair.
* </ul>
*
- * <p> See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * <p> See the <a href=
+ * "../../../technotes/guides/security/StandardNames.html">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard cryptographic service names, standard
* algorithm names and standard attribute names.
*
--- a/jdk/src/share/classes/java/security/Signature.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/Signature.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,7 @@
import sun.security.jca.GetInstance.Instance;
/**
- * This Signature class is used to provide applications the functionality
+ * The Signature class is used to provide applications the functionality
* of a digital signature algorithm. Digital signatures are used for
* authentication and integrity assurance of digital data.
*
@@ -98,6 +98,20 @@
* the superclass are intended for cryptographic service providers who wish to
* supply their own implementations of digital signature algorithms.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>Signature</code> algorithms:
+ * <ul>
+ * <li><tt>SHA1withDSA</tt></li>
+ * <li><tt>SHA1withRSA</tt></li>
+ * <li><tt>SHA256withRSA</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Signature section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Benjamin Renaud
*
*/
@@ -144,9 +158,9 @@
* Creates a Signature object for the specified algorithm.
*
* @param algorithm the standard string name of the algorithm.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Signature section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*/
protected Signature(String algorithm) {
@@ -184,9 +198,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Signature section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new Signature object.
@@ -303,9 +317,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Signature section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -353,9 +367,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the name of the algorithm requested.
- * See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Signature section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/java/security/cert/CertPath.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertPath.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -83,6 +83,19 @@
* may not follow these conventions. PKIX <code>CertPathValidator</code>s will
* detect any departure from these conventions that cause the certification
* path to be invalid and throw a <code>CertPathValidatorException</code>.
+ *
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertPath</code> encodings:
+ * <ul>
+ * <li><tt>PKCS7</tt></li>
+ * <li><tt>PkiPath</tt></li>
+ * </ul>
+ * These encodings are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * CertPath Encodings section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other encodings are supported.
* <p>
* <b>Concurrent Access</b>
* <p>
--- a/jdk/src/share/classes/java/security/cert/CertPathBuilder.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertPathBuilder.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,6 +52,19 @@
* result (including the <code>CertPath</code> that was built) is returned
* in an object that implements the <code>CertPathBuilderResult</code>
* interface.
+ *
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertPathBuilder</code> algorithm:
+ * <ul>
+ * <li><tt>PKIX</tt></li>
+ * </ul>
+ * This algorithm is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * CertPathBuilder section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* <p>
* <b>Concurrent Access</b>
* <p>
@@ -118,10 +131,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested <code>CertPathBuilder</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathBuilder section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @return a <code>CertPathBuilder</code> object that implements the
* specified algorithm.
@@ -153,10 +166,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested <code>CertPathBuilder</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathBuilder section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @param provider the name of the provider.
*
@@ -193,10 +206,10 @@
* does not have to be registered in the provider list.
*
* @param algorithm the name of the requested <code>CertPathBuilder</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathBuilder section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @param provider the provider.
*
--- a/jdk/src/share/classes/java/security/cert/CertPathValidator.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertPathValidator.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,6 +53,19 @@
* and an algorithm-specific set of parameters. If successful, the result is
* returned in an object that implements the
* <code>CertPathValidatorResult</code> interface.
+ *
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertPathValidator</code> algorithm:
+ * <ul>
+ * <li><tt>PKIX</tt></li>
+ * </ul>
+ * This algorithm is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator">
+ * CertPathValidator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* <p>
* <b>Concurrent Access</b>
* <p>
@@ -118,10 +131,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested <code>CertPathValidator</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathValidator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @return a <code>CertPathValidator</code> object that implements the
* specified algorithm.
@@ -153,10 +166,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested <code>CertPathValidator</code>
- * algorithm. See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * algorithm. See the CertPathValidator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @param provider the name of the provider.
*
@@ -193,12 +206,11 @@
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
- * @param algorithm the name of the requested
- * <code>CertPathValidator</code> algorithm.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard algorithm names.
+ * @param algorithm the name of the requested <code>CertPathValidator</code>
+ * algorithm. See the CertPathValidator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard algorithm names.
*
* @param provider the provider.
*
--- a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -286,6 +286,11 @@
/**
* The signature is invalid.
*/
- INVALID_SIGNATURE
+ INVALID_SIGNATURE,
+
+ /**
+ * The public key or the signature algorithm has been constrained.
+ */
+ ALGORITHM_CONSTRAINED
}
}
--- a/jdk/src/share/classes/java/security/cert/CertStore.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertStore.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,10 +58,20 @@
* vast repository of untrusted certificates and CRLs. For example, an LDAP
* implementation of <code>CertStore</code> provides access to certificates
* and CRLs stored in one or more directories using the LDAP protocol and the
- * schema as defined in the RFC service attribute. See Appendix A in the
- * <a href= "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide</a> for more information about
- * standard <code>CertStore</code> types.
+ * schema as defined in the RFC service attribute.
+ *
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertStore</code> type:
+ * <ul>
+ * <li><tt>Collection</tt></li>
+ * </ul>
+ * This type is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertStore">
+ * CertStore section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other types are supported.
+ *
* <p>
* <b>Concurrent Access</b>
* <p>
@@ -192,10 +202,10 @@
* cloned.
*
* @param type the name of the requested <code>CertStore</code> type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard types.
+ * See the CertStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard types.
*
* @param params the initialization parameters (may be <code>null</code>).
*
@@ -252,10 +262,10 @@
* cloned.
*
* @param type the requested <code>CertStore</code> type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard types.
+ * See the CertStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard types.
*
* @param params the initialization parameters (may be <code>null</code>).
*
@@ -310,10 +320,10 @@
* cloned.
*
* @param type the requested <code>CertStore</code> type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide </a>
- * for information about standard types.
+ * See the CertStore section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertStore">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard types.
*
* @param params the initialization parameters (may be <code>null</code>).
*
--- a/jdk/src/share/classes/java/security/cert/Certificate.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/Certificate.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -69,9 +69,9 @@
* Creates a certificate of the specified type.
*
* @param type the standard name of the certificate type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the CertificateFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard certificate types.
*/
protected Certificate(String type) {
--- a/jdk/src/share/classes/java/security/cert/CertificateFactory.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertificateFactory.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -91,11 +91,29 @@
* }
* </pre>
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>CertificateFactory</code> type:
+ * <ul>
+ * <li><tt>X.509</tt></li>
+ * </ul>
+ * and the following standard <code>CertPath</code> encodings:
+ * <ul>
+ * <li><tt>PKCS7</tt></li>
+ * <li><tt>PkiPath</tt></li>
+ * </ul>
+ * The type and encodings are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * CertificateFactory section</a> and the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * CertPath Encodings section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other types or encodings are supported.
+ *
* @author Hemma Prafullchandra
* @author Jan Luehe
* @author Sean Mullan
*
- *
* @see Certificate
* @see X509Certificate
* @see CertPath
@@ -146,9 +164,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param type the name of the requested certificate type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the CertificateFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard certificate types.
*
* @return a certificate factory object for the specified type.
@@ -184,9 +202,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param type the certificate type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the CertificateFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard certificate types.
*
* @param provider the name of the provider.
@@ -228,11 +246,10 @@
* does not have to be registered in the provider list.
*
* @param type the certificate type.
- * See Appendix A in the <a href=
- * "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the CertificateFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard certificate types.
-
* @param provider the provider.
*
* @return a certificate factory object for the specified type.
@@ -325,10 +342,10 @@
/**
* Returns an iteration of the <code>CertPath</code> encodings supported
* by this certificate factory, with the default encoding first. See
- * Appendix A in the
- * <a href="../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide</a> for information about
- * standard encoding names and their formats.
+ * the CertPath Encodings section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
+ * for information about standard encoding names and their formats.
* <p>
* Attempts to modify the returned <code>Iterator</code> via its
* <code>remove</code> method result in an
@@ -364,9 +381,10 @@
/**
* Generates a <code>CertPath</code> object and initializes it with
* the data read from the <code>InputStream</code> inStream. The data
- * is assumed to be in the specified encoding. See Appendix A in the
- * <a href="../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide</a>
+ * is assumed to be in the specified encoding. See
+ * the CertPath Encodings section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard encoding names and their formats.
*
* @param inStream an <code>InputStream</code> containing the data
--- a/jdk/src/share/classes/java/security/cert/CertificateFactorySpi.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertificateFactorySpi.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -182,9 +182,9 @@
/**
* Returns an iteration of the <code>CertPath</code> encodings supported
* by this certificate factory, with the default encoding first. See
- * Appendix A in the
- * <a href="../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
- * Java Certification Path API Programmer's Guide</a>
+ * the CertPath Encodings section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard encoding names.
* <p>
* Attempts to modify the returned <code>Iterator</code> via its
--- a/jdk/src/share/classes/java/security/cert/package.html Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/cert/package.html Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
<!--
- Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -35,9 +35,15 @@
<h2>Package Specification</h2>
<ul>
- <li><a href="../../../../technotes/guides/security/crypto/CryptoSpec.html"><b>Cryptography
- Architecture</b></a>
- <li>RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile
+ <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture (JCA) Reference Guide</b></a>
+ <li>RFC 3280: Internet X.509 Public Key Infrastructure Certificate and
+ Certificate Revocation List (CRL) Profile
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
</ul>
<h2>Related Documentation</h2>
@@ -45,11 +51,13 @@
For information about X.509 certificates and CRLs, please see:
<ul>
<li><a href="http://www.ietf.org/rfc/rfc3280.txt">
-http://www.ietf.org/rfc/rfc3280.txt</a>
- <li><a href="../../../../technotes/guides/security/certpath/CertPathProgGuide.html">
-PKI API Programmer's Guide</a>
- <li><a href="../../../../technotes/guides/security/cert3.html">
-X.509 Certificates and CRLs</a>
+ http://www.ietf.org/rfc/rfc3280.txt</a>
+ <li><a href=
+ "{@docRoot}/../technotes/guides/security/certpath/CertPathProgGuide.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ PKI Programmer's Guide</a>
+ <li><a href="{@docRoot}/../technotes/guides/security/cert3.html">
+ X.509 Certificates and Certificate Revocation Lists (CRLs)</a>
</ul>
@since 1.2
--- a/jdk/src/share/classes/java/security/package.html Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/security/package.html Tue Feb 08 14:25:33 2011 -0800
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -51,10 +51,17 @@
<h2>Package Specification</h2>
<ul>
- <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html"><b>
- Cryptography Architecture</b></a></li>
+ <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture (JCA) Reference Guide</b></a></li>
- <li>PKCS8: Private-Key Information Standard, Version 1.2, November 1993</li>
+ <li>PKCS #8: Private-Key Information Syntax Standard, Version 1.2,
+ November 1993</li>
+
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
</ul>
<h2>Related Documentation</h2>
@@ -62,13 +69,16 @@
For further documentation, please see:
<ul>
<li><a href=
- "{@docRoot}/../technotes/guides/security/spec/security-spec.doc.html"><b>
- Security Architecture</b></a></li>
+ "{@docRoot}/../technotes/guides/security/spec/security-spec.doc.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ SE Platform Security Architecture</b></a></li>
<li><a href=
- "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html"><b>
- How to Implement a Provider for the Java Cryptography Architecture
+ "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
+ <b>How to Implement a Provider in the
+ Java<FONT SIZE=-2><SUP>TM</SUP></FONT> Cryptography Architecture
</b></a></li>
+
<li><a href=
"{@docRoot}/../technotes/guides/security/PolicyFiles.html"><b>
Default Policy Implementation and Policy File Syntax
@@ -76,12 +86,14 @@
<li><a href=
"{@docRoot}/../technotes/guides/security/permissions.html"><b>
- Policy Permissions
+ Permissions in the
+ Java<FONT SIZE=-2><SUP>TM</SUP></FONT> SE Development Kit (JDK)
</b></a></li>
<li><a href=
"{@docRoot}/../technotes/guides/security/SecurityToolsSummary.html"><b>
- Security Tools Summary
+ Summary of Tools for
+ Java<FONT SIZE=-2><SUP>TM</SUP></FONT> Platform Security
</b></a></li>
<li><b>keytool</b>
@@ -100,6 +112,6 @@
</ul>
-@since JDK1.1
+@since 1.1
</body>
</html>
--- a/jdk/src/share/classes/java/sql/package.html Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/sql/package.html Tue Feb 08 14:25:33 2011 -0800
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -45,21 +45,22 @@
use and update data from a spread sheet, flat file, or any other tabular
data source.
<P>
-<h2>What the JDBC<sup><font size=-2>TM</font></sup> 4.0 API Includes</h2>
-The JDBC<sup><font size=-2>TM</font></sup> 4.0 API includes both
+<h2>What the JDBC<sup><font size=-2>TM</font></sup> 4.1 API Includes</h2>
+The JDBC<sup><font size=-2>TM</font></sup> 4.1 API includes both
the <code>java.sql</code> package, referred to as the JDBC core API,
and the <code>javax.sql</code> package, referred to as the JDBC Optional
Package API. This complete JDBC API
is included in the Java<sup><font size=-2>TM</font></sup>
-Standard Edition (Java SE<sup><font size=-2>TM</font></sup>), version 6.
+Standard Edition (Java SE<sup><font size=-2>TM</font></sup>), version 7.
The <code>javax.sql</code> package extends the functionality of the JDBC API
from a client-side API to a server-side API, and it is an essential part
of the Java<sup><font size=-2>TM</font></sup> Enterprise Edition
(Java EE<sup><font size=-2>TM</font></sup>) technology.
<P>
<h2>Versions</h2>
-The JDBC 4.0 API incorporates all of the previous JDBC API versions:
+The JDBC 4.1 API incorporates all of the previous JDBC API versions:
<UL>
+ <LI> The JDBC 4.0 API
<LI> The JDBC 3.0 API
<LI> The JDBC 2.1 core API
<LI> The JDBC 2.0 Optional Package API<br>
@@ -75,7 +76,9 @@
Javadoc<sup><font size=-2>TM</font></sup> comments for the JDBC API,
they indicate the following:
<UL>
- <LI>Since 1.6 -- new in the JDBC 4.0 API and part of the Java SE platform,
+ <LI>Since 1.7 -- new in the JDBC 4.1 API and part of the Java SE platform,
+ version 7
+<LI>Since 1.6 -- new in the JDBC 4.0 API and part of the Java SE platform,
version 6
<LI>Since 1.4 -- new in the JDBC 3.0 API and part of the J2SE platform,
version 1.4
@@ -176,6 +179,25 @@
</UL>
</UL>
<P>
+ <h3><code>java.sql</code> and <code>javax.sql</code> Features Introduced in the JDBC 4.1 API</h3>
+<UL>
+ <LI>Allow <code>Connection</code>,
+ <code>ResultSet</code> and <code>Statement</code> objects to be
+ used with the try-with-resources statement</LI>
+ <LI>Supported added to <code>CallableStatement</code> and
+ <code>ResultSet</code> to specify the Java type to convert to via the
+ <code>getObject</code> method</LI>
+ <LI><code>DatabaseMetaData</code> methods to return PseudoColumns and if a
+ generated key is always returned</LI>
+ <LI>Added support to <code>Connection</code> to specify a database schema,
+ abort and timeout a physical connection.</LI>
+ <LI>Added support to close a <code>Statement</code> object when its dependent
+ objects have been closed</LI>
+ <LI>Support for obtaining the parent logger for a <code>Driver</code>,
+ <code>DataSource</code>, <code>ConnectionPoolDataSource</code> and
+ <code>XADataSource</code></LI>
+
+</UL>
<h3><code>java.sql</code> and <code>javax.sql</code> Features Introduced in the JDBC 4.0 API</h3>
<UL>
<LI>auto java.sql.Driver discovery -- no longer need to load a
@@ -190,7 +212,7 @@
<li>Support added to allow a JDBC application to access an instance of a JDBC resource
that has been wrapped by a vendor, usually in an application server or connection
pooling environment.
- <li>Availability to be notfied when a <code>PreparedStatement</code> that is associated
+ <li>Availability to be notified when a <code>PreparedStatement</code> that is associated
with a <code>PooledConnection</code> has been closed or the driver determines is invalid
@@ -288,7 +310,7 @@
<h2>Related Documentation</h2>
<ul>
- <li><a href="../../../guide/jdbc/getstart/GettingStartedTOC.fm.html">Getting Started</a>--overviews of the major interfaces
+ <li><a href="../../../technotes/guides/jdbc/getstart/GettingStartedTOC.fm.html">Getting Started</a>--overviews of the major interfaces
<P>
<li><a href="http://java.sun.com/docs/books/tutorial/jdbc">Chapters on the JDBC
API</a>--from the online version of <i>The Java Tutorial Continued</i>
--- a/jdk/src/share/classes/java/util/Arrays.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/util/Arrays.java Tue Feb 08 14:25:33 2011 -0800
@@ -2823,6 +2823,7 @@
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
+ @SafeVarargs
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
--- a/jdk/src/share/classes/java/util/Collections.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/util/Collections.java Tue Feb 08 14:25:33 2011 -0800
@@ -3827,6 +3827,7 @@
* @see Collection#addAll(Collection)
* @since 1.5
*/
+ @SafeVarargs
public static <T> boolean addAll(Collection<? super T> c, T... elements) {
boolean result = false;
for (T element : elements)
--- a/jdk/src/share/classes/java/util/DualPivotQuicksort.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/util/DualPivotQuicksort.java Tue Feb 08 14:25:33 2011 -0800
@@ -36,7 +36,7 @@
* @author Jon Bentley
* @author Josh Bloch
*
- * @version 2010.10.13 m765.827.12i:5\7p
+ * @version 2011.01.21 m765.827.12i:5\7pm
* @since 1.7
*/
final class DualPivotQuicksort {
@@ -51,6 +51,22 @@
*/
/**
+ * The maximum number of runs in merge sort.
+ */
+ private static final int MAX_RUN_COUNT = 67;
+
+ /**
+ * The maximum length of run in merge sort.
+ */
+ private static final int MAX_RUN_LENGTH = 33;
+
+ /**
+ * If the length of an array to be sorted is less than this
+ * constant, Quicksort is used in preference to merge sort.
+ */
+ private static final int QUICKSORT_THRESHOLD = 286;
+
+ /**
* If the length of an array to be sorted is less than this
* constant, insertion sort is used in preference to Quicksort.
*/
@@ -78,7 +94,7 @@
* @param a the array to be sorted
*/
public static void sort(int[] a) {
- sort(a, 0, a.length - 1, true);
+ sort(a, 0, a.length - 1);
}
/**
@@ -89,7 +105,89 @@
* @param right the index of the last element, inclusive, to be sorted
*/
public static void sort(int[] a, int left, int right) {
- sort(a, left, right, true);
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ int[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new int[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new int[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ int[] t = a; a = b; b = t;
+ }
}
/**
@@ -103,7 +201,7 @@
private static void sort(int[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -126,26 +224,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- int a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ int a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -202,19 +298,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- int pivot1 = a[e2];
- int pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ int pivot1 = a[e2];
+ int pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -259,7 +355,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -269,7 +365,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -278,7 +374,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -299,10 +395,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -330,7 +427,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -348,12 +445,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = pivot1;
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -361,7 +458,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ int pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -383,35 +486,35 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
int ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
*/
- a[k] = pivot1;
+ a[k] = pivot;
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -431,7 +534,7 @@
* @param a the array to be sorted
*/
public static void sort(long[] a) {
- sort(a, 0, a.length - 1, true);
+ sort(a, 0, a.length - 1);
}
/**
@@ -442,7 +545,89 @@
* @param right the index of the last element, inclusive, to be sorted
*/
public static void sort(long[] a, int left, int right) {
- sort(a, left, right, true);
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ long t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ long[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new long[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new long[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ long[] t = a; a = b; b = t;
+ }
}
/**
@@ -456,7 +641,7 @@
private static void sort(long[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -479,26 +664,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- long a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ long a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -555,19 +738,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- long pivot1 = a[e2];
- long pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ long pivot1 = a[e2];
+ long pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -612,7 +795,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -622,7 +805,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -631,7 +814,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -652,10 +835,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -683,7 +867,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -701,12 +885,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = pivot1;
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -714,7 +898,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ long pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -736,35 +926,35 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
long ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
*/
- a[k] = pivot1;
+ a[k] = pivot;
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -799,9 +989,9 @@
if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
int[] count = new int[NUM_SHORT_VALUES];
- for (int i = left - 1; ++i <= right; ) {
- count[a[i] - Short.MIN_VALUE]++;
- }
+ for (int i = left - 1; ++i <= right;
+ count[a[i] - Short.MIN_VALUE]++
+ );
for (int i = NUM_SHORT_VALUES, k = right + 1; k > left; ) {
while (count[--i] == 0);
short value = (short) (i + Short.MIN_VALUE);
@@ -812,7 +1002,7 @@
} while (--s > 0);
}
} else { // Use Dual-Pivot Quicksort on small arrays
- sort(a, left, right, true);
+ doSort(a, left, right);
}
}
@@ -820,6 +1010,99 @@
private static final int NUM_SHORT_VALUES = 1 << 16;
/**
+ * Sorts the specified range of the array.
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ */
+ private static void doSort(short[] a, int left, int right) {
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ short t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ short[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new short[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new short[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ short[] t = a; a = b; b = t;
+ }
+ }
+
+ /**
* Sorts the specified range of the array by Dual-Pivot Quicksort.
*
* @param a the array to be sorted
@@ -827,10 +1110,10 @@
* @param right the index of the last element, inclusive, to be sorted
* @param leftmost indicates if this part is the leftmost in the range
*/
- private static void sort(short[] a, int left, int right,boolean leftmost) {
+ private static void sort(short[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -853,26 +1136,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- short a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ short a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -929,19 +1210,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- short pivot1 = a[e2];
- short pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ short pivot1 = a[e2];
+ short pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -986,7 +1267,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -996,7 +1277,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -1005,7 +1286,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1026,10 +1307,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -1057,7 +1339,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -1075,12 +1357,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = pivot1;
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -1088,7 +1370,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ short pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -1110,35 +1398,35 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
short ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
*/
- a[k] = pivot1;
+ a[k] = pivot;
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1173,9 +1461,9 @@
if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
int[] count = new int[NUM_CHAR_VALUES];
- for (int i = left - 1; ++i <= right; ) {
- count[a[i]]++;
- }
+ for (int i = left - 1; ++i <= right;
+ count[a[i]]++
+ );
for (int i = NUM_CHAR_VALUES, k = right + 1; k > left; ) {
while (count[--i] == 0);
char value = (char) i;
@@ -1186,7 +1474,7 @@
} while (--s > 0);
}
} else { // Use Dual-Pivot Quicksort on small arrays
- sort(a, left, right, true);
+ doSort(a, left, right);
}
}
@@ -1194,6 +1482,99 @@
private static final int NUM_CHAR_VALUES = 1 << 16;
/**
+ * Sorts the specified range of the array.
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ */
+ private static void doSort(char[] a, int left, int right) {
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ char t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ char[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new char[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new char[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ char[] t = a; a = b; b = t;
+ }
+ }
+
+ /**
* Sorts the specified range of the array by Dual-Pivot Quicksort.
*
* @param a the array to be sorted
@@ -1204,7 +1585,7 @@
private static void sort(char[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -1227,26 +1608,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- char a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ char a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -1303,19 +1682,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- char pivot1 = a[e2];
- char pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ char pivot1 = a[e2];
+ char pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -1360,7 +1739,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -1370,7 +1749,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -1379,7 +1758,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1400,10 +1779,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -1431,7 +1811,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -1449,12 +1829,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = pivot1;
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -1462,7 +1842,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ char pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -1484,35 +1870,35 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
char ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
*/
- a[k] = pivot1;
+ a[k] = pivot;
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1550,9 +1936,9 @@
if (right - left > COUNTING_SORT_THRESHOLD_FOR_BYTE) {
int[] count = new int[NUM_BYTE_VALUES];
- for (int i = left - 1; ++i <= right; ) {
- count[a[i] - Byte.MIN_VALUE]++;
- }
+ for (int i = left - 1; ++i <= right;
+ count[a[i] - Byte.MIN_VALUE]++
+ );
for (int i = NUM_BYTE_VALUES, k = right + 1; k > left; ) {
while (count[--i] == 0);
byte value = (byte) (i + Byte.MIN_VALUE);
@@ -1597,21 +1983,21 @@
* Phase 1: Move NaNs to the end of the array.
*/
while (left <= right && Float.isNaN(a[right])) {
- right--;
+ --right;
}
for (int k = right; --k >= left; ) {
float ak = a[k];
if (ak != ak) { // a[k] is NaN
a[k] = a[right];
a[right] = ak;
- right--;
+ --right;
}
}
/*
* Phase 2: Sort everything except NaNs (which are already in place).
*/
- sort(a, left, right, true);
+ doSort(a, left, right);
/*
* Phase 3: Place negative zeros before positive zeros.
@@ -1636,7 +2022,7 @@
* Skip the last negative value (if any) or all leading negative zeros.
*/
while (left <= right && Float.floatToRawIntBits(a[left]) < 0) {
- left++;
+ ++left;
}
/*
@@ -1673,6 +2059,99 @@
}
/**
+ * Sorts the specified range of the array.
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ */
+ private static void doSort(float[] a, int left, int right) {
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ float t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ float[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new float[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new float[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ float[] t = a; a = b; b = t;
+ }
+ }
+
+ /**
* Sorts the specified range of the array by Dual-Pivot Quicksort.
*
* @param a the array to be sorted
@@ -1680,10 +2159,10 @@
* @param right the index of the last element, inclusive, to be sorted
* @param leftmost indicates if this part is the leftmost in the range
*/
- private static void sort(float[] a, int left, int right,boolean leftmost) {
+ private static void sort(float[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -1706,26 +2185,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- float a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ float a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -1782,19 +2259,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- float pivot1 = a[e2];
- float pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ float pivot1 = a[e2];
+ float pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -1839,7 +2316,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -1849,7 +2326,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -1858,7 +2335,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -1879,10 +2356,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -1910,7 +2388,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -1928,12 +2406,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -1941,7 +2419,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ float pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -1963,27 +2447,27 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
float ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
@@ -1991,7 +2475,7 @@
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
@@ -2026,21 +2510,21 @@
* Phase 1: Move NaNs to the end of the array.
*/
while (left <= right && Double.isNaN(a[right])) {
- right--;
+ --right;
}
for (int k = right; --k >= left; ) {
double ak = a[k];
if (ak != ak) { // a[k] is NaN
a[k] = a[right];
a[right] = ak;
- right--;
+ --right;
}
}
/*
* Phase 2: Sort everything except NaNs (which are already in place).
*/
- sort(a, left, right, true);
+ doSort(a, left, right);
/*
* Phase 3: Place negative zeros before positive zeros.
@@ -2065,7 +2549,7 @@
* Skip the last negative value (if any) or all leading negative zeros.
*/
while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) {
- left++;
+ ++left;
}
/*
@@ -2102,6 +2586,99 @@
}
/**
+ * Sorts the specified range of the array.
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ */
+ private static void doSort(double[] a, int left, int right) {
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT];
+ int count = 0; run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]);
+ } else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]);
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ double t = a[lo]; a[lo] = a[hi]; a[hi] = t;
+ }
+ } else { // equal
+ for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
+ if (--m == 0) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+ }
+
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ if (run[count] == right++) { // The last run contains one element
+ run[++count] = right;
+ } else if (count == 1) { // The array is already sorted
+ return;
+ }
+
+ /*
+ * Create temporary array, which is used for merging.
+ * Implementation note: variable "right" is increased by 1.
+ */
+ double[] b; byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1);
+
+ if (odd == 0) {
+ b = a; a = new double[b.length];
+ for (int i = left - 1; ++i < right; a[i] = b[i]);
+ } else {
+ b = new double[a.length];
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p] <= a[q]) {
+ b[i] = a[p++];
+ } else {
+ b[i] = a[q++];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i] = a[i]
+ );
+ run[++last] = right;
+ }
+ double[] t = a; a = b; b = t;
+ }
+ }
+
+ /**
* Sorts the specified range of the array by Dual-Pivot Quicksort.
*
* @param a the array to be sorted
@@ -2109,10 +2686,10 @@
* @param right the index of the last element, inclusive, to be sorted
* @param leftmost indicates if this part is the leftmost in the range
*/
- private static void sort(double[] a, int left,int right,boolean leftmost) {
+ private static void sort(double[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
- // Use insertion sort on small arrays
+ // Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
@@ -2135,26 +2712,24 @@
* Skip the longest ascending sequence.
*/
do {
- if (left++ >= right) {
+ if (left >= right) {
return;
}
- } while (a[left - 1] <= a[left]);
+ } while (a[++left] >= a[left - 1]);
/*
* Every element from adjoining part plays the role
* of sentinel, therefore this allows us to avoid the
* left range check on each iteration. Moreover, we use
- * the best improved algorithm, so called pair insertion
- * sort, which is faster than traditional implementation
- * in the context of Dual-Pivot Quicksort.
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
*/
- for (int k = left--; (left += 2) <= right; ) {
- double a1, a2; k = left - 1;
+ for (int k = left; ++left <= right; k = ++left) {
+ double a1 = a[k], a2 = a[left];
- if (a[k] < a[left]) {
- a2 = a[k]; a1 = a[left];
- } else {
- a1 = a[k]; a2 = a[left];
+ if (a1 < a2) {
+ a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
@@ -2211,19 +2786,19 @@
}
}
- /*
- * Use the second and fourth of the five sorted elements as pivots.
- * These values are inexpensive approximations of the first and
- * second terciles of the array. Note that pivot1 <= pivot2.
- */
- double pivot1 = a[e2];
- double pivot2 = a[e4];
-
// Pointers
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
- if (pivot1 != pivot2) {
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ double pivot1 = a[e2];
+ double pivot2 = a[e4];
+
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
@@ -2268,7 +2843,7 @@
* of "a[i++] = b;" due to performance issue.
*/
a[less] = ak;
- less++;
+ ++less;
} else if (ak > pivot2) { // Move a[k] to right part
while (a[great] > pivot2) {
if (great-- == k) {
@@ -2278,7 +2853,7 @@
if (a[great] < pivot1) { // a[great] <= pivot2
a[k] = a[less];
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 <= a[great] <= pivot2
a[k] = a[great];
}
@@ -2287,7 +2862,7 @@
* of "a[i--] = b;" due to performance issue.
*/
a[great] = ak;
- great--;
+ --great;
}
}
@@ -2308,10 +2883,11 @@
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
- less++;
+ ++less;
}
+
while (a[great] == pivot2) {
- great--;
+ --great;
}
/*
@@ -2339,7 +2915,7 @@
if (ak == pivot1) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
+ ++less;
} else if (ak == pivot2) { // Move a[k] to right part
while (a[great] == pivot2) {
if (great-- == k) {
@@ -2357,12 +2933,12 @@
* accurate assignment a[less] = a[great].
*/
a[less] = a[great];
- less++;
+ ++less;
} else { // pivot1 < a[great] < pivot2
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
}
@@ -2370,7 +2946,13 @@
// Sort center part recursively
sort(a, less, great, false);
- } else { // Pivots are equal
+ } else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ double pivot = a[e3];
+
/*
* Partitioning degenerates to the traditional 3-way
* (or "Dutch National Flag") schema:
@@ -2392,27 +2974,27 @@
* Pointer k is the first index of ?-part.
*/
for (int k = less; k <= great; ++k) {
- if (a[k] == pivot1) {
+ if (a[k] == pivot) {
continue;
}
double ak = a[k];
- if (ak < pivot1) { // Move a[k] to left part
+ if (ak < pivot) { // Move a[k] to left part
a[k] = a[less];
a[less] = ak;
- less++;
- } else { // a[k] > pivot1 - Move a[k] to right part
- while (a[great] > pivot1) {
- great--;
+ ++less;
+ } else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
}
- if (a[great] < pivot1) { // a[great] <= pivot1
+ if (a[great] < pivot) { // a[great] <= pivot
a[k] = a[less];
a[less] = a[great];
- less++;
- } else { // a[great] == pivot1
+ ++less;
+ } else { // a[great] == pivot
/*
- * Even though a[great] equals to pivot1, the
- * assignment a[k] = pivot1 may be incorrect,
- * if a[great] and pivot1 are floating-point
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
* zeros of different signs. Therefore in float
* and double sorting methods we have to use
* more accurate assignment a[k] = a[great].
@@ -2420,7 +3002,7 @@
a[k] = a[great];
}
a[great] = ak;
- great--;
+ --great;
}
}
--- a/jdk/src/share/classes/java/util/EnumSet.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/util/EnumSet.java Tue Feb 08 14:25:33 2011 -0800
@@ -317,6 +317,7 @@
* or if <tt>rest</tt> is null
* @return an enum set initially containing the specified elements
*/
+ @SafeVarargs
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
EnumSet<E> result = noneOf(first.getDeclaringClass());
result.add(first);
--- a/jdk/src/share/classes/java/util/Formatter.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/util/Formatter.java Tue Feb 08 14:25:33 2011 -0800
@@ -47,9 +47,6 @@
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -1859,7 +1856,7 @@
private static Charset toCharset(String csn)
throws UnsupportedEncodingException
{
- Objects.nonNull(csn, "charsetName");
+ Objects.requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
@@ -2179,7 +2176,7 @@
*/
public Formatter(PrintStream ps) {
this(Locale.getDefault(Locale.Category.FORMAT),
- (Appendable)Objects.nonNull(ps));
+ (Appendable)Objects.requireNonNull(ps));
}
/**
--- a/jdk/src/share/classes/java/util/Objects.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/util/Objects.java Tue Feb 08 14:25:33 2011 -0800
@@ -187,7 +187,7 @@
* and constructors, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar) {
- * this.bar = Objects.nonNull(bar);
+ * this.bar = Objects.requireNonNull(bar);
* }
* </pre></blockquote>
*
@@ -196,7 +196,7 @@
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
- public static <T> T nonNull(T obj) {
+ public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
@@ -209,8 +209,8 @@
* constructors with multiple parameters, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar, Baz baz) {
- * this.bar = Objects.nonNull(bar, "bar must not be null");
- * this.baz = Objects.nonNull(baz, "baz must not be null");
+ * this.bar = Objects.requireNonNull(bar, "bar must not be null");
+ * this.baz = Objects.requireNonNull(baz, "baz must not be null");
* }
* </pre></blockquote>
*
@@ -221,7 +221,7 @@
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
- public static <T> T nonNull(T obj, String message) {
+ public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
--- a/jdk/src/share/classes/java/util/Scanner.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/util/Scanner.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,7 +25,8 @@
package java.util;
-import java.nio.file.FileRef;
+import java.nio.file.Path;
+import java.nio.file.Files;
import java.util.regex.*;
import java.io.*;
import java.math.*;
@@ -34,6 +35,7 @@
import java.nio.charset.*;
import java.text.*;
import java.util.Locale;
+
import sun.misc.LRUCache;
/**
@@ -591,7 +593,7 @@
* interface
*/
public Scanner(Readable source) {
- this(Objects.nonNull(source, "source"), WHITESPACE_PATTERN);
+ this(Objects.requireNonNull(source, "source"), WHITESPACE_PATTERN);
}
/**
@@ -618,7 +620,7 @@
* does not exist
*/
public Scanner(InputStream source, String charsetName) {
- this(makeReadable(Objects.nonNull(source, "source"), toCharset(charsetName)),
+ this(makeReadable(Objects.requireNonNull(source, "source"), toCharset(charsetName)),
WHITESPACE_PATTERN);
}
@@ -628,7 +630,7 @@
* @throws IllegalArgumentException if the charset is not supported
*/
private static Charset toCharset(String csn) {
- Objects.nonNull(csn, "charsetName");
+ Objects.requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException e) {
@@ -669,7 +671,7 @@
public Scanner(File source, String charsetName)
throws FileNotFoundException
{
- this(Objects.nonNull(source), toDecoder(charsetName));
+ this(Objects.requireNonNull(source), toDecoder(charsetName));
}
private Scanner(File source, CharsetDecoder dec)
@@ -679,7 +681,7 @@
}
private static CharsetDecoder toDecoder(String charsetName) {
- Objects.nonNull(charsetName, "charsetName");
+ Objects.requireNonNull(charsetName, "charsetName");
try {
return Charset.forName(charsetName).newDecoder();
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
@@ -699,16 +701,16 @@
* {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
*
* @param source
- * A file to be scanned
+ * the path to the file to be scanned
* @throws IOException
* if an I/O error occurs opening source
*
* @since 1.7
*/
- public Scanner(FileRef source)
+ public Scanner(Path source)
throws IOException
{
- this(source.newInputStream());
+ this(Files.newInputStream(source));
}
/**
@@ -717,7 +719,7 @@
* characters using the specified charset.
*
* @param source
- * A file to be scanned
+ * the path to the file to be scanned
* @param charsetName
* The encoding type used to convert bytes from the file
* into characters to be scanned
@@ -727,12 +729,12 @@
* if the specified encoding is not found
* @since 1.7
*/
- public Scanner(FileRef source, String charsetName) throws IOException {
- this(Objects.nonNull(source), toCharset(charsetName));
+ public Scanner(Path source, String charsetName) throws IOException {
+ this(Objects.requireNonNull(source), toCharset(charsetName));
}
- private Scanner(FileRef source, Charset charset) throws IOException {
- this(makeReadable(source.newInputStream(), charset));
+ private Scanner(Path source, Charset charset) throws IOException {
+ this(makeReadable(Files.newInputStream(source), charset));
}
/**
@@ -754,7 +756,7 @@
* @param source A channel to scan
*/
public Scanner(ReadableByteChannel source) {
- this(makeReadable(Objects.nonNull(source, "source")),
+ this(makeReadable(Objects.requireNonNull(source, "source")),
WHITESPACE_PATTERN);
}
@@ -774,7 +776,7 @@
* does not exist
*/
public Scanner(ReadableByteChannel source, String charsetName) {
- this(makeReadable(Objects.nonNull(source, "source"), toDecoder(charsetName)),
+ this(makeReadable(Objects.requireNonNull(source, "source"), toDecoder(charsetName)),
WHITESPACE_PATTERN);
}
--- a/jdk/src/share/classes/java/util/regex/Pattern.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java Tue Feb 08 14:25:33 2011 -0800
@@ -101,6 +101,11 @@
* <td headers="matches">The character with hexadecimal value <tt>0x</tt><i>hh</i></td></tr>
* <tr><td valign="top" headers="construct characters"><tt>\u</tt><i>hhhh</i></td>
* <td headers="matches">The character with hexadecimal value <tt>0x</tt><i>hhhh</i></td></tr>
+ * <tr><td valign="top" headers="construct characters"><tt>\x</tt><i>{h...h}</i></td>
+ * <td headers="matches">The character with hexadecimal value <tt>0x</tt><i>h...h</i>
+ * ({@link java.lang.Character#MIN_CODE_POINT Character.MIN_CODE_POINT}
+ * <= <tt>0x</tt><i>h...h</i> <= 
+ * {@link java.lang.Character#MAX_CODE_POINT Character.MAX_CODE_POINT})</td></tr>
* <tr><td valign="top" headers="matches"><tt>\t</tt></td>
* <td headers="matches">The tab character (<tt>'\u0009'</tt>)</td></tr>
* <tr><td valign="top" headers="construct characters"><tt>\n</tt></td>
@@ -529,6 +534,13 @@
* while not equal, compile into the same pattern, which matches the character
* with hexadecimal value <tt>0x2014</tt>.
*
+ * <p> A Unicode character can also be represented in a regular-expression by
+ * using its hexadecimal code point value directly as described in construct
+ * <tt>\x{...}</tt>, for example a supplementary character U+2011F
+ * can be specified as <tt>\x{2011F}</tt>, instead of two consecutive
+ * Unicode escape sequences of the surrogate pair
+ * <tt>\uD840</tt><tt>\uDD1F</tt>.
+ *
* <a name="ubc">
* <p>Unicode scripts, blocks and categories are written with the <tt>\p</tt> and
* <tt>\P</tt> constructs as in Perl. <tt>\p{</tt><i>prop</i><tt>}</tt> matches if
@@ -2993,6 +3005,16 @@
if (ASCII.isHexDigit(m)) {
return ASCII.toDigit(n) * 16 + ASCII.toDigit(m);
}
+ } else if (n == '{' && ASCII.isHexDigit(peek())) {
+ int ch = 0;
+ while (ASCII.isHexDigit(n = read())) {
+ ch = (ch << 4) + ASCII.toDigit(n);
+ if (ch > Character.MAX_CODE_POINT)
+ throw error("Hexadecimal codepoint is too big");
+ }
+ if (n != '}')
+ throw error("Unclosed hexadecimal escape sequence");
+ return ch;
}
throw error("Illegal hexadecimal escape sequence");
}
--- a/jdk/src/share/classes/javax/crypto/Cipher.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/Cipher.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,7 +78,7 @@
* Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
* </pre>
*
- * Using modes such as <code>CFB</code> and <code>OFB<code>, block
+ * Using modes such as <code>CFB</code> and <code>OFB</code>, block
* ciphers can encrypt data in units smaller than the cipher's actual
* block size. When requesting such a mode, you may optionally specify
* the number of bits to be processed at a time by appending this number
@@ -89,6 +89,33 @@
* Thus, block ciphers can be turned into byte-oriented stream ciphers by
* using an 8 bit mode such as CFB8 or OFB8.
*
+ * <p> Every implementation of the Java platform is required to support
+ * the following standard <code>Cipher</code> transformations with the keysizes
+ * in parentheses:
+ * <ul>
+ * <li><tt>AES/CBC/NoPadding</tt> (128)</li>
+ * <li><tt>AES/CBC/PKCS5Padding</tt> (128)</li>
+ * <li><tt>AES/ECB/NoPadding</tt> (128)</li>
+ * <li><tt>AES/ECB/PKCS5Padding</tt> (128)</li>
+ * <li><tt>DES/CBC/NoPadding</tt> (56)</li>
+ * <li><tt>DES/CBC/PKCS5Padding</tt> (56)</li>
+ * <li><tt>DES/ECB/NoPadding</tt> (56)</li>
+ * <li><tt>DES/ECB/PKCS5Padding</tt> (56)</li>
+ * <li><tt>DESede/CBC/NoPadding</tt> (168)</li>
+ * <li><tt>DESede/CBC/PKCS5Padding</tt> (168)</li>
+ * <li><tt>DESede/ECB/NoPadding</tt> (168)</li>
+ * <li><tt>DESede/ECB/PKCS5Padding</tt> (168)</li>
+ * <li><tt>RSA/ECB/PKCS1Padding</tt> (1024, 2048)</li>
+ * <li><tt>RSA/ECB/OAEPWithSHA-1AndMGF1Padding</tt> (1024, 2048)</li>
+ * <li><tt>RSA/ECB/OAEPWithSHA-256AndMGF1Padding</tt> (1024, 2048)</li>
+ * </ul>
+ * These transformations are described in the
+ * <a href="{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
+ * Cipher section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other transformations are supported.
+ *
* @author Jan Luehe
* @see KeyGenerator
* @see SecretKey
@@ -408,10 +435,9 @@
*
* @param transformation the name of the transformation, e.g.,
* <i>DES/CBC/PKCS5Padding</i>.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Cipher section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard transformation names.
*
* @return a cipher that implements the requested transformation.
@@ -485,10 +511,9 @@
*
* @param transformation the name of the transformation,
* e.g., <i>DES/CBC/PKCS5Padding</i>.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Cipher section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard transformation names.
*
* @param provider the name of the provider.
@@ -538,10 +563,9 @@
*
* @param transformation the name of the transformation,
* e.g., <i>DES/CBC/PKCS5Padding</i>.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Cipher section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard transformation names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/ExemptionMechanism.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/ExemptionMechanism.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -114,10 +114,10 @@
*
* @param algorithm the standard name of the requested exemption
* mechanism.
- * See Appendix A in the
+ * See the ExemptionMechanism section in the
* <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * "{docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard exemption mechanism names.
*
* @return the new <code>ExemptionMechanism</code> object.
@@ -153,10 +153,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
* @param algorithm the standard name of the requested exemption mechanism.
- * See Appendix A in the
+ * See the ExemptionMechanism section in the
* <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * "{docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard exemption mechanism names.
*
* @param provider the name of the provider.
@@ -197,10 +197,10 @@
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested exemption mechanism.
- * See Appendix A in the
+ * See the ExemptionMechanism section in the
* <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * "{docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard exemption mechanism names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/KeyAgreement.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/KeyAgreement.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,18 @@
* <code>false</code>, and the second time setting it to <code>true</code>.
* There may be any number of parties involved in a key exchange.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>KeyAgreement</code> algorithm:
+ * <ul>
+ * <li><tt>DiffieHellman</tt></li>
+ * </ul>
+ * This algorithm is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
+ * KeyAgreement section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
* @see KeyGenerator
@@ -135,10 +147,9 @@
*
* @param algorithm the standard name of the requested key agreement
* algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyAgreement section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
* @return the new <code>KeyAgreement</code> object.
@@ -182,10 +193,9 @@
*
* @param algorithm the standard name of the requested key agreement
* algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyAgreement section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -227,10 +237,9 @@
*
* @param algorithm the standard name of the requested key agreement
* algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyAgreement section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/KeyGenerator.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/KeyGenerator.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -84,6 +84,23 @@
* (via a call to an <code>init</code> method), each provider must
* supply (and document) a default initialization.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>KeyGenerator</code> algorithms with the keysizes in
+ * parentheses:
+ * <ul>
+ * <li><tt>AES</tt> (128)</li>
+ * <li><tt>DES</tt> (56)</li>
+ * <li><tt>DESede</tt> (168)</li>
+ * <li><tt>HmacSHA1</tt></li>
+ * <li><tt>HmacSHA256</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
+ * KeyGenerator section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
* @see SecretKey
@@ -170,10 +187,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested key algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new <code>KeyGenerator</code> object.
@@ -204,10 +220,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested key algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -247,10 +262,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested key algorithm.
- * See Appendix A in the
- * <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the KeyGenerator section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/Mac.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/Mac.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,6 +53,20 @@
* e.g., MD5 or SHA-1, in combination with a secret shared key. HMAC is
* specified in RFC 2104.
*
+ * <p> Every implementation of the Java platform is required to support
+ * the following standard <code>Mac</code> algorithms:
+ * <ul>
+ * <li><tt>HmacMD5</tt></li>
+ * <li><tt>HmacSHA1</tt></li>
+ * <li><tt>HmacSHA256</tt></li>
+ * </ul>
+ * These algorithms are described in the
+ * <a href="{@docRoot}/../technotes/guides/security/StandardNames.html#Mac">
+ * Mac section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
* @since 1.4
@@ -134,9 +148,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested MAC algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Mac section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Mac">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new <code>Mac</code> object.
@@ -176,9 +190,9 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested MAC algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Mac section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Mac">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -214,9 +228,9 @@
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested MAC algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the Mac section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Mac">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/SecretKeyFactory.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/SecretKeyFactory.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,20 @@
* <code>DESedeKeySpec</code> as a transparent representation of Triple DES
* keys.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>SecretKeyFactory</code> algorithms:
+ * <ul>
+ * <li><tt>AES</tt></li>
+ * <li><tt>DES</tt></li>
+ * <li><tt>DESede</tt></li>
+ * </ul>
+ * These algorithms are described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
+ * SecretKeyFactory section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @author Jan Luehe
*
* @see SecretKey
@@ -125,9 +139,9 @@
*
* @param algorithm the standard name of the requested secret-key
* algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the SecretKeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @return the new <code>SecretKeyFactory</code> object.
@@ -160,9 +174,9 @@
*
* @param algorithm the standard name of the requested secret-key
* algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the SecretKeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@@ -204,9 +218,9 @@
*
* @param algorithm the standard name of the requested secret-key
* algorithm.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture Reference Guide</a>
+ * See the SecretKeyFactory section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for information about standard algorithm names.
*
* @param provider the provider.
--- a/jdk/src/share/classes/javax/crypto/package.html Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/crypto/package.html Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
<!--
-Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,15 @@
Therefore application developers may take advantage of any number of
provider-based implementations without having to add or rewrite code.
+<h2>Package Specification</h2>
+
+<ul>
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html"><b>
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
+</ul>
+
<h2>Related Documentation</h2>
For further documentation, please see:
@@ -52,12 +61,12 @@
<a href=
"{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
<b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
- Cryptography Architecture API Specification and Reference
+ Cryptography Architecture (JCA) Reference Guide
</b></a></li>
<li>
<a href=
"{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
- <b>How to Implement a Provider for the
+ <b>How to Implement a Provider in the
Java<FONT SIZE=-2><SUP>TM</SUP></FONT> Cryptography Architecture
</b></a></li>
</ul>
--- a/jdk/src/share/classes/javax/net/ssl/SSLContext.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/net/ssl/SSLContext.java Tue Feb 08 14:25:33 2011 -0800
@@ -37,6 +37,18 @@
* with an optional set of key and trust managers and source of
* secure random bytes.
*
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard <code>SSLContext</code> protocol:
+ * <ul>
+ * <li><tt>TLSv1</tt></li>
+ * </ul>
+ * This protocol is described in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
+ * SSLContext section</a> of the
+ * Java Cryptography Architecture Standard Algorithm Name Documentation.
+ * Consult the release documentation for your implementation to see if any
+ * other algorithms are supported.
+ *
* @since 1.4
*/
public class SSLContext {
@@ -124,9 +136,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param protocol the standard name of the requested protocol.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html#AppA">
- * Java Secure Socket Extension Reference Guide </a>
+ * See the SSLContext section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a>
* for information about standard protocol names.
*
* @return the new <code>SSLContext</code> object.
@@ -159,9 +172,10 @@
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param protocol the standard name of the requested protocol.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html#AppA">
- * Java Secure Socket Extension Reference Guide </a>
+ * See the SSLContext section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a>
* for information about standard protocol names.
*
* @param provider the name of the provider.
@@ -198,9 +212,10 @@
* does not have to be registered in the provider list.
*
* @param protocol the standard name of the requested protocol.
- * See Appendix A in the <a href=
- * "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html#AppA">
- * Java Secure Socket Extension Reference Guide </a>
+ * See the SSLContext section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a>
* for information about standard protocol names.
*
* @param provider an instance of the provider.
--- a/jdk/src/share/classes/javax/net/ssl/package.html Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/net/ssl/package.html Tue Feb 08 14:25:33 2011 -0800
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -33,14 +33,17 @@
classes, you can communicate using SSL or a related security protocol
to reliably detect any errors introduced into the network byte stream
and to optionally encrypt the data and/or authenticate the communicating peers.
-<!--
+
<h2>Package Specification</h2>
-##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
<ul>
- <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
</ul>
+<!--
<h2>Related Documentation</h2>
For overviews, tutorials, examples, guides, and tool documentation, please see:
--- a/jdk/src/share/classes/javax/security/auth/login/Configuration.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/security/auth/login/Configuration.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -184,9 +184,9 @@
* implementation. In addition, an instance of a Configuration object can be
* constructed by invoking one of the <code>getInstance</code> factory methods
* with a standard type. The default policy type is "JavaLoginConfig".
- * See Appendix A in the
- * <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
+ * See the Configuration section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
+ * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for a list of standard Configuration types.
*
* @see javax.security.auth.login.LoginContext
@@ -319,10 +319,11 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * @param type the specified Configuration type. See Appendix A in the
- * <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for a list of standard Configuration types.
+ * @param type the specified Configuration type. See the Configuration
+ * section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a> for a list of standard Configuration types.
*
* @param params parameters for the Configuration, which may be null.
*
@@ -374,10 +375,11 @@
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
- * @param type the specified Configuration type. See Appendix A in the
- * <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for a list of standard Configuration types.
+ * @param type the specified Configuration type. See the Configuration
+ * section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a> for a list of standard Configuration types.
*
* @param params parameters for the Configuration, which may be null.
*
@@ -439,10 +441,11 @@
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
- * @param type the specified Configuration type. See Appendix A in the
- * <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for a list of standard Configuration types.
+ * @param type the specified Configuration type. See the Configuration
+ * section in the <a href=
+ * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
+ * Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</a> for a list of standard Configuration types.
*
* @param params parameters for the Configuration, which may be null.
*
--- a/jdk/src/share/classes/javax/security/auth/login/package.html Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/security/auth/login/package.html Tue Feb 08 14:25:33 2011 -0800
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -30,14 +30,16 @@
<body bgcolor="white">
This package provides a pluggable authentication framework.
-<!--
<h2>Package Specification</h2>
-##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
<ul>
- <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
+ <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
+ <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
+ Cryptography Architecture Standard Algorithm Name
+ Documentation</b></a></li>
</ul>
+<!--
<h2>Related Documentation</h2>
For overviews, tutorials, examples, guides, and tool documentation, please see:
@@ -47,6 +49,6 @@
-->
-@since JDK1.4
+@since 1.4
</body>
</html>
--- a/jdk/src/share/classes/javax/swing/JComponent.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/JComponent.java Tue Feb 08 14:25:33 2011 -0800
@@ -4911,7 +4911,7 @@
* painting to originate from this Component, or one of its ancestors.
* <p/>
* Calling {@link JComponent#repaint} on a Swing component will be delegated to
- * the first ancestor which {@code isPaintingOrigin()} returns {@true},
+ * the first ancestor which {@code isPaintingOrigin()} returns {@code true},
* if there are any.
* <p/>
* {@code JComponent} subclasses that need to be repainted when any of their
--- a/jdk/src/share/classes/javax/swing/SwingWorker.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/SwingWorker.java Tue Feb 08 14:25:33 2011 -0800
@@ -404,6 +404,7 @@
* @see #process
*
*/
+ @SafeVarargs
protected final void publish(V... chunks) {
synchronized (this) {
if (doProcess == null) {
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java Tue Feb 08 14:25:33 2011 -0800
@@ -92,7 +92,7 @@
* </ol>
*
* @param c the editor component
- * @see BasicTextUI#installUI
+ * @see javax.swing.plaf.basic.BasicTextUI#installUI
* @see ComponentUI#installUI
*/
@Override
--- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java Tue Feb 08 14:25:33 2011 -0800
@@ -63,8 +63,6 @@
public enum LauncherHelper {
INSTANCE;
- private static final String defaultBundleName =
- "sun.launcher.resources.launcher";
private static final String MAIN_CLASS = "Main-Class";
private static StringBuilder outBuf = new StringBuilder();
@@ -76,11 +74,14 @@
private static final String PROP_SETTINGS = "Property settings:";
private static final String LOCALE_SETTINGS = "Locale settings:";
- private static synchronized ResourceBundle getLauncherResourceBundle() {
- if (javarb == null) {
- javarb = ResourceBundle.getBundle(defaultBundleName);
- }
- return javarb;
+ // sync with java.c and sun.misc.VM
+ private static final String diagprop = "sun.java.launcher.diag";
+
+ private static final String defaultBundleName =
+ "sun.launcher.resources.launcher";
+ private static class ResourceBundleHolder {
+ private static final ResourceBundle RB =
+ ResourceBundle.getBundle(defaultBundleName);
}
/*
@@ -308,7 +309,7 @@
* apply any arguments that we might pass.
*/
private static String getLocalizedMessage(String key, Object... args) {
- String msg = getLauncherResourceBundle().getString(key);
+ String msg = ResourceBundleHolder.RB.getString(key);
return (args != null) ? MessageFormat.format(msg, args) : msg;
}
@@ -380,25 +381,29 @@
File.pathSeparator));
}
- static String getMainClassFromJar(String jarname) throws IOException {
- JarFile jarFile = null;
+ static String getMainClassFromJar(PrintStream ostream, String jarname) {
try {
- jarFile = new JarFile(jarname);
- Manifest manifest = jarFile.getManifest();
- if (manifest == null) {
- throw new IOException("manifest not found in " + jarname);
+ JarFile jarFile = null;
+ try {
+ jarFile = new JarFile(jarname);
+ Manifest manifest = jarFile.getManifest();
+ if (manifest == null) {
+ abort(ostream, null, "java.launcher.jar.error2", jarname);
+ }
+ Attributes mainAttrs = manifest.getMainAttributes();
+ if (mainAttrs == null) {
+ abort(ostream, null, "java.launcher.jar.error3", jarname);
+ }
+ return mainAttrs.getValue(MAIN_CLASS).trim();
+ } finally {
+ if (jarFile != null) {
+ jarFile.close();
+ }
}
- Attributes mainAttrs = manifest.getMainAttributes();
- if (mainAttrs == null) {
- throw new IOException("no main mainifest attributes, in " +
- jarname);
- }
- return mainAttrs.getValue(MAIN_CLASS).trim();
- } finally {
- if (jarFile != null) {
- jarFile.close();
- }
+ } catch (IOException ioe) {
+ abort(ostream, ioe, "java.launcher.jar.error1", jarname);
}
+ return null;
}
@@ -409,6 +414,20 @@
private static final int LM_CLASS = 1;
private static final int LM_JAR = 2;
+ static void abort(PrintStream ostream, Throwable t, String msgKey, Object... args) {
+ if (msgKey != null) {
+ ostream.println(getLocalizedMessage(msgKey, args));
+ }
+ if (sun.misc.VM.getSavedProperty(diagprop) != null) {
+ if (t != null) {
+ t.printStackTrace();
+ } else {
+ Thread.currentThread().dumpStack();
+ }
+ }
+ System.exit(1);
+ }
+
/**
* This method does the following:
* 1. gets the classname from a Jar's manifest, if necessary
@@ -426,39 +445,31 @@
* @param isJar
* @param name
* @return
- * @throws java.io.IOException
*/
public static Class<?> checkAndLoadMain(boolean printToStderr,
int mode,
- String what) throws IOException
- {
-
- ClassLoader ld = ClassLoader.getSystemClassLoader();
-
+ String what) {
+ final PrintStream ostream = (printToStderr) ? System.err : System.out;
+ final ClassLoader ld = ClassLoader.getSystemClassLoader();
// get the class name
String cn = null;
switch (mode) {
- case LM_CLASS:
- cn = what;
- break;
- case LM_JAR:
- cn = getMainClassFromJar(what);
- break;
- default:
- throw new InternalError("" + mode + ": Unknown launch mode");
+ case LM_CLASS:
+ cn = what;
+ break;
+ case LM_JAR:
+ cn = getMainClassFromJar(ostream, what);
+ break;
+ default:
+ // should never happen
+ throw new InternalError("" + mode + ": Unknown launch mode");
}
cn = cn.replace('/', '.');
-
- PrintStream ostream = (printToStderr) ? System.err : System.out;
Class<?> c = null;
try {
c = ld.loadClass(cn);
} catch (ClassNotFoundException cnfe) {
- ostream.println(getLocalizedMessage("java.launcher.cls.error1",
- cn));
- NoClassDefFoundError ncdfe = new NoClassDefFoundError(cn);
- ncdfe.initCause(cnfe);
- throw ncdfe;
+ abort(ostream, cnfe, "java.launcher.cls.error1", cn);
}
signatureDiagnostic(ostream, c);
return c;
@@ -470,9 +481,7 @@
try {
method = clazz.getMethod("main", String[].class);
} catch (NoSuchMethodException nsme) {
- ostream.println(getLocalizedMessage("java.launcher.cls.error4",
- classname));
- throw new RuntimeException("Main method not found in " + classname);
+ abort(ostream, null, "java.launcher.cls.error4", classname);
}
/*
* getMethod (above) will choose the correct method, based
@@ -481,17 +490,10 @@
*/
int mod = method.getModifiers();
if (!Modifier.isStatic(mod)) {
- ostream.println(getLocalizedMessage("java.launcher.cls.error2",
- "static", classname));
- throw new RuntimeException("Main method is not static in class " +
- classname);
+ abort(ostream, null, "java.launcher.cls.error2", "static", classname);
}
if (method.getReturnType() != java.lang.Void.TYPE) {
- ostream.println(getLocalizedMessage("java.launcher.cls.error3",
- classname));
- throw new RuntimeException("Main method must return a value" +
- " of type void in class " +
- classname);
+ abort(ostream, null, "java.launcher.cls.error3", classname);
}
return;
}
--- a/jdk/src/share/classes/sun/launcher/resources/launcher.properties Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/launcher/resources/launcher.properties Tue Feb 08 14:25:33 2011 -0800
@@ -84,6 +84,7 @@
\ append to end of bootstrap class path\n\
\ -Xbootclasspath/p:<directories and zip/jar files separated by {0}>\n\
\ prepend in front of bootstrap class path\n\
+\ -Xdiag show additional diagnostic messages\n\
\ -Xnoclassgc disable class garbage collection\n\
\ -Xincgc enable incremental garbage collection\n\
\ -Xloggc:<file> log GC status to a file with time stamps\n\
@@ -109,7 +110,7 @@
The -X options are non-standard and subject to change without notice.\n
java.launcher.cls.error1=\
- Error: Could not find main class {0}
+ Error: Could not find or load main class {0}
java.launcher.cls.error2=\
Error: Main method is not {0} in class {1}, please define the main method as:\n\
\ public static void main(String[] args)
@@ -120,5 +121,7 @@
java.launcher.cls.error4=\
Error: Main method not found in class {0}, please define the main method as:\n\
\ public static void main(String[] args)
-
-
+java.launcher.jar.error1=\
+ Error: An unexpected error occurred while trying to open file {0}
+java.launcher.jar.error2=manifest not found in {0}
+java.launcher.jar.error3=no main manifest attribute, in {0}
--- a/jdk/src/share/classes/sun/misc/FloatingDecimal.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/misc/FloatingDecimal.java Tue Feb 08 14:25:33 2011 -0800
@@ -1547,7 +1547,7 @@
if ( (cmpResult = bigB.cmp( bigD ) ) > 0 ){
overvalue = true; // our candidate is too big.
diff = bigB.sub( bigD );
- if ( (bigIntNBits == 1) && (bigIntExp > -expBias) ){
+ if ( (bigIntNBits == 1) && (bigIntExp > -expBias+1) ){
// candidate is a normalized exact power of 2 and
// is too big. We will be subtracting.
// For our purposes, ulp is the ulp of the
--- a/jdk/src/share/classes/sun/misc/JarIndex.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/misc/JarIndex.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,6 +67,14 @@
public static final String INDEX_NAME = "META-INF/INDEX.LIST";
/**
+ * true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true.
+ * If true, the names of the files in META-INF, and its subdirectories, will
+ * be added to the index. Otherwise, just the directory names are added.
+ */
+ private static final boolean metaInfFilenames =
+ "true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames"));
+
+ /**
* Constructs a new, empty jar index.
*/
public JarIndex() {
@@ -187,6 +195,18 @@
}
/**
+ * Same as add(String,String) except that it doesn't strip off from the
+ * last index of '/'. It just adds the filename.
+ */
+ private void addExplicit(String fileName, String jarName) {
+ // add the mapping to indexMap
+ addToList(fileName, jarName, indexMap);
+
+ // add the mapping to jarMap
+ addToList(jarName, fileName, jarMap);
+ }
+
+ /**
* Go through all the jar files and construct the
* index table.
*/
@@ -204,15 +224,31 @@
Enumeration entries = zrf.entries();
while(entries.hasMoreElements()) {
- String fileName = ((ZipEntry)(entries.nextElement())).getName();
- // Index the META-INF directory, but not the index or manifest.
- if (!fileName.startsWith("META-INF/") ||
- !(fileName.equals("META-INF/") ||
- fileName.equals(INDEX_NAME) ||
- fileName.equals(JarFile.MANIFEST_NAME))) {
+ ZipEntry entry = (ZipEntry) entries.nextElement();
+ String fileName = entry.getName();
+
+ // Skip the META-INF directory, the index, and manifest.
+ // Any files in META-INF/ will be indexed explicitly
+ if (fileName.equals("META-INF/") ||
+ fileName.equals(INDEX_NAME) ||
+ fileName.equals(JarFile.MANIFEST_NAME))
+ continue;
+
+ if (!metaInfFilenames) {
add(fileName, currentJar);
+ } else {
+ if (!fileName.startsWith("META-INF/")) {
+ add(fileName, currentJar);
+ } else if (!entry.isDirectory()) {
+ // Add files under META-INF explicitly so that certain
+ // services, like ServiceLoader, etc, can be located
+ // with greater accuracy. Directories can be skipped
+ // since each file will be added explicitly.
+ addExplicit(fileName, currentJar);
+ }
}
}
+
zrf.close();
}
}
--- a/jdk/src/share/classes/sun/misc/VM.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/misc/VM.java Tue Feb 08 14:25:33 2011 -0800
@@ -235,6 +235,9 @@
return savedProps.getProperty(key);
}
+ // TODO: the Property Management needs to be refactored and
+ // the appropriate prop keys need to be accessible to the
+ // calling classes to avoid duplication of keys.
private static final Properties savedProps = new Properties();
// Save a private copy of the system properties and remove
@@ -283,6 +286,9 @@
// used by java.util.zip.ZipFile
props.remove("sun.zip.disableMemoryMapping");
+
+ // used by sun.launcher.LauncherHelper
+ props.remove("sun.java.launcher.diag");
}
// Initialize any miscellenous operating system settings that need to be
--- a/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java Tue Feb 08 14:25:33 2011 -0800
@@ -106,6 +106,9 @@
keepAliveTimer = new Thread(grp, cache, "Keep-Alive-Timer");
keepAliveTimer.setDaemon(true);
keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2);
+ // Set the context class loader to null in order to avoid
+ // keeping a strong reference to an application classloader.
+ keepAliveTimer.setContextClassLoader(null);
keepAliveTimer.start();
return null;
}
--- a/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java Tue Feb 08 14:25:33 2011 -0800
@@ -185,6 +185,9 @@
cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner");
cleanerThread.setDaemon(true);
cleanerThread.setPriority(Thread.MAX_PRIORITY - 2);
+ // Set the context class loader to null in order to avoid
+ // keeping a strong reference to an application classloader.
+ cleanerThread.setContextClassLoader(null);
cleanerThread.start();
return null;
}
--- a/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -45,15 +45,6 @@
}
@Override
- public final Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(OWNER_NAME))
- return getOwner();
- if (attribute.equals(ACL_NAME))
- return getAcl();
- return null;
- }
-
- @Override
@SuppressWarnings("unchecked")
public final void setAttribute(String attribute, Object value)
throws IOException
@@ -71,7 +62,7 @@
}
@Override
- public final Map<String,?> readAttributes(String[] attributes)
+ public final Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
boolean acl = false;
@@ -91,7 +82,7 @@
continue;
}
}
- Map<String,Object> result = new HashMap<String,Object>(2);
+ Map<String,Object> result = new HashMap<>(2);
if (acl)
result.put(ACL_NAME, getAcl());
if (owner)
--- a/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -54,30 +54,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- BasicFileAttributes attrs = readAttributes();
- if (attribute.equals(SIZE_NAME))
- return attrs.size();
- if (attribute.equals(CREATION_TIME_NAME))
- return attrs.creationTime();
- if (attribute.equals(LAST_ACCESS_TIME_NAME))
- return attrs.lastAccessTime();
- if (attribute.equals(LAST_MODIFIED_TIME_NAME))
- return attrs.lastModifiedTime();
- if (attribute.equals(FILE_KEY_NAME))
- return attrs.fileKey();
- if (attribute.equals(IS_DIRECTORY_NAME))
- return attrs.isDirectory();
- if (attribute.equals(IS_REGULAR_FILE_NAME))
- return attrs.isRegularFile();
- if (attribute.equals(IS_SYMBOLIC_LINK_NAME))
- return attrs.isSymbolicLink();
- if (attribute.equals(IS_OTHER_NAME))
- return attrs.isOther();
- return null;
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -101,8 +77,8 @@
* 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 Set<String> set = new HashSet<>();
+ private Map<String,Object> map = new HashMap<>();
private boolean copyAll;
private AttributesBuilder(String[] attributes) {
@@ -172,7 +148,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes) throws IOException {
+ public Map<String,Object> readAttributes(String[] attributes) throws IOException {
AttributesBuilder builder = AttributesBuilder.create(attributes);
addBasicAttributesToBuilder(readAttributes(), builder);
return builder.unmodifiableMap();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractFileSystemProvider.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Collections;
+
+/**
+ * Base implementation class of FileSystemProvider
+ */
+
+abstract class AbstractFileSystemProvider extends FileSystemProvider {
+ protected AbstractFileSystemProvider() { }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Gets a DynamicFileAttributeView by name. Returns {@code null} if the
+ * view is not available.
+ */
+ abstract DynamicFileAttributeView getFileAttributeView(Path file,
+ String name,
+ LinkOption... options);
+
+ @Override
+ public final void setAttribute(Path file,
+ String attribute,
+ Object value,
+ LinkOption... options)
+ throws IOException
+ {
+ String[] s = split(attribute);
+ DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
+ if (view == null)
+ throw new UnsupportedOperationException("View '" + s[0] + "' not available");
+ view.setAttribute(s[1], value);
+ }
+
+ @Override
+ public final Map<String,Object> readAttributes(Path file, String attributes, LinkOption... options)
+ throws IOException
+ {
+ String[] s = split(attributes);
+ DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
+ if (view == null)
+ return Collections.emptyMap();
+ return view.readAttributes(s[1].split(","));
+ }
+
+ /**
+ * Deletes a file. The {@code failIfNotExists} parameters determines if an
+ * {@code IOException} is thrown when the file does not exist.
+ */
+ abstract boolean implDelete(Path file, boolean failIfNotExists) throws IOException;
+
+ @Override
+ public final void delete(Path file) throws IOException {
+ implDelete(file, true);
+ }
+
+ @Override
+ public final boolean deleteIfExists(Path file) throws IOException {
+ return implDelete(file, false);
+ }
+}
--- a/jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,7 +25,7 @@
package sun.nio.fs;
-import java.nio.file.FileRef;
+import java.nio.file.Path;
import java.nio.file.spi.FileTypeDetector;
import java.util.Locale;
import java.io.IOException;
@@ -46,7 +46,7 @@
* and checks that the content type's syntax is valid.
*/
@Override
- public final String probeContentType(FileRef file) throws IOException {
+ public final String probeContentType(Path file) throws IOException {
if (file == null)
throw new NullPointerException("'file' is null");
String result = implProbeContentType(file);
@@ -56,7 +56,7 @@
/**
* Probes the given file to guess its content type.
*/
- protected abstract String implProbeContentType(FileRef file)
+ protected abstract String implProbeContentType(Path file)
throws IOException;
/**
--- a/jdk/src/share/classes/sun/nio/fs/AbstractPath.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractPath.java Tue Feb 08 14:25:33 2011 -0800
@@ -26,391 +26,81 @@
package sun.nio.fs;
import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import java.nio.file.attribute.*;
-import java.nio.channels.*;
-import java.nio.ByteBuffer;
-import java.io.*;
-import java.util.*;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
/**
- * Base implementation class for a {@code Path}.
+ * Base implementation class of {@code Path}.
*/
-abstract class AbstractPath extends Path {
+abstract class AbstractPath implements Path {
protected AbstractPath() { }
@Override
- public final Path createFile(FileAttribute<?>... attrs)
- throws IOException
- {
- EnumSet<StandardOpenOption> options = EnumSet.of(CREATE_NEW, WRITE);
- SeekableByteChannel sbc = newByteChannel(options, attrs);
- try {
- sbc.close();
- } catch (IOException x) {
- // ignore
- }
- return this;
- }
-
- /**
- * Deletes a file. The {@code failIfNotExists} parameters determines if an
- * {@code IOException} is thrown when the file does not exist.
- */
- abstract void implDelete(boolean failIfNotExists) throws IOException;
-
- @Override
- public final void delete() throws IOException {
- implDelete(true);
+ public final boolean startsWith(String other) {
+ return startsWith(getFileSystem().getPath(other));
}
@Override
- public final void deleteIfExists() throws IOException {
- implDelete(false);
+ public final boolean endsWith(String other) {
+ return endsWith(getFileSystem().getPath(other));
}
@Override
- public final InputStream newInputStream(OpenOption... options)
- throws IOException
- {
- if (options.length > 0) {
- for (OpenOption opt: options) {
- if (opt != READ)
- throw new UnsupportedOperationException("'" + opt + "' not allowed");
- }
- }
- return Channels.newInputStream(newByteChannel());
+ public final Path resolve(String other) {
+ return resolve(getFileSystem().getPath(other));
}
@Override
- public final OutputStream newOutputStream(OpenOption... options)
- throws IOException
- {
- int len = options.length;
- Set<OpenOption> opts = new HashSet<OpenOption>(len + 3);
- if (len == 0) {
- opts.add(CREATE);
- opts.add(TRUNCATE_EXISTING);
- } else {
- for (OpenOption opt: options) {
- if (opt == READ)
- throw new IllegalArgumentException("READ not allowed");
- opts.add(opt);
- }
- }
- opts.add(WRITE);
- return Channels.newOutputStream(newByteChannel(opts));
+ public final Path resolveSibling(Path other) {
+ if (other == null)
+ throw new NullPointerException();
+ Path parent = getParent();
+ return (parent == null) ? other : parent.resolve(other);
}
@Override
- public final SeekableByteChannel newByteChannel(OpenOption... options)
- throws IOException
- {
- Set<OpenOption> set = new HashSet<OpenOption>(options.length);
- Collections.addAll(set, options);
- return newByteChannel(set);
- }
-
- private static final DirectoryStream.Filter<Path> acceptAllFilter =
- new DirectoryStream.Filter<Path>() {
- @Override public boolean accept(Path entry) { return true; }
- };
-
- @Override
- public final DirectoryStream<Path> newDirectoryStream() throws IOException {
- return newDirectoryStream(acceptAllFilter);
+ public final Path resolveSibling(String other) {
+ return resolveSibling(getFileSystem().getPath(other));
}
@Override
- public final DirectoryStream<Path> newDirectoryStream(String glob)
- throws IOException
- {
- // avoid creating a matcher if all entries are required.
- if (glob.equals("*"))
- return newDirectoryStream();
-
- // create a matcher and return a filter that uses it.
- final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
- DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ public final Iterator<Path> iterator() {
+ return new Iterator<Path>() {
+ private int i = 0;
+ @Override
+ public boolean hasNext() {
+ return (i < getNameCount());
+ }
@Override
- public boolean accept(Path entry) {
- return matcher.matches(entry.getName());
+ public Path next() {
+ if (i < getNameCount()) {
+ Path result = getName(i);
+ i++;
+ return result;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
}
};
- return newDirectoryStream(filter);
}
@Override
- public final boolean exists() {
- try {
- checkAccess();
- return true;
- } catch (IOException x) {
- // unable to determine if file exists
- }
- return false;
+ public final File toFile() {
+ return new File(toString());
}
@Override
- public final boolean notExists() {
- try {
- checkAccess();
- return false;
- } catch (NoSuchFileException x) {
- // file confirmed not to exist
- return true;
- } catch (IOException x) {
- return false;
- }
- }
-
- private static final WatchEvent.Modifier[] NO_MODIFIERS = new WatchEvent.Modifier[0];
-
- @Override
public final WatchKey register(WatchService watcher,
WatchEvent.Kind<?>... events)
throws IOException
{
- return register(watcher, events, NO_MODIFIERS);
- }
-
- abstract void implCopyTo(Path target, CopyOption... options)
- throws IOException;
-
- @Override
- public final Path copyTo(Path target, CopyOption... options)
- throws IOException
- {
- if ((getFileSystem().provider() == target.getFileSystem().provider())) {
- implCopyTo(target, options);
- } else {
- copyToForeignTarget(target, options);
- }
- return target;
- }
-
- abstract void implMoveTo(Path target, CopyOption... options)
- throws IOException;
-
- @Override
- public final Path moveTo(Path target, CopyOption... options)
- throws IOException
- {
- if ((getFileSystem().provider() == target.getFileSystem().provider())) {
- implMoveTo(target, options);
- } else {
- // different providers so copy + delete
- copyToForeignTarget(target, convertMoveToCopyOptions(options));
- delete();
- }
- return target;
- }
-
- /**
- * Converts the given array of options for moving a file to options suitable
- * for copying the file when a move is implemented as copy + delete.
- */
- private static CopyOption[] convertMoveToCopyOptions(CopyOption... options)
- throws AtomicMoveNotSupportedException
- {
- int len = options.length;
- CopyOption[] newOptions = new CopyOption[len+2];
- for (int i=0; i<len; i++) {
- CopyOption option = options[i];
- if (option == StandardCopyOption.ATOMIC_MOVE) {
- throw new AtomicMoveNotSupportedException(null, null,
- "Atomic move between providers is not supported");
- }
- newOptions[i] = option;
- }
- newOptions[len] = LinkOption.NOFOLLOW_LINKS;
- newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
- return newOptions;
- }
-
- /**
- * Parses the arguments for a file copy operation.
- */
- private static class CopyOptions {
- boolean replaceExisting = false;
- boolean copyAttributes = false;
- boolean followLinks = true;
-
- private CopyOptions() { }
-
- static CopyOptions parse(CopyOption... options) {
- CopyOptions result = new CopyOptions();
- for (CopyOption option: options) {
- if (option == StandardCopyOption.REPLACE_EXISTING) {
- result.replaceExisting = true;
- continue;
- }
- if (option == LinkOption.NOFOLLOW_LINKS) {
- result.followLinks = false;
- continue;
- }
- if (option == StandardCopyOption.COPY_ATTRIBUTES) {
- result.copyAttributes = true;
- continue;
- }
- if (option == null)
- throw new NullPointerException();
- throw new UnsupportedOperationException("'" + option +
- "' is not a recognized copy option");
- }
- return result;
- }
- }
-
- /**
- * Simple cross-provider copy where the target is a Path.
- */
- private void copyToForeignTarget(Path target, CopyOption... options)
- throws IOException
- {
- CopyOptions opts = CopyOptions.parse(options);
- LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
- new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
-
- // attributes of source file
- BasicFileAttributes attrs = Attributes
- .readBasicFileAttributes(this, linkOptions);
- if (attrs.isSymbolicLink())
- throw new IOException("Copying of symbolic links not supported");
-
- // check if target exists
- boolean exists;
- if (opts.replaceExisting) {
- try {
- target.deleteIfExists();
- exists = false;
- } catch (DirectoryNotEmptyException x) {
- // let exception translate to FileAlreadyExistsException (6895012)
- exists = true;
- }
- } else {
- exists = target.exists();
- }
- if (exists)
- throw new FileAlreadyExistsException(target.toString());
-
- // create directory or file
- if (attrs.isDirectory()) {
- target.createDirectory();
- } else {
- copyRegularFileToForeignTarget(target);
- }
-
- // copy basic attributes to target
- if (opts.copyAttributes) {
- BasicFileAttributeView view = target
- .getFileAttributeView(BasicFileAttributeView.class, linkOptions);
- try {
- view.setTimes(attrs.lastModifiedTime(),
- attrs.lastAccessTime(),
- attrs.creationTime());
- } catch (IOException x) {
- // rollback
- try {
- target.delete();
- } catch (IOException ignore) { }
- throw x;
- }
- }
- }
-
-
- /**
- * Simple copy of regular file to a target file that exists.
- */
- private void copyRegularFileToForeignTarget(Path target)
- throws IOException
- {
- ReadableByteChannel rbc = newByteChannel();
- try {
- // open target file for writing
- SeekableByteChannel sbc = target.newByteChannel(CREATE_NEW, WRITE);
-
- // simple copy loop
- try {
- ByteBuffer buf = ByteBuffer.wrap(new byte[8192]);
- int n = 0;
- for (;;) {
- n = rbc.read(buf);
- if (n < 0)
- break;
- assert n > 0;
- buf.flip();
- while (buf.hasRemaining()) {
- sbc.write(buf);
- }
- buf.rewind();
- }
-
- } finally {
- sbc.close();
- }
- } finally {
- rbc.close();
- }
- }
-
- /**
- * 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;
- }
-
- /**
- * Gets a DynamicFileAttributeView by name. Returns {@code null} if the
- * view is not available.
- */
- abstract DynamicFileAttributeView getFileAttributeView(String name,
- LinkOption... options);
-
- @Override
- public final void setAttribute(String attribute,
- Object value,
- LinkOption... options)
- throws IOException
- {
- String[] s = split(attribute);
- DynamicFileAttributeView view = getFileAttributeView(s[0], options);
- if (view == null)
- throw new UnsupportedOperationException("View '" + s[0] + "' not available");
- view.setAttribute(s[1], value);
- }
-
- @Override
- public final Object getAttribute(String attribute, LinkOption... options)
- throws IOException
- {
- String[] s = split(attribute);
- DynamicFileAttributeView view = getFileAttributeView(s[0], options);
- return (view == null) ? null : view.getAttribute(s[1]);
- }
-
- @Override
- public final Map<String,?> readAttributes(String attributes, LinkOption... options)
- throws IOException
- {
- String[] s = split(attributes);
- DynamicFileAttributeView view = getFileAttributeView(s[0], options);
- if (view == null)
- return Collections.emptyMap();
- return view.readAttributes(s[1].split(","));
+ return register(watcher, events, new WatchEvent.Modifier[0]);
}
}
--- a/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java Tue Feb 08 14:25:33 2011 -0800
@@ -92,7 +92,7 @@
/**
* Requests, and waits on, poller thread to register given file.
*/
- final WatchKey register(FileRef dir,
+ final WatchKey register(Path dir,
WatchEvent.Kind<?>[] events,
WatchEvent.Modifier... modifiers)
throws IOException
@@ -102,7 +102,7 @@
throw new NullPointerException();
if (events.length == 0)
throw new IllegalArgumentException("No events to register");
- Set<WatchEvent.Kind<?>> eventSet = new HashSet<WatchEvent.Kind<?>>(events.length);
+ Set<WatchEvent.Kind<?>> eventSet = new HashSet<>(events.length);
for (WatchEvent.Kind<?> event: events) {
// standard events
if (event == StandardWatchEventKind.ENTRY_CREATE ||
--- a/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -59,8 +59,7 @@
return "user";
}
- @Override
- public final Object getAttribute(String attribute) throws IOException {
+ private Object getAttribute(String attribute) throws IOException {
int size;
try {
size = size(attribute);
@@ -90,11 +89,11 @@
}
@Override
- public final Map<String,?> readAttributes(String[] attributes)
+ public final Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
// names of attributes to return
- List<String> names = new ArrayList<String>();
+ List<String> names = new ArrayList<>();
for (String name: attributes) {
if (name.equals("*")) {
@@ -106,7 +105,7 @@
}
// read each value and return in map
- Map<String,Object> result = new HashMap<String,Object>();
+ Map<String,Object> result = new HashMap<>();
for (String name: names) {
Object value = getAttribute(name);
if (value != null)
--- a/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java Tue Feb 08 14:25:33 2011 -0800
@@ -32,7 +32,7 @@
* Base implementation class for watch keys.
*/
-abstract class AbstractWatchKey extends WatchKey {
+abstract class AbstractWatchKey implements WatchKey {
/**
* Maximum size of event list (in the future this may be tunable)
@@ -53,6 +53,9 @@
// reference to watcher
private final AbstractWatchService watcher;
+ // reference to the original directory
+ private final Path dir;
+
// key state
private State state;
@@ -63,8 +66,9 @@
// event for the context is an ENTRY_MODIFY event).
private Map<Object,WatchEvent<?>> lastModifyEvents;
- protected AbstractWatchKey(AbstractWatchService watcher) {
+ protected AbstractWatchKey(Path dir, AbstractWatchService watcher) {
this.watcher = watcher;
+ this.dir = dir;
this.state = State.READY;
this.events = new ArrayList<WatchEvent<?>>();
this.lastModifyEvents = new HashMap<Object,WatchEvent<?>>();
@@ -75,6 +79,13 @@
}
/**
+ * Return the original watchable (Path)
+ */
+ Path watchable() {
+ return dir;
+ }
+
+ /**
* Enqueues this key to the watch service
*/
final void signal() {
@@ -175,7 +186,7 @@
/**
* WatchEvent implementation
*/
- private static class Event<T> extends WatchEvent<T> {
+ private static class Event<T> implements WatchEvent<T> {
private final WatchEvent.Kind<T> kind;
private final T context;
--- a/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java Tue Feb 08 14:25:33 2011 -0800
@@ -33,7 +33,7 @@
* Base implementation class for watch services.
*/
-abstract class AbstractWatchService extends WatchService {
+abstract class AbstractWatchService implements WatchService {
// signaled keys waiting to be dequeued
private final LinkedBlockingDeque<WatchKey> pendingKeys =
@@ -41,7 +41,7 @@
// special key to indicate that watch service is closed
private final WatchKey CLOSE_KEY =
- new AbstractWatchKey(null) {
+ new AbstractWatchKey(null, null) {
@Override
public boolean isValid() {
return true;
@@ -54,7 +54,7 @@
// used when closing watch service
private volatile boolean closed;
- private Object closeLock = new Object();
+ private final Object closeLock = new Object();
protected AbstractWatchService() {
}
@@ -93,7 +93,7 @@
}
@Override
- public final WatchKey poll() {
+ public final WatchKey poll() {
checkOpen();
WatchKey key = pendingKeys.poll();
checkKey(key);
--- a/jdk/src/share/classes/sun/nio/fs/DynamicFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/DynamicFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -35,11 +35,6 @@
interface DynamicFileAttributeView {
/**
- * Reads the value of an attribute.
- */
- Object getAttribute(String attribute) throws IOException;
-
- /**
* Sets/updates the value of an attribute.
*/
void setAttribute(String attribute, Object value) throws IOException;
@@ -47,5 +42,5 @@
/**
* Reads a set of file attributes as a bulk operation.
*/
- Map<String,?> readAttributes(String[] attributes) throws IOException;
+ Map<String,Object> readAttributes(String[] attributes) throws IOException;
}
--- a/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java Tue Feb 08 14:25:33 2011 -0800
@@ -58,13 +58,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(OWNER_NAME))
- return getOwner();
- return null;
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -77,8 +70,8 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes) throws IOException {
- Map<String,Object> result = new HashMap<String,Object>();
+ public Map<String,Object> readAttributes(String[] attributes) throws IOException {
+ Map<String,Object> result = new HashMap<>();
for (String attribute: attributes) {
if (attribute.equals("*") || attribute.equals(OWNER_NAME)) {
result.put(OWNER_NAME, getOwner());
--- a/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java Tue Feb 08 14:25:33 2011 -0800
@@ -146,7 +146,7 @@
throws IOException
{
// check file is a directory and get its file key if possible
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
+ BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
if (!attrs.isDirectory()) {
throw new NotDirectoryException(path.toString());
}
@@ -164,7 +164,7 @@
watchKey = map.get(fileKey);
if (watchKey == null) {
// new registration
- watchKey = new PollingWatchKey(this, path, fileKey);
+ watchKey = new PollingWatchKey(path, this, fileKey);
map.put(fileKey, watchKey);
} else {
// update to existing registration
@@ -228,7 +228,6 @@
* directory and queue keys when entries are added, modified, or deleted.
*/
private class PollingWatchKey extends AbstractWatchKey {
- private final Path dir;
private final Object fileKey;
// current event set
@@ -246,44 +245,28 @@
// map of entries in directory
private Map<Path,CacheEntry> entries;
- PollingWatchKey(PollingWatchService watcher,
- Path dir,
- Object fileKey)
+ PollingWatchKey(Path dir, PollingWatchService watcher, Object fileKey)
throws IOException
{
- super(watcher);
- this.dir = dir;
+ super(dir, watcher);
this.fileKey = fileKey;
this.valid = true;
this.tickCount = 0;
this.entries = new HashMap<Path,CacheEntry>();
// get the initial entries in the directory
- DirectoryStream<Path> stream = dir.newDirectoryStream();
- try {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path entry: stream) {
// don't follow links
- long lastModified = Attributes
- .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
- .lastModifiedTime().toMillis();
- entries.put(entry.getName(),
- new CacheEntry(lastModified, tickCount));
+ long lastModified =
+ Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).toMillis();
+ entries.put(entry.getFileName(), new CacheEntry(lastModified, tickCount));
}
- } catch (ConcurrentModificationException cme) {
- // thrown if directory iteration fails
- Throwable cause = cme.getCause();
- if (cause != null && cause instanceof IOException)
- throw (IOException)cause;
- throw new AssertionError(cme);
- } finally {
- stream.close();
+ } catch (DirectoryIteratorException e) {
+ throw e.getCause();
}
}
- FileRef directory() {
- return dir;
- }
-
Object fileKey() {
return fileKey;
}
@@ -342,7 +325,7 @@
// open directory
DirectoryStream<Path> stream = null;
try {
- stream = dir.newDirectoryStream();
+ stream = Files.newDirectoryStream(watchable());
} catch (IOException x) {
// directory is no longer accessible so cancel key
cancel();
@@ -355,9 +338,8 @@
for (Path entry: stream) {
long lastModified = 0L;
try {
- lastModified = Attributes
- .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
- .lastModifiedTime().toMillis();
+ lastModified =
+ Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).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
@@ -366,15 +348,15 @@
}
// lookup cache
- CacheEntry e = entries.get(entry.getName());
+ CacheEntry e = entries.get(entry.getFileName());
if (e == null) {
// new file found
- entries.put(entry.getName(),
+ entries.put(entry.getFileName(),
new CacheEntry(lastModified, tickCount));
// queue ENTRY_CREATE if event enabled
if (events.contains(StandardWatchEventKind.ENTRY_CREATE)) {
- signalEvent(StandardWatchEventKind.ENTRY_CREATE, entry.getName());
+ signalEvent(StandardWatchEventKind.ENTRY_CREATE, entry.getFileName());
continue;
} else {
// if ENTRY_CREATE is not enabled and ENTRY_MODIFY is
@@ -382,7 +364,7 @@
// modifications to the file immediately after it is
// created.
if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
- signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getName());
+ signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getFileName());
}
}
continue;
@@ -391,15 +373,17 @@
// check if file has changed
if (e.lastModified != lastModified) {
if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
- signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getName());
+ signalEvent(StandardWatchEventKind.ENTRY_MODIFY,
+ entry.getFileName());
}
}
// entry in cache so update poll time
e.update(lastModified, tickCount);
}
- } catch (ConcurrentModificationException x) {
- // FIXME - should handle this
+ } catch (DirectoryIteratorException e) {
+ // ignore for now; if the directory is no longer accessible
+ // then the key will be cancelled on the next poll
} finally {
// close directory stream
--- a/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java Tue Feb 08 14:25:33 2011 -0800
@@ -173,7 +173,7 @@
}
Credentials getCreds() {
- return Objects.nonNull(creds, "Creds not available yet.");
+ return Objects.requireNonNull(creds, "Creds not available yet.");
}
sun.security.krb5.internal.ccache.Credentials getCCreds() {
--- a/jdk/src/share/classes/sun/security/provider/SeedGenerator.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/SeedGenerator.java Tue Feb 08 14:25:33 2011 -0800
@@ -63,13 +63,14 @@
* @author Gadi Guy
*/
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
import java.security.*;
import java.io.*;
import java.util.Properties;
import java.util.Enumeration;
import java.net.*;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Random;
import sun.security.util.Debug;
@@ -177,37 +178,21 @@
// The temporary dir
File f = new File(p.getProperty("java.io.tmpdir"));
-
- // Go thru files in the tmp dir using NIO's
- // DirectoryStream. Fallback to File.list()
- // if NIO is not available.
- if (NIODirectoryStream.isAvailable()) {
- int count = 0;
- Iterable<?> stream =
- NIODirectoryStream.newDirectoryStream(f);
+ int count = 0;
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(f.toPath())) {
// We use a Random object to choose what file names
// should be used. Otherwise on a machine with too
// many files, the same first 1024 files always get
// used. Any, We make sure the first 512 files are
// always used.
Random r = new Random();
- try {
- for (Object entry: stream) {
- if (count < 512 || r.nextBoolean()) {
- md.update(NIODirectoryStream.getName(
- entry).getBytes());
- }
- if (count++ > 1024) {
- break;
- }
+ for (Path entry: stream) {
+ if (count < 512 || r.nextBoolean()) {
+ md.update(entry.getFileName().toString().getBytes());
}
- } finally {
- ((Closeable)stream).close();
- }
- } else {
- String[] sa = f.list();
- for(int i = 0; i < sa.length; i++) {
- md.update(sa[i].getBytes());
+ if (count++ > 1024) {
+ break;
+ }
}
}
} catch (Exception ex) {
@@ -553,77 +538,4 @@
}
}
-
- /**
- * A wrapper of NIO DirectoryStream using reflection.
- */
- private static class NIODirectoryStream {
- private static final Class<?> pathClass =
- getClass("java.nio.file.Path");
-
- private static final Method toPathMethod =
- (pathClass == null) ? null : getMethod(File.class, "toPath");
- private static final Method getNameMethod =
- getMethod(pathClass, "getName");
- private static final Method newDirectoryStreamMethod =
- getMethod(pathClass, "newDirectoryStream");
-
- private static Class<?> getClass(String name) {
- try {
- return Class.forName(name, true, null);
- } catch (ClassNotFoundException e) {
- return null;
- }
- }
-
- private static Method getMethod(Class<?> clazz,
- String name,
- Class<?>... paramTypes) {
- if (clazz != null) {
- try {
- return clazz.getMethod(name, paramTypes);
- } catch (NoSuchMethodException e) {
- throw new AssertionError(e);
- }
- } else {
- return null;
- }
- }
-
- static boolean isAvailable() {
- return pathClass != null;
- }
-
- static Iterable<?> newDirectoryStream(File dir) throws IOException {
- assert pathClass != null;
- try {
- Object path = toPathMethod.invoke(dir);
- return (Iterable<?>)newDirectoryStreamMethod.invoke(path);
- } catch (InvocationTargetException e) {
- Throwable cause = e.getCause();
- if (cause instanceof IOException)
- throw (IOException)cause;
- if (cause instanceof RuntimeException)
- throw (RuntimeException)cause;
- if (cause instanceof Error)
- throw (Error)cause;
- throw new AssertionError(e);
- } catch (IllegalAccessException iae) {
- throw new AssertionError(iae);
- }
- }
-
- static String getName(Object path) {
- assert pathClass != null;
- try {
- Object name = getNameMethod.invoke(path);
- return name.toString();
- } catch (InvocationTargetException e) {
- throw new AssertionError(e);
- } catch (IllegalAccessException iae) {
- throw new AssertionError(iae);
- }
- }
- }
}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.provider.certpath;
+
+import java.io.IOException;
+import java.util.Date;
+
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.cert.X509CertSelector;
+import java.security.cert.CertificateException;
+
+import sun.security.util.DerOutputStream;
+import sun.security.x509.SerialNumber;
+import sun.security.x509.KeyIdentifier;
+import sun.security.x509.AuthorityKeyIdentifierExtension;
+
+/**
+ * An adaptable X509 certificate selector for forward certification path
+ * building.
+ *
+ * @since 1.7
+ */
+class AdaptableX509CertSelector extends X509CertSelector {
+ // The start date of a validity period.
+ private Date startDate = null;
+
+ // The end date of a validity period.
+ private Date endDate = null;
+
+ AdaptableX509CertSelector() {
+ super();
+ }
+
+ /**
+ * Sets the criterion of the X509Certificate validity period.
+ *
+ * Normally, we may not have to check that a certificate validity period
+ * must fall within its issuer's certificate validity period. However,
+ * when we face root CA key updates for version 1 certificates, according
+ * to scheme of RFC 4210 or 2510, the validity periods should be checked
+ * to determine the right issuer's certificate.
+ *
+ * Conservatively, we will only check the validity periods for version
+ * 1 and version 2 certificates. For version 3 certificates, we can
+ * determine the right issuer by authority and subject key identifier
+ * extensions.
+ *
+ * @param startDate the start date of a validity period that must fall
+ * within the certificate validity period for the X509Certificate
+ * @param endDate the end date of a validity period that must fall
+ * within the certificate validity period for the X509Certificate
+ */
+ void setValidityPeriod(Date startDate, Date endDate) {
+ this.startDate = startDate;
+ this.endDate = endDate;
+ }
+
+ /**
+ * Parse the authority key identifier extension.
+ *
+ * If the keyIdentifier field of the extension is non-null, set the
+ * subjectKeyIdentifier criterion. If the authorityCertSerialNumber
+ * field is non-null, set the serialNumber criterion.
+ *
+ * Note that we will not set the subject criterion according to the
+ * authorityCertIssuer field of the extension. The caller MUST set
+ * the subject criterion before call match().
+ *
+ * @param akidext the authorityKeyIdentifier extension
+ */
+ void parseAuthorityKeyIdentifierExtension(
+ AuthorityKeyIdentifierExtension akidext) throws IOException {
+ if (akidext != null) {
+ KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID);
+ if (akid != null) {
+ DerOutputStream derout = new DerOutputStream();
+ derout.putOctetString(akid.getIdentifier());
+ super.setSubjectKeyIdentifier(derout.toByteArray());
+ }
+
+ SerialNumber asn =
+ (SerialNumber)akidext.get(akidext.SERIAL_NUMBER);
+ if (asn != null) {
+ super.setSerialNumber(asn.getNumber());
+ }
+
+ // the subject criterion should be set by the caller.
+ }
+ }
+
+ /**
+ * Decides whether a <code>Certificate</code> should be selected.
+ *
+ * For the purpose of compatibility, when a certificate is of
+ * version 1 and version 2, or the certificate does not include
+ * a subject key identifier extension, the selection criterion
+ * of subjectKeyIdentifier will be disabled.
+ */
+ @Override
+ public boolean match(Certificate cert) {
+ if (!(cert instanceof X509Certificate)) {
+ return false;
+ }
+
+ X509Certificate xcert = (X509Certificate)cert;
+ int version = xcert.getVersion();
+
+ // Check the validity period for version 1 and 2 certificate.
+ if (version < 3) {
+ if (startDate != null) {
+ try {
+ xcert.checkValidity(startDate);
+ } catch (CertificateException ce) {
+ return false;
+ }
+ }
+
+ if (endDate != null) {
+ try {
+ xcert.checkValidity(endDate);
+ } catch (CertificateException ce) {
+ return false;
+ }
+ }
+ }
+
+ if (version < 3 || xcert.getExtensionValue("2.5.29.14") == null) {
+ // If no SubjectKeyIdentifier extension, don't bother to check it.
+ setSubjectKeyIdentifier(null);
+ }
+
+ return super.match(cert);
+ }
+
+ @Override
+ public Object clone() {
+ AdaptableX509CertSelector copy =
+ (AdaptableX509CertSelector)super.clone();
+ if (startDate != null) {
+ copy.startDate = (Date)startDate.clone();
+ }
+
+ if (endDate != null) {
+ copy.endDate = (Date)endDate.clone();
+ }
+
+ return copy;
+ }
+}
--- a/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,8 @@
import java.security.cert.CRLException;
import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertPathValidatorException.BasicReason;
+import java.security.cert.PKIXReason;
import java.io.IOException;
import java.security.interfaces.*;
import java.security.spec.*;
@@ -196,14 +198,16 @@
SIGNATURE_PRIMITIVE_SET,
currSigAlg, currSigAlgParams)) {
throw new CertPathValidatorException(
- "Algorithm constraints check failed: " + currSigAlg);
+ "Algorithm constraints check failed: " + currSigAlg,
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
// check the key usage and key size
boolean[] keyUsage = x509Cert.getKeyUsage();
if (keyUsage != null && keyUsage.length < 9) {
throw new CertPathValidatorException(
- "incorrect KeyUsage extension");
+ "incorrect KeyUsage extension",
+ null, null, -1, PKIXReason.INVALID_KEY_USAGE);
}
if (keyUsage != null) {
@@ -236,7 +240,8 @@
if (!primitives.isEmpty()) {
if (!constraints.permits(primitives, currPubKey)) {
throw new CertPathValidatorException(
- "algorithm constraints check failed");
+ "algorithm constraints check failed",
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
}
@@ -248,7 +253,8 @@
SIGNATURE_PRIMITIVE_SET,
currSigAlg, prevPubKey, currSigAlgParams)) {
throw new CertPathValidatorException(
- "Algorithm constraints check failed: " + currSigAlg);
+ "Algorithm constraints check failed: " + currSigAlg,
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -258,7 +264,7 @@
// Inherit DSA parameters from previous key
if (!(prevPubKey instanceof DSAPublicKey)) {
throw new CertPathValidatorException("Input key is not " +
- "of a appropriate type for inheriting parameters");
+ "of a appropriate type for inheriting parameters");
}
DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
@@ -352,7 +358,8 @@
if (!certPathDefaultConstraints.permits(
SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
throw new CertPathValidatorException(
- "algorithm check failed: " + sigAlgName + " is disabled");
+ "algorithm check failed: " + sigAlgName + " is disabled",
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -317,7 +317,7 @@
// we accept the case that a CRL issuer provide status
// information for itself.
- if (ForwardBuilder.issues(certImpl, crlImpl, provider)) {
+ if (issues(certImpl, crlImpl, provider)) {
// reset the public key used to verify the CRL's signature
prevKey = certImpl.getPublicKey();
} else {
@@ -338,7 +338,7 @@
if (!Arrays.equals(certAKID, crlAKID)) {
// we accept the case that a CRL issuer provide status
// information for itself.
- if (ForwardBuilder.issues(certImpl, crlImpl, provider)) {
+ if (issues(certImpl, crlImpl, provider)) {
// reset the public key used to verify the CRL's signature
prevKey = certImpl.getPublicKey();
} else {
@@ -687,4 +687,41 @@
fullNames.add(new GeneralName(fullName));
return fullNames;
}
+
+ /** Verifies whether a CRL is issued by a certain certificate
+ *
+ * @param cert the certificate
+ * @param crl the CRL to be verified
+ * @param provider the name of the signature provider
+ */
+ private static boolean issues(X509CertImpl cert, X509CRLImpl crl,
+ String provider) throws IOException {
+
+ AdaptableX509CertSelector issuerSelector =
+ new AdaptableX509CertSelector();
+
+ // check certificate's key usage
+ boolean[] usages = cert.getKeyUsage();
+ if (usages != null) {
+ usages[6] = true; // cRLSign
+ issuerSelector.setKeyUsage(usages);
+ }
+
+ // check certificate's subject
+ X500Principal crlIssuer = crl.getIssuerX500Principal();
+ issuerSelector.setSubject(crlIssuer);
+
+ /*
+ * Facilitate certification path construction with authority
+ * key identifier and subject key identifier.
+ *
+ * In practice, conforming CAs MUST use the key identifier method,
+ * and MUST include authority key identifier extension in all CRLs
+ * issued. [section 5.2.1, RFC 2459]
+ */
+ issuerSelector.parseAuthorityKeyIdentifierExtension(
+ crl.getAuthKeyIdExtension());
+
+ return issuerSelector.match(cert);
+ }
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,7 @@
private final Set<X500Principal> trustedSubjectDNs;
private final Set<TrustAnchor> trustAnchors;
private X509CertSelector eeSelector;
- private X509CertSelector caSelector;
+ private AdaptableX509CertSelector caSelector;
private X509CertSelector caTargetSelector;
TrustAnchor trustAnchor;
private Comparator<X509Certificate> comparator;
@@ -230,9 +230,11 @@
targetCertConstraints.clone();
/*
- * Match on certificate validity date
+ * Since we don't check the validity period of trusted
+ * certificates, please don't set the certificate valid
+ * criterion unless the trusted certificate matching is
+ * completed.
*/
- caTargetSelector.setCertificateValid(date);
/*
* Policy processing optimizations
@@ -246,17 +248,19 @@
* at least as many CA certs that have already been traversed
*/
caTargetSelector.setBasicConstraints(currentState.traversedCACerts);
+
sel = caTargetSelector;
-
} else {
if (caSelector == null) {
caSelector = new AdaptableX509CertSelector();
/*
- * Match on certificate validity date.
+ * Since we don't check the validity period of trusted
+ * certificates, please don't set the certificate valid
+ * criterion unless the trusted certificate matching is
+ * completed.
*/
- caSelector.setCertificateValid(date);
/*
* Policy processing optimizations
@@ -290,42 +294,19 @@
*/
AuthorityKeyIdentifierExtension akidext =
currentState.cert.getAuthorityKeyIdentifierExtension();
- if (akidext != null) {
- KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID);
- if (akid != null) {
- DerOutputStream derout = new DerOutputStream();
- derout.putOctetString(akid.getIdentifier());
- caSelector.setSubjectKeyIdentifier(derout.toByteArray());
- }
+ caSelector.parseAuthorityKeyIdentifierExtension(akidext);
- SerialNumber asn =
- (SerialNumber)akidext.get(akidext.SERIAL_NUMBER);
- if (asn != null) {
- caSelector.setSerialNumber(asn.getNumber());
- }
- // the subject criterion was set previously.
- }
+ /*
+ * check the validity period
+ */
+ caSelector.setValidityPeriod(currentState.cert.getNotBefore(),
+ currentState.cert.getNotAfter());
sel = caSelector;
}
- /*
- * Check if any of the trusted certs could be a match.
- * Since we are not validating the trusted cert, we can't
- * re-use the selector we've built up (sel) - we need
- * to use a new selector (trustedSel)
- */
- X509CertSelector trustedSel = null;
- if (currentState.isInitial()) {
- trustedSel = targetCertConstraints;
- } else {
- trustedSel = new X509CertSelector();
- trustedSel.setSubject(currentState.issuerDN);
- }
-
- boolean foundMatchingCert = false;
for (X509Certificate trustedCert : trustedCerts) {
- if (trustedSel.match(trustedCert)) {
+ if (sel.match(trustedCert)) {
if (debug != null) {
debug.println("ForwardBuilder.getMatchingCACerts: "
+ "found matching trust anchor");
@@ -336,6 +317,11 @@
}
}
+ /*
+ * The trusted certificate matching is completed. We need to match
+ * on certificate validity date.
+ */
+ sel.setCertificateValid(date);
/*
* If we have already traversed as many CA certs as the maxPathLength
@@ -348,8 +334,8 @@
(buildParams.getMaxPathLength() == -1) ||
(buildParams.getMaxPathLength() > currentState.traversedCACerts))
{
- if (addMatchingCerts(sel, certStores, caCerts, searchAllCertStores)
- && !searchAllCertStores) {
+ if (addMatchingCerts(sel, certStores,
+ caCerts, searchAllCertStores) && !searchAllCertStores) {
return;
}
}
@@ -939,120 +925,4 @@
void removeFinalCertFromPath(LinkedList<X509Certificate> certPathList) {
certPathList.removeFirst();
}
-
- /** Verifies whether a CRL is issued by a certain certificate
- *
- * @param cert the certificate
- * @param crl the CRL to be verified
- * @param provider the name of the signature provider
- */
- static boolean issues(X509CertImpl cert, X509CRLImpl crl, String provider)
- throws IOException {
-
- boolean kidmatched = false;
-
- // check certificate's key usage
- boolean[] usages = cert.getKeyUsage();
- if (usages != null && !usages[6]) {
- return false;
- }
-
- // check certificate's SKID and CRL's AKID
- AuthorityKeyIdentifierExtension akidext = crl.getAuthKeyIdExtension();
- if (akidext != null) {
- // the highest priority, matching KID
- KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID);
- if (akid != null) {
- SubjectKeyIdentifierExtension skidext =
- cert.getSubjectKeyIdentifierExtension();
- if (skidext != null) {
- KeyIdentifier skid =
- (KeyIdentifier)skidext.get(skidext.KEY_ID);
- if (!akid.equals(skid)) {
- return false;
- }
-
- kidmatched = true;
- }
- // conservatively, in case of X509 V1 certificate,
- // does return false here if no SKID extension.
- }
-
- // the medium priority, matching issuer name/serial number
- SerialNumber asn = (SerialNumber)akidext.get(akidext.SERIAL_NUMBER);
- GeneralNames anames = (GeneralNames)akidext.get(akidext.AUTH_NAME);
- if (asn != null && anames != null) {
- X500Name subject = (X500Name)cert.getSubjectDN();
- BigInteger serial = cert.getSerialNumber();
-
- if (serial != null && subject != null) {
- if (serial.equals(asn.getNumber())) {
- return false;
- }
-
- for (GeneralName name : anames.names()) {
- GeneralNameInterface gni = name.getName();
- if (subject.equals(gni)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- if (kidmatched) {
- return true;
- }
- }
-
- // the last priority, verify the CRL signature with the cert.
- X500Principal crlIssuer = crl.getIssuerX500Principal();
- X500Principal certSubject = cert.getSubjectX500Principal();
- if (certSubject != null && certSubject.equals(crlIssuer)) {
- try {
- crl.verify(cert.getPublicKey(), provider);
- return true;
- } catch (Exception e) {
- // ignore all exceptions.
- }
- }
-
- return false;
- }
-
- /**
- * An adaptable X509 certificate selector for forward certification path
- * building.
- */
- private static class AdaptableX509CertSelector extends X509CertSelector {
- public AdaptableX509CertSelector() {
- super();
- }
-
- /**
- * Decides whether a <code>Certificate</code> should be selected.
- *
- * For the purpose of compatibility, when a certificate is of
- * version 1 and version 2, or the certificate does not include
- * a subject key identifier extension, the selection criterion
- * of subjectKeyIdentifier will be disabled.
- *
- * @Override
- */
- public boolean match(Certificate cert) {
- if (!(cert instanceof X509Certificate)) {
- return false;
- }
- X509Certificate xcert = (X509Certificate)cert;
-
- if (xcert.getVersion() < 3 ||
- xcert.getExtensionValue("2.5.29.14") == null) {
- // disable the subjectKeyIdentifier criterion
- setSubjectKeyIdentifier(null);
- }
-
- return super.match(cert);
- }
- }
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,9 @@
import sun.security.action.GetBooleanSecurityPropertyAction;
import sun.security.util.Debug;
+import sun.security.x509.X509CertImpl;
+
+
/**
* This class implements the PKIX validation algorithm for certification
* paths consisting exclusively of <code>X509Certificates</code>. It uses
@@ -162,6 +165,7 @@
debug.println("PKIXCertPathValidator.engineValidate() "
+ "anchor.getTrustedCert() != null");
}
+
// if this trust anchor is not worth trying,
// we move on to the next one
if (!isWorthTrying(trustedCert, firstCert)) {
@@ -211,8 +215,10 @@
* worth trying to validate in the chain.
*/
private boolean isWorthTrying(X509Certificate trustedCert,
- X509Certificate firstCert)
- {
+ X509Certificate firstCert) {
+
+ boolean worthy = false;
+
if (debug != null) {
debug.println("PKIXCertPathValidator.isWorthTrying() checking "
+ "if this trusted cert is worth trying ...");
@@ -222,19 +228,46 @@
return true;
}
- // the subject of the trusted cert should match the
- // issuer of the first cert in the certpath
+ AdaptableX509CertSelector issuerSelector =
+ new AdaptableX509CertSelector();
+
+ // check trusted certificate's key usage
+ boolean[] usages = trustedCert.getKeyUsage();
+ if (usages != null) {
+ usages[5] = true; // keyCertSign
+ issuerSelector.setKeyUsage(usages);
+ }
+
+ // check trusted certificate's subject
+ issuerSelector.setSubject(firstCert.getIssuerX500Principal());
+
+ // check the validity period
+ issuerSelector.setValidityPeriod(firstCert.getNotBefore(),
+ firstCert.getNotAfter());
- X500Principal trustedSubject = trustedCert.getSubjectX500Principal();
- if (trustedSubject.equals(firstCert.getIssuerX500Principal())) {
- if (debug != null)
+ /*
+ * Facilitate certification path construction with authority
+ * key identifier and subject key identifier.
+ */
+ try {
+ X509CertImpl firstCertImpl = X509CertImpl.toImpl(firstCert);
+ issuerSelector.parseAuthorityKeyIdentifierExtension(
+ firstCertImpl.getAuthorityKeyIdentifierExtension());
+
+ worthy = issuerSelector.match(trustedCert);
+ } catch (Exception e) {
+ // It is not worth trying.
+ }
+
+ if (debug != null) {
+ if (worthy) {
debug.println("YES - try this trustedCert");
- return true;
- } else {
- if (debug != null)
+ } else {
debug.println("NO - don't try this trustedCert");
- return false;
+ }
}
+
+ return worthy;
}
/**
--- a/jdk/src/share/classes/sun/security/validator/SimpleValidator.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/security/validator/SimpleValidator.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -156,8 +156,8 @@
// check certificate algorithm
try {
- // Algorithm checker don't care about the unresolved critical
- // extensions.
+ // Algorithm checker does not care about the unresolved
+ // critical extensions.
defaultAlgChecker.check(cert, Collections.<String>emptySet());
if (appAlgChecker != null) {
appAlgChecker.check(cert, Collections.<String>emptySet());
--- a/jdk/src/share/classes/sun/swing/AccumulativeRunnable.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/swing/AccumulativeRunnable.java Tue Feb 08 14:25:33 2011 -0800
@@ -120,6 +120,7 @@
* {@code Runnable} for execution.
* @param args the arguments to accumulate
*/
+ @SafeVarargs
public final synchronized void add(T... args) {
boolean isSubmitted = true;
if (arguments == null) {
--- a/jdk/src/share/classes/sun/tools/jar/Main.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java Tue Feb 08 14:25:33 2011 -0800
@@ -27,6 +27,7 @@
import java.io.*;
import java.nio.file.Path;
+import java.nio.file.Files;
import java.util.*;
import java.util.zip.*;
import java.util.jar.*;
@@ -1017,17 +1018,17 @@
Path jarPath = jarFile.toPath();
Path tmpPath = createTempFileInSameDirectoryAs(jarFile).toPath();
try {
- if (update(jarPath.newInputStream(),
- tmpPath.newOutputStream(),
+ if (update(Files.newInputStream(jarPath),
+ Files.newOutputStream(tmpPath),
null, index)) {
try {
- tmpPath.moveTo(jarPath, REPLACE_EXISTING);
+ Files.move(tmpPath, jarPath, REPLACE_EXISTING);
} catch (IOException e) {
throw new IOException(getMsg("error.write.file"), e);
}
}
} finally {
- tmpPath.deleteIfExists();
+ Files.deleteIfExists(tmpPath);
}
}
--- a/jdk/src/share/demo/nio/zipfs/Demo.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/Demo.java Tue Feb 08 14:25:33 2011 -0800
@@ -33,6 +33,7 @@
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
+import java.nio.file.spi.*;
import java.nio.file.attribute.*;
import java.net.*;
import java.text.DateFormat;
@@ -144,78 +145,76 @@
}
public static void main(String[] args) throws Throwable {
+ FileSystemProvider provider = getZipFSProvider();
+ if (provider == null) {
+ System.err.println("ZIP filesystem provider is not installed");
+ System.exit(1);
+ }
Action action = Action.valueOf(args[0]);
Map<String, Object> env = env = new HashMap<>();
if (action == Action.create)
env.put("create", "true");
- if (action == Action.tlist || action == Action.twalk)
- env.put("buildDirTree", true);
- FileSystem fs = FileSystems.newFileSystem(Paths.get(args[1]), env, null);
-
- try {
- FileSystem fs2;
+ try (FileSystem fs = provider.newFileSystem(Paths.get(args[1]), env)) {
Path path, src, dst;
boolean isRename = false;
switch (action) {
case rename:
src = fs.getPath(args[2]);
dst = fs.getPath(args[3]);
- src.moveTo(dst);
+ Files.move(src, dst);
break;
case moveout:
src = fs.getPath(args[2]);
dst = Paths.get(args[3]);
- src.moveTo(dst);
+ Files.move(src, dst);
break;
case movein:
src = Paths.get(args[2]);
dst = fs.getPath(args[3]);
- src.moveTo(dst);
+ Files.move(src, dst);
break;
case copy:
src = fs.getPath(args[2]);
dst = fs.getPath(args[3]);
- src.copyTo(dst);
+ Files.copy(src, dst);
break;
case copyout:
src = fs.getPath(args[2]);
dst = Paths.get(args[3]);
- src.copyTo(dst);
+ Files.copy(src, dst);
break;
case copyin:
src = Paths.get(args[2]);
dst = fs.getPath(args[3]);
- src.copyTo(dst);
+ Files.copy(src, dst);
break;
case copyin_attrs:
src = Paths.get(args[2]);
dst = fs.getPath(args[3]);
- src.copyTo(dst, COPY_ATTRIBUTES);
+ Files.copy(src, dst, COPY_ATTRIBUTES);
break;
case copyout_attrs:
src = fs.getPath(args[2]);
dst = Paths.get(args[3]);
- src.copyTo(dst, COPY_ATTRIBUTES);
+ Files.copy(src, dst, COPY_ATTRIBUTES);
break;
case zzmove:
- fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
- //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
- z2zmove(fs, fs2, args[3]);
- fs2.close();
+ try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) {
+ z2zmove(fs, fs2, args[3]);
+ }
break;
case zzcopy:
- fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
- //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
- z2zcopy(fs, fs2, args[3]);
- fs2.close();
+ try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) {
+ z2zcopy(fs, fs2, args[3]);
+ }
break;
case attrs:
for (int i = 2; i < args.length; i++) {
path = fs.getPath(args[i]);
System.out.println(path);
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
}
break;
case setmtime:
@@ -223,10 +222,10 @@
Date newDatetime = df.parse(args[2]);
for (int i = 3; i < args.length; i++) {
path = fs.getPath(args[i]);
- path.setAttribute("lastModifiedTime",
- FileTime.fromMillis(newDatetime.getTime()));
+ Files.setAttribute(path, "lastModifiedTime",
+ FileTime.fromMillis(newDatetime.getTime()));
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
}
break;
case setctime:
@@ -234,10 +233,10 @@
newDatetime = df.parse(args[2]);
for (int i = 3; i < args.length; i++) {
path = fs.getPath(args[i]);
- path.setAttribute("creationTime",
- FileTime.fromMillis(newDatetime.getTime()));
+ Files.setAttribute(path, "creationTime",
+ FileTime.fromMillis(newDatetime.getTime()));
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
}
break;
case setatime:
@@ -245,25 +244,22 @@
newDatetime = df.parse(args[2]);
for (int i = 3; i < args.length; i++) {
path = fs.getPath(args[i]);
- path.setAttribute("lastAccessTime",
- FileTime.fromMillis(newDatetime.getTime()));
+ Files.setAttribute(path, "lastAccessTime",
+ FileTime.fromMillis(newDatetime.getTime()));
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
}
break;
case attrsspace:
path = fs.getPath("/");
- FileStore fstore = path.getFileStore();
- //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
- // .readAttributes());
- // or
+ FileStore fstore = Files.getFileStore(path);
System.out.printf("filestore[%s]%n", fstore.name());
System.out.printf(" totalSpace: %d%n",
- (Long)fstore.getAttribute("space:totalSpace"));
+ (Long)fstore.getAttribute("totalSpace"));
System.out.printf(" usableSpace: %d%n",
- (Long)fstore.getAttribute("space:usableSpace"));
+ (Long)fstore.getAttribute("usableSpace"));
System.out.printf(" unallocSpace: %d%n",
- (Long)fstore.getAttribute("space:unallocatedSpace"));
+ (Long)fstore.getAttribute("unallocatedSpace"));
break;
case list:
case tlist:
@@ -293,7 +289,7 @@
break;
case delete:
for (int i = 2; i < args.length; i++)
- fs.getPath(args[i]).delete();
+ Files.delete(fs.getPath(args[i]));
break;
case create:
case add:
@@ -305,17 +301,19 @@
case lsdir:
path = fs.getPath(args[2]);
final String fStr = (args.length > 3)?args[3]:"";
- DirectoryStream<Path> ds = path.newDirectoryStream(
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(path,
new DirectoryStream.Filter<Path>() {
public boolean accept(Path path) {
return path.toString().contains(fStr);
}
- });
- for (Path p : ds)
- System.out.println(p);
+ }))
+ {
+ for (Path p : ds)
+ System.out.println(p);
+ }
break;
case mkdir:
- fs.getPath(args[2]).createDirectory();
+ Files.createDirectory(fs.getPath(args[2]));
break;
case mkdirs:
mkdirs(fs.getPath(args[2]));
@@ -326,14 +324,14 @@
System.out.printf("%n%s%n", path);
System.out.println("-------(1)---------");
System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
+ Files.readAttributes(path, BasicFileAttributes.class).toString());
System.out.println("-------(2)---------");
- Map<String, ?> map = path.readAttributes("zip:*");
- for (Map.Entry<String, ?> e : map.entrySet()) {
+ Map<String, Object> map = Files.readAttributes(path, "zip:*");
+ for (Map.Entry<String, Object> e : map.entrySet()) {
System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
}
System.out.println("-------(3)---------");
- map = path.readAttributes("size,lastModifiedTime,isDirectory");
+ map = Files.readAttributes(path, "size,lastModifiedTime,isDirectory");
for (Map.Entry<String, ?> e : map.entrySet()) {
System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
}
@@ -349,12 +347,17 @@
}
} catch (Exception x) {
x.printStackTrace();
- } finally {
- if (fs != null)
- fs.close();
}
}
+ private static FileSystemProvider getZipFSProvider() {
+ for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {
+ if ("jar".equals(provider.getScheme()))
+ return provider;
+ }
+ return null;
+ }
+
private static byte[] getBytes(String name) {
return name.getBytes();
}
@@ -380,7 +383,7 @@
BasicFileAttributes attrs)
{
indent();
- System.out.printf("%s%n", file.getName().toString());
+ System.out.printf("%s%n", file.getFileName().toString());
return FileVisitResult.CONTINUE;
}
@@ -406,35 +409,35 @@
private static void update(FileSystem fs, String path) throws Throwable{
Path src = FileSystems.getDefault().getPath(path);
- if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
- DirectoryStream<Path> ds = src.newDirectoryStream();
- for (Path child : ds)
- update(fs, child.toString());
- ds.close();
+ if (Files.isDirectory(src)) {
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(src)) {
+ for (Path child : ds)
+ update(fs, child.toString());
+ }
} else {
Path dst = fs.getPath(path);
Path parent = dst.getParent();
- if (parent != null && parent.notExists())
+ if (parent != null && Files.notExists(parent))
mkdirs(parent);
- src.copyTo(dst, REPLACE_EXISTING);
+ Files.copy(src, dst, REPLACE_EXISTING);
}
}
private static void extract(FileSystem fs, String path) throws Throwable{
Path src = fs.getPath(path);
- if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
- DirectoryStream<Path> ds = src.newDirectoryStream();
- for (Path child : ds)
- extract(fs, child.toString());
- ds.close();
+ if (Files.isDirectory(src)) {
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(src)) {
+ for (Path child : ds)
+ extract(fs, child.toString());
+ }
} else {
if (path.startsWith("/"))
path = path.substring(1);
Path dst = FileSystems.getDefault().getPath(path);
Path parent = dst.getParent();
- if (parent.notExists())
+ if (Files.notExists(parent))
mkdirs(parent);
- src.copyTo(dst, REPLACE_EXISTING);
+ Files.copy(src, dst, REPLACE_EXISTING);
}
}
@@ -445,21 +448,21 @@
Path srcPath = src.getPath(path);
Path dstPath = dst.getPath(path);
- if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
- if (!dstPath.exists()) {
+ if (Files.isDirectory(srcPath)) {
+ if (!Files.exists(dstPath)) {
try {
mkdirs(dstPath);
} catch (FileAlreadyExistsException x) {}
}
- DirectoryStream<Path> ds = srcPath.newDirectoryStream();
- for (Path child : ds) {
- z2zcopy(src, dst,
- path + (path.endsWith("/")?"":"/") + child.getName());
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(srcPath)) {
+ for (Path child : ds) {
+ z2zcopy(src, dst,
+ path + (path.endsWith("/")?"":"/") + child.getFileName());
+ }
}
- ds.close();
} else {
//System.out.println("copying..." + path);
- srcPath.copyTo(dstPath);
+ Files.copy(srcPath, dstPath);
}
}
@@ -480,9 +483,9 @@
dst = dstPath.resolve(dst);
try {
Path parent = dstPath.getParent();
- if (parent != null && parent.notExists())
+ if (parent != null && Files.notExists(parent))
mkdirs(parent);
- file.moveTo(dst);
+ Files.move(file, dst);
} catch (IOException x) {
x.printStackTrace();
}
@@ -497,7 +500,7 @@
dst = dstPath.resolve(dst);
try {
- if (dst.notExists())
+ if (Files.notExists(dst))
mkdirs(dst);
} catch (IOException x) {
x.printStackTrace();
@@ -511,7 +514,7 @@
throws IOException
{
try {
- dir.delete();
+ Files.delete(dir);
} catch (IOException x) {
//x.printStackTrace();
}
@@ -525,15 +528,15 @@
path = path.toAbsolutePath();
Path parent = path.getParent();
if (parent != null) {
- if (parent.notExists())
+ if (Files.notExists(parent))
mkdirs(parent);
}
- path.createDirectory();
+ Files.createDirectory(path);
}
private static void rmdirs(Path path) throws IOException {
while (path != null && path.getNameCount() != 0) {
- path.delete();
+ Files.delete(path);
path = path.getParent();
}
}
@@ -542,15 +545,15 @@
if (!"/".equals(path.toString())) {
System.out.printf(" %s%n", path.toString());
if (verbose)
- System.out.println(Attributes.readBasicFileAttributes(path).toString());
+ System.out.println(Files.readAttributes(path, BasicFileAttributes.class).toString());
}
- if (path.notExists())
+ if (Files.notExists(path))
return;
- if (Attributes.readBasicFileAttributes(path).isDirectory()) {
- DirectoryStream<Path> ds = path.newDirectoryStream();
- for (Path child : ds)
- list(child, verbose);
- ds.close();
+ if (Files.isDirectory(path)) {
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
+ for (Path child : ds)
+ list(child, verbose);
+ }
}
}
@@ -561,12 +564,11 @@
// src.toString(), dst.toString());
//streams
- InputStream isSrc = src.newInputStream();
- InputStream isDst = dst.newInputStream();
byte[] bufSrc = new byte[8192];
byte[] bufDst = new byte[8192];
-
- try {
+ try (InputStream isSrc = Files.newInputStream(src);
+ InputStream isDst = Files.newInputStream(dst))
+ {
int nSrc = 0;
while ((nSrc = isSrc.read(bufSrc)) != -1) {
int nDst = 0;
@@ -588,24 +590,22 @@
nSrc--;
}
}
- } finally {
- isSrc.close();
- isDst.close();
}
// channels
- SeekableByteChannel chSrc = src.newByteChannel();
- SeekableByteChannel chDst = dst.newByteChannel();
- if (chSrc.size() != chDst.size()) {
- System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
- chSrc.toString(), chSrc.size(),
- chDst.toString(), chDst.size());
- throw new RuntimeException("CHECK FAILED!");
- }
- ByteBuffer bbSrc = ByteBuffer.allocate(8192);
- ByteBuffer bbDst = ByteBuffer.allocate(8192);
- try {
+ try (SeekableByteChannel chSrc = Files.newByteChannel(src);
+ SeekableByteChannel chDst = Files.newByteChannel(dst))
+ {
+ if (chSrc.size() != chDst.size()) {
+ System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
+ chSrc.toString(), chSrc.size(),
+ chDst.toString(), chDst.size());
+ throw new RuntimeException("CHECK FAILED!");
+ }
+ ByteBuffer bbSrc = ByteBuffer.allocate(8192);
+ ByteBuffer bbDst = ByteBuffer.allocate(8192);
+
int nSrc = 0;
while ((nSrc = chSrc.read(bbSrc)) != -1) {
int nDst = chDst.read(bbDst);
@@ -627,9 +627,6 @@
}
} catch (IOException x) {
x.printStackTrace();
- } finally {
- chSrc.close();
- chDst.close();
}
}
@@ -641,23 +638,15 @@
openwrite.add(CREATE_NEW);
openwrite.add(WRITE);
- FileChannel srcFc = src.getFileSystem()
- .provider()
- .newFileChannel(src, read);
- FileChannel dstFc = dst.getFileSystem()
- .provider()
- .newFileChannel(dst, openwrite);
-
- try {
+ try (FileChannel srcFc = src.getFileSystem().provider().newFileChannel(src, read);
+ FileChannel dstFc = dst.getFileSystem().provider().newFileChannel(dst, openwrite))
+ {
ByteBuffer bb = ByteBuffer.allocate(8192);
while (srcFc.read(bb) >= 0) {
bb.flip();
dstFc.write(bb);
bb.clear();
}
- } finally {
- srcFc.close();
- dstFc.close();
}
}
@@ -669,35 +658,28 @@
openwrite.add(CREATE_NEW);
openwrite.add(WRITE);
- SeekableByteChannel srcCh = src.newByteChannel(read);
- SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
-
- try {
+ try (SeekableByteChannel srcCh = Files.newByteChannel(src, read);
+ SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite))
+ {
ByteBuffer bb = ByteBuffer.allocate(8192);
while (srcCh.read(bb) >= 0) {
bb.flip();
dstCh.write(bb);
bb.clear();
}
- } finally {
- srcCh.close();
- dstCh.close();
}
}
private static void streamCopy(Path src, Path dst) throws IOException
{
- InputStream isSrc = src.newInputStream();
- OutputStream osDst = dst.newOutputStream();
byte[] buf = new byte[8192];
- try {
+ try (InputStream isSrc = Files.newInputStream(src);
+ OutputStream osDst = Files.newOutputStream(dst))
+ {
int n = 0;
while ((n = isSrc.read(buf)) != -1) {
osDst.write(buf, 0, n);
}
- } finally {
- isSrc.close();
- osDst.close();
}
}
}
--- a/jdk/src/share/demo/nio/zipfs/README.txt Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/README.txt Tue Feb 08 14:25:33 2011 -0800
@@ -5,9 +5,8 @@
used to create a FileSystem, eg:
// use file type detection
- Map<String,?> env = Collections.emptyMap();
Path jarfile = Paths.get("foo.jar");
- FileSystem fs = FileSystems.newFileSystem(jarfile, env, null);
+ FileSystem fs = FileSystems.newFileSystem(jarfile, null);
-or
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -32,11 +32,10 @@
package com.sun.nio.zipfs;
-import java.nio.file.attribute.BasicFileAttributeView;
-import java.nio.file.attribute.FileAttributeView;
-import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.LinkedHashMap;
+import java.util.Map;
/*
* @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
@@ -122,25 +121,19 @@
"' is unknown or read-only attribute");
}
- public Object getAttribute(String attribute, boolean domap)
+ Map<String, Object> readAttributes(String attributes)
throws IOException
{
ZipFileAttributes zfas = readAttributes();
- if (!domap) {
- try {
- return attribute(AttrID.valueOf(attribute), zfas);
- } catch (IllegalArgumentException x) {}
- return null;
- }
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
- if ("*".equals(attribute)) {
+ if ("*".equals(attributes)) {
for (AttrID id : AttrID.values()) {
try {
map.put(id.name(), attribute(id, zfas));
} catch (IllegalArgumentException x) {}
}
} else {
- String[] as = attribute.split(",");
+ String[] as = attributes.split(",");
for (String a : as) {
try {
map.put(a, attribute(AttrID.valueOf(a), zfas));
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileStore.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileStore.java Tue Feb 08 14:25:33 2011 -0800
@@ -32,14 +32,13 @@
package com.sun.nio.zipfs;
import java.io.IOException;
+import java.nio.file.Files;
import java.nio.file.FileStore;
import java.nio.file.FileSystems;
import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileStoreAttributeView;
-import java.nio.file.attribute.FileStoreSpaceAttributeView;
-import java.nio.file.attribute.FileStoreSpaceAttributes;
-import java.nio.file.attribute.Attributes;
import java.nio.file.attribute.BasicFileAttributeView;
import java.util.Formatter;
@@ -87,71 +86,61 @@
public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
if (type == null)
throw new NullPointerException();
- if (type == FileStoreSpaceAttributeView.class)
- return (V) new ZipFileStoreAttributeView(this);
- return null;
+ return (V)null;
+ }
+
+ @Override
+ public long getTotalSpace() throws IOException {
+ return new ZipFileStoreAttributes(this).totalSpace();
+ }
+
+ @Override
+ public long getUsableSpace() throws IOException {
+ return new ZipFileStoreAttributes(this).usableSpace();
+ }
+
+ @Override
+ public long getUnallocatedSpace() throws IOException {
+ return new ZipFileStoreAttributes(this).unallocatedSpace();
}
@Override
public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals("space:totalSpace"))
- return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
- if (attribute.equals("space:usableSpace"))
- return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
- if (attribute.equals("space:unallocatedSpace"))
- return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
+ if (attribute.equals("totalSpace"))
+ return getTotalSpace();
+ if (attribute.equals("usableSpace"))
+ return getUsableSpace();
+ if (attribute.equals("unallocatedSpace"))
+ return getUnallocatedSpace();
throw new UnsupportedOperationException("does not support the given attribute");
}
- private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
-
- private final ZipFileStore fileStore;
+ private static class ZipFileStoreAttributes {
+ final FileStore fstore;
+ final long size;
- public ZipFileStoreAttributeView(ZipFileStore fileStore) {
- this.fileStore = fileStore;
- }
-
- @Override
- public String name() {
- return "space";
+ public ZipFileStoreAttributes(ZipFileStore fileStore)
+ throws IOException
+ {
+ Path path = FileSystems.getDefault().getPath(fileStore.name());
+ this.size = Files.size(path);
+ this.fstore = Files.getFileStore(path);
}
- @Override
- public FileStoreSpaceAttributes readAttributes() throws IOException {
- final String file = fileStore.name();
- Path path = FileSystems.getDefault().getPath(file);
- final long size = Attributes.readBasicFileAttributes(path).size();
- final FileStore fstore = path.getFileStore();
- final FileStoreSpaceAttributes fstoreAttrs =
- Attributes.readFileStoreSpaceAttributes(fstore);
- return new FileStoreSpaceAttributes() {
- public long totalSpace() {
- return size;
- }
+ public long totalSpace() {
+ return size;
+ }
- public long usableSpace() {
- if (!fstore.isReadOnly())
- return fstoreAttrs.usableSpace();
- return 0;
- }
-
- public long unallocatedSpace() {
- if (!fstore.isReadOnly())
- return fstoreAttrs.unallocatedSpace();
- return 0;
- }
+ public long usableSpace() throws IOException {
+ if (!fstore.isReadOnly())
+ return fstore.getUsableSpace();
+ return 0;
+ }
- public String toString() {
- StringBuilder sb = new StringBuilder();
- Formatter fm = new Formatter(sb);
- fm.format("FileStoreSpaceAttributes[%s]%n", file);
- fm.format(" totalSpace: %d%n", totalSpace());
- fm.format(" usableSpace: %d%n", usableSpace());
- fm.format(" unallocSpace: %d%n", unallocatedSpace());
- fm.close();
- return sb.toString();
- }
- };
+ public long unallocatedSpace() throws IOException {
+ if (!fstore.isReadOnly())
+ return fstore.getUnallocatedSpace();
+ return 0;
}
}
}
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Tue Feb 08 14:25:33 2011 -0800
@@ -101,24 +101,25 @@
this.provider = provider;
this.zfpath = zfpath;
- if (zfpath.notExists()) {
+ if (Files.notExists(zfpath)) {
if (createNew) {
- OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE);
- new END().write(os, 0);
- os.close();
+ try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) {
+ new END().write(os, 0);
+ }
} else {
throw new FileSystemNotFoundException(zfpath.toString());
}
}
- zfpath.checkAccess(AccessMode.READ); // sm and existence check
+ // sm and existence check
+ zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ);
try {
- zfpath.checkAccess(AccessMode.WRITE);
+ zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.WRITE);
} catch (AccessDeniedException x) {
this.readOnly = true;
}
this.zc = ZipCoder.get(nameEncoding);
this.defaultdir = new ZipPath(this, getBytes(defaultDir));
- this.ch = zfpath.newByteChannel(READ);
+ this.ch = Files.newByteChannel(zfpath, READ);
this.cen = initCEN();
}
@@ -159,9 +160,22 @@
}
@Override
- public ZipPath getPath(String path) {
- if (path.length() == 0)
- throw new InvalidPathException(path, "path should not be empty");
+ public ZipPath getPath(String first, String... more) {
+ String path;
+ if (more.length == 0) {
+ path = first;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(first);
+ for (String segment: more) {
+ if (segment.length() > 0) {
+ if (sb.length() > 0)
+ sb.append('/');
+ sb.append(segment);
+ }
+ }
+ path = sb.toString();
+ }
return new ZipPath(this, getBytes(path));
}
@@ -268,16 +282,22 @@
def.end();
}
+ IOException ioe = null;
synchronized (tmppaths) {
for (Path p: tmppaths) {
try {
- p.deleteIfExists();
+ Files.deleteIfExists(p);
} catch (IOException x) {
- x.printStackTrace();
+ if (ioe == null)
+ ioe = x;
+ else
+ ioe.addSuppressed(x);
}
}
}
- provider.removeFileSystem(zfpath);
+ provider.removeFileSystem(zfpath, this);
+ if (ioe != null)
+ throw ioe;
}
ZipFileAttributes getFileAttributes(byte[] path)
@@ -444,7 +464,7 @@
u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
else if (eSrc.file != null) {
u.file = getTempPathForEntry(null);
- eSrc.file.copyTo(u.file, REPLACE_EXISTING);
+ Files.copy(eSrc.file, u.file, REPLACE_EXISTING);
}
}
}
@@ -778,7 +798,8 @@
fch.close();
if (forWrite) {
u.mtime = System.currentTimeMillis();
- u.size = Attributes.readBasicFileAttributes(u.file).size();
+ u.size = Files.size(u.file);
+
update(u);
} else {
if (!isFCH) // if this is a new fch for reading
@@ -805,13 +826,8 @@
if (path != null) {
Entry e = getEntry0(path);
if (e != null) {
- InputStream is = newInputStream(path);
- OutputStream os = tmpPath.newOutputStream(WRITE);
- try {
- copyStream(is, os);
- } finally {
- is.close();
- os.close();
+ try (InputStream is = newInputStream(path)) {
+ Files.copy(is, tmpPath, REPLACE_EXISTING);
}
}
}
@@ -819,7 +835,7 @@
}
private void removeTempPathForEntry(Path path) throws IOException {
- path.delete();
+ Files.delete(path);
tmppaths.remove(path);
}
@@ -1073,11 +1089,11 @@
// shared key. consumer guarantees the "writeLock" before use it.
private final IndexNode LOOKUPKEY = IndexNode.keyOf(null);
- private void updateDelete(Entry e) {
+ private void updateDelete(IndexNode inode) {
beginWrite();
try {
- removeFromTree(e);
- inodes.remove(e);
+ removeFromTree(inode);
+ inodes.remove(inode);
hasUpdate = true;
} finally {
endWrite();
@@ -1158,7 +1174,7 @@
for (ExChannelCloser ecc : exChClosers) {
if (ecc.streams.isEmpty()) {
ecc.ch.close();
- ecc.path.delete();
+ Files.delete(ecc.path);
exChClosers.remove(ecc);
}
}
@@ -1166,7 +1182,7 @@
if (!hasUpdate)
return;
Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
- OutputStream os = tmpFile.newOutputStream(WRITE);
+ OutputStream os = Files.newOutputStream(tmpFile, WRITE);
ArrayList<Entry> elist = new ArrayList<>(inodes.size());
long written = 0;
byte[] buf = new byte[8192];
@@ -1191,26 +1207,26 @@
os.write(e.bytes); // already
written += e.bytes.length;
} else if (e.file != null) { // tmp file
- InputStream is = e.file.newInputStream();
- int n;
- if (e.type == Entry.NEW) { // deflated already
- while ((n = is.read(buf)) != -1) {
- os.write(buf, 0, n);
- written += n;
+ try (InputStream is = Files.newInputStream(e.file)) {
+ int n;
+ if (e.type == Entry.NEW) { // deflated already
+ while ((n = is.read(buf)) != -1) {
+ os.write(buf, 0, n);
+ written += n;
+ }
+ } else if (e.type == Entry.FILECH) {
+ // the data are not deflated, use ZEOS
+ try (OutputStream os2 = new EntryOutputStream(e, os)) {
+ while ((n = is.read(buf)) != -1) {
+ os2.write(buf, 0, n);
+ }
+ }
+ written += e.csize;
+ if ((e.flag & FLAG_DATADESCR) != 0)
+ written += e.writeEXT(os);
}
- } else if (e.type == Entry.FILECH) {
- // the data are not deflated, use ZEOS
- OutputStream os2 = new EntryOutputStream(e, os);
- while ((n = is.read(buf)) != -1) {
- os2.write(buf, 0, n);
- }
- os2.close();
- written += e.csize;
- if ((e.flag & FLAG_DATADESCR) != 0)
- written += e.writeEXT(os);
}
- is.close();
- e.file.delete();
+ Files.delete(e.file);
tmppaths.remove(e.file);
} else {
// dir, 0-length data
@@ -1257,15 +1273,15 @@
createTempFileInSameDirectoryAs(zfpath),
ch,
streams);
- zfpath.moveTo(ecc.path, REPLACE_EXISTING);
+ Files.move(zfpath, ecc.path, REPLACE_EXISTING);
exChClosers.add(ecc);
streams = Collections.synchronizedSet(new HashSet<InputStream>());
} else {
ch.close();
- zfpath.delete();
+ Files.delete(zfpath);
}
- tmpFile.moveTo(zfpath, REPLACE_EXISTING);
+ Files.move(tmpFile, zfpath, REPLACE_EXISTING);
hasUpdate = false; // clear
/*
if (isOpen) {
@@ -1304,16 +1320,17 @@
throws IOException
{
checkWritable();
- Entry e = getEntry0(path);
- if (e == null) {
+
+ IndexNode inode = getInode(path);
+ if (inode == null) {
if (path != null && path.length == 0)
throw new ZipException("root directory </> can't not be delete");
if (failIfNotExists)
throw new NoSuchFileException(getString(path));
} else {
- if (e.isDir() && e.child != null)
+ if (inode.isDir() && inode.child != null)
throw new DirectoryNotEmptyException(getString(path));
- updateDelete(e);
+ updateDelete(inode);
}
}
@@ -1343,7 +1360,7 @@
OutputStream os;
if (useTempFile) {
e.file = getTempPathForEntry(null);
- os = e.file.newOutputStream(WRITE);
+ os = Files.newOutputStream(e.file, WRITE);
} else {
os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
}
@@ -1359,12 +1376,12 @@
if (e.bytes != null)
eis = new ByteArrayInputStream(e.bytes);
else if (e.file != null)
- eis = e.file.newInputStream();
+ eis = Files.newInputStream(e.file);
else
throw new ZipException("update entry data is missing");
} else if (e.type == Entry.FILECH) {
// FILECH result is un-compressed.
- eis = e.file.newInputStream();
+ eis = Files.newInputStream(e.file);
// TBD: wrap to hook close()
// streams.add(eis);
return eis;
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Tue Feb 08 14:25:33 2011 -0800
@@ -31,23 +31,18 @@
package com.sun.nio.zipfs;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.file.FileRef;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystemNotFoundException;
-import java.nio.file.FileSystemAlreadyExistsException;
-import java.nio.file.OpenOption;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.ProviderMismatchException;
-import java.nio.file.attribute.FileAttribute;
+import java.io.*;
+import java.nio.channels.*;
+import java.nio.file.*;
+import java.nio.file.DirectoryStream.Filter;
+import java.nio.file.attribute.*;
import java.nio.file.spi.FileSystemProvider;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
/*
*
@@ -87,28 +82,25 @@
public FileSystem newFileSystem(URI uri, Map<String, ?> env)
throws IOException
{
- return newFileSystem(uriToPath(uri), env);
+ return newFileSystem(uriToPath(uri), env, true);
}
@Override
- public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
+ public FileSystem newFileSystem(Path path, Map<String, ?> env)
throws IOException
{
- if (!(file instanceof Path))
- throw new UnsupportedOperationException();
- Path path = (Path)file;
if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
throw new UnsupportedOperationException();
}
- return newFileSystem(path, env);
+ return newFileSystem(path, env, false);
}
- private FileSystem newFileSystem(Path path, Map<String, ?> env)
+ private FileSystem newFileSystem(Path path, Map<String, ?> env, boolean checkIfFSExists)
throws IOException
{
synchronized(filesystems) {
Path realPath = null;
- if (path.exists()) {
+ if (checkIfFSExists && Files.exists(path)) {
realPath = path.toRealPath(true);
if (filesystems.containsKey(realPath))
throw new FileSystemAlreadyExistsException();
@@ -116,7 +108,8 @@
ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
if (realPath == null)
realPath = path.toRealPath(true);
- filesystems.put(realPath, zipfs);
+ if (!filesystems.containsKey(realPath))
+ filesystems.put(realPath, zipfs);
return zipfs;
}
}
@@ -133,18 +126,6 @@
return getFileSystem(uri).getPath(spec.substring(sep + 1));
}
- @Override
- public FileChannel newFileChannel(Path path,
- Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- if (path == null)
- throw new NullPointerException("path is null");
- if (path instanceof ZipPath)
- return ((ZipPath)path).newFileChannel(options, attrs);
- throw new ProviderMismatchException();
- }
@Override
public FileSystem getFileSystem(URI uri) {
@@ -161,9 +142,155 @@
}
}
- void removeFileSystem(Path zfpath) throws IOException {
+ // Checks that the given file is a UnixPath
+ static final ZipPath toZipPath(Path path) {
+ if (path == null)
+ throw new NullPointerException();
+ if (!(path instanceof ZipPath))
+ throw new ProviderMismatchException();
+ return (ZipPath)path;
+ }
+
+ @Override
+ public void checkAccess(Path path, AccessMode... modes) throws IOException {
+ toZipPath(path).checkAccess(modes);
+ }
+
+ @Override
+ public void copy(Path src, Path target, CopyOption... options)
+ throws IOException
+ {
+ toZipPath(src).copy(toZipPath(target), options);
+ }
+
+ @Override
+ public void createDirectory(Path path, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ toZipPath(path).createDirectory(attrs);
+ }
+
+ @Override
+ public final void delete(Path path) throws IOException {
+ toZipPath(path).delete();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V
+ getFileAttributeView(Path path, Class<V> type, LinkOption... options)
+ {
+ return (V)ZipFileAttributeView.get(toZipPath(path), type);
+ }
+
+ @Override
+ public FileStore getFileStore(Path path) throws IOException {
+ return toZipPath(path).getFileStore();
+ }
+
+ @Override
+ public boolean isHidden(Path path) {
+ return toZipPath(path).isHidden();
+ }
+
+ @Override
+ public boolean isSameFile(Path path, Path other) throws IOException {
+ return toZipPath(path).isSameFile(other);
+ }
+
+ @Override
+ public void move(Path src, Path target, CopyOption... options)
+ throws IOException
+ {
+ toZipPath(src).move(toZipPath(target), options);
+ }
+
+ @Override
+ public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
+ Set<? extends OpenOption> options,
+ ExecutorService exec,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return toZipPath(path).newByteChannel(options, attrs);
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(
+ Path path, Filter<? super Path> filter) throws IOException
+ {
+ return toZipPath(path).newDirectoryStream(filter);
+ }
+
+ @Override
+ public FileChannel newFileChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return toZipPath(path).newFileChannel(options, attrs);
+ }
+
+ @Override
+ public InputStream newInputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return toZipPath(path).newInputStream(options);
+ }
+
+ @Override
+ public OutputStream newOutputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return toZipPath(path).newOutputStream(options);
+ }
+
+ @Override
+ public <A extends BasicFileAttributes> A
+ readAttributes(Path path, Class<A> type, LinkOption... options)
+ throws IOException
+ {
+ if (type == BasicFileAttributes.class || type == ZipFileAttributes.class)
+ return (A)toZipPath(path).getAttributes();
+ return null;
+ }
+
+ @Override
+ public Map<String, Object>
+ readAttributes(Path path, String attribute, LinkOption... options)
+ throws IOException
+ {
+ return toZipPath(path).readAttributes(attribute, options);
+ }
+
+ @Override
+ public Path readSymbolicLink(Path link) throws IOException {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void setAttribute(Path path, String attribute,
+ Object value, LinkOption... options)
+ throws IOException
+ {
+ toZipPath(path).setAttribute(attribute, value, options);
+ }
+
+ //////////////////////////////////////////////////////////////
+ void removeFileSystem(Path zfpath, ZipFileSystem zfs) throws IOException {
synchronized (filesystems) {
- filesystems.remove(zfpath.toRealPath(true));
+ zfpath = zfpath.toRealPath(true);
+ if (filesystems.get(zfpath) == zfs)
+ filesystems.remove(zfpath);
}
}
}
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java Tue Feb 08 14:25:33 2011 -0800
@@ -31,29 +31,23 @@
package com.sun.nio.zipfs;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
import java.net.URI;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SeekableByteChannel;
+import java.nio.channels.*;
import java.nio.file.*;
import java.nio.file.DirectoryStream.Filter;
-import java.nio.file.attribute.BasicFileAttributeView;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.file.attribute.FileAttributeView;
-import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.*;
import java.util.*;
import static java.nio.file.StandardOpenOption.*;
import static java.nio.file.StandardCopyOption.*;
+
/**
*
* @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
*/
-public class ZipPath extends Path {
+public class ZipPath implements Path {
private final ZipFileSystem zfs;
private final byte[] path;
@@ -82,7 +76,7 @@
}
@Override
- public Path getName() {
+ public Path getFileName() {
initOffsets();
int count = offsets.length;
if (count == 0)
@@ -162,8 +156,7 @@
return realPath;
}
- @Override
- public boolean isHidden() {
+ boolean isHidden() {
return false;
}
@@ -230,7 +223,7 @@
public Path relativize(Path other) {
final ZipPath o = checkPath(other);
if (o.equals(this))
- return null;
+ return new ZipPath(getFileSystem(), new byte[0], true);
if (/* this.getFileSystem() != o.getFileSystem() || */
this.isAbsolute() != o.isAbsolute()) {
throw new IllegalArgumentException();
@@ -272,13 +265,11 @@
@Override
public boolean isAbsolute() {
- return (this.path[0] == '/');
+ return (this.path.length > 0 && path[0] == '/');
}
@Override
public ZipPath resolve(Path other) {
- if (other == null)
- return this;
final ZipPath o = checkPath(other);
if (o.isAbsolute())
return o;
@@ -297,39 +288,70 @@
}
@Override
- public ZipPath resolve(String other) {
- return resolve(getFileSystem().getPath(other));
+ public Path resolveSibling(Path other) {
+ if (other == null)
+ throw new NullPointerException();
+ Path parent = getParent();
+ return (parent == null) ? other : parent.resolve(other);
}
@Override
public boolean startsWith(Path other) {
final ZipPath o = checkPath(other);
- if (o.isAbsolute() != this.isAbsolute())
+ if (o.isAbsolute() != this.isAbsolute() ||
+ o.path.length > this.path.length)
return false;
- final int oCount = o.getNameCount();
- if (getNameCount() < oCount)
- return false;
- for (int i = 0; i < oCount; i++) {
- if (!o.getName(i).equals(getName(i)))
+ int olast = o.path.length;
+ for (int i = 0; i < olast; i++) {
+ if (o.path[i] != this.path[i])
return false;
}
- return true;
+ olast--;
+ return o.path.length == this.path.length ||
+ o.path[olast] == '/' ||
+ this.path[olast + 1] == '/';
}
@Override
public boolean endsWith(Path other) {
final ZipPath o = checkPath(other);
- if (o.isAbsolute())
- return this.isAbsolute() ? this.equals(o) : false;
- int i = o.getNameCount();
- int j = this.getNameCount();
- if (j < i)
+ int olast = o.path.length - 1;
+ if (olast > 0 && o.path[olast] == '/')
+ olast--;
+ int last = this.path.length - 1;
+ if (last > 0 && this.path[last] == '/')
+ last--;
+ if (olast == -1) // o.path.length == 0
+ return last == -1;
+ if ((o.isAbsolute() &&(!this.isAbsolute() || olast != last)) ||
+ (last < olast))
return false;
- for (--i, --j; i >= 0; i--, j--) {
- if (!o.getName(i).equals(this.getName(j)))
+ for (; olast >= 0; olast--, last--) {
+ if (o.path[olast] != this.path[last])
return false;
}
- return true;
+ return o.path[olast + 1] == '/' ||
+ last == -1 || this.path[last] == '/';
+ }
+
+ @Override
+ public ZipPath resolve(String other) {
+ return resolve(getFileSystem().getPath(other));
+ }
+
+ @Override
+ public final Path resolveSibling(String other) {
+ return resolveSibling(getFileSystem().getPath(other));
+ }
+
+ @Override
+ public final boolean startsWith(String other) {
+ return startsWith(getFileSystem().getPath(other));
+ }
+
+ @Override
+ public final boolean endsWith(String other) {
+ return endsWith(getFileSystem().getPath(other));
}
@Override
@@ -337,8 +359,6 @@
byte[] resolved = getResolved();
if (resolved == path) // no change
return this;
- if (resolved.length == 0)
- return null;
return new ZipPath(zfs, resolved, true);
}
@@ -548,198 +568,6 @@
return len1 - len2;
}
- @Override
- public Path createSymbolicLink(
- Path target, FileAttribute<?>... attrs) throws IOException {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public Path createLink(
- Path existing) throws IOException {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public Path readSymbolicLink() throws IOException {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public Path createDirectory(FileAttribute<?>... attrs)
- throws IOException
- {
- zfs.createDirectory(getResolvedPath(), attrs);
- return this;
- }
-
- public final Path createFile(FileAttribute<?>... attrs)
- throws IOException
- {
- OutputStream os = newOutputStream(CREATE_NEW, WRITE);
- try {
- os.close();
- } catch (IOException x) {}
- return this;
- }
-
- @Override
- public InputStream newInputStream(OpenOption... options)
- throws IOException {
- if (options.length > 0) {
- for (OpenOption opt : options) {
- if (opt != READ)
- throw new UnsupportedOperationException("'" + opt + "' not allowed");
- }
- }
- return zfs.newInputStream(getResolvedPath());
- }
-
- private static final DirectoryStream.Filter<Path> acceptAllFilter =
- new DirectoryStream.Filter<>() {
- @Override public boolean accept(Path entry) { return true; }
- };
-
- @Override
- public final DirectoryStream<Path> newDirectoryStream() throws IOException {
- return newDirectoryStream(acceptAllFilter);
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
- throws IOException
- {
- return new ZipDirectoryStream(this, filter);
- }
-
- @Override
- public final DirectoryStream<Path> newDirectoryStream(String glob)
- throws IOException
- {
- // avoid creating a matcher if all entries are required.
- if (glob.equals("*"))
- return newDirectoryStream();
-
- // create a matcher and return a filter that uses it.
- final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
- DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<>() {
- @Override
- public boolean accept(Path entry) {
- return matcher.matches(entry.getName());
- }
- };
- return newDirectoryStream(filter);
- }
-
- @Override
- public final void delete() throws IOException {
- zfs.deleteFile(getResolvedPath(), true);
- }
-
- @Override
- public final void deleteIfExists() throws IOException {
- zfs.deleteFile(getResolvedPath(), false);
- }
-
- ZipFileAttributes getAttributes() throws IOException
- {
- ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
- if (zfas == null)
- throw new NoSuchFileException(toString());
- return zfas;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
- LinkOption... options)
- {
- return (V)ZipFileAttributeView.get(this, type);
- }
-
- @Override
- public void setAttribute(String attribute,
- Object value,
- LinkOption... options)
- throws IOException
- {
- String type = null;
- String attr = null;
- int colonPos = attribute.indexOf(':');
- if (colonPos == -1) {
- type = "basic";
- attr = attribute;
- } else {
- type = attribute.substring(0, colonPos++);
- attr = attribute.substring(colonPos);
- }
- ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
- if (view == null)
- throw new UnsupportedOperationException("view <" + view + "> is not supported");
- view.setAttribute(attr, value);
- }
-
- void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
- throws IOException
- {
- zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
- }
-
- private Object getAttributesImpl(String attribute, boolean domap)
- throws IOException
- {
- String view = null;
- String attr = null;
- int colonPos = attribute.indexOf(':');
- if (colonPos == -1) {
- view = "basic";
- attr = attribute;
- } else {
- view = attribute.substring(0, colonPos++);
- attr = attribute.substring(colonPos);
- }
- ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
- if (zfv == null) {
- throw new UnsupportedOperationException("view not supported");
- }
- return zfv.getAttribute(attr, domap);
- }
-
- @Override
- public Object getAttribute(String attribute, LinkOption... options)
- throws IOException
- {
- return getAttributesImpl(attribute, false);
- }
-
- @Override
- public Map<String,?> readAttributes(String attribute, LinkOption... options)
- throws IOException
- {
- return (Map<String, ?>)getAttributesImpl(attribute, true);
- }
-
- @Override
- public FileStore getFileStore() throws IOException {
- // each ZipFileSystem only has one root (as requested for now)
- if (exists())
- return zfs.getFileStore(this);
- throw new NoSuchFileException(zfs.getString(path));
- }
-
- @Override
- public boolean isSameFile(Path other) throws IOException {
- if (this.equals(other))
- return true;
- if (other == null ||
- this.getFileSystem() != other.getFileSystem())
- return false;
- this.checkAccess();
- other.checkAccess();
- return Arrays.equals(this.getResolvedPath(),
- ((ZipPath)other).getResolvedPath());
- }
-
public WatchKey register(
WatchService watcher,
WatchEvent.Kind<?>[] events,
@@ -756,6 +584,11 @@
}
@Override
+ public final File toFile() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public Iterator<Path> iterator() {
return new Iterator<>() {
private int i = 0;
@@ -783,9 +616,115 @@
};
}
- @Override
- public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
+ /////////////////////////////////////////////////////////////////////
+
+
+ void createDirectory(FileAttribute<?>... attrs)
+ throws IOException
+ {
+ zfs.createDirectory(getResolvedPath(), attrs);
+ }
+
+ InputStream newInputStream(OpenOption... options) throws IOException
+ {
+ if (options.length > 0) {
+ for (OpenOption opt : options) {
+ if (opt != READ)
+ throw new UnsupportedOperationException("'" + opt + "' not allowed");
+ }
+ }
+ return zfs.newInputStream(getResolvedPath());
+ }
+
+ DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
+ throws IOException
+ {
+ return new ZipDirectoryStream(this, filter);
+ }
+
+ void delete() throws IOException {
+ zfs.deleteFile(getResolvedPath(), true);
+ }
+
+ void deleteIfExists() throws IOException {
+ zfs.deleteFile(getResolvedPath(), false);
+ }
+
+ ZipFileAttributes getAttributes() throws IOException
+ {
+ ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
+ if (zfas == null)
+ throw new NoSuchFileException(toString());
+ return zfas;
+ }
+
+ void setAttribute(String attribute, Object value, LinkOption... options)
+ throws IOException
+ {
+ String type = null;
+ String attr = null;
+ int colonPos = attribute.indexOf(':');
+ if (colonPos == -1) {
+ type = "basic";
+ attr = attribute;
+ } else {
+ type = attribute.substring(0, colonPos++);
+ attr = attribute.substring(colonPos);
+ }
+ ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
+ if (view == null)
+ throw new UnsupportedOperationException("view <" + view + "> is not supported");
+ view.setAttribute(attr, value);
+ }
+
+ void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
+ throws IOException
+ {
+ zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
+ }
+
+ Map<String, Object> readAttributes(String attributes, LinkOption... options)
+ throws IOException
+
+ {
+ String view = null;
+ String attrs = null;
+ int colonPos = attributes.indexOf(':');
+ if (colonPos == -1) {
+ view = "basic";
+ attrs = attributes;
+ } else {
+ view = attributes.substring(0, colonPos++);
+ attrs = attributes.substring(colonPos);
+ }
+ ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
+ if (zfv == null) {
+ throw new UnsupportedOperationException("view not supported");
+ }
+ return zfv.readAttributes(attrs);
+ }
+
+ FileStore getFileStore() throws IOException {
+ // each ZipFileSystem only has one root (as requested for now)
+ if (exists())
+ return zfs.getFileStore(this);
+ throw new NoSuchFileException(zfs.getString(path));
+ }
+
+ boolean isSameFile(Path other) throws IOException {
+ if (this.equals(other))
+ return true;
+ if (other == null ||
+ this.getFileSystem() != other.getFileSystem())
+ return false;
+ this.checkAccess();
+ ((ZipPath)other).checkAccess();
+ return Arrays.equals(this.getResolvedPath(),
+ ((ZipPath)other).getResolvedPath());
+ }
+
+ SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
throws IOException
{
return zfs.newByteChannel(getResolvedPath(), options, attrs);
@@ -799,16 +738,7 @@
return zfs.newFileChannel(getResolvedPath(), options, attrs);
}
- @Override
- public SeekableByteChannel newByteChannel(OpenOption... options)
- throws IOException {
- Set<OpenOption> set = new HashSet<>(options.length);
- Collections.addAll(set, options);
- return newByteChannel(set);
- }
-
- @Override
- public void checkAccess(AccessMode... modes) throws IOException {
+ void checkAccess(AccessMode... modes) throws IOException {
boolean w = false;
boolean x = false;
for (AccessMode mode : modes) {
@@ -834,11 +764,9 @@
}
if (x)
throw new AccessDeniedException(toString());
-
}
- @Override
- public boolean exists() {
+ boolean exists() {
if (path.length == 1 && path[0] == '/')
return true;
try {
@@ -847,15 +775,7 @@
return false;
}
- @Override
- public boolean notExists() {
- return !exists();
- }
-
-
- @Override
- public OutputStream newOutputStream(OpenOption... options)
- throws IOException
+ OutputStream newOutputStream(OpenOption... options) throws IOException
{
if (options.length == 0)
return zfs.newOutputStream(getResolvedPath(),
@@ -863,42 +783,32 @@
return zfs.newOutputStream(getResolvedPath(), options);
}
- @Override
- public Path moveTo(Path target, CopyOption... options)
+ void move(ZipPath target, CopyOption... options)
throws IOException
{
- if (this.zfs.provider() == target.getFileSystem().provider() &&
- this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
+ if (Files.isSameFile(this.zfs.getZipFile(), target.zfs.getZipFile()))
{
zfs.copyFile(true,
- getResolvedPath(),
- ((ZipPath)target).getResolvedPath(),
+ getResolvedPath(), target.getResolvedPath(),
options);
} else {
copyToTarget(target, options);
delete();
}
- return target;
}
- @Override
- public Path copyTo(Path target, CopyOption... options)
+ void copy(ZipPath target, CopyOption... options)
throws IOException
{
- if (this.zfs.provider() == target.getFileSystem().provider() &&
- this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
- {
+ if (Files.isSameFile(this.zfs.getZipFile(), target.zfs.getZipFile()))
zfs.copyFile(false,
- getResolvedPath(),
- ((ZipPath)target).getResolvedPath(),
+ getResolvedPath(), target.getResolvedPath(),
options);
- } else {
+ else
copyToTarget(target, options);
- }
- return target;
}
- private void copyToTarget(Path target, CopyOption... options)
+ private void copyToTarget(ZipPath target, CopyOption... options)
throws IOException
{
boolean replaceExisting = false;
@@ -948,7 +858,7 @@
}
if (copyAttrs) {
BasicFileAttributeView view =
- target.getFileAttributeView(BasicFileAttributeView.class);
+ ZipFileAttributeView.get(target, BasicFileAttributeView.class);
try {
view.setTimes(zfas.lastModifiedTime(),
zfas.lastAccessTime(),
--- a/jdk/src/share/demo/zipfs Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,703 +0,0 @@
-/*
- * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.io.*;
-import java.nio.*;
-import java.nio.channels.*;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.net.*;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-import static java.nio.file.StandardOpenOption.*;
-import static java.nio.file.StandardCopyOption.*;
-
-/*
- * ZipFileSystem usage demo
- *
- * java Demo action ZipfileName [...]
- *
- * @author Xueming Shen
- */
-
-public class Demo {
-
- static enum Action {
- rename, // <java Demo rename zipfile src dst>
- // rename entry src to dst inside zipfile
-
- movein, // <java Demo movein zipfile src dst>
- // move an external src file into zipfile
- // as entry dst
-
- moveout, // <java Demo moveout zipfile src dst>
- // move a zipfile entry src out to dst
-
- copy, // <java Demo copy zipfile src dst>
- // copy entry src to dst inside zipfile
-
- copyin, // <java Demo copyin zipfile src dst>
- // copy an external src file into zipfile
- // as entry dst
-
- copyin_attrs, // <java Demo copyin_attrs zipfile src dst>
- // copy an external src file into zipfile
- // as entry dst, with attributes (timestamp)
-
- copyout, // <java Demo copyout zipfile src dst>
- // copy zipfile entry src" out to file dst
-
- copyout_attrs, // <java Demo copyout_attrs zipfile src dst>
-
- zzmove, // <java Demo zzmove zfsrc zfdst path>
- // move entry path/dir from zfsrc to zfdst
-
- zzcopy, // <java Demo zzcopy zfsrc zfdst path>
- // copy path from zipfile zfsrc to zipfile
- // zfdst
-
- attrs, // <java Demo attrs zipfile path>
- // printout the attributes of entry path
-
- attrsspace, // <java Demo attrsspace zipfile path>
- // printout the storespace attrs of entry path
-
- setmtime, // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
- // set the lastModifiedTime of entry path
-
- setatime, // <java Demo setatime zipfile "MM/dd/yy-HH:mm:ss" path...>
- setctime, // <java Demo setctime zipfile "MM/dd/yy-HH:mm:ss" path...>
-
- lsdir, // <java Demo lsdir zipfile dir>
- // list dir's direct child files/dirs
-
- mkdir, // <java Demo mkdir zipfile dir>
-
- mkdirs, // <java Demo mkdirs zipfile dir>
-
- rmdirs, // <java Demo rmdirs zipfile dir>
-
- list, // <java Demo list zipfile [dir]>
- // recursively list all entries of dir
- // via DirectoryStream
-
- tlist, // <java Demo tlist zipfile [dir]>
- // list with buildDirTree=true
-
- vlist, // <java Demo vlist zipfile [dir]>
- // recursively verbose list all entries of
- // dir via DirectoryStream
-
- walk, // <java Demo walk zipfile [dir]>
- // recursively walk all entries of dir
- // via Files.walkFileTree
-
- twalk, // <java Demo twalk zipfile [dir]>
- // walk with buildDirTree=true
-
- extract, // <java Demo extract zipfile file [...]>
-
- update, // <java Demo extract zipfile file [...]>
-
- delete, // <java Demo delete zipfile file [...]>
-
- add, // <java Demo add zipfile file [...]>
-
- create, // <java Demo create zipfile file [...]>
- // create a new zipfile if it doesn't exit
- // and then add the file(s) into it.
-
- attrs2, // <java Demo attrs2 zipfile file [...]>
- // test different ways to print attrs
-
- prof,
- }
-
- public static void main(String[] args) throws Throwable {
-
- Action action = Action.valueOf(args[0]);
- Map<String, Object> env = env = new HashMap<>();
- if (action == Action.create)
- env.put("create", "true");
- if (action == Action.tlist || action == Action.twalk)
- env.put("buildDirTree", true);
- FileSystem fs = FileSystems.newFileSystem(Paths.get(args[1]), env, null);
-
- try {
- FileSystem fs2;
- Path path, src, dst;
- boolean isRename = false;
- switch (action) {
- case rename:
- src = fs.getPath(args[2]);
- dst = fs.getPath(args[3]);
- src.moveTo(dst);
- break;
- case moveout:
- src = fs.getPath(args[2]);
- dst = Paths.get(args[3]);
- src.moveTo(dst);
- break;
- case movein:
- src = Paths.get(args[2]);
- dst = fs.getPath(args[3]);
- src.moveTo(dst);
- break;
- case copy:
- src = fs.getPath(args[2]);
- dst = fs.getPath(args[3]);
- src.copyTo(dst);
- break;
- case copyout:
- src = fs.getPath(args[2]);
- dst = Paths.get(args[3]);
- src.copyTo(dst);
- break;
- case copyin:
- src = Paths.get(args[2]);
- dst = fs.getPath(args[3]);
- src.copyTo(dst);
- break;
- case copyin_attrs:
- src = Paths.get(args[2]);
- dst = fs.getPath(args[3]);
- src.copyTo(dst, COPY_ATTRIBUTES);
- break;
- case copyout_attrs:
- src = fs.getPath(args[2]);
- dst = Paths.get(args[3]);
- src.copyTo(dst, COPY_ATTRIBUTES);
- break;
- case zzmove:
- fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
- //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
- z2zmove(fs, fs2, args[3]);
- fs2.close();
- break;
- case zzcopy:
- fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
- //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
- z2zcopy(fs, fs2, args[3]);
- fs2.close();
- break;
- case attrs:
- for (int i = 2; i < args.length; i++) {
- path = fs.getPath(args[i]);
- System.out.println(path);
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- }
- break;
- case setmtime:
- DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
- Date newDatetime = df.parse(args[2]);
- for (int i = 3; i < args.length; i++) {
- path = fs.getPath(args[i]);
- path.setAttribute("lastModifiedTime",
- FileTime.fromMillis(newDatetime.getTime()));
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- }
- break;
- case setctime:
- df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
- newDatetime = df.parse(args[2]);
- for (int i = 3; i < args.length; i++) {
- path = fs.getPath(args[i]);
- path.setAttribute("creationTime",
- FileTime.fromMillis(newDatetime.getTime()));
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- }
- break;
- case setatime:
- df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
- newDatetime = df.parse(args[2]);
- for (int i = 3; i < args.length; i++) {
- path = fs.getPath(args[i]);
- path.setAttribute("lastAccessTime",
- FileTime.fromMillis(newDatetime.getTime()));
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- }
- break;
- case attrsspace:
- path = fs.getPath("/");
- FileStore fstore = path.getFileStore();
- //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
- // .readAttributes());
- // or
- System.out.printf("filestore[%s]%n", fstore.name());
- System.out.printf(" totalSpace: %d%n",
- (Long)fstore.getAttribute("space:totalSpace"));
- System.out.printf(" usableSpace: %d%n",
- (Long)fstore.getAttribute("space:usableSpace"));
- System.out.printf(" unallocSpace: %d%n",
- (Long)fstore.getAttribute("space:unallocatedSpace"));
- break;
- case list:
- case tlist:
- if (args.length < 3)
- list(fs.getPath("/"), false);
- else
- list(fs.getPath(args[2]), false);
- break;
- case vlist:
- if (args.length < 3)
- list(fs.getPath("/"), true);
- else
- list(fs.getPath(args[2]), true);
- break;
- case twalk:
- case walk:
- walk(fs.getPath((args.length > 2)? args[2] : "/"));
- break;
- case extract:
- if (args.length == 2) {
- extract(fs, "/");
- } else {
- for (int i = 2; i < args.length; i++) {
- extract(fs, args[i]);
- }
- }
- break;
- case delete:
- for (int i = 2; i < args.length; i++)
- fs.getPath(args[i]).delete();
- break;
- case create:
- case add:
- case update:
- for (int i = 2; i < args.length; i++) {
- update(fs, args[i]);
- }
- break;
- case lsdir:
- path = fs.getPath(args[2]);
- final String fStr = (args.length > 3)?args[3]:"";
- DirectoryStream<Path> ds = path.newDirectoryStream(
- new DirectoryStream.Filter<Path>() {
- public boolean accept(Path path) {
- return path.toString().contains(fStr);
- }
- });
- for (Path p : ds)
- System.out.println(p);
- break;
- case mkdir:
- fs.getPath(args[2]).createDirectory();
- break;
- case mkdirs:
- mkdirs(fs.getPath(args[2]));
- break;
- case attrs2:
- for (int i = 2; i < args.length; i++) {
- path = fs.getPath(args[i]);
- System.out.printf("%n%s%n", path);
- System.out.println("-------(1)---------");
- System.out.println(
- Attributes.readBasicFileAttributes(path).toString());
- System.out.println("-------(2)---------");
- Map<String, ?> map = path.readAttributes("zip:*");
- for (Map.Entry<String, ?> e : map.entrySet()) {
- System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
- }
- System.out.println("-------(3)---------");
- map = path.readAttributes("size,lastModifiedTime,isDirectory");
- for (Map.Entry<String, ?> e : map.entrySet()) {
- System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
- }
- }
- break;
- case prof:
- list(fs.getPath("/"), false);
- while (true) {
- Thread.sleep(10000);
- //list(fs.getPath("/"), true);
- System.out.println("sleeping...");
- }
- }
- } catch (Exception x) {
- x.printStackTrace();
- } finally {
- if (fs != null)
- fs.close();
- }
- }
-
- private static byte[] getBytes(String name) {
- return name.getBytes();
- }
-
- private static String getString(byte[] name) {
- return new String(name);
- }
-
- private static void walk(Path path) throws IOException
- {
- Files.walkFileTree(
- path,
- new SimpleFileVisitor<Path>() {
- private int indent = 0;
- private void indent() {
- int n = 0;
- while (n++ < indent)
- System.out.printf(" ");
- }
-
- @Override
- public FileVisitResult visitFile(Path file,
- BasicFileAttributes attrs)
- {
- indent();
- System.out.printf("%s%n", file.getName().toString());
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir,
- BasicFileAttributes attrs)
- {
- indent();
- System.out.printf("[%s]%n", dir.toString());
- indent += 2;
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path dir,
- IOException ioe)
- {
- indent -= 2;
- return FileVisitResult.CONTINUE;
- }
- });
- }
-
- private static void update(FileSystem fs, String path) throws Throwable{
- Path src = FileSystems.getDefault().getPath(path);
- if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
- DirectoryStream<Path> ds = src.newDirectoryStream();
- for (Path child : ds)
- update(fs, child.toString());
- ds.close();
- } else {
- Path dst = fs.getPath(path);
- Path parent = dst.getParent();
- if (parent != null && parent.notExists())
- mkdirs(parent);
- src.copyTo(dst, REPLACE_EXISTING);
- }
- }
-
- private static void extract(FileSystem fs, String path) throws Throwable{
- Path src = fs.getPath(path);
- if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
- DirectoryStream<Path> ds = src.newDirectoryStream();
- for (Path child : ds)
- extract(fs, child.toString());
- ds.close();
- } else {
- if (path.startsWith("/"))
- path = path.substring(1);
- Path dst = FileSystems.getDefault().getPath(path);
- Path parent = dst.getParent();
- if (parent.notExists())
- mkdirs(parent);
- src.copyTo(dst, REPLACE_EXISTING);
- }
- }
-
- // use DirectoryStream
- private static void z2zcopy(FileSystem src, FileSystem dst, String path)
- throws IOException
- {
- Path srcPath = src.getPath(path);
- Path dstPath = dst.getPath(path);
-
- if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
- if (!dstPath.exists()) {
- try {
- mkdirs(dstPath);
- } catch (FileAlreadyExistsException x) {}
- }
- DirectoryStream<Path> ds = srcPath.newDirectoryStream();
- for (Path child : ds) {
- z2zcopy(src, dst,
- path + (path.endsWith("/")?"":"/") + child.getName());
- }
- ds.close();
- } else {
- //System.out.println("copying..." + path);
- srcPath.copyTo(dstPath);
- }
- }
-
- // use TreeWalk to move
- private static void z2zmove(FileSystem src, FileSystem dst, String path)
- throws IOException
- {
- final Path srcPath = src.getPath(path).toAbsolutePath();
- final Path dstPath = dst.getPath(path).toAbsolutePath();
-
- Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
-
- @Override
- public FileVisitResult visitFile(Path file,
- BasicFileAttributes attrs)
- {
- Path dst = srcPath.relativize(file);
- dst = dstPath.resolve(dst);
- try {
- Path parent = dstPath.getParent();
- if (parent != null && parent.notExists())
- mkdirs(parent);
- file.moveTo(dst);
- } catch (IOException x) {
- x.printStackTrace();
- }
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir,
- BasicFileAttributes attrs)
- {
- Path dst = srcPath.relativize(dir);
- dst = dstPath.resolve(dst);
- try {
-
- if (dst.notExists())
- mkdirs(dst);
- } catch (IOException x) {
- x.printStackTrace();
- }
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path dir,
- IOException ioe)
- throws IOException
- {
- try {
- dir.delete();
- } catch (IOException x) {
- //x.printStackTrace();
- }
- return FileVisitResult.CONTINUE;
- }
- });
-
- }
-
- private static void mkdirs(Path path) throws IOException {
- path = path.toAbsolutePath();
- Path parent = path.getParent();
- if (parent != null) {
- if (parent.notExists())
- mkdirs(parent);
- }
- path.createDirectory();
- }
-
- private static void rmdirs(Path path) throws IOException {
- while (path != null && path.getNameCount() != 0) {
- path.delete();
- path = path.getParent();
- }
- }
-
- private static void list(Path path, boolean verbose ) throws IOException {
- if (!"/".equals(path.toString())) {
- System.out.printf(" %s%n", path.toString());
- if (verbose)
- System.out.println(Attributes.readBasicFileAttributes(path).toString());
- }
- if (path.notExists())
- return;
- if (Attributes.readBasicFileAttributes(path).isDirectory()) {
- DirectoryStream<Path> ds = path.newDirectoryStream();
- for (Path child : ds)
- list(child, verbose);
- ds.close();
- }
- }
-
- // check the content of two paths are equal
- private static void checkEqual(Path src, Path dst) throws IOException
- {
- //System.out.printf("checking <%s> vs <%s>...%n",
- // src.toString(), dst.toString());
-
- //streams
- InputStream isSrc = src.newInputStream();
- InputStream isDst = dst.newInputStream();
- byte[] bufSrc = new byte[8192];
- byte[] bufDst = new byte[8192];
-
- try {
- int nSrc = 0;
- while ((nSrc = isSrc.read(bufSrc)) != -1) {
- int nDst = 0;
- while (nDst < nSrc) {
- int n = isDst.read(bufDst, nDst, nSrc - nDst);
- if (n == -1) {
- System.out.printf("checking <%s> vs <%s>...%n",
- src.toString(), dst.toString());
- throw new RuntimeException("CHECK FAILED!");
- }
- nDst += n;
- }
- while (--nSrc >= 0) {
- if (bufSrc[nSrc] != bufDst[nSrc]) {
- System.out.printf("checking <%s> vs <%s>...%n",
- src.toString(), dst.toString());
- throw new RuntimeException("CHECK FAILED!");
- }
- nSrc--;
- }
- }
- } finally {
- isSrc.close();
- isDst.close();
- }
-
- // channels
- SeekableByteChannel chSrc = src.newByteChannel();
- SeekableByteChannel chDst = dst.newByteChannel();
- if (chSrc.size() != chDst.size()) {
- System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
- chSrc.toString(), chSrc.size(),
- chDst.toString(), chDst.size());
- throw new RuntimeException("CHECK FAILED!");
- }
- ByteBuffer bbSrc = ByteBuffer.allocate(8192);
- ByteBuffer bbDst = ByteBuffer.allocate(8192);
-
- try {
- int nSrc = 0;
- while ((nSrc = chSrc.read(bbSrc)) != -1) {
- int nDst = chDst.read(bbDst);
- if (nSrc != nDst) {
- System.out.printf("checking <%s> vs <%s>...%n",
- src.toString(), dst.toString());
- throw new RuntimeException("CHECK FAILED!");
- }
- while (--nSrc >= 0) {
- if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
- System.out.printf("checking <%s> vs <%s>...%n",
- src.toString(), dst.toString());
- throw new RuntimeException("CHECK FAILED!");
- }
- nSrc--;
- }
- bbSrc.flip();
- bbDst.flip();
- }
- } catch (IOException x) {
- x.printStackTrace();
- } finally {
- chSrc.close();
- chDst.close();
- }
- }
-
- private static void fchCopy(Path src, Path dst) throws IOException
- {
- Set<OpenOption> read = new HashSet<>();
- read.add(READ);
- Set<OpenOption> openwrite = new HashSet<>();
- openwrite.add(CREATE_NEW);
- openwrite.add(WRITE);
-
- FileChannel srcFc = src.getFileSystem()
- .provider()
- .newFileChannel(src, read);
- FileChannel dstFc = dst.getFileSystem()
- .provider()
- .newFileChannel(dst, openwrite);
-
- try {
- ByteBuffer bb = ByteBuffer.allocate(8192);
- while (srcFc.read(bb) >= 0) {
- bb.flip();
- dstFc.write(bb);
- bb.clear();
- }
- } finally {
- srcFc.close();
- dstFc.close();
- }
- }
-
- private static void chCopy(Path src, Path dst) throws IOException
- {
- Set<OpenOption> read = new HashSet<>();
- read.add(READ);
- Set<OpenOption> openwrite = new HashSet<>();
- openwrite.add(CREATE_NEW);
- openwrite.add(WRITE);
-
- SeekableByteChannel srcCh = src.newByteChannel(read);
- SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
-
- try {
- ByteBuffer bb = ByteBuffer.allocate(8192);
- while (srcCh.read(bb) >= 0) {
- bb.flip();
- dstCh.write(bb);
- bb.clear();
- }
- } finally {
- srcCh.close();
- dstCh.close();
- }
- }
-
- private static void streamCopy(Path src, Path dst) throws IOException
- {
- InputStream isSrc = src.newInputStream();
- OutputStream osDst = dst.newOutputStream();
- byte[] buf = new byte[8192];
- try {
- int n = 0;
- while ((n = isSrc.read(buf)) != -1) {
- osDst.write(buf, 0, n);
- }
- } finally {
- isSrc.close();
- osDst.close();
- }
- }
-}
--- a/jdk/src/share/native/java/io/io_util.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/java/io/io_util.c Tue Feb 08 14:25:33 2011 -0800
@@ -44,7 +44,7 @@
JNU_ThrowIOException(env, "Stream Closed");
return -1;
}
- nread = IO_Read(fd, &ret, 1);
+ nread = (jint)IO_Read(fd, &ret, 1);
if (nread == 0) { /* EOF */
return -1;
} else if (nread == JVM_IO_ERR) { /* error */
@@ -108,7 +108,7 @@
JNU_ThrowIOException(env, "Stream Closed");
nread = -1;
} else {
- nread = IO_Read(fd, buf, len);
+ nread = (jint)IO_Read(fd, buf, len);
if (nread > 0) {
(*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf);
} else if (nread == JVM_IO_ERR) {
@@ -137,9 +137,9 @@
return;
}
if (append == JNI_TRUE) {
- n = IO_Append(fd, &c, 1);
+ n = (jint)IO_Append(fd, &c, 1);
} else {
- n = IO_Write(fd, &c, 1);
+ n = (jint)IO_Write(fd, &c, 1);
}
if (n == JVM_IO_ERR) {
JNU_ThrowIOExceptionWithLastError(env, "Write error");
@@ -190,9 +190,9 @@
break;
}
if (append == JNI_TRUE) {
- n = IO_Append(fd, buf+off, len);
+ n = (jint)IO_Append(fd, buf+off, len);
} else {
- n = IO_Write(fd, buf+off, len);
+ n = (jint)IO_Write(fd, buf+off, len);
}
if (n == JVM_IO_ERR) {
JNU_ThrowIOExceptionWithLastError(env, "Write error");
--- a/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp Tue Feb 08 14:25:33 2011 -0800
@@ -38,7 +38,7 @@
/*
* Throws an arbitrary Java exception.
*/
-void ThrowException(JNIEnv *env, char *exceptionName)
+void ThrowException(JNIEnv *env, const char *exceptionName)
{
jclass exceptionClazz = env->FindClass(exceptionName);
env->ThrowNew(exceptionClazz, NULL);
@@ -89,7 +89,7 @@
// Fill a new ECParams using the supplied OID
if (EC_DecodeParams(¶ms_item, &ecparams, 0) != SECSuccess) {
/* bad curve OID */
- ThrowException(env, (char *) INVALID_ALGORITHM_PARAMETER_EXCEPTION);
+ ThrowException(env, INVALID_ALGORITHM_PARAMETER_EXCEPTION);
goto cleanup;
}
@@ -101,7 +101,7 @@
// Generate the new keypair (using the supplied seed)
if (EC_NewKey(ecparams, &privKey, (unsigned char *) pSeedBuffer,
jSeedLength, 0) != SECSuccess) {
- ThrowException(env, (char *) KEY_EXCEPTION);
+ ThrowException(env, KEY_EXCEPTION);
goto cleanup;
}
--- a/jdk/src/share/native/sun/security/ec/impl/ec.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec.c Tue Feb 08 14:25:33 2011 -0800
@@ -51,12 +51,10 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mplogic.h"
#include "ec.h"
#include "ecl.h"
@@ -67,6 +65,7 @@
#include <string.h>
#ifndef _WIN32
+#include <stdio.h>
#include <strings.h>
#endif /* _WIN32 */
@@ -116,7 +115,7 @@
ECGroup *group = NULL;
SECStatus rv = SECFailure;
mp_err err = MP_OKAY;
- int len;
+ unsigned int len;
#if EC_DEBUG
int i;
@@ -278,10 +277,6 @@
printf("ec_NewKey called\n");
#endif
-#ifndef _WIN32
-int printf();
-#endif /* _WIN32 */
-
if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -361,8 +356,9 @@
cleanup:
mp_clear(&k);
- if (rv)
+ if (rv) {
PORT_FreeArena(arena, PR_TRUE);
+ }
#if EC_DEBUG
printf("ec_NewKey returning %s\n",
@@ -504,7 +500,7 @@
ECGroup *group = NULL;
SECStatus rv = SECFailure;
mp_err err = MP_OKAY;
- int len;
+ unsigned int len;
if (!ecParams || !publicValue) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -778,7 +774,7 @@
/* In the definition of EC signing, digests are truncated
* to the length of n in bits.
* (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
- if (digest->len*8 > ecParams->fieldID.size) {
+ if (digest->len*8 > (unsigned int)ecParams->fieldID.size) {
mpl_rsh(&s,&s,digest->len*8 - ecParams->fieldID.size);
}
@@ -993,7 +989,8 @@
/* In the definition of EC signing, digests are truncated
* to the length of n in bits.
* (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
- if (digest->len*8 > ecParams->fieldID.size) { /* u1 = HASH(M') */
+ /* u1 = HASH(M') */
+ if (digest->len*8 > (unsigned int)ecParams->fieldID.size) {
mpl_rsh(&u1,&u1,digest->len*8- ecParams->fieldID.size);
}
--- a/jdk/src/share/native/sun/security/ec/impl/ec.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec.h Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,6 @@
#ifndef __ec_h_
#define __ec_h_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#define EC_DEBUG 0
#define EC_POINT_FORM_COMPRESSED_Y0 0x02
#define EC_POINT_FORM_COMPRESSED_Y1 0x03
--- a/jdk/src/share/native/sun/security/ec/impl/ec2.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2.h Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _EC2_H
#define _EC2_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl-priv.h"
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_163.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_163.c Tue Feb 08 14:25:33 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mp_gf2m.h"
#include "mp_gf2m-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_193.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_193.c Tue Feb 08 14:25:33 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mp_gf2m.h"
#include "mp_gf2m-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_233.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_233.c Tue Feb 08 14:25:33 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mp_gf2m.h"
#include "mp_gf2m-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_aff.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_aff.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mplogic.h"
#include "mp_gf2m.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec2_mont.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_mont.c Tue Feb 08 14:25:33 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ec2.h"
#include "mplogic.h"
#include "mp_gf2m.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ec_naf.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ec_naf.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl-priv.h"
/* Returns 2^e as an integer. This is meant to be used for small powers of
--- a/jdk/src/share/native/sun/security/ec/impl/ecc_impl.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecc_impl.h Tue Feb 08 14:25:33 2011 -0800
@@ -51,15 +51,13 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _ECC_IMPL_H
#define _ECC_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -82,6 +80,7 @@
typedef unsigned char uint8_t;
typedef unsigned long ulong_t;
typedef enum boolean { B_FALSE, B_TRUE } boolean_t;
+#define strdup _strdup /* Replace POSIX name with ISO C++ name */
#endif /* _WIN32 */
#ifndef _KERNEL
--- a/jdk/src/share/native/sun/security/ec/impl/ecdecode.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecdecode.c Tue Feb 08 14:25:33 2011 -0800
@@ -55,8 +55,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#ifndef _WIN32
@@ -90,7 +88,7 @@
{
int i = 0;
int byteval = 0;
- int tmp = strlen(str);
+ int tmp = (int)strlen(str);
if ((tmp % 2) != 0) return NULL;
@@ -134,7 +132,8 @@
/* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
- if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup;
+ if (((int)name < ECCurve_noName) || (name > ECCurve_pastLastCurve))
+ goto cleanup;
params->name = name;
curveParams = ecCurve_map[params->name];
CHECK_OK(curveParams);
--- a/jdk/src/share/native/sun/security/ec/impl/ecl-curve.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl-curve.h Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _ECL_CURVE_H
#define _ECL_CURVE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl-exp.h"
#ifndef _KERNEL
#include <stdlib.h>
--- a/jdk/src/share/native/sun/security/ec/impl/ecl-exp.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl-exp.h Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _ECL_EXP_H
#define _ECL_EXP_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* Curve field type */
typedef enum {
ECField_GFp,
--- a/jdk/src/share/native/sun/security/ec/impl/ecl-priv.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl-priv.h Tue Feb 08 14:25:33 2011 -0800
@@ -58,8 +58,6 @@
#ifndef _ECL_PRIV_H
#define _ECL_PRIV_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl.h"
#include "mpi.h"
#include "mplogic.h"
@@ -90,6 +88,10 @@
s = ACCUM(w); \
cout = CARRYOUT(w); }
+/* Handle case when carry-in value is zero */
+#define MP_ADD_CARRY_ZERO(a1, a2, s, cout) \
+ MP_ADD_CARRY(a1, a2, s, 0, cout);
+
#define MP_SUB_BORROW(a1, a2, s, bin, bout) \
{ mp_word w; \
w = ((mp_word)(a1)) - (a2) - (bin); \
@@ -111,6 +113,15 @@
s = sum += (cin); \
cout = tmp + (sum < (cin)); }
+/* Handle case when carry-in value is zero */
+#define MP_ADD_CARRY_ZERO(a1, a2, s, cout) \
+ { mp_digit tmp,sum; \
+ tmp = (a1); \
+ sum = tmp + (a2); \
+ tmp = (sum < tmp); /* detect overflow */ \
+ s = sum; \
+ cout = tmp; }
+
#define MP_SUB_BORROW(a1, a2, s, bin, bout) \
{ mp_digit tmp; \
tmp = (a1); \
--- a/jdk/src/share/native/sun/security/ec/impl/ecl.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
#include "mplogic.h"
#include "ecl.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecl.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl.h Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _ECL_H
#define _ECL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* Although this is not an exported header file, code which uses elliptic
* curve point operations will need to include it. */
--- a/jdk/src/share/native/sun/security/ec/impl/ecl_curve.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl_curve.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl.h"
#include "ecl-curve.h"
#include "ecl-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecl_gf.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl_gf.c Tue Feb 08 14:25:33 2011 -0800
@@ -55,8 +55,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
#include "mp_gf2m.h"
#include "ecl-priv.h"
@@ -307,7 +305,7 @@
}
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
#else
@@ -394,7 +392,7 @@
}
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
MP_ADD_CARRY(a3, r3, r3, carry, carry);
@@ -491,7 +489,7 @@
r0 = MP_DIGIT(b,0);
}
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
MP_ADD_CARRY(a3, r3, r3, carry, carry);
@@ -572,7 +570,7 @@
r0 = MP_DIGIT(b,0);
}
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
MP_ADD_CARRY(a3, r3, r3, carry, carry);
@@ -675,7 +673,7 @@
b1 = MP_DIGIT(&meth->irr,1);
b0 = MP_DIGIT(&meth->irr,0);
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
+ MP_ADD_CARRY_ZERO(b0, r0, r0, borrow);
MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
#else
@@ -766,7 +764,7 @@
b1 = MP_DIGIT(&meth->irr,1);
b0 = MP_DIGIT(&meth->irr,0);
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
+ MP_ADD_CARRY_ZERO(b0, r0, r0, borrow);
MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
@@ -850,7 +848,7 @@
b2 = MP_DIGIT(&meth->irr,2);
b1 = MP_DIGIT(&meth->irr,1);
b0 = MP_DIGIT(&meth->irr,0);
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
+ MP_ADD_CARRY_ZERO(b0, r0, r0, borrow);
MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
@@ -924,7 +922,7 @@
b2 = MP_DIGIT(&meth->irr,2);
b1 = MP_DIGIT(&meth->irr,1);
b0 = MP_DIGIT(&meth->irr,0);
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
+ MP_ADD_CARRY_ZERO(b0, r0, r0, borrow);
MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
--- a/jdk/src/share/native/sun/security/ec/impl/ecl_mult.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl_mult.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
#include "mplogic.h"
#include "ecl.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecp.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp.h Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _ECP_H
#define _ECP_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecl-priv.h"
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_192.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_192.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
@@ -210,15 +208,15 @@
/* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(r0, a3, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, a3, r0, carry);
MP_ADD_CARRY(r1, a3, r1, carry, carry);
MP_ADD_CARRY(r2, a4, r2, carry, carry);
r3 = carry;
- MP_ADD_CARRY(r0, a5, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, a5, r0, carry);
MP_ADD_CARRY(r1, a5, r1, carry, carry);
MP_ADD_CARRY(r2, a5, r2, carry, carry);
r3 += carry;
- MP_ADD_CARRY(r1, a4, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a4, r1, carry);
MP_ADD_CARRY(r2, 0, r2, carry, carry);
r3 += carry;
@@ -251,7 +249,7 @@
/* reduce out the carry */
while (r3) {
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(r0, r3, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, r3, r0, carry);
MP_ADD_CARRY(r1, r3, r1, carry, carry);
MP_ADD_CARRY(r2, 0, r2, carry, carry);
r3 = carry;
@@ -335,7 +333,7 @@
}
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(a0, r0, r0, carry);
MP_ADD_CARRY(a1, r1, r1, carry, carry);
MP_ADD_CARRY(a2, r2, r2, carry, carry);
#else
@@ -357,7 +355,7 @@
((r1 == MP_DIGIT_MAX) ||
((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(r0, 1, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, 1, r0, carry);
MP_ADD_CARRY(r1, 1, r1, carry, carry);
MP_ADD_CARRY(r2, 0, r2, carry, carry);
#else
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_224.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_224.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
@@ -251,10 +249,10 @@
+( 0, a6,a5b, 0)
-( 0 0, 0|a6b, a6a|a5b )
-( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
- MP_ADD_CARRY (r1, a3b, r1, 0, carry);
+ MP_ADD_CARRY_ZERO (r1, a3b, r1, carry);
MP_ADD_CARRY (r2, a4 , r2, carry, carry);
MP_ADD_CARRY (r3, a5a, r3, carry, carry);
- MP_ADD_CARRY (r1, a5b, r1, 0, carry);
+ MP_ADD_CARRY_ZERO (r1, a5b, r1, carry);
MP_ADD_CARRY (r2, a6 , r2, carry, carry);
MP_ADD_CARRY (r3, 0, r3, carry, carry);
@@ -275,7 +273,7 @@
r3b = (int)(r3 >>32);
while (r3b > 0) {
r3 &= 0xffffffff;
- MP_ADD_CARRY(r1,((mp_digit)r3b) << 32, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1,((mp_digit)r3b) << 32, r1, carry);
if (carry) {
MP_ADD_CARRY(r2, 0, r2, carry, carry);
MP_ADD_CARRY(r3, 0, r3, carry, carry);
@@ -290,7 +288,7 @@
}
while (r3b < 0) {
- MP_ADD_CARRY (r0, 1, r0, 0, carry);
+ MP_ADD_CARRY_ZERO (r0, 1, r0, carry);
MP_ADD_CARRY (r1, MP_DIGIT_MAX <<32, r1, carry, carry);
MP_ADD_CARRY (r2, MP_DIGIT_MAX, r2, carry, carry);
MP_ADD_CARRY (r3, MP_DIGIT_MAX >> 32, r3, carry, carry);
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_256.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_256.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
@@ -303,32 +301,32 @@
r0 = MP_DIGIT(a,0);
/* sum 1 */
- MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a5h << 32, r1, carry);
MP_ADD_CARRY(r2, a6, r2, carry, carry);
MP_ADD_CARRY(r3, a7, r3, carry, carry);
r4 = carry;
- MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a5h << 32, r1, carry);
MP_ADD_CARRY(r2, a6, r2, carry, carry);
MP_ADD_CARRY(r3, a7, r3, carry, carry);
r4 += carry;
/* sum 2 */
- MP_ADD_CARRY(r1, a6l, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a6l, r1, carry);
MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
MP_ADD_CARRY(r3, a7h, r3, carry, carry);
r4 += carry;
- MP_ADD_CARRY(r1, a6l, r1, 0, carry);
+ MP_ADD_CARRY_ZERO(r1, a6l, r1, carry);
MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
MP_ADD_CARRY(r3, a7h, r3, carry, carry);
r4 += carry;
/* sum 3 */
- MP_ADD_CARRY(r0, a4, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, a4, r0, carry);
MP_ADD_CARRY(r1, a5l >> 32, r1, carry, carry);
MP_ADD_CARRY(r2, 0, r2, carry, carry);
MP_ADD_CARRY(r3, a7, r3, carry, carry);
r4 += carry;
/* sum 4 */
- MP_ADD_CARRY(r0, a4h | a5l, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, a4h | a5l, r0, carry);
MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry, carry);
MP_ADD_CARRY(r2, a7, r2, carry, carry);
MP_ADD_CARRY(r3, a6h | a4l, r3, carry, carry);
@@ -362,7 +360,7 @@
while (r4 > 0) {
mp_digit r4_long = r4;
mp_digit r4l = (r4_long << 32);
- MP_ADD_CARRY(r0, r4_long, r0, 0, carry);
+ MP_ADD_CARRY_ZERO(r0, r4_long, r0, carry);
MP_ADD_CARRY(r1, -r4l, r1, carry, carry);
MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry, carry);
MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry, carry);
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_384.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_384.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_521.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_521.c Tue Feb 08 14:25:33 2011 -0800
@@ -50,12 +50,10 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mpi.h"
#include "mplogic.h"
@@ -74,7 +72,7 @@
{
mp_err res = MP_OKAY;
int a_bits = mpl_significant_bits(a);
- int i;
+ unsigned int i;
/* m1, m2 are statically-allocated mp_int of exactly the size we need */
mp_int m1;
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_aff.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_aff.c Tue Feb 08 14:25:33 2011 -0800
@@ -59,8 +59,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mplogic.h"
#ifndef _KERNEL
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_jac.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_jac.c Tue Feb 08 14:25:33 2011 -0800
@@ -59,8 +59,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "mplogic.h"
#ifndef _KERNEL
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_jm.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_jm.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ecp.h"
#include "ecl-priv.h"
#include "mplogic.h"
--- a/jdk/src/share/native/sun/security/ec/impl/ecp_mont.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_mont.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,8 +54,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* Uses Montgomery reduction for field arithmetic. See mpi/mpmontg.c for
* code implementation. */
--- a/jdk/src/share/native/sun/security/ec/impl/logtab.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/logtab.h Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _LOGTAB_H
#define _LOGTAB_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
const float s_logv_2[] = {
0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f, /* 0 1 2 3 */
0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f, /* 4 5 6 7 */
--- a/jdk/src/share/native/sun/security/ec/impl/mp_gf2m-priv.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mp_gf2m-priv.h Tue Feb 08 14:25:33 2011 -0800
@@ -58,8 +58,6 @@
#ifndef _MP_GF2M_PRIV_H_
#define _MP_GF2M_PRIV_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi-priv.h"
extern const mp_digit mp_gf2m_sqr_tb[16];
--- a/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.c Tue Feb 08 14:25:33 2011 -0800
@@ -55,8 +55,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mp_gf2m.h"
#include "mp_gf2m-priv.h"
#include "mplogic.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.h Tue Feb 08 14:25:33 2011 -0800
@@ -58,8 +58,6 @@
#ifndef _MP_GF2M_H_
#define _MP_GF2M_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
mp_err mp_badd(const mp_int *a, const mp_int *b, mp_int *c);
--- a/jdk/src/share/native/sun/security/ec/impl/mpi-config.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi-config.h Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _MPI_CONFIG_H
#define _MPI_CONFIG_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpi-config.h,v 1.5 2004/04/25 15:03:10 gerv%gerv.net Exp $ */
/*
--- a/jdk/src/share/native/sun/security/ec/impl/mpi-priv.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi-priv.h Tue Feb 08 14:25:33 2011 -0800
@@ -63,8 +63,6 @@
#ifndef _MPI_PRIV_H
#define _MPI_PRIV_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpi-priv.h,v 1.20 2005/11/22 07:16:43 relyea%netscape.com Exp $ */
#include "mpi.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mpi.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi.c Tue Feb 08 14:25:33 2011 -0800
@@ -54,12 +54,10 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpi.c,v 1.45 2006/09/29 20:12:21 alexei.volkov.bugs%sun.com Exp $ */
#include "mpi-priv.h"
@@ -1148,7 +1146,7 @@
mp_int s, x;
mp_err res;
mp_digit d;
- int dig, bit;
+ unsigned int dig, bit;
ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
@@ -1523,7 +1521,7 @@
mp_int s, x, mu;
mp_err res;
mp_digit d;
- int dig, bit;
+ unsigned int dig, bit;
ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
@@ -2057,7 +2055,7 @@
{
mp_digit d;
mp_size n = 0;
- int ix;
+ unsigned int ix;
if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
return n;
@@ -2900,9 +2898,9 @@
/* Allocate ni records of nb bytes each, and return a pointer to that */
void *s_mp_alloc(size_t nb, size_t ni, int kmflag)
{
- mp_int *mp;
++mp_allocs;
#ifdef _KERNEL
+ mp_int *mp;
mp = kmem_zalloc(nb * ni, kmflag);
if (mp != NULL)
FLAG(mp) = kmflag;
@@ -3112,7 +3110,7 @@
mp_err s_mp_mul_2(mp_int *mp)
{
mp_digit *pd;
- int ix, used;
+ unsigned int ix, used;
mp_digit kin = 0;
/* Shift digits leftward by 1 bit */
@@ -4663,7 +4661,7 @@
{
char ch;
- if(val >= r)
+ if(val >= (unsigned int)r)
return 0;
ch = s_dmap_1[val];
@@ -4778,7 +4776,7 @@
mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
{
int ix, pos = 0;
- int bytes;
+ unsigned int bytes;
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
@@ -4810,7 +4808,7 @@
mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
{
int ix, pos = 0;
- int bytes;
+ unsigned int bytes;
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
@@ -4850,7 +4848,7 @@
mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
{
int ix, pos = 0;
- int bytes;
+ unsigned int bytes;
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
--- a/jdk/src/share/native/sun/security/ec/impl/mpi.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi.h Tue Feb 08 14:25:33 2011 -0800
@@ -60,8 +60,6 @@
#ifndef _MPI_H
#define _MPI_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpi.h,v 1.22 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
#include "mpi-config.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mplogic.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mplogic.c Tue Feb 08 14:25:33 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mplogic.c,v 1.15 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
#include "mpi-priv.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mplogic.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mplogic.h Tue Feb 08 14:25:33 2011 -0800
@@ -59,8 +59,6 @@
#ifndef _MPLOGIC_H
#define _MPLOGIC_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mplogic.h,v 1.7 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
#include "mpi.h"
--- a/jdk/src/share/native/sun/security/ec/impl/mpmontg.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpmontg.c Tue Feb 08 14:25:33 2011 -0800
@@ -56,8 +56,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* $Id: mpmontg.c,v 1.20 2006/08/29 02:41:38 nelson%bolyard.com Exp $ */
/* This file implements moduluar exponentiation using Montgomery's
--- a/jdk/src/share/native/sun/security/ec/impl/mpprime.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/mpprime.h Tue Feb 08 14:25:33 2011 -0800
@@ -60,8 +60,6 @@
#ifndef _MP_PRIME_H
#define _MP_PRIME_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mpi.h"
extern const int prime_tab_size; /* number of primes available */
--- a/jdk/src/share/native/sun/security/ec/impl/oid.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/oid.c Tue Feb 08 14:25:33 2011 -0800
@@ -50,12 +50,10 @@
*
*********************************************************************** */
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#ifndef _WIN32
@@ -433,8 +431,7 @@
SECOID_FindOID(const SECItem *oid)
{
SECOidData *po;
- SECOidData *ret;
- int i;
+ SECOidData *ret = NULL;
if (oid->len == 8) {
if (oid->data[6] == 0x00) {
@@ -454,8 +451,6 @@
po = &SECG_oids[oid->data[4]];
if (memcmp(oid->data, po->oid.data, 5) == 0)
ret = po;
- } else {
- ret = NULL;
}
return(ret);
}
--- a/jdk/src/share/native/sun/security/ec/impl/secitem.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/secitem.c Tue Feb 08 14:25:33 2011 -0800
@@ -53,8 +53,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Support routines for SECItem data structure.
*
--- a/jdk/src/share/native/sun/security/ec/impl/secoidt.h Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/native/sun/security/ec/impl/secoidt.h Tue Feb 08 14:25:33 2011 -0800
@@ -57,8 +57,6 @@
#ifndef _SECOIDT_H_
#define _SECOIDT_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* secoidt.h - public data structures for ASN.1 OID functions
*
--- a/jdk/src/share/sample/nio/file/AclEdit.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/sample/nio/file/AclEdit.java Tue Feb 08 14:25:33 2011 -0800
@@ -239,7 +239,7 @@
// read file's ACL
AclFileAttributeView view =
- file.getFileAttributeView(AclFileAttributeView.class);
+ Files.getFileAttributeView(file, AclFileAttributeView.class);
if (view == null) {
System.err.println("ACLs not supported on this platform");
System.exit(-1);
--- a/jdk/src/share/sample/nio/file/Chmod.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/sample/nio/file/Chmod.java Tue Feb 08 14:25:33 2011 -0800
@@ -264,11 +264,10 @@
/**
* Changes the permissions of the file using the given Changer.
*/
- static void chmod(FileRef file, Changer changer) {
+ static void chmod(Path file, Changer changer) {
try {
- Set<PosixFilePermission> perms = Attributes
- .readPosixFileAttributes(file).permissions();
- Attributes.setPosixFilePermissions(file, changer.change(perms));
+ Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
+ Files.setPosixFilePermissions(file, changer.change(perms));
} catch (IOException x) {
System.err.println(x);
}
@@ -277,7 +276,7 @@
/**
* Changes the permission of each file and directory visited
*/
- static class TreeVisitor implements FileVisitor<FileRef> {
+ static class TreeVisitor implements FileVisitor<Path> {
private final Changer changer;
TreeVisitor(Changer changer) {
@@ -285,26 +284,26 @@
}
@Override
- public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
chmod(dir, changer);
return CONTINUE;
}
@Override
- public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
chmod(file, changer);
return CONTINUE;
}
@Override
- public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
if (exc != null)
System.err.println("WARNING: " + exc);
return CONTINUE;
}
@Override
- public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
+ public FileVisitResult visitFileFailed(Path file, IOException exc) {
System.err.println("WARNING: " + exc);
return CONTINUE;
}
--- a/jdk/src/share/sample/nio/file/Copy.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/sample/nio/file/Copy.java Tue Feb 08 14:25:33 2011 -0800
@@ -45,7 +45,7 @@
/**
* Returns {@code true} if okay to overwrite a file ("cp -i")
*/
- static boolean okayToOverwrite(FileRef file) {
+ static boolean okayToOverwrite(Path file) {
String answer = System.console().readLine("overwrite %s (yes/no)? ", file);
return (answer.equalsIgnoreCase("y") || answer.equalsIgnoreCase("yes"));
}
@@ -59,9 +59,9 @@
CopyOption[] options = (preserve) ?
new CopyOption[] { COPY_ATTRIBUTES, REPLACE_EXISTING } :
new CopyOption[] { REPLACE_EXISTING };
- if (!prompt || target.notExists() || okayToOverwrite(target)) {
+ if (!prompt || Files.notExists(target) || okayToOverwrite(target)) {
try {
- source.copyTo(target, options);
+ Files.copy(source, target, options);
} catch (IOException x) {
System.err.format("Unable to copy: %s: %s%n", source, x);
}
@@ -93,7 +93,7 @@
Path newdir = target.resolve(source.relativize(dir));
try {
- dir.copyTo(newdir, options);
+ Files.copy(dir, newdir, options);
} catch (FileAlreadyExistsException x) {
// ignore
} catch (IOException x) {
@@ -116,8 +116,8 @@
if (exc == null && preserve) {
Path newdir = target.resolve(source.relativize(dir));
try {
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
- Attributes.setLastModifiedTime(newdir, attrs.lastModifiedTime());
+ FileTime time = Files.getLastModifiedTime(dir);
+ Files.setLastModifiedTime(newdir, time);
} catch (IOException x) {
System.err.format("Unable to copy all attributes to: %s: %s%n", newdir, x);
}
@@ -180,16 +180,11 @@
Path target = Paths.get(args[argi]);
// check if target is a directory
- boolean isDir = false;
- try {
- isDir = Attributes.readBasicFileAttributes(target).isDirectory();
- } catch (IOException x) {
- // ignore (probably target does not exist)
- }
+ boolean isDir = Files.isDirectory(target);
// copy each source file/directory to target
for (i=0; i<source.length; i++) {
- Path dest = (isDir) ? target.resolve(source[i].getName()) : target;
+ Path dest = (isDir) ? target.resolve(source[i].getFileName()) : target;
if (recursive) {
// follow links when copying files
@@ -198,13 +193,9 @@
Files.walkFileTree(source[i], opts, Integer.MAX_VALUE, tc);
} else {
// not recursive so source must not be a directory
- try {
- if (Attributes.readBasicFileAttributes(source[i]).isDirectory()) {
- System.err.format("%s: is a directory%n", source[i]);
- continue;
- }
- } catch (IOException x) {
- // assume not directory
+ if (Files.isDirectory(source[i])) {
+ System.err.format("%s: is a directory%n", source[i]);
+ continue;
}
copyFile(source[i], dest, prompt, preserve);
}
--- a/jdk/src/share/sample/nio/file/DiskUsage.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/sample/nio/file/DiskUsage.java Tue Feb 08 14:25:33 2011 -0800
@@ -43,11 +43,9 @@
static final long K = 1024;
static void printFileStore(FileStore store) throws IOException {
- FileStoreSpaceAttributes attrs = Attributes.readFileStoreSpaceAttributes(store);
-
- long total = attrs.totalSpace() / K;
- long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / K;
- long avail = attrs.usableSpace() / K;
+ long total = store.getTotalSpace() / K;
+ long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / K;
+ long avail = store.getUsableSpace() / K;
String s = store.toString();
if (s.length() > 20) {
@@ -66,7 +64,7 @@
}
} else {
for (String file: args) {
- FileStore store = Paths.get(file).getFileStore();
+ FileStore store = Files.getFileStore(Paths.get(file));
printFileStore(store);
}
}
--- a/jdk/src/share/sample/nio/file/FileType.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/sample/nio/file/FileType.java Tue Feb 08 14:25:33 2011 -0800
@@ -30,7 +30,6 @@
*/
import java.nio.file.*;
-import java.nio.file.attribute.*;
import java.io.IOException;
public class FileType {
@@ -41,10 +40,8 @@
}
for (String arg: args) {
Path file = Paths.get(arg);
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
-
String type;
- if (attrs.isDirectory()) {
+ if (Files.isDirectory(file)) {
type = "directory";
} else {
type = Files.probeContentType(file);
--- a/jdk/src/share/sample/nio/file/WatchDir.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/sample/nio/file/WatchDir.java Tue Feb 08 14:25:33 2011 -0800
@@ -58,7 +58,7 @@
private void register(Path dir) throws IOException {
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
if (trace) {
- FileRef prev = keys.get(key);
+ Path prev = keys.get(key);
if (prev == null) {
System.out.format("register: %s\n", dir);
} else {
@@ -147,7 +147,7 @@
// register it and its sub-directories
if (recursive && (kind == ENTRY_CREATE)) {
try {
- if (Attributes.readBasicFileAttributes(child, NOFOLLOW_LINKS).isDirectory()) {
+ if (Files.isDirectory(child, NOFOLLOW_LINKS)) {
registerAll(child);
}
} catch (IOException x) {
--- a/jdk/src/share/sample/nio/file/Xdd.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/share/sample/nio/file/Xdd.java Tue Feb 08 14:25:33 2011 -0800
@@ -58,14 +58,14 @@
Paths.get(args[0]) : Paths.get(args[2]);
// check that user defined attributes are supported by the file store
- FileStore store = file.getFileStore();
+ FileStore store = Files.getFileStore(file);
if (!store.supportsFileAttributeView(UserDefinedFileAttributeView.class)) {
System.err.format("UserDefinedFileAttributeView not supported on %s\n", store);
System.exit(-1);
}
- UserDefinedFileAttributeView view = file.
- getFileAttributeView(UserDefinedFileAttributeView.class);
+ UserDefinedFileAttributeView view =
+ Files.getFileAttributeView(file, UserDefinedFileAttributeView.class);
// list user defined attributes
if (args.length == 1) {
--- a/jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,7 +25,7 @@
package sun.nio.fs;
-import java.nio.file.FileRef;
+import java.nio.file.Path;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -57,7 +57,7 @@
}
@Override
- public String implProbeContentType(FileRef obj) throws IOException {
+ public String implProbeContentType(Path obj) throws IOException {
if (!gioAvailable && !gnomeVfsAvailable)
return null;
if (!(obj instanceof UnixPath))
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -67,19 +67,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(READONLY_NAME))
- return readAttributes().isReadOnly();
- if (attribute.equals(ARCHIVE_NAME))
- return readAttributes().isArchive();
- if (attribute.equals(SYSTEM_NAME))
- return readAttributes().isSystem();
- if (attribute.equals(HIDDEN_NAME))
- return readAttributes().isHidden();
- return super.getAttribute(attribute);
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -103,7 +90,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes)
+ public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java Tue Feb 08 14:25:33 2011 -0800
@@ -26,7 +26,6 @@
package sun.nio.fs;
import java.nio.file.*;
-import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.*;
import java.security.AccessController;
@@ -76,39 +75,14 @@
}
}
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
- UnixPath file,
- LinkOption... options)
- {
- if (view == DosFileAttributeView.class)
- return (V) new LinuxDosFileAttributeView(file, followLinks(options));
- if (view == UserDefinedFileAttributeView.class)
- return (V) new LinuxUserDefinedFileAttributeView(file, followLinks(options));
- return super.newFileAttributeView(view, file, options);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public DynamicFileAttributeView newFileAttributeView(String name,
- UnixPath file,
- LinkOption... options)
- {
- if (name.equals("dos"))
- return new LinuxDosFileAttributeView(file, followLinks(options));
- if (name.equals("user"))
- return new LinuxUserDefinedFileAttributeView(file, followLinks(options));
- return super.newFileAttributeView(name, file, options);
- }
// lazy initialization of the list of supported attribute views
private static class SupportedFileFileAttributeViewsHolder {
static final Set<String> supportedFileAttributeViews =
supportedFileAttributeViews();
private static Set<String> supportedFileAttributeViews() {
- Set<String> result = new HashSet<String>();
- result.addAll(UnixFileSystem.standardFileAttributeViews());
+ Set<String> result = new HashSet<>();
+ result.addAll(standardFileAttributeViews());
// additional Linux-specific views
result.add("dos");
result.add("user");
@@ -130,7 +104,7 @@
* Returns object to iterate over the mount entries in the given fstab file.
*/
Iterable<UnixMountEntry> getMountEntries(String fstab) {
- ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
+ ArrayList<UnixMountEntry> entries = new ArrayList<>();
try {
long fp = setmntent(fstab.getBytes(), "r".getBytes());
try {
@@ -159,10 +133,7 @@
return getMountEntries("/etc/mtab");
}
- @Override
- FileStore getFileStore(UnixPath path) throws IOException {
- return new LinuxFileStore(path);
- }
+
@Override
FileStore getFileStore(UnixMountEntry entry) throws IOException {
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,6 +25,10 @@
package sun.nio.fs;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
/**
* Linux implementation of FileSystemProvider
*/
@@ -38,4 +42,58 @@
LinuxFileSystem newFileSystem(String dir) {
return new LinuxFileSystem(this, dir);
}
+
+ @Override
+ LinuxFileStore getFileStore(UnixPath path) throws IOException {
+ return new LinuxFileStore(path);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+ Class<V> type,
+ LinkOption... options)
+ {
+ if (type == DosFileAttributeView.class) {
+ return (V) new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ if (type == UserDefinedFileAttributeView.class) {
+ return (V) new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ return super.getFileAttributeView(obj, type, options);
+ }
+
+ @Override
+ public DynamicFileAttributeView getFileAttributeView(Path obj,
+ String name,
+ LinkOption... options)
+ {
+ if (name.equals("dos")) {
+ return new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ if (name.equals("user")) {
+ return new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ return super.getFileAttributeView(obj, name, options);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ if (type == DosFileAttributes.class) {
+ DosFileAttributeView view =
+ getFileAttributeView(file, DosFileAttributeView.class, options);
+ return (A) view.readAttributes();
+ } else {
+ return super.readAttributes(file, type, options);
+ }
+ }
}
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -63,7 +63,7 @@
// Parses buffer as array of NULL-terminated C strings.
private List<String> asList(long address, int size) {
- final List<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<>();
int start = 0;
int pos = 0;
while (pos < size) {
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java Tue Feb 08 14:25:33 2011 -0800
@@ -102,8 +102,8 @@
// watch descriptor
private volatile int wd;
- LinuxWatchKey(LinuxWatchService watcher, int ifd, int wd) {
- super(watcher);
+ LinuxWatchKey(UnixPath dir, LinuxWatchService watcher, int ifd, int wd) {
+ super(dir, watcher);
this.ifd = ifd;
this.wd = wd;
}
@@ -266,7 +266,7 @@
// ensure watch descriptor is in map
LinuxWatchKey key = wdToKey.get(wd);
if (key == null) {
- key = new LinuxWatchKey(watcher, ifd, wd);
+ key = new LinuxWatchKey(dir, watcher, ifd, wd);
wdToKey.put(wd, key);
}
return key;
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -198,7 +198,7 @@
* Decode the buffer, returning an ACL
*/
private static List<AclEntry> decode(long address, int n) {
- ArrayList<AclEntry> acl = new ArrayList<AclEntry>(n);
+ ArrayList<AclEntry> acl = new ArrayList<>(n);
for (int i=0; i<n; i++) {
long offset = address + i*SIZEOF_ACE_T;
@@ -244,7 +244,7 @@
assert false;
}
- HashSet<AclEntryPermission> aceMask = new HashSet<AclEntryPermission>();
+ Set<AclEntryPermission> aceMask = EnumSet.noneOf(AclEntryPermission.class);
if ((mask & ACE_READ_DATA) > 0)
aceMask.add(AclEntryPermission.READ_DATA);
if ((mask & ACE_WRITE_DATA) > 0)
@@ -274,7 +274,7 @@
if ((mask & ACE_SYNCHRONIZE) > 0)
aceMask.add(AclEntryPermission.SYNCHRONIZE);
- HashSet<AclEntryFlag> aceFlags = new HashSet<AclEntryFlag>();
+ Set<AclEntryFlag> aceFlags = EnumSet.noneOf(AclEntryFlag.class);
if ((flags & ACE_FILE_INHERIT_ACE) > 0)
aceFlags.add(AclEntryFlag.FILE_INHERIT);
if ((flags & ACE_DIRECTORY_INHERIT_ACE) > 0)
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java Tue Feb 08 14:25:33 2011 -0800
@@ -26,7 +26,6 @@
package sun.nio.fs;
import java.nio.file.*;
-import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.*;
import java.security.AccessController;
@@ -71,38 +70,14 @@
}
}
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
- UnixPath file, LinkOption... options)
- {
- if (view == AclFileAttributeView.class)
- return (V) new SolarisAclFileAttributeView(file, followLinks(options));
- if (view == UserDefinedFileAttributeView.class) {
- return(V) new SolarisUserDefinedFileAttributeView(file, followLinks(options));
- }
- return super.newFileAttributeView(view, file, options);
- }
-
- @Override
- protected DynamicFileAttributeView newFileAttributeView(String name,
- UnixPath file,
- LinkOption... options)
- {
- if (name.equals("acl"))
- return new SolarisAclFileAttributeView(file, followLinks(options));
- if (name.equals("user"))
- return new SolarisUserDefinedFileAttributeView(file, followLinks(options));
- return super.newFileAttributeView(name, file, options);
- }
// lazy initialization of the list of supported attribute views
private static class SupportedFileFileAttributeViewsHolder {
static final Set<String> supportedFileAttributeViews =
supportedFileAttributeViews();
private static Set<String> supportedFileAttributeViews() {
- Set<String> result = new HashSet<String>();
- result.addAll(UnixFileSystem.standardFileAttributeViews());
+ Set<String> result = new HashSet<>();
+ result.addAll(standardFileAttributeViews());
// additional Solaris-specific views
result.add("acl");
result.add("user");
@@ -126,7 +101,7 @@
*/
@Override
Iterable<UnixMountEntry> getMountEntries() {
- ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
+ ArrayList<UnixMountEntry> entries = new ArrayList<>();
try {
UnixPath mnttab = new UnixPath(this, "/etc/mnttab");
long fp = fopen(mnttab, "r");
@@ -148,11 +123,6 @@
}
@Override
- FileStore getFileStore(UnixPath path) throws IOException {
- return new SolarisFileStore(path);
- }
-
- @Override
FileStore getFileStore(UnixMountEntry entry) throws IOException {
return new SolarisFileStore(this, entry);
}
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,6 +25,10 @@
package sun.nio.fs;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
/**
* Solaris implementation of FileSystemProvider
*/
@@ -38,4 +42,41 @@
SolarisFileSystem newFileSystem(String dir) {
return new SolarisFileSystem(this, dir);
}
+
+ @Override
+ SolarisFileStore getFileStore(UnixPath path) throws IOException {
+ return new SolarisFileStore(path);
+ }
+
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+ Class<V> type,
+ LinkOption... options)
+ {
+ if (type == AclFileAttributeView.class) {
+ return (V) new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ if (type == UserDefinedFileAttributeView.class) {
+ return(V) new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ }
+ return super.getFileAttributeView(obj, type, options);
+ }
+
+ @Override
+ public DynamicFileAttributeView getFileAttributeView(Path obj,
+ String name,
+ LinkOption... options)
+ {
+ if (name.equals("acl"))
+ return new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ if (name.equals("user"))
+ return new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+ followLinks(options));
+ return super.getFileAttributeView(obj, name, options);
+ }
}
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -83,7 +83,7 @@
}
// read list of extended attributes
- final List<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<>();
try {
byte[] name;
while ((name = readdir(dp)) != null) {
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java Tue Feb 08 14:25:33 2011 -0800
@@ -128,7 +128,6 @@
private class SolarisWatchKey extends AbstractWatchKey
implements DirectoryNode
{
- private final UnixPath dir;
private final UnixFileKey fileKey;
// pointer to native file_obj object
@@ -147,15 +146,14 @@
long object,
Set<? extends WatchEvent.Kind<?>> events)
{
- super(watcher);
- this.dir = dir;
+ super(dir, watcher);
this.fileKey = fileKey;
this.object = object;
this.events = events;
}
- UnixPath getFileRef() {
- return dir;
+ UnixPath getDirectory() {
+ return (UnixPath)watchable();
}
UnixFileKey getFileKey() {
@@ -487,7 +485,7 @@
*/
void processDirectoryEvents(SolarisWatchKey key, int mask) {
if ((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) {
- registerChildren(key.getFileRef(), key,
+ registerChildren(key.getDirectory(), key,
key.events().contains(StandardWatchEventKind.ENTRY_CREATE));
}
}
@@ -524,7 +522,7 @@
boolean removed = true;
try {
UnixFileAttributes
- .get(key.getFileRef().resolve(node.name()), false);
+ .get(key.getDirectory().resolve(node.name()), false);
removed = false;
} catch (UnixException x) { }
@@ -554,14 +552,14 @@
DirectoryStream<Path> stream = null;
try {
- stream = dir.newDirectoryStream();
+ stream = Files.newDirectoryStream(dir);
} catch (IOException x) {
// nothing we can do
return;
}
try {
for (Path entry: stream) {
- Path name = entry.getName();
+ Path name = entry.getFileName();
// skip entry if already registered
if (parent.getChild(name) != null)
@@ -582,9 +580,9 @@
}
// create node
- EntryNode node = new EntryNode(object, entry.getName(), parent);
+ EntryNode node = new EntryNode(object, entry.getFileName(), parent);
// tell the parent about it
- parent.addChild(entry.getName(), node);
+ parent.addChild(entry.getFileName(), node);
object2Node.put(object, node);
}
} catch (ConcurrentModificationException x) {
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java Tue Feb 08 14:25:33 2011 -0800
@@ -237,7 +237,7 @@
fo = open(target,
(O_WRONLY |
O_CREAT |
- O_TRUNC),
+ O_EXCL),
attrs.mode());
} catch (UnixException x) {
x.rethrowAsIOException(target);
@@ -435,10 +435,8 @@
if (targetAttrs.isDirectory() &&
(x.errno() == EEXIST || x.errno() == ENOTEMPTY))
{
- throw new FileAlreadyExistsException(
- source.getPathForExecptionMessage(),
- target.getPathForExecptionMessage(),
- x.getMessage());
+ throw new DirectoryNotEmptyException(
+ target.getPathForExecptionMessage());
}
x.rethrowAsIOException(target);
}
@@ -556,10 +554,8 @@
if (targetAttrs.isDirectory() &&
(x.errno() == EEXIST || x.errno() == ENOTEMPTY))
{
- throw new FileAlreadyExistsException(
- source.getPathForExecptionMessage(),
- target.getPathForExecptionMessage(),
- x.getMessage());
+ throw new DirectoryNotEmptyException(
+ target.getPathForExecptionMessage());
}
x.rethrowAsIOException(target);
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java Tue Feb 08 14:25:33 2011 -0800
@@ -149,17 +149,6 @@
}
@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
@@ -195,7 +184,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes)
+ public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
@@ -308,27 +297,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(MODE_NAME))
- return readAttributes().mode();
- if (attribute.equals(INO_NAME))
- return readAttributes().ino();
- if (attribute.equals(DEV_NAME))
- 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))
- return readAttributes().gid();
- if (attribute.equals(CTIME_NAME))
- return readAttributes().ctime();
- return super.getAttribute(attribute);
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -348,7 +316,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes)
+ public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java Tue Feb 08 14:25:33 2011 -0800
@@ -124,7 +124,7 @@
@Override
public FileTime creationTime() {
- return null;
+ return lastModifiedTime();
}
@Override
@@ -194,7 +194,7 @@
@Override
public Set<PosixFilePermission> permissions() {
int bits = (st_mode & UnixConstants.S_IAMB);
- HashSet<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
+ HashSet<PosixFilePermission> perms = new HashSet<>();
if ((bits & UnixConstants.S_IRUSR) > 0)
perms.add(PosixFilePermission.OWNER_READ);
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java Tue Feb 08 14:25:33 2011 -0800
@@ -103,28 +103,50 @@
return entry.isReadOnly();
}
+ // uses statvfs to read the file system information
+ private UnixFileStoreAttributes readAttributes() throws IOException {
+ try {
+ return UnixFileStoreAttributes.get(file);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(file);
+ return null; // keep compile happy
+ }
+ }
+
@Override
- @SuppressWarnings("unchecked")
+ public long getTotalSpace() throws IOException {
+ UnixFileStoreAttributes attrs = readAttributes();
+ return attrs.blockSize() * attrs.totalBlocks();
+ }
+
+ @Override
+ public long getUsableSpace() throws IOException {
+ UnixFileStoreAttributes attrs = readAttributes();
+ return attrs.blockSize() * attrs.availableBlocks();
+ }
+
+ @Override
+ public long getUnallocatedSpace() throws IOException {
+ UnixFileStoreAttributes attrs = readAttributes();
+ return attrs.blockSize() * attrs.freeBlocks();
+ }
+
+ @Override
public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> view)
{
if (view == null)
throw new NullPointerException();
- if (view == FileStoreSpaceAttributeView.class)
- return (V) new UnixFileStoreSpaceAttributeView(this);
return (V) null;
}
@Override
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();
+ if (attribute.equals("totalSpace"))
+ return getTotalSpace();
+ if (attribute.equals("usableSpace"))
+ return getUsableSpace();
+ if (attribute.equals("unallocatedSpace"))
+ return getUnallocatedSpace();
throw new UnsupportedOperationException("'" + attribute + "' not recognized");
}
@@ -181,50 +203,6 @@
return sb.toString();
}
- private static class UnixFileStoreSpaceAttributeView
- implements FileStoreSpaceAttributeView
- {
- private final UnixFileStore fs;
-
- UnixFileStoreSpaceAttributeView(UnixFileStore fs) {
- this.fs = fs;
- }
-
- @Override
- public String name() {
- return "space";
- }
-
- @Override
- public FileStoreSpaceAttributes readAttributes()
- throws IOException
- {
- UnixPath file = fs.file();
- final UnixFileStoreAttributes attrs;
- try {
- attrs = UnixFileStoreAttributes.get(file);
- } catch (UnixException x) {
- x.rethrowAsIOException(file);
- return null; // keep compile happy
- }
-
- return new FileStoreSpaceAttributes() {
- @Override
- public long totalSpace() {
- return attrs.blockSize() * attrs.totalBlocks();
- }
- @Override
- public long usableSpace() {
- return attrs.blockSize() * attrs.availableBlocks();
- }
- @Override
- public long unallocatedSpace() {
- return attrs.blockSize() * attrs.freeBlocks();
- }
- };
- }
- }
-
// -- fstypes.properties --
private static final Object loadLock = new Object();
@@ -277,11 +255,8 @@
String fstypes = System.getProperty("java.home") + "/lib/fstypes.properties";
Path file = Paths.get(fstypes);
try {
- ReadableByteChannel rbc = file.newByteChannel();
- try {
+ try (ReadableByteChannel rbc = Files.newByteChannel(file)) {
result.load(Channels.newReader(rbc, "UTF-8"));
- } finally {
- rbc.close();
}
} catch (IOException x) {
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Tue Feb 08 14:25:33 2011 -0800
@@ -98,6 +98,10 @@
return false;
}
+ static List<String> standardFileAttributeViews() {
+ return Arrays.asList("basic", "posix", "unix", "owner");
+ }
+
@Override
public final FileSystemProvider provider() {
return provider;
@@ -169,12 +173,6 @@
abstract Iterable<UnixMountEntry> getMountEntries();
/**
- * Returns a FileStore to represent the file system where the given file
- * reside.
- */
- abstract FileStore getFileStore(UnixPath path) throws IOException;
-
- /**
* Returns a FileStore to represent the file system for the given mount
* mount.
*/
@@ -264,7 +262,22 @@
}
@Override
- public final UnixPath getPath(String path) {
+ public final Path getPath(String first, String... more) {
+ String path;
+ if (more.length == 0) {
+ path = first;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(first);
+ for (String segment: more) {
+ if (segment.length() > 0) {
+ if (sb.length() > 0)
+ sb.append('/');
+ sb.append(segment);
+ }
+ }
+ path = sb.toString();
+ }
return new UnixPath(this, path);
}
@@ -300,77 +313,30 @@
private static final String GLOB_SYNTAX = "glob";
private static final String REGEX_SYNTAX = "regex";
- protected boolean followLinks(LinkOption... options) {
- boolean followLinks = true;
- for (LinkOption option: options) {
- if (option == LinkOption.NOFOLLOW_LINKS) {
- followLinks = false;
- continue;
- }
- if (option == null)
- throw new NullPointerException();
- throw new AssertionError("Should not get here");
- }
- return followLinks;
- }
- @SuppressWarnings("unchecked")
- protected <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
- UnixPath file,
- LinkOption... options)
- {
- if (view == null)
- throw new NullPointerException();
- boolean followLinks = followLinks(options);
- Class<?> c = view;
- if (c == BasicFileAttributeView.class)
- return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
- if (c == PosixFileAttributeView.class)
- return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
- if (c == FileOwnerAttributeView.class)
- return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
- return (V) null;
- }
-
- static List<String> standardFileAttributeViews() {
- return Arrays.asList("basic", "posix", "unix", "owner");
- }
-
- protected DynamicFileAttributeView newFileAttributeView(String name,
- UnixPath file,
- LinkOption... options)
- {
- boolean followLinks = followLinks(options);
- if (name.equals("basic"))
- return UnixFileAttributeViews.createBasicView(file, followLinks);
- if (name.equals("posix"))
- return UnixFileAttributeViews.createPosixView(file, followLinks);
- if (name.equals("unix"))
- return UnixFileAttributeViews.createUnixView(file, followLinks);
- if (name.equals("owner"))
- return UnixFileAttributeViews.createOwnerView(file, followLinks);
- return null;
- }
@Override
public final UserPrincipalLookupService getUserPrincipalLookupService() {
- return theLookupService;
+ return LookupService.instance;
}
- private static final UserPrincipalLookupService theLookupService =
- new UserPrincipalLookupService() {
- @Override
- public UserPrincipal lookupPrincipalByName(String name)
- throws IOException
- {
- return UnixUserPrincipals.lookupUser(name);
- }
+ private static class LookupService {
+ static final UserPrincipalLookupService instance =
+ new UserPrincipalLookupService() {
+ @Override
+ public UserPrincipal lookupPrincipalByName(String name)
+ throws IOException
+ {
+ return UnixUserPrincipals.lookupUser(name);
+ }
- @Override
- public GroupPrincipal lookupPrincipalByGroupName(String group)
- throws IOException
- {
- return UnixUserPrincipals.lookupGroup(group);
- }
- };
+ @Override
+ public GroupPrincipal lookupPrincipalByGroupName(String group)
+ throws IOException
+ {
+ return UnixUserPrincipals.lookupGroup(group);
+ }
+ };
+ }
+
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Tue Feb 08 14:25:33 2011 -0800
@@ -27,21 +27,25 @@
import java.nio.file.*;
import java.nio.file.attribute.*;
-import java.nio.file.spi.FileSystemProvider;
import java.nio.channels.*;
import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.io.IOException;
+import java.io.FilePermission;
import java.util.*;
+import java.security.AccessController;
import sun.nio.ch.ThreadPool;
+import sun.security.util.SecurityConstants;
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
/**
* Base implementation of FileSystemProvider
*/
public abstract class UnixFileSystemProvider
- extends FileSystemProvider
+ extends AbstractFileSystemProvider
{
private static final String USER_DIR = "user.dir";
private final UnixFileSystem theFileSystem;
@@ -93,7 +97,7 @@
return UnixUriUtils.fromUri(theFileSystem, uri);
}
- protected UnixPath checkPath(Path obj) {
+ UnixPath checkPath(Path obj) {
if (obj == null)
throw new NullPointerException();
if (!(obj instanceof UnixPath))
@@ -101,6 +105,76 @@
return (UnixPath)obj;
}
+ boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption option: options) {
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ continue;
+ }
+ if (option == null)
+ throw new NullPointerException();
+ throw new AssertionError("Should not get here");
+ }
+ return followLinks;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+ Class<V> type,
+ LinkOption... options)
+ {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ boolean followLinks = followLinks(options);
+ if (type == BasicFileAttributeView.class)
+ return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
+ if (type == PosixFileAttributeView.class)
+ return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
+ if (type == FileOwnerAttributeView.class)
+ return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
+ if (type == null)
+ throw new NullPointerException();
+ return (V) null;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ Class<? extends BasicFileAttributeView> view;
+ if (type == BasicFileAttributes.class)
+ view = BasicFileAttributeView.class;
+ else if (type == PosixFileAttributes.class)
+ view = PosixFileAttributeView.class;
+ else if (type == null)
+ throw new NullPointerException();
+ else
+ throw new UnsupportedOperationException();
+ return (A) getFileAttributeView(file, view, options).readAttributes();
+ }
+
+ @Override
+ protected DynamicFileAttributeView getFileAttributeView(Path obj,
+ String name,
+ LinkOption... options)
+ {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ boolean followLinks = followLinks(options);
+ if (name.equals("basic"))
+ return UnixFileAttributeViews.createBasicView(file, followLinks);
+ if (name.equals("posix"))
+ return UnixFileAttributeViews.createPosixView(file, followLinks);
+ if (name.equals("unix"))
+ return UnixFileAttributeViews.createUnixView(file, followLinks);
+ if (name.equals("owner"))
+ return UnixFileAttributeViews.createOwnerView(file, followLinks);
+ return null;
+ }
+
@Override
public FileChannel newFileChannel(Path obj,
Set<? extends OpenOption> options,
@@ -136,4 +210,303 @@
return null;
}
}
+
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path obj,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ int mode = UnixFileModeAttribute
+ .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
+ try {
+ return UnixChannelFactory.newFileChannel(file, options, mode);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(file);
+ return null; // keep compiler happy
+ }
+ }
+
+ @Override
+ boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ file.checkDelete();
+
+ // need file attributes to know if file is directory
+ UnixFileAttributes attrs = null;
+ try {
+ attrs = UnixFileAttributes.get(file, false);
+ if (attrs.isDirectory()) {
+ rmdir(file);
+ } else {
+ unlink(file);
+ }
+ return true;
+ } catch (UnixException x) {
+ // no-op if file does not exist
+ if (!failIfNotExists && x.errno() == ENOENT)
+ return false;
+
+ // DirectoryNotEmptyException if not empty
+ if (attrs != null && attrs.isDirectory() &&
+ (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
+ throw new DirectoryNotEmptyException(file.getPathForExecptionMessage());
+
+ x.rethrowAsIOException(file);
+ return false;
+ }
+ }
+
+ @Override
+ public void copy(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ UnixCopyFile.copy(UnixPath.toUnixPath(source),
+ UnixPath.toUnixPath(target),
+ options);
+ }
+
+ @Override
+ public void move(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ UnixCopyFile.move(UnixPath.toUnixPath(source),
+ UnixPath.toUnixPath(target),
+ options);
+ }
+
+ @Override
+ public void checkAccess(Path obj, AccessMode... modes) throws IOException {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ boolean e = false;
+ boolean r = false;
+ boolean w = false;
+ boolean x = false;
+
+ if (modes.length == 0) {
+ e = true;
+ } else {
+ for (AccessMode mode: modes) {
+ switch (mode) {
+ case READ : r = true; break;
+ case WRITE : w = true; break;
+ case EXECUTE : x = true; break;
+ default: throw new AssertionError("Should not get here");
+ }
+ }
+ }
+
+ int mode = 0;
+ if (e || r) {
+ file.checkRead();
+ mode |= (r) ? R_OK : F_OK;
+ }
+ if (w) {
+ file.checkWrite();
+ mode |= W_OK;
+ }
+ if (x) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ // not cached
+ sm.checkExec(file.getPathForPermissionCheck());
+ }
+ mode |= X_OK;
+ }
+ try {
+ access(file, mode);
+ } catch (UnixException exc) {
+ exc.rethrowAsIOException(file);
+ }
+ }
+
+ @Override
+ public boolean isSameFile(Path obj1, Path obj2) throws IOException {
+ UnixPath file1 = UnixPath.toUnixPath(obj1);
+ if (file1.equals(obj2))
+ return true;
+ if (obj2 == null)
+ throw new NullPointerException();
+ if (!(obj2 instanceof UnixPath))
+ return false;
+ UnixPath file2 = (UnixPath)obj2;
+
+ // check security manager access to both files
+ file1.checkRead();
+ file2.checkRead();
+
+ UnixFileAttributes attrs1;
+ UnixFileAttributes attrs2;
+ try {
+ attrs1 = UnixFileAttributes.get(file1, true);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(file1);
+ return false; // keep compiler happy
+ }
+ try {
+ attrs2 = UnixFileAttributes.get(file2, true);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(file2);
+ return false; // keep compiler happy
+ }
+ return attrs1.isSameFile(attrs2);
+ }
+
+ @Override
+ public boolean isHidden(Path obj) {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ file.checkRead();
+ UnixPath name = file.getFileName();
+ if (name == null)
+ return false;
+ return (name.asByteArray()[0] == '.');
+ }
+
+ /**
+ * Returns a FileStore to represent the file system where the given file
+ * reside.
+ */
+ abstract FileStore getFileStore(UnixPath path) throws IOException;
+
+ @Override
+ public FileStore getFileStore(Path obj) throws IOException {
+ UnixPath file = UnixPath.toUnixPath(obj);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+ file.checkRead();
+ }
+ return getFileStore(file);
+ }
+
+ @Override
+ public void createDirectory(Path obj, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ UnixPath dir = UnixPath.toUnixPath(obj);
+ dir.checkWrite();
+
+ int mode = UnixFileModeAttribute
+ .toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
+ try {
+ mkdir(dir, mode);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(dir);
+ }
+ }
+
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ UnixPath dir = UnixPath.toUnixPath(obj);
+ dir.checkRead();
+ if (filter == null)
+ throw new NullPointerException();
+
+ // can't return SecureDirectoryStream on kernels that don't support
+ // openat, etc.
+ if (!supportsAtSysCalls()) {
+ try {
+ long ptr = opendir(dir);
+ return new UnixDirectoryStream(dir, ptr, filter);
+ } catch (UnixException x) {
+ if (x.errno() == ENOTDIR)
+ throw new NotDirectoryException(dir.getPathForExecptionMessage());
+ x.rethrowAsIOException(dir);
+ }
+ }
+
+ // open directory and dup file descriptor for use by
+ // opendir/readdir/closedir
+ int dfd1 = -1;
+ int dfd2 = -1;
+ long dp = 0L;
+ try {
+ dfd1 = open(dir, O_RDONLY, 0);
+ dfd2 = dup(dfd1);
+ dp = fdopendir(dfd1);
+ } catch (UnixException x) {
+ if (dfd1 != -1)
+ UnixNativeDispatcher.close(dfd1);
+ if (dfd2 != -1)
+ UnixNativeDispatcher.close(dfd2);
+ if (x.errno() == UnixConstants.ENOTDIR)
+ throw new NotDirectoryException(dir.getPathForExecptionMessage());
+ x.rethrowAsIOException(dir);
+ }
+ return new UnixSecureDirectoryStream(dir, dp, dfd2, filter);
+ }
+
+ @Override
+ public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ UnixPath link = UnixPath.toUnixPath(obj1);
+ UnixPath target = UnixPath.toUnixPath(obj2);
+
+ // no attributes supported when creating links
+ if (attrs.length > 0) {
+ UnixFileModeAttribute.toUnixMode(0, attrs); // may throw NPE or UOE
+ throw new UnsupportedOperationException("Initial file attributes" +
+ "not supported when creating symbolic link");
+ }
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new LinkPermission("symbolic"));
+ link.checkWrite();
+ }
+
+ // create link
+ try {
+ symlink(target.asByteArray(), link);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(link);
+ }
+ }
+
+ @Override
+ public void createLink(Path obj1, Path obj2) throws IOException {
+ UnixPath link = UnixPath.toUnixPath(obj1);
+ UnixPath existing = UnixPath.toUnixPath(obj2);
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new LinkPermission("hard"));
+ link.checkWrite();
+ existing.checkWrite();
+ }
+ try {
+ link(existing, link);
+ } catch (UnixException x) {
+ x.rethrowAsIOException(link, existing);
+ }
+ }
+
+ @Override
+ public Path readSymbolicLink(Path obj1) throws IOException {
+ UnixPath link = UnixPath.toUnixPath(obj1);
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
+ SecurityConstants.FILE_READLINK_ACTION);
+ AccessController.checkPermission(perm);
+ }
+ try {
+ byte[] target = readlink(link);
+ return new UnixPath(link.getFileSystem(), target);
+ } catch (UnixException x) {
+ if (x.errno() == UnixConstants.EINVAL)
+ throw new NotLinkException(link.getPathForExecptionMessage());
+ x.rethrowAsIOException(link);
+ return null; // keep compiler happy
+ }
+ }
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Tue Feb 08 14:25:33 2011 -0800
@@ -27,15 +27,11 @@
import java.nio.*;
import java.nio.file.*;
-import java.nio.file.attribute.*;
import java.nio.charset.*;
-import java.nio.channels.*;
-import java.security.AccessController;
import java.io.*;
import java.net.URI;
import java.util.*;
import java.lang.ref.SoftReference;
-import sun.security.util.SecurityConstants;
import static sun.nio.fs.UnixNativeDispatcher.*;
import static sun.nio.fs.UnixConstants.*;
@@ -79,8 +75,6 @@
// removes redundant slashes and check input for invalid characters
static String normalizeAndCheck(String input) {
int n = input.length();
- if (n == 0)
- throw new InvalidPathException(input, "Path is empty");
char prevChar = 0;
for (int i=0; i < n; i++) {
char c = input.charAt(i);
@@ -174,7 +168,13 @@
if (getFileSystem().needToResolveAgainstDefaultDirectory()) {
return resolve(getFileSystem().defaultDirectory(), path);
} else {
- return path;
+ if (!isEmpty()) {
+ return path;
+ } else {
+ // empty path case will access current directory
+ byte[] here = { '.' };
+ return here;
+ }
}
}
@@ -193,7 +193,7 @@
}
// Checks that the given file is a UnixPath
- private UnixPath checkPath(FileRef obj) {
+ static UnixPath toUnixPath(Path obj) {
if (obj == null)
throw new NullPointerException();
if (!(obj instanceof UnixPath))
@@ -209,12 +209,17 @@
// count names
count = 0;
index = 0;
- while (index < path.length) {
- byte c = path[index++];
- if (c != '/') {
- count++;
- while (index < path.length && path[index] != '/')
- index++;
+ if (isEmpty()) {
+ // empty path has one name
+ count = 1;
+ } else {
+ while (index < path.length) {
+ byte c = path[index++];
+ if (c != '/') {
+ count++;
+ while (index < path.length && path[index] != '/')
+ index++;
+ }
}
}
@@ -239,6 +244,16 @@
}
}
+ // returns {@code true} if this path is an empty path
+ private boolean isEmpty() {
+ return path.length == 0;
+ }
+
+ // returns an empty path
+ private UnixPath emptyPath() {
+ return new UnixPath(getFileSystem(), new byte[0]);
+ }
+
@Override
public UnixFileSystem getFileSystem() {
return fs;
@@ -246,7 +261,7 @@
@Override
public UnixPath getRoot() {
- if (path[0] == '/') {
+ if (path.length > 0 && path[0] == '/') {
return getFileSystem().rootDirectory();
} else {
return null;
@@ -254,14 +269,17 @@
}
@Override
- public UnixPath getName() {
+ public UnixPath getFileName() {
initOffsets();
int count = offsets.length;
+
+ // no elements so no name
if (count == 0)
- return null; // no elements so no name
+ return null;
- if (count == 1 && path[0] != '/')
+ // one name element and no root component
+ if (count == 1 && path.length > 0 && path[0] != '/')
return this;
int lastOffset = offsets[count-1];
@@ -349,57 +367,58 @@
@Override
public boolean isAbsolute() {
- return (path[0] == '/');
+ return (path.length > 0 && path[0] == '/');
}
// Resolve child against given base
private static byte[] resolve(byte[] base, byte[] child) {
- if (child[0] == '/')
+ int baseLength = base.length;
+ int childLength = child.length;
+ if (childLength == 0)
+ return base;
+ if (baseLength == 0 || child[0] == '/')
return child;
byte[] result;
- if (base.length == 1 && base[0] == '/') {
- result = new byte[child.length + 1];
+ if (baseLength == 1 && base[0] == '/') {
+ result = new byte[childLength + 1];
result[0] = '/';
- System.arraycopy(child, 0, result, 1, child.length);
+ System.arraycopy(child, 0, result, 1, childLength);
} else {
- result = new byte[base.length + 1 + child.length];
- System.arraycopy(base, 0, result, 0, base.length);
+ result = new byte[baseLength + 1 + childLength];
+ System.arraycopy(base, 0, result, 0, baseLength);
result[base.length] = '/';
- System.arraycopy(child, 0, result, base.length+1, child.length);
+ System.arraycopy(child, 0, result, baseLength+1, childLength);
}
return result;
}
@Override
public UnixPath resolve(Path obj) {
- if (obj == null)
- return this;
- byte[] other = checkPath(obj).path;
- if (other[0] == '/')
+ byte[] other = toUnixPath(obj).path;
+ if (other.length > 0 && other[0] == '/')
return ((UnixPath)obj);
byte[] result = resolve(path, other);
return new UnixPath(getFileSystem(), result);
}
- @Override
- public UnixPath resolve(String other) {
- return resolve(new UnixPath(getFileSystem(), other));
- }
-
UnixPath resolve(byte[] other) {
return resolve(new UnixPath(getFileSystem(), other));
}
@Override
public UnixPath relativize(Path obj) {
- UnixPath other = checkPath(obj);
+ UnixPath other = toUnixPath(obj);
if (other.equals(this))
- return null;
+ return emptyPath();
// can only relativize paths of the same type
if (this.isAbsolute() != other.isAbsolute())
throw new IllegalArgumentException("'other' is different type of Path");
+ // this path is the empty path
+ if (this.isEmpty())
+ return other;
+
int bn = this.getNameCount();
int cn = other.getNameCount();
@@ -419,14 +438,27 @@
if (dotdots == 0)
return remainder;
+ // other is the empty path
+ boolean isOtherEmpty = other.isEmpty();
+
// result is a "../" for each remaining name in base
- // followed by the remaining names in other
- byte[] result = new byte[dotdots*3 + remainder.path.length];
+ // followed by the remaining names in other. If the remainder is
+ // the empty path then we don't add the final trailing slash.
+ int len = dotdots*3 + remainder.path.length;
+ if (isOtherEmpty) {
+ assert remainder.isEmpty();
+ len--;
+ }
+ byte[] result = new byte[len];
int pos = 0;
while (dotdots > 0) {
result[pos++] = (byte)'.';
result[pos++] = (byte)'.';
- result[pos++] = (byte)'/';
+ if (isOtherEmpty) {
+ if (dotdots > 1) result[pos++] = (byte)'/';
+ } else {
+ result[pos++] = (byte)'/';
+ }
dotdots--;
}
System.arraycopy(remainder.path, 0, result, pos, remainder.path.length);
@@ -457,7 +489,7 @@
int[] size = new int[count]; // length of name
int remaining = count; // number of names remaining
boolean hasDotDot = false; // has at least one ..
- boolean isAbsolute = path[0] == '/';
+ boolean isAbsolute = isAbsolute();
// first pass:
// 1. compute length of names
@@ -542,7 +574,7 @@
// corner case - all names removed
if (remaining == 0) {
- return isAbsolute ? getFileSystem().rootDirectory() : null;
+ return isAbsolute ? getFileSystem().rootDirectory() : emptyPath();
}
// compute length of result
@@ -574,7 +606,7 @@
@Override
public boolean startsWith(Path other) {
- UnixPath that = checkPath(other);
+ UnixPath that = toUnixPath(other);
// other path is longer
if (that.path.length > path.length)
@@ -584,8 +616,9 @@
int thatOffsetCount = that.getNameCount();
// other path has no name elements
- if (thatOffsetCount == 0 && this.isAbsolute())
- return true;
+ if (thatOffsetCount == 0 && this.isAbsolute()) {
+ return that.isEmpty() ? false : true;
+ }
// given path has more elements that this path
if (thatOffsetCount > thisOffsetCount)
@@ -622,7 +655,7 @@
@Override
public boolean endsWith(Path other) {
- UnixPath that = checkPath(other);
+ UnixPath that = toUnixPath(other);
int thisLen = path.length;
int thatLen = that.path.length;
@@ -631,6 +664,10 @@
if (thatLen > thisLen)
return false;
+ // other path is the empty path
+ if (thisLen > 0 && thatLen == 0)
+ return false;
+
// other path is absolute so this path must be absolute
if (that.isAbsolute() && !this.isAbsolute())
return false;
@@ -721,32 +758,6 @@
return stringValue;
}
- @Override
- public Iterator<Path> iterator() {
- initOffsets();
- return new Iterator<Path>() {
- int i = 0;
- @Override
- public boolean hasNext() {
- return (i < offsets.length);
- }
- @Override
- public Path next() {
- if (i < offsets.length) {
- Path result = getName(i);
- i++;
- return result;
- } else {
- throw new NoSuchElementException();
- }
- }
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-
// -- file operations --
// package-private
@@ -770,7 +781,6 @@
}
}
-
void checkRead() {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
@@ -790,296 +800,6 @@
}
@Override
- public FileStore getFileStore()
- throws IOException
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
- checkRead();
- }
- return getFileSystem().getFileStore(this);
- }
-
- @Override
- public void checkAccess(AccessMode... modes) throws IOException {
- boolean e = false;
- boolean r = false;
- boolean w = false;
- boolean x = false;
-
- if (modes.length == 0) {
- e = true;
- } else {
- for (AccessMode mode: modes) {
- switch (mode) {
- case READ : r = true; break;
- case WRITE : w = true; break;
- case EXECUTE : x = true; break;
- default: throw new AssertionError("Should not get here");
- }
- }
- }
-
- int mode = 0;
- if (e || r) {
- checkRead();
- mode |= (r) ? R_OK : F_OK;
- }
- if (w) {
- checkWrite();
- mode |= W_OK;
- }
- if (x) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- // not cached
- sm.checkExec(getPathForPermissionCheck());
- }
- mode |= X_OK;
- }
- try {
- access(this, mode);
- } catch (UnixException exc) {
- exc.rethrowAsIOException(this);
- }
- }
-
- @Override
- void implDelete(boolean failIfNotExists) throws IOException {
- checkDelete();
-
- // need file attributes to know if file is directory
- UnixFileAttributes attrs = null;
- try {
- attrs = UnixFileAttributes.get(this, false);
- if (attrs.isDirectory()) {
- rmdir(this);
- } else {
- unlink(this);
- }
- } catch (UnixException x) {
- // no-op if file does not exist
- if (!failIfNotExists && x.errno() == ENOENT)
- return;
-
- // DirectoryNotEmptyException if not empty
- if (attrs != null && attrs.isDirectory() &&
- (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
- throw new DirectoryNotEmptyException(getPathForExecptionMessage());
-
- x.rethrowAsIOException(this);
- }
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
- throws IOException
- {
- if (filter == null)
- throw new NullPointerException();
- checkRead();
-
- // 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() == ENOTDIR)
- throw new NotDirectoryException(getPathForExecptionMessage());
- x.rethrowAsIOException(this);
- }
- }
-
- // open directory and dup file descriptor for use by
- // opendir/readdir/closedir
- int dfd1 = -1;
- int dfd2 = -1;
- long dp = 0L;
- try {
- dfd1 = open(this, O_RDONLY, 0);
- dfd2 = dup(dfd1);
- dp = fdopendir(dfd1);
- } catch (UnixException x) {
- if (dfd1 != -1)
- close(dfd1);
- if (dfd2 != -1)
- close(dfd2);
- if (x.errno() == UnixConstants.ENOTDIR)
- throw new NotDirectoryException(getPathForExecptionMessage());
- x.rethrowAsIOException(this);
- }
- return new UnixSecureDirectoryStream(this, dp, dfd2, filter);
- }
-
- // invoked by AbstractPath#copyTo
- @Override
- public void implCopyTo(Path obj, CopyOption... options)
- throws IOException
- {
- UnixPath target = (UnixPath)obj;
- UnixCopyFile.copy(this, target, options);
- }
-
- @Override
- public void implMoveTo(Path obj, CopyOption... options)
- throws IOException
- {
- UnixPath target = (UnixPath)obj;
- UnixCopyFile.move(this, target, options);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V
- getFileAttributeView(Class<V> type, LinkOption... options)
- {
- FileAttributeView view = getFileSystem()
- .newFileAttributeView(type, this, options);
- if (view == null)
- return null;
- return (V) view;
- }
-
- @Override
- public DynamicFileAttributeView getFileAttributeView(String name,
- LinkOption... options)
- {
- return getFileSystem().newFileAttributeView(name, this, options);
- }
-
- @Override
- public Path createDirectory(FileAttribute<?>... attrs)
- throws IOException
- {
- checkWrite();
-
- int mode = UnixFileModeAttribute
- .toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
- try {
- mkdir(this, mode);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- }
- return this;
- }
-
- @Override
- public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- int mode = UnixFileModeAttribute
- .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
- try {
- return UnixChannelFactory.newFileChannel(this, options, mode);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- return null; // keep compiler happy
- }
- }
-
- @Override
- public boolean isSameFile(Path obj) throws IOException {
- if (this.equals(obj))
- return true;
- if (!(obj instanceof UnixPath)) // includes null check
- return false;
- UnixPath other = (UnixPath)obj;
-
- // check security manager access to both files
- this.checkRead();
- other.checkRead();
-
- UnixFileAttributes thisAttrs;
- UnixFileAttributes otherAttrs;
- try {
- thisAttrs = UnixFileAttributes.get(this, true);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- return false; // keep compiler happy
- }
- try {
- otherAttrs = UnixFileAttributes.get(other, true);
- } catch (UnixException x) {
- x.rethrowAsIOException(other);
- return false; // keep compiler happy
- }
- return thisAttrs.isSameFile(otherAttrs);
- }
-
- @Override
- public Path createSymbolicLink(Path obj, FileAttribute<?>... attrs)
- throws IOException
- {
- UnixPath target = checkPath(obj);
-
- // no attributes supported when creating links
- if (attrs.length > 0) {
- UnixFileModeAttribute.toUnixMode(0, attrs); // may throw NPE or UOE
- throw new UnsupportedOperationException("Initial file attributes" +
- "not supported when creating symbolic link");
- }
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new LinkPermission("symbolic"));
- checkWrite();
- }
-
- // create link
- try {
- symlink(target.asByteArray(), this);
- } catch (UnixException x) {
- x.rethrowAsIOException(this);
- }
-
- return this;
- }
-
- @Override
- public Path createLink(Path obj) throws IOException {
- UnixPath existing = checkPath(obj);
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new LinkPermission("hard"));
- this.checkWrite();
- existing.checkWrite();
- }
- try {
- link(existing, this);
- } catch (UnixException x) {
- x.rethrowAsIOException(this, existing);
- }
- return this;
- }
-
- @Override
- public Path readSymbolicLink() throws IOException {
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- FilePermission perm = new FilePermission(getPathForPermissionCheck(),
- SecurityConstants.FILE_READLINK_ACTION);
- AccessController.checkPermission(perm);
- }
- try {
- byte[] target = readlink(this);
- return new UnixPath(getFileSystem(), target);
- } catch (UnixException x) {
- if (x.errno() == UnixConstants.EINVAL)
- throw new NotLinkException(getPathForExecptionMessage());
- x.rethrowAsIOException(this);
- return null; // keep compiler happy
- }
- }
-
- @Override
public UnixPath toAbsolutePath() {
if (isAbsolute()) {
return this;
@@ -1095,7 +815,7 @@
}
@Override
- public UnixPath toRealPath(boolean resolveLinks) throws IOException {
+ public Path toRealPath(boolean resolveLinks) throws IOException {
checkRead();
UnixPath absolute = toAbsolutePath();
@@ -1112,8 +832,7 @@
// if resolveLinks is false then eliminate "." and also ".."
// where the previous element is not a link.
- UnixPath root = getFileSystem().rootDirectory();
- UnixPath result = root;
+ UnixPath result = fs.rootDirectory();
for (int i=0; i<absolute.getNameCount(); i++) {
UnixPath element = absolute.getName(i);
@@ -1134,7 +853,7 @@
if (!attrs.isSymbolicLink()) {
result = result.getParent();
if (result == null) {
- result = root;
+ result = fs.rootDirectory();
}
continue;
}
@@ -1152,15 +871,6 @@
}
@Override
- public boolean isHidden() {
- checkRead();
- UnixPath name = getName();
- if (name == null)
- return false;
- return (name.asByteArray()[0] == '.');
- }
-
- @Override
public URI toUri() {
return UnixUriUtils.toUri(this);
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java Tue Feb 08 14:25:33 2011 -0800
@@ -40,7 +40,7 @@
*/
class UnixSecureDirectoryStream
- extends SecureDirectoryStream<Path>
+ implements SecureDirectoryStream<Path>
{
private final UnixDirectoryStream ds;
private final int dfd;
@@ -81,6 +81,20 @@
return (UnixPath)obj;
}
+ private boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption option: options) {
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ continue;
+ }
+ if (option == null)
+ throw new NullPointerException();
+ throw new AssertionError("Should not get here");
+ }
+ return followLinks;
+ }
+
/**
* Opens sub-directory in this directory
*/
@@ -91,7 +105,7 @@
{
UnixPath file = getName(obj);
UnixPath child = ds.directory().resolve(file);
- boolean followLinks = file.getFileSystem().followLinks(options);
+ boolean followLinks = followLinks(options);
// permission check using name resolved against original path of directory
SecurityManager sm = System.getSecurityManager();
@@ -302,7 +316,7 @@
LinkOption... options)
{
UnixPath file = getName(obj);
- boolean followLinks = file.getFileSystem().followLinks(options);
+ boolean followLinks = followLinks(options);
return getFileAttributeViewImpl(file, type, followLinks);
}
@@ -336,7 +350,11 @@
private void checkWriteAccess() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ds.directory().resolve(file).checkWrite();
+ if (file == null) {
+ ds.directory().checkWrite();
+ } else {
+ ds.directory().resolve(file).checkWrite();
+ }
}
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,8 +25,11 @@
package sun.nio.fs;
+import java.nio.file.Path;
+import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.Arrays;
/**
* Unix specific Path <--> URI conversion
@@ -38,7 +41,7 @@
/**
* Converts URI to Path
*/
- static UnixPath fromUri(UnixFileSystem fs, URI uri) {
+ static Path fromUri(UnixFileSystem fs, URI uri) {
if (!uri.isAbsolute())
throw new IllegalArgumentException("URI is not absolute");
if (uri.isOpaque())
@@ -53,22 +56,41 @@
if (uri.getQuery() != null)
throw new IllegalArgumentException("URI has a query component");
- String path = uri.getPath();
- if (path.equals(""))
+ // compatability with java.io.File
+ if (!uri.toString().startsWith("file:///"))
+ return new File(uri).toPath();
+
+ // transformation use raw path
+ String p = uri.getRawPath();
+ int len = p.length();
+ if (len == 0)
throw new IllegalArgumentException("URI path component is empty");
- if (path.endsWith("/") && (path.length() > 1)) {
- // "/foo/" --> "/foo", but "/" --> "/"
- path = path.substring(0, path.length() - 1);
- }
- // preserve bytes
- byte[] result = new byte[path.length()];
- for (int i=0; i<path.length(); i++) {
- byte v = (byte)(path.charAt(i));
- if (v == 0)
- throw new IllegalArgumentException("Nul character not allowed");
- result[i] = v;
+ // transform escaped octets and unescaped characters to bytes
+ if (p.endsWith("/") && len > 1)
+ len--;
+ byte[] result = new byte[len];
+ int rlen = 0;
+ int pos = 0;
+ while (pos < len) {
+ char c = p.charAt(pos++);
+ byte b;
+ if (c == '%') {
+ assert (pos+2) <= len;
+ char c1 = p.charAt(pos++);
+ char c2 = p.charAt(pos++);
+ b = (byte)((decode(c1) << 4) | decode(c2));
+ if (b == 0)
+ throw new IllegalArgumentException("Nul character not allowed");
+ } else {
+ assert c < 0x80;
+ b = (byte)c;
+ }
+ result[rlen++] = b;
}
+ if (rlen != result.length)
+ result = Arrays.copyOf(result, rlen);
+
return new UnixPath(fs, result);
}
@@ -86,7 +108,7 @@
} else {
sb.append('%');
sb.append(hexDigits[(c >> 4) & 0x0f]);
- sb.append(hexDigits[(c >> 0) & 0x0f]);
+ sb.append(hexDigits[(c) & 0x0f]);
}
}
@@ -164,6 +186,17 @@
return false;
}
+ // decode
+ private static int decode(char c) {
+ if ((c >= '0') && (c <= '9'))
+ return c - '0';
+ if ((c >= 'a') && (c <= 'f'))
+ return c - 'a' + 10;
+ if ((c >= 'A') && (c <= 'F'))
+ return c - 'A' + 10;
+ throw new AssertionError();
+ }
+
// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
// "8" | "9"
private static final long L_DIGIT = lowMask('0', '9');
--- a/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Tue Feb 08 14:25:33 2011 -0800
@@ -55,12 +55,23 @@
#include "sun_nio_fs_UnixNativeDispatcher.h"
+/**
+ * Size of password or group entry when not available via sysconf
+ */
+#define ENT_BUF_SIZE 1024
+
#define RESTARTABLE(_cmd, _result) do { \
do { \
_result = _cmd; \
} while((_result == -1) && (errno == EINTR)); \
} while(0)
+#define RESTARTABLE_RETURN_PTR(_cmd, _result) do { \
+ do { \
+ _result = _cmd; \
+ } while((_result == NULL) && (errno == EINTR)); \
+} while(0)
+
static jfieldID attrs_st_mode;
static jfieldID attrs_st_ino;
static jfieldID attrs_st_dev;
@@ -858,37 +869,41 @@
{
jbyteArray result = NULL;
int buflen;
+ char* pwbuf;
+ /* allocate buffer for password record */
buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
+ pwbuf = (char*)malloc(buflen);
+ if (pwbuf == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "native heap");
} else {
- char* pwbuf = (char*)malloc(buflen);
- if (pwbuf == NULL) {
- JNU_ThrowOutOfMemoryError(env, "native heap");
- } else {
- struct passwd pwent;
- struct passwd* p;
- int res = 0;
+ struct passwd pwent;
+ struct passwd* p = NULL;
+ int res = 0;
-#ifdef __solaris__
- p = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen);
-#else
- res = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p);
-#endif
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen), p);
+ #else
+ RESTARTABLE(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p), res);
+ #endif
- if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+ if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT)
throwUnixException(env, errno);
- } else {
- jsize len = strlen(p->pw_name);
- result = (*env)->NewByteArray(env, len);
- if (result != NULL) {
- (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
- }
+ } else {
+ jsize len = strlen(p->pw_name);
+ result = (*env)->NewByteArray(env, len);
+ if (result != NULL) {
+ (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
}
- free(pwbuf);
}
+ free(pwbuf);
}
+
return result;
}
@@ -898,36 +913,55 @@
{
jbyteArray result = NULL;
int buflen;
+ int retry;
+ /* initial size of buffer for group record */
buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
- } else {
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
+
+ do {
+ struct group grent;
+ struct group* g = NULL;
+ int res = 0;
+
char* grbuf = (char*)malloc(buflen);
if (grbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
- } else {
- struct group grent;
- struct group* g;
- int res = 0;
+ return NULL;
+ }
+
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen), g);
+ #else
+ RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g), res);
+ #endif
-#ifdef __solaris__
- g = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen);
-#else
- res = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g);
-#endif
- if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
- throwUnixException(env, errno);
- } else {
- jsize len = strlen(g->gr_name);
- result = (*env)->NewByteArray(env, len);
- if (result != NULL) {
- (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
+ retry = 0;
+ if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT) {
+ if (errno == ERANGE) {
+ /* insufficient buffer size so need larger buffer */
+ buflen += ENT_BUF_SIZE;
+ retry = 1;
+ } else {
+ throwUnixException(env, errno);
}
}
- free(grbuf);
+ } else {
+ jsize len = strlen(g->gr_name);
+ result = (*env)->NewByteArray(env, len);
+ if (result != NULL) {
+ (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
+ }
}
- }
+
+ free(grbuf);
+
+ } while (retry);
+
return result;
}
@@ -938,36 +972,37 @@
jint uid = -1;
int buflen;
char* pwbuf;
- struct passwd pwent;
- struct passwd* p;
- int res = 0;
- const char* name = (const char*)jlong_to_ptr(nameAddress);
+ /* allocate buffer for password record */
buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
- return -1;
- }
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
pwbuf = (char*)malloc(buflen);
if (pwbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
- return -1;
- }
+ } else {
+ struct passwd pwent;
+ struct passwd* p = NULL;
+ int res = 0;
+ const char* name = (const char*)jlong_to_ptr(nameAddress);
-#ifdef __solaris__
- p = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen);
-#else
- res = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p);
-#endif
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen), p);
+ #else
+ RESTARTABLE(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p), res);
+ #endif
- if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
- /* not found or error */
- } else {
- uid = p->pw_uid;
+ if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT)
+ throwUnixException(env, errno);
+ } else {
+ uid = p->pw_uid;
+ }
+ free(pwbuf);
}
- free(pwbuf);
-
return uid;
}
@@ -976,36 +1011,52 @@
jlong nameAddress)
{
jint gid = -1;
- int buflen;
- char* grbuf;
- struct group grent;
- struct group* g;
- int res = 0;
- const char* name = (const char*)jlong_to_ptr(nameAddress);
+ int buflen, retry;
+ /* initial size of buffer for group record */
buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
- return -1;
- }
- grbuf = (char*)malloc(buflen);
- if (grbuf == NULL) {
- JNU_ThrowOutOfMemoryError(env, "native heap");
- return -1;
- }
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
+
+ do {
+ struct group grent;
+ struct group* g = NULL;
+ int res = 0;
+ char *grbuf;
+ const char* name = (const char*)jlong_to_ptr(nameAddress);
+
+ grbuf = (char*)malloc(buflen);
+ if (grbuf == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "native heap");
+ return -1;
+ }
-#ifdef __solaris__
- g = getgrnam_r(name, &grent, grbuf, (size_t)buflen);
-#else
- res = getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g);
-#endif
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getgrnam_r(name, &grent, grbuf, (size_t)buflen), g);
+ #else
+ RESTARTABLE(getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g), res);
+ #endif
- if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
- /* not found or error */
- } else {
- gid = g->gr_gid;
- }
- free(grbuf);
+ retry = 0;
+ if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT) {
+ if (errno == ERANGE) {
+ /* insufficient buffer size so need larger buffer */
+ buflen += ENT_BUF_SIZE;
+ retry = 1;
+ } else {
+ throwUnixException(env, errno);
+ }
+ }
+ } else {
+ gid = g->gr_gid;
+ }
+
+ free(grbuf);
+
+ } while (retry);
return gid;
}
--- a/jdk/src/windows/classes/java/net/PlainSocketImpl.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/java/net/PlainSocketImpl.java Tue Feb 08 14:25:33 2011 -0800
@@ -138,6 +138,9 @@
protected synchronized void create(boolean stream) throws IOException {
impl.create(stream);
+
+ // set fd to delegate's fd to be compatible with older releases
+ this.fd = impl.fd;
}
protected void connect(String host, int port)
@@ -166,7 +169,7 @@
impl.doConnect(address, port, timeout);
}
- protected synchronized void bind(InetAddress address, int lport)
+ protected synchronized void bind(InetAddress address, int lport)
throws IOException
{
impl.bind(address, lport);
@@ -174,9 +177,13 @@
protected synchronized void accept(SocketImpl s) throws IOException {
// pass in the real impl not the wrapper.
- ((PlainSocketImpl)s).impl.address = new InetAddress();
- ((PlainSocketImpl)s).impl.fd = new FileDescriptor();
- impl.accept(((PlainSocketImpl)s).impl);
+ SocketImpl delegate = ((PlainSocketImpl)s).impl;
+ delegate.address = new InetAddress();
+ delegate.fd = new FileDescriptor();
+ impl.accept(delegate);
+
+ // set fd to delegate's fd to be compatible with older releases
+ s.fd = delegate.fd;
}
void setFileDescriptor(FileDescriptor fd) {
@@ -208,11 +215,21 @@
}
protected void close() throws IOException {
- impl.close();
+ try {
+ impl.close();
+ } finally {
+ // set fd to delegate's fd to be compatible with older releases
+ this.fd = null;
+ }
}
void reset() throws IOException {
- impl.reset();
+ try {
+ impl.reset();
+ } finally {
+ // set fd to delegate's fd to be compatible with older releases
+ this.fd = null;
+ }
}
protected void shutdownInput() throws IOException {
--- a/jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java Tue Feb 08 14:25:33 2011 -0800
@@ -42,12 +42,12 @@
}
@Override
- public String implProbeContentType(FileRef file) throws IOException {
+ public String implProbeContentType(Path file) throws IOException {
if (!(file instanceof Path))
return null;
// get file extension
- Path name = ((Path)file).getName();
+ Path name = file.getFileName();
if (name == null)
return null;
String filename = name.toString();
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Tue Feb 08 14:25:33 2011 -0800
@@ -167,22 +167,6 @@
}
@Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals(READONLY_NAME))
- return readAttributes().isReadOnly();
- if (attribute.equals(ARCHIVE_NAME))
- return readAttributes().isArchive();
- if (attribute.equals(SYSTEM_NAME))
- return readAttributes().isSystem();
- if (attribute.equals(HIDDEN_NAME))
- return readAttributes().isHidden();
- // implementation specific
- if (attribute.equals(ATTRIBUTES_NAME))
- return readAttributes().attributes();
- return super.getAttribute(attribute);
- }
-
- @Override
public void setAttribute(String attribute, Object value)
throws IOException
{
@@ -206,7 +190,7 @@
}
@Override
- public Map<String,?> readAttributes(String[] attributes)
+ public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java Tue Feb 08 14:25:33 2011 -0800
@@ -158,7 +158,7 @@
if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
x.lastError() == ERROR_ALREADY_EXISTS)
{
- throw new FileAlreadyExistsException(
+ throw new DirectoryNotEmptyException(
target.getPathForExceptionMessage());
}
}
@@ -369,7 +369,7 @@
if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
x.lastError() == ERROR_ALREADY_EXISTS)
{
- throw new FileAlreadyExistsException(
+ throw new DirectoryNotEmptyException(
target.getPathForExceptionMessage());
}
}
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java Tue Feb 08 14:25:33 2011 -0800
@@ -117,28 +117,47 @@
return ((volInfo.flags() & FILE_READ_ONLY_VOLUME) != 0);
}
+ // read the free space info
+ private DiskFreeSpace readDiskFreeSpace() throws IOException {
+ try {
+ return GetDiskFreeSpaceEx(root);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(root);
+ return null;
+ }
+ }
+
@Override
- @SuppressWarnings("unchecked")
+ public long getTotalSpace() throws IOException {
+ return readDiskFreeSpace().totalNumberOfBytes();
+ }
+
+ @Override
+ public long getUsableSpace() throws IOException {
+ return readDiskFreeSpace().freeBytesAvailable();
+ }
+
+ @Override
+ public long getUnallocatedSpace() throws IOException {
+ return readDiskFreeSpace().freeBytesAvailable();
+ }
+
+ @Override
public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
if (type == null)
throw new NullPointerException();
- if (type == FileStoreSpaceAttributeView.class)
- return (V) new WindowsFileStoreAttributeView(this);
return (V) null;
}
@Override
public Object getAttribute(String attribute) throws IOException {
// standard
- if (attribute.equals("space:totalSpace"))
- return new WindowsFileStoreAttributeView(this)
- .readAttributes().totalSpace();
- if (attribute.equals("space:usableSpace"))
- return new WindowsFileStoreAttributeView(this)
- .readAttributes().usableSpace();
- if (attribute.equals("space:unallocatedSpace"))
- return new WindowsFileStoreAttributeView(this)
- .readAttributes().unallocatedSpace();
+ if (attribute.equals("totalSpace"))
+ return getTotalSpace();
+ if (attribute.equals("usableSpace"))
+ return getUsableSpace();
+ if (attribute.equals("unallocatedSpace"))
+ return getUnallocatedSpace();
// windows specific for testing purposes
if (attribute.equals("volume:vsn"))
return volInfo.volumeSerialNumber();
@@ -202,48 +221,4 @@
sb.append(")");
return sb.toString();
}
-
- static class WindowsFileStoreAttributeView
- implements FileStoreSpaceAttributeView
- {
- private final WindowsFileStore fs;
-
- WindowsFileStoreAttributeView(WindowsFileStore fs) {
- this.fs = fs;
- }
-
- @Override
- public String name() {
- return "space";
- }
-
- @Override
- public FileStoreSpaceAttributes readAttributes()
- throws IOException
- {
- // read the free space info
- DiskFreeSpace info = null;
- try {
- info = GetDiskFreeSpaceEx(fs.root);
- } catch (WindowsException x) {
- x.rethrowAsIOException(fs.root);
- }
-
- final DiskFreeSpace result = info;
- return new FileStoreSpaceAttributes() {
- @Override
- public long totalSpace() {
- return result.totalNumberOfBytes();
- }
- @Override
- public long usableSpace() {
- return result.freeBytesAvailable();
- }
- @Override
- public long unallocatedSpace() {
- return result.totalNumberOfFreeBytes();
- }
- };
- }
- }
}
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java Tue Feb 08 14:25:33 2011 -0800
@@ -127,7 +127,7 @@
}
// iterate over roots, ignoring those that the security manager denies
- ArrayList<Path> result = new ArrayList<Path>();
+ ArrayList<Path> result = new ArrayList<>();
SecurityManager sm = System.getSecurityManager();
for (int i = 0; i <= 25; i++) { // 0->A, 1->B, 2->C...
if ((drives & (1 << i)) != 0) {
@@ -235,33 +235,50 @@
}
@Override
- public Path getPath(String path) {
+ public final Path getPath(String first, String... more) {
+ String path;
+ if (more.length == 0) {
+ path = first;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(first);
+ for (String segment: more) {
+ if (segment.length() > 0) {
+ if (sb.length() > 0)
+ sb.append('\\');
+ sb.append(segment);
+ }
+ }
+ path = sb.toString();
+ }
return WindowsPath.parse(this, path);
}
@Override
public UserPrincipalLookupService getUserPrincipalLookupService() {
- return theLookupService;
+ return LookupService.instance;
}
- private static final UserPrincipalLookupService theLookupService =
- new UserPrincipalLookupService() {
- @Override
- public UserPrincipal lookupPrincipalByName(String name)
- throws IOException
- {
- return WindowsUserPrincipals.lookup(name);
- }
- @Override
- public GroupPrincipal lookupPrincipalByGroupName(String group)
- throws IOException
- {
- UserPrincipal user = WindowsUserPrincipals.lookup(group);
- if (!(user instanceof GroupPrincipal))
- throw new UserPrincipalNotFoundException(group);
- return (GroupPrincipal)user;
- }
- };
+ private static class LookupService {
+ static final UserPrincipalLookupService instance =
+ new UserPrincipalLookupService() {
+ @Override
+ public UserPrincipal lookupPrincipalByName(String name)
+ throws IOException
+ {
+ return WindowsUserPrincipals.lookup(name);
+ }
+ @Override
+ public GroupPrincipal lookupPrincipalByGroupName(String group)
+ throws IOException
+ {
+ UserPrincipal user = WindowsUserPrincipals.lookup(group);
+ if (!(user instanceof GroupPrincipal))
+ throw new UserPrincipalNotFoundException(group);
+ return (GroupPrincipal)user;
+ }
+ };
+ }
@Override
public PathMatcher getPathMatcher(String syntaxAndInput) {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Tue Feb 08 14:25:33 2011 -0800
@@ -26,19 +26,25 @@
package sun.nio.fs;
import java.nio.file.*;
-import java.nio.file.spi.*;
import java.nio.file.attribute.*;
import java.nio.channels.*;
import java.net.URI;
import java.util.concurrent.ExecutorService;
-import java.io.IOException;
+import java.io.*;
import java.util.*;
+import java.security.AccessController;
+import sun.misc.Unsafe;
+import sun.nio.ch.ThreadPool;
+import sun.security.util.SecurityConstants;
-import sun.nio.ch.ThreadPool;
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
public class WindowsFileSystemProvider
- extends FileSystemProvider
+ extends AbstractFileSystemProvider
{
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+
private static final String USER_DIR = "user.dir";
private final WindowsFileSystem theFileSystem;
@@ -143,4 +149,505 @@
sd.release();
}
}
+
+ private boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption option: options) {
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ continue;
+ }
+ if (option == null)
+ throw new NullPointerException();
+ throw new AssertionError("Should not get here");
+ }
+ return followLinks;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V
+ getFileAttributeView(Path obj, Class<V> view, LinkOption... options)
+ {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ if (view == null)
+ throw new NullPointerException();
+ boolean followLinks = followLinks(options);
+ if (view == BasicFileAttributeView.class)
+ return (V) WindowsFileAttributeViews.createBasicView(file, followLinks);
+ if (view == DosFileAttributeView.class)
+ return (V) WindowsFileAttributeViews.createDosView(file, followLinks);
+ if (view == AclFileAttributeView.class)
+ return (V) new WindowsAclFileAttributeView(file, followLinks);
+ if (view == FileOwnerAttributeView.class)
+ return (V) new FileOwnerAttributeViewImpl(
+ new WindowsAclFileAttributeView(file, followLinks));
+ if (view == UserDefinedFileAttributeView.class)
+ return (V) new WindowsUserDefinedFileAttributeView(file, followLinks);
+ return (V) null;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ Class<? extends BasicFileAttributeView> view;
+ if (type == BasicFileAttributes.class)
+ view = BasicFileAttributeView.class;
+ else if (type == DosFileAttributes.class)
+ view = DosFileAttributeView.class;
+ else if (type == null)
+ throw new NullPointerException();
+ else
+ throw new UnsupportedOperationException();
+ return (A) getFileAttributeView(file, view, options).readAttributes();
+ }
+
+ @Override
+ public DynamicFileAttributeView getFileAttributeView(Path obj, String name, LinkOption... options) {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ boolean followLinks = followLinks(options);
+ if (name.equals("basic"))
+ return WindowsFileAttributeViews.createBasicView(file, followLinks);
+ if (name.equals("dos"))
+ return WindowsFileAttributeViews.createDosView(file, followLinks);
+ if (name.equals("acl"))
+ return new WindowsAclFileAttributeView(file, followLinks);
+ if (name.equals("owner"))
+ return new FileOwnerAttributeViewImpl(
+ new WindowsAclFileAttributeView(file, followLinks));
+ if (name.equals("user"))
+ return new WindowsUserDefinedFileAttributeView(file, followLinks);
+ return null;
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path obj,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ WindowsSecurityDescriptor sd =
+ WindowsSecurityDescriptor.fromAttribute(attrs);
+ try {
+ return WindowsChannelFactory
+ .newFileChannel(file.getPathForWin32Calls(),
+ file.getPathForPermissionCheck(),
+ options,
+ sd.address());
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file);
+ return null; // keep compiler happy
+ } finally {
+ sd.release();
+ }
+ }
+
+ @Override
+ boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ file.checkDelete();
+
+ WindowsFileAttributes attrs = null;
+ try {
+ // need to know if file is a directory or junction
+ attrs = WindowsFileAttributes.get(file, false);
+ if (attrs.isDirectory() || attrs.isDirectoryLink()) {
+ RemoveDirectory(file.getPathForWin32Calls());
+ } else {
+ DeleteFile(file.getPathForWin32Calls());
+ }
+ return true;
+ } catch (WindowsException x) {
+
+ // no-op if file does not exist
+ if (!failIfNotExists &&
+ (x.lastError() == ERROR_FILE_NOT_FOUND ||
+ x.lastError() == ERROR_PATH_NOT_FOUND)) return false;
+
+ if (attrs != null && attrs.isDirectory()) {
+ // ERROR_ALREADY_EXISTS is returned when attempting to delete
+ // non-empty directory on SAMBA servers.
+ if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
+ x.lastError() == ERROR_ALREADY_EXISTS)
+ {
+ throw new DirectoryNotEmptyException(
+ file.getPathForExceptionMessage());
+ }
+ }
+ x.rethrowAsIOException(file);
+ return false;
+ }
+ }
+
+ @Override
+ public void copy(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ WindowsFileCopy.copy(WindowsPath.toWindowsPath(source),
+ WindowsPath.toWindowsPath(target),
+ options);
+ }
+
+ @Override
+ public void move(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ WindowsFileCopy.move(WindowsPath.toWindowsPath(source),
+ WindowsPath.toWindowsPath(target),
+ options);
+ }
+
+ /**
+ * Returns buffer with SID_AND_ATTRIBUTES structure representing the user
+ * associated with the current thread access token.
+ * FIXME - this should be cached.
+ */
+ private static NativeBuffer getUserInfo(WindowsPath file) throws IOException {
+ try {
+ long hToken = WindowsSecurity.processTokenWithQueryAccess;
+ int size = GetTokenInformation(hToken, TokenUser, 0L, 0);
+ assert size > 0;
+
+ NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
+ try {
+ int newsize = GetTokenInformation(hToken, TokenUser,
+ buffer.address(), size);
+ if (newsize != size)
+ throw new AssertionError();
+ return buffer;
+ } catch (WindowsException x) {
+ buffer.release();
+ throw x;
+ }
+ } catch (WindowsException x) {
+ throw new IOException(x.getMessage());
+ }
+ }
+
+ /**
+ * Reads the file ACL and return the effective access as ACCESS_MASK
+ */
+ private static int getEffectiveAccess(WindowsPath file) throws IOException {
+ // read security descriptor continaing ACL (symlinks are followed)
+ String target = WindowsLinkSupport.getFinalPath(file, true);
+ NativeBuffer aclBuffer = WindowsAclFileAttributeView
+ .getFileSecurity(target, DACL_SECURITY_INFORMATION);
+
+ // retrieves DACL from security descriptor
+ long pAcl = GetSecurityDescriptorDacl(aclBuffer.address());
+
+ // Use GetEffectiveRightsFromAcl to get effective access to file
+ try {
+ NativeBuffer userBuffer = getUserInfo(file);
+ try {
+ try {
+ // SID_AND_ATTRIBUTES->pSid
+ long pSid = unsafe.getAddress(userBuffer.address());
+ long pTrustee = BuildTrusteeWithSid(pSid);
+ try {
+ return GetEffectiveRightsFromAcl(pAcl, pTrustee);
+ } finally {
+ LocalFree(pTrustee);
+ }
+ } catch (WindowsException x) {
+ throw new IOException("Unable to get effective rights from ACL: " +
+ x.getMessage());
+ }
+ } finally {
+ userBuffer.release();
+ }
+ } finally {
+ aclBuffer.release();
+ }
+ }
+
+ @Override
+ public void checkAccess(Path obj, AccessMode... modes) throws IOException {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ // if no access modes then simply file attributes
+ if (modes.length == 0) {
+ file.checkRead();
+ try {
+ WindowsFileAttributes.get(file, true);
+ } catch (WindowsException exc) {
+ exc.rethrowAsIOException(file);
+ }
+ return;
+ }
+
+ boolean r = false;
+ boolean w = false;
+ boolean x = false;
+ for (AccessMode mode: modes) {
+ switch (mode) {
+ case READ : r = true; break;
+ case WRITE : w = true; break;
+ case EXECUTE : x = true; break;
+ default: throw new AssertionError("Should not get here");
+ }
+ }
+
+ int mask = 0;
+ if (r) {
+ file.checkRead();
+ mask |= FILE_READ_DATA;
+ }
+ if (w) {
+ file.checkWrite();
+ mask |= FILE_WRITE_DATA;
+ }
+ if (x) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkExec(file.getPathForPermissionCheck());
+ mask |= FILE_EXECUTE;
+ }
+
+ if ((getEffectiveAccess(file) & mask) == 0)
+ throw new AccessDeniedException(
+ file.getPathForExceptionMessage(), null,
+ "Effective permissions does not allow requested access");
+
+ // for write access we neeed to check if the DOS readonly attribute
+ // and if the volume is read-only
+ if (w) {
+ try {
+ WindowsFileAttributes attrs = WindowsFileAttributes.get(file, true);
+ if (!attrs.isDirectory() && attrs.isReadOnly())
+ throw new AccessDeniedException(
+ file.getPathForExceptionMessage(), null,
+ "DOS readonly attribute is set");
+ } catch (WindowsException exc) {
+ exc.rethrowAsIOException(file);
+ }
+
+ if (WindowsFileStore.create(file).isReadOnly()) {
+ throw new AccessDeniedException(
+ file.getPathForExceptionMessage(), null, "Read-only file system");
+ }
+ return;
+ }
+ }
+
+ @Override
+ public boolean isSameFile(Path obj1, Path obj2) throws IOException {
+ WindowsPath file1 = WindowsPath.toWindowsPath(obj1);
+ if (file1.equals(obj2))
+ return true;
+ if (obj2 == null)
+ throw new NullPointerException();
+ if (!(obj2 instanceof WindowsPath))
+ return false;
+ WindowsPath file2 = (WindowsPath)obj2;
+
+ // check security manager access to both files
+ file1.checkRead();
+ file2.checkRead();
+
+ // open both files and see if they are the same
+ long h1 = 0L;
+ try {
+ h1 = file1.openForReadAttributeAccess(true);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file1);
+ }
+ try {
+ WindowsFileAttributes attrs1 = null;
+ try {
+ attrs1 = WindowsFileAttributes.readAttributes(h1);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file1);
+ }
+ long h2 = 0L;
+ try {
+ h2 = file2.openForReadAttributeAccess(true);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file2);
+ }
+ try {
+ WindowsFileAttributes attrs2 = null;
+ try {
+ attrs2 = WindowsFileAttributes.readAttributes(h2);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file2);
+ }
+ return WindowsFileAttributes.isSameFile(attrs1, attrs2);
+ } finally {
+ CloseHandle(h2);
+ }
+ } finally {
+ CloseHandle(h1);
+ }
+ }
+
+ @Override
+ public boolean isHidden(Path obj) throws IOException {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ file.checkRead();
+ WindowsFileAttributes attrs = null;
+ try {
+ attrs = WindowsFileAttributes.get(file, true);
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(file);
+ }
+ // DOS hidden attribute not meaningful when set on directories
+ if (attrs.isDirectory())
+ return false;
+ return attrs.isHidden();
+ }
+
+ @Override
+ public FileStore getFileStore(Path obj) throws IOException {
+ WindowsPath file = WindowsPath.toWindowsPath(obj);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+ file.checkRead();
+ }
+ return WindowsFileStore.create(file);
+ }
+
+
+ @Override
+ public void createDirectory(Path obj, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ WindowsPath dir = WindowsPath.toWindowsPath(obj);
+ dir.checkWrite();
+ WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.fromAttribute(attrs);
+ try {
+ CreateDirectory(dir.getPathForWin32Calls(), sd.address());
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(dir);
+ } finally {
+ sd.release();
+ }
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ WindowsPath dir = WindowsPath.toWindowsPath(obj);
+ dir.checkRead();
+ if (filter == null)
+ throw new NullPointerException();
+ return new WindowsDirectoryStream(dir, filter);
+ }
+
+ @Override
+ public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ WindowsPath link = WindowsPath.toWindowsPath(obj1);
+ WindowsPath target = WindowsPath.toWindowsPath(obj2);
+
+ if (!link.getFileSystem().supportsLinks()) {
+ throw new UnsupportedOperationException("Symbolic links not supported "
+ + "on this operating system");
+ }
+
+ // no attributes allowed
+ if (attrs.length > 0) {
+ WindowsSecurityDescriptor.fromAttribute(attrs); // may throw NPE or UOE
+ throw new UnsupportedOperationException("Initial file attributes" +
+ "not supported when creating symbolic link");
+ }
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new LinkPermission("symbolic"));
+ link.checkWrite();
+ }
+
+ /**
+ * Throw I/O exception for the drive-relative case because Windows
+ * creates a link with the resolved target for this case.
+ */
+ if (target.type() == WindowsPathType.DRIVE_RELATIVE) {
+ throw new IOException("Cannot create symbolic link to working directory relative target");
+ }
+
+ /*
+ * Windows treates symbolic links to directories differently than it
+ * does to other file types. For that reason we need to check if the
+ * target is a directory (or a directory junction).
+ */
+ WindowsPath resolvedTarget;
+ if (target.type() == WindowsPathType.RELATIVE) {
+ WindowsPath parent = link.getParent();
+ resolvedTarget = (parent == null) ? target : parent.resolve(target);
+ } else {
+ resolvedTarget = link.resolve(target);
+ }
+ int flags = 0;
+ try {
+ WindowsFileAttributes wattrs = WindowsFileAttributes.get(resolvedTarget, false);
+ if (wattrs.isDirectory() || wattrs.isDirectoryLink())
+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
+ } catch (WindowsException x) {
+ // unable to access target so assume target is not a directory
+ }
+
+ // create the link
+ try {
+ CreateSymbolicLink(link.getPathForWin32Calls(),
+ WindowsPath.addPrefixIfNeeded(target.toString()),
+ flags);
+ } catch (WindowsException x) {
+ if (x.lastError() == ERROR_INVALID_REPARSE_DATA) {
+ x.rethrowAsIOException(link, target);
+ } else {
+ x.rethrowAsIOException(link);
+ }
+ }
+ }
+
+ @Override
+ public void createLink(Path obj1, Path obj2) throws IOException {
+ WindowsPath link = WindowsPath.toWindowsPath(obj1);
+ WindowsPath existing = WindowsPath.toWindowsPath(obj2);
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new LinkPermission("hard"));
+ link.checkWrite();
+ existing.checkWrite();
+ }
+
+ // create hard link
+ try {
+ CreateHardLink(link.getPathForWin32Calls(),
+ existing.getPathForWin32Calls());
+ } catch (WindowsException x) {
+ x.rethrowAsIOException(link, existing);
+ }
+ }
+
+ @Override
+ public Path readSymbolicLink(Path obj1) throws IOException {
+ WindowsPath link = WindowsPath.toWindowsPath(obj1);
+ WindowsFileSystem fs = link.getFileSystem();
+ if (!fs.supportsLinks()) {
+ throw new UnsupportedOperationException("symbolic links not supported");
+ }
+
+ // permission check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
+ SecurityConstants.FILE_READLINK_ACTION);
+ AccessController.checkPermission(perm);
+ }
+
+ String target = WindowsLinkSupport.readLink(link);
+ return WindowsPath.createFromNormalizedPath(fs, target);
+ }
}
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Tue Feb 08 14:25:33 2011 -0800
@@ -27,18 +27,13 @@
import java.nio.file.*;
import java.nio.file.attribute.*;
-import java.nio.channels.*;
import java.io.*;
import java.net.URI;
-import java.security.AccessController;
import java.util.*;
import java.lang.ref.WeakReference;
import com.sun.nio.file.ExtendedWatchEventModifier;
-import sun.security.util.SecurityConstants;
-import sun.misc.Unsafe;
-
import static sun.nio.fs.WindowsNativeDispatcher.*;
import static sun.nio.fs.WindowsConstants.*;
@@ -47,7 +42,6 @@
*/
class WindowsPath extends AbstractPath {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
// The maximum path that does not require long path prefix. On Windows
// the maximum path is 260 minus 1 (NUL) but for directories it is 260
@@ -229,6 +223,8 @@
// Relative path ("foo" for example)
if (type == WindowsPathType.RELATIVE) {
String defaultDirectory = getFileSystem().defaultDirectory();
+ if (isEmpty())
+ return defaultDirectory;
if (defaultDirectory.endsWith("\\")) {
return defaultDirectory + path;
} else {
@@ -286,7 +282,7 @@
}
// Add long path prefix to path if required
- private static String addPrefixIfNeeded(String path) {
+ static String addPrefixIfNeeded(String path) {
if (path.length() > 248) {
if (path.startsWith("\\\\")) {
path = "\\\\?\\UNC" + path.substring(1, path.length());
@@ -304,10 +300,22 @@
// -- Path operations --
+ private boolean isEmpty() {
+ return path.length() == 0;
+ }
+
+ private WindowsPath emptyPath() {
+ return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", "");
+ }
+
@Override
- public Path getName() {
+ public Path getFileName() {
+ int len = path.length();
+ // represents empty path
+ if (len == 0)
+ return this;
// represents root component only
- if (root.length() == path.length())
+ if (root.length() == len)
return null;
int off = path.lastIndexOf('\\');
if (off < root.length())
@@ -340,6 +348,11 @@
}
// package-private
+ WindowsPathType type() {
+ return type;
+ }
+
+ // package-private
boolean isUnc() {
return type == WindowsPathType.UNC;
}
@@ -355,7 +368,7 @@
return type == WindowsPathType.ABSOLUTE || type == WindowsPathType.UNC;
}
- private WindowsPath checkPath(FileRef path) {
+ static WindowsPath toWindowsPath(Path path) {
if (path == null)
throw new NullPointerException();
if (!(path instanceof WindowsPath)) {
@@ -366,9 +379,9 @@
@Override
public WindowsPath relativize(Path obj) {
- WindowsPath other = checkPath(obj);
+ WindowsPath other = toWindowsPath(obj);
if (this.equals(other))
- return null;
+ return emptyPath();
// can only relativize paths of the same type
if (this.type != other.type)
@@ -410,7 +423,7 @@
@Override
public Path normalize() {
final int count = getNameCount();
- if (count == 0)
+ if (count == 0 || isEmpty())
return this;
boolean[] ignore = new boolean[count]; // true => ignore name
@@ -488,7 +501,7 @@
// corner case - all names removed
if (remaining == 0) {
- return getRoot();
+ return (root.length() == 0) ? emptyPath() : getRoot();
}
// re-constitute the path from the remaining names.
@@ -497,7 +510,7 @@
result.append(root);
for (int i=0; i<count; i++) {
if (!ignore[i]) {
- result.append(getName(i).toString());
+ result.append(getName(i));
result.append("\\");
}
}
@@ -509,9 +522,9 @@
@Override
public WindowsPath resolve(Path obj) {
- if (obj == null)
+ WindowsPath other = toWindowsPath(obj);
+ if (other.isEmpty())
return this;
- WindowsPath other = checkPath(obj);
if (other.isAbsolute())
return other;
@@ -559,27 +572,27 @@
}
}
- @Override
- public WindowsPath resolve(String other) {
- return resolve(getFileSystem().getPath(other));
- }
-
// generate offset array
private void initOffsets() {
if (offsets == null) {
- ArrayList<Integer> list = new ArrayList<Integer>();
- int start = root.length();
- int off = root.length();
- while (off < path.length()) {
- if (path.charAt(off) != '\\') {
- off++;
- } else {
+ ArrayList<Integer> list = new ArrayList<>();
+ if (isEmpty()) {
+ // empty path considered to have one name element
+ list.add(0);
+ } else {
+ int start = root.length();
+ int off = root.length();
+ while (off < path.length()) {
+ if (path.charAt(off) != '\\') {
+ off++;
+ } else {
+ list.add(start);
+ start = ++off;
+ }
+ }
+ if (start != off)
list.add(start);
- start = ++off;
- }
}
- if (start != off)
- list.add(start);
synchronized (this) {
if (offsets == null)
offsets = list.toArray(new Integer[list.size()]);
@@ -633,11 +646,16 @@
@Override
public boolean startsWith(Path obj) {
- WindowsPath other = checkPath(obj);
+ WindowsPath other = toWindowsPath(obj);
// if this path has a root component the given path's root must match
- if (!this.root.equalsIgnoreCase(other.root))
+ if (!this.root.equalsIgnoreCase(other.root)) {
return false;
+ }
+
+ // empty path starts with itself
+ if (other.isEmpty())
+ return this.isEmpty();
// roots match so compare elements
int thisCount = getNameCount();
@@ -657,13 +675,18 @@
@Override
public boolean endsWith(Path obj) {
- WindowsPath other = checkPath(obj);
+ WindowsPath other = toWindowsPath(obj);
// other path is longer
- if (other.path.length() > path.length()) {
+ if (other.path.length() > this.path.length()) {
return false;
}
+ // empty path ends in itself
+ if (other.isEmpty()) {
+ return this.isEmpty();
+ }
+
int thisCount = this.getNameCount();
int otherCount = other.getNameCount();
@@ -742,31 +765,6 @@
return path;
}
- @Override
- public Iterator<Path> iterator() {
- return new Iterator<Path>() {
- private int i = 0;
- @Override
- public boolean hasNext() {
- return (i < getNameCount());
- }
- @Override
- public Path next() {
- if (i < getNameCount()) {
- Path result = getName(i);
- i++;
- return result;
- } else {
- throw new NoSuchElementException();
- }
- }
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-
// -- file operations --
// package-private
@@ -806,453 +804,6 @@
}
@Override
- public FileStore getFileStore()
- throws IOException
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
- checkRead();
- }
- return WindowsFileStore.create(this);
- }
-
- /**
- * Returns buffer with SID_AND_ATTRIBUTES structure representing the user
- * associated with the current thread access token.
- * FIXME - this should be cached.
- */
- private NativeBuffer getUserInfo() throws IOException {
- try {
- long hToken = WindowsSecurity.processTokenWithQueryAccess;
- int size = GetTokenInformation(hToken, TokenUser, 0L, 0);
- assert size > 0;
-
- NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
- try {
- int newsize = GetTokenInformation(hToken, TokenUser,
- buffer.address(), size);
- if (newsize != size)
- throw new AssertionError();
- return buffer;
- } catch (WindowsException x) {
- buffer.release();
- throw x;
- }
- } catch (WindowsException x) {
- throw new IOException(x.getMessage());
- }
- }
-
- /**
- * Reads the file ACL and return the effective access as ACCESS_MASK
- */
- private int getEffectiveAccess() throws IOException {
- // read security descriptor continaing ACL (symlinks are followed)
- String target = WindowsLinkSupport.getFinalPath(this, true);
- NativeBuffer aclBuffer = WindowsAclFileAttributeView
- .getFileSecurity(target, DACL_SECURITY_INFORMATION);
-
- // retrieves DACL from security descriptor
- long pAcl = GetSecurityDescriptorDacl(aclBuffer.address());
-
- // Use GetEffectiveRightsFromAcl to get effective access to file
- try {
- NativeBuffer userBuffer = getUserInfo();
- try {
- try {
- // SID_AND_ATTRIBUTES->pSid
- long pSid = unsafe.getAddress(userBuffer.address());
- long pTrustee = BuildTrusteeWithSid(pSid);
- try {
- return GetEffectiveRightsFromAcl(pAcl, pTrustee);
- } finally {
- LocalFree(pTrustee);
- }
- } catch (WindowsException x) {
- throw new IOException("Unable to get effective rights from ACL: " +
- x.getMessage());
- }
- } finally {
- userBuffer.release();
- }
- } finally {
- aclBuffer.release();
- }
- }
-
- @Override
- public void checkAccess(AccessMode... modes) throws IOException {
- // if no access modes then simply file attributes
- if (modes.length == 0) {
- checkRead();
- try {
- WindowsFileAttributes.get(this, true);
- } catch (WindowsException exc) {
- exc.rethrowAsIOException(this);
- }
- return;
- }
-
- boolean r = false;
- boolean w = false;
- boolean x = false;
- for (AccessMode mode: modes) {
- switch (mode) {
- case READ : r = true; break;
- case WRITE : w = true; break;
- case EXECUTE : x = true; break;
- default: throw new AssertionError("Should not get here");
- }
- }
-
- int mask = 0;
- if (r) {
- checkRead();
- mask |= FILE_READ_DATA;
- }
- if (w) {
- checkWrite();
- mask |= FILE_WRITE_DATA;
- }
- if (x) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkExec(getPathForPermissionCheck());
- mask |= FILE_EXECUTE;
- }
-
- if ((getEffectiveAccess() & mask) == 0)
- throw new AccessDeniedException(
- this.getPathForExceptionMessage(), null,
- "Effective permissions does not allow requested access");
-
- // for write access we neeed to check if the DOS readonly attribute
- // and if the volume is read-only
- if (w) {
- try {
- WindowsFileAttributes attrs = WindowsFileAttributes.get(this, true);
- if (!attrs.isDirectory() && attrs.isReadOnly())
- throw new AccessDeniedException(
- this.getPathForExceptionMessage(), null,
- "DOS readonly attribute is set");
- } catch (WindowsException exc) {
- exc.rethrowAsIOException(this);
- }
-
- if (WindowsFileStore.create(this).isReadOnly()) {
- throw new AccessDeniedException(
- this.getPathForExceptionMessage(), null, "Read-only file system");
- }
- return;
- }
- }
-
- @Override
- void implDelete(boolean failIfNotExists) throws IOException {
- checkDelete();
-
- WindowsFileAttributes attrs = null;
- try {
- // need to know if file is a directory or junction
- attrs = WindowsFileAttributes.get(this, false);
- if (attrs.isDirectory() || attrs.isDirectoryLink()) {
- RemoveDirectory(getPathForWin32Calls());
- } else {
- DeleteFile(getPathForWin32Calls());
- }
- } catch (WindowsException x) {
-
- // no-op if file does not exist
- if (!failIfNotExists &&
- (x.lastError() == ERROR_FILE_NOT_FOUND ||
- x.lastError() == ERROR_PATH_NOT_FOUND)) return;
-
- if (attrs != null && attrs.isDirectory()) {
- // ERROR_ALREADY_EXISTS is returned when attempting to delete
- // non-empty directory on SAMBA servers.
- if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
- x.lastError() == ERROR_ALREADY_EXISTS)
- {
- throw new DirectoryNotEmptyException(
- getPathForExceptionMessage());
- }
- }
- x.rethrowAsIOException(this);
- }
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
- throws IOException
- {
- checkRead();
- if (filter == null)
- throw new NullPointerException();
- return new WindowsDirectoryStream(this, filter);
- }
-
- @Override
- public void implCopyTo(Path obj, CopyOption... options) throws IOException {
- WindowsPath target = (WindowsPath)obj;
- WindowsFileCopy.copy(this, target, options);
- }
-
- @Override
- public void implMoveTo(Path obj, CopyOption... options) throws IOException {
- WindowsPath target = (WindowsPath)obj;
- WindowsFileCopy.move(this, target, options);
- }
-
- private boolean followLinks(LinkOption... options) {
- boolean followLinks = true;
- for (LinkOption option: options) {
- if (option == LinkOption.NOFOLLOW_LINKS) {
- followLinks = false;
- continue;
- }
- if (option == null)
- throw new NullPointerException();
- throw new AssertionError("Should not get here");
- }
- return followLinks;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V
- getFileAttributeView(Class<V> view, LinkOption... options)
- {
- if (view == null)
- throw new NullPointerException();
- boolean followLinks = followLinks(options);
- if (view == BasicFileAttributeView.class)
- return (V) WindowsFileAttributeViews.createBasicView(this, followLinks);
- if (view == DosFileAttributeView.class)
- return (V) WindowsFileAttributeViews.createDosView(this, followLinks);
- if (view == AclFileAttributeView.class)
- return (V) new WindowsAclFileAttributeView(this, followLinks);
- if (view == FileOwnerAttributeView.class)
- return (V) new FileOwnerAttributeViewImpl(
- new WindowsAclFileAttributeView(this, followLinks));
- if (view == UserDefinedFileAttributeView.class)
- return (V) new WindowsUserDefinedFileAttributeView(this, followLinks);
- return (V) null;
- }
-
- @Override
- public DynamicFileAttributeView getFileAttributeView(String name, LinkOption... options) {
- boolean followLinks = followLinks(options);
- if (name.equals("basic"))
- return WindowsFileAttributeViews.createBasicView(this, followLinks);
- if (name.equals("dos"))
- return WindowsFileAttributeViews.createDosView(this, followLinks);
- if (name.equals("acl"))
- return new WindowsAclFileAttributeView(this, followLinks);
- if (name.equals("owner"))
- return new FileOwnerAttributeViewImpl(
- new WindowsAclFileAttributeView(this, followLinks));
- if (name.equals("user"))
- return new WindowsUserDefinedFileAttributeView(this, followLinks);
- return null;
- }
-
- @Override
- public WindowsPath createDirectory(FileAttribute<?>... attrs)
- throws IOException
- {
- checkWrite();
- WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.fromAttribute(attrs);
- try {
- CreateDirectory(getPathForWin32Calls(), sd.address());
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- } finally {
- sd.release();
- }
- return this;
- }
-
- @Override
- public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- WindowsSecurityDescriptor sd =
- WindowsSecurityDescriptor.fromAttribute(attrs);
- try {
- return WindowsChannelFactory
- .newFileChannel(getPathForWin32Calls(),
- getPathForPermissionCheck(),
- options,
- sd.address());
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- return null; // keep compiler happy
- } finally {
- sd.release();
- }
- }
-
- @Override
- public boolean isSameFile(Path obj) throws IOException {
- if (this.equals(obj))
- return true;
- if (!(obj instanceof WindowsPath)) // includes null check
- return false;
- WindowsPath other = (WindowsPath)obj;
-
- // check security manager access to both files
- this.checkRead();
- other.checkRead();
-
- // open both files and see if they are the same
- long h1 = 0L;
- try {
- h1 = this.openForReadAttributeAccess(true);
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- }
- try {
- WindowsFileAttributes attrs1 = null;
- try {
- attrs1 = WindowsFileAttributes.readAttributes(h1);
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- }
- long h2 = 0L;
- try {
- h2 = other.openForReadAttributeAccess(true);
- } catch (WindowsException x) {
- x.rethrowAsIOException(other);
- }
- try {
- WindowsFileAttributes attrs2 = null;
- try {
- attrs2 = WindowsFileAttributes.readAttributes(h2);
- } catch (WindowsException x) {
- x.rethrowAsIOException(other);
- }
- return WindowsFileAttributes.isSameFile(attrs1, attrs2);
- } finally {
- CloseHandle(h2);
- }
- } finally {
- CloseHandle(h1);
- }
- }
-
- @Override
- public WindowsPath createSymbolicLink(Path obj, FileAttribute<?>... attrs)
- throws IOException
- {
- if (!getFileSystem().supportsLinks()) {
- throw new UnsupportedOperationException("Symbolic links not supported "
- + "on this operating system");
- }
-
- WindowsPath target = checkPath(obj);
-
- // no attributes allowed
- if (attrs.length > 0) {
- WindowsSecurityDescriptor.fromAttribute(attrs); // may throw NPE or UOE
- throw new UnsupportedOperationException("Initial file attributes" +
- "not supported when creating symbolic link");
- }
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new LinkPermission("symbolic"));
- this.checkWrite();
- }
-
- /**
- * Throw I/O exception for the drive-relative case because Windows
- * creates a link with the resolved target for this case.
- */
- if (target.type == WindowsPathType.DRIVE_RELATIVE) {
- throw new IOException("Cannot create symbolic link to working directory relative target");
- }
-
- /*
- * Windows treates symbolic links to directories differently than it
- * does to other file types. For that reason we need to check if the
- * target is a directory (or a directory junction).
- */
- WindowsPath resolvedTarget;
- if (target.type == WindowsPathType.RELATIVE) {
- WindowsPath parent = getParent();
- resolvedTarget = (parent == null) ? target : parent.resolve(target);
- } else {
- resolvedTarget = resolve(target);
- }
- int flags = 0;
- try {
- WindowsFileAttributes wattrs = WindowsFileAttributes.get(resolvedTarget, false);
- if (wattrs.isDirectory() || wattrs.isDirectoryLink())
- flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
- } catch (WindowsException x) {
- // unable to access target so assume target is not a directory
- }
-
- // create the link
- try {
- CreateSymbolicLink(getPathForWin32Calls(),
- addPrefixIfNeeded(target.toString()),
- flags);
- } catch (WindowsException x) {
- if (x.lastError() == ERROR_INVALID_REPARSE_DATA) {
- x.rethrowAsIOException(this, target);
- } else {
- x.rethrowAsIOException(this);
- }
- }
- return this;
- }
-
- @Override
- public Path createLink(Path obj) throws IOException {
- WindowsPath existing = checkPath(obj);
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new LinkPermission("hard"));
- this.checkWrite();
- existing.checkWrite();
- }
-
- // create hard link
- try {
- CreateHardLink(this.getPathForWin32Calls(),
- existing.getPathForWin32Calls());
- } catch (WindowsException x) {
- x.rethrowAsIOException(this, existing);
- }
-
- return this;
- }
-
- @Override
- public WindowsPath readSymbolicLink() throws IOException {
- if (!getFileSystem().supportsLinks()) {
- throw new UnsupportedOperationException("symbolic links not supported");
- }
-
- // permission check
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- FilePermission perm = new FilePermission(getPathForPermissionCheck(),
- SecurityConstants.FILE_READLINK_ACTION);
- AccessController.checkPermission(perm);
- }
-
- String target = WindowsLinkSupport.readLink(this);
- return createFromNormalizedPath(getFileSystem(), target);
- }
-
- @Override
public URI toUri() {
return WindowsUriSupport.toUri(this);
}
@@ -1283,21 +834,6 @@
}
@Override
- public boolean isHidden() throws IOException {
- checkRead();
- WindowsFileAttributes attrs = null;
- try {
- attrs = WindowsFileAttributes.get(this, true);
- } catch (WindowsException x) {
- x.rethrowAsIOException(this);
- }
- // DOS hidden attribute not meaningful when set on directories
- if (attrs.isDirectory())
- return false;
- return attrs.isHidden();
- }
-
- @Override
public WatchKey register(WatchService watcher,
WatchEvent.Kind<?>[] events,
WatchEvent.Modifier... modifiers)
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java Tue Feb 08 14:25:33 2011 -0800
@@ -74,8 +74,6 @@
* Parses the given input as a Windows path
*/
static Result parse(String input) {
- if (input == null || input.length() == 0)
- throw new InvalidPathException(input, "Empty or null path");
return parse(input, true);
}
@@ -135,7 +133,7 @@
}
}
if (off == 0) {
- if (isSlash(input.charAt(0))) {
+ if (len > 0 && isSlash(input.charAt(0))) {
type = WindowsPathType.DIRECTORY_RELATIVE;
root = "\\";
} else {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java Tue Feb 08 14:25:33 2011 -0800
@@ -214,7 +214,7 @@
// map flags
byte aceFlags = unsafe.getByte(aceAddress + OFFSETOF_FLAGS);
- Set<AclEntryFlag> flags = new HashSet<AclEntryFlag>();
+ Set<AclEntryFlag> flags = EnumSet.noneOf(AclEntryFlag.class);
if ((aceFlags & OBJECT_INHERIT_ACE) != 0)
flags.add(AclEntryFlag.FILE_INHERIT);
if ((aceFlags & CONTAINER_INHERIT_ACE) != 0)
@@ -226,7 +226,7 @@
// map access mask
int mask = unsafe.getInt(aceAddress + OFFSETOF_ACCESS_MASK);
- Set<AclEntryPermission> perms = new HashSet<AclEntryPermission>();
+ Set<AclEntryPermission> perms = EnumSet.noneOf(AclEntryPermission.class);
if ((mask & FILE_READ_DATA) > 0)
perms.add(AclEntryPermission.READ_DATA);
if ((mask & FILE_WRITE_DATA) > 0)
@@ -378,7 +378,7 @@
AclInformation aclInfo = GetAclInformation(aclAddress);
aceCount = aclInfo.aceCount();
}
- ArrayList<AclEntry> result = new ArrayList<AclEntry>(aceCount);
+ ArrayList<AclEntry> result = new ArrayList<>(aceCount);
// decode each of the ACEs to AclEntry objects
for (int i=0; i<aceCount; i++) {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java Tue Feb 08 14:25:33 2011 -0800
@@ -65,7 +65,7 @@
// enumerates the file streams using FindFirstStream/FindNextStream APIs.
private List<String> listUsingStreamEnumeration() throws IOException {
- List<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<>();
try {
FirstStream first = FindFirstStream(file.getPathForWin32Calls());
if (first != null) {
@@ -114,7 +114,7 @@
NativeBuffer buffer = null;
// result with names of alternative data streams
- final List<String> list = new ArrayList<String>();
+ final List<String> list = new ArrayList<>();
try {
buffer = NativeBuffers.getNativeBuffer(BUFFER_SIZE);
@@ -216,7 +216,7 @@
// wrap with channel
FileChannel fc = null;
try {
- Set<OpenOption> opts = new HashSet<OpenOption>();
+ Set<OpenOption> opts = new HashSet<>();
opts.add(READ);
if (!followLinks)
opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
@@ -243,7 +243,7 @@
// wrap with channel
FileChannel fc = null;
try {
- Set<OpenOption> opts = new HashSet<OpenOption>();
+ Set<OpenOption> opts = new HashSet<>();
opts.add(READ);
if (!followLinks)
opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
@@ -298,7 +298,7 @@
x.rethrowAsIOException(file);
}
try {
- Set<OpenOption> opts = new HashSet<OpenOption>();
+ Set<OpenOption> opts = new HashSet<>();
if (!followLinks)
opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
opts.add(CREATE);
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java Tue Feb 08 14:25:33 2011 -0800
@@ -106,8 +106,11 @@
// completion key (used to map I/O completion to WatchKey)
private int completionKey;
- WindowsWatchKey(AbstractWatchService watcher, FileKey fileKey) {
- super(watcher);
+ WindowsWatchKey(Path dir,
+ AbstractWatchService watcher,
+ FileKey fileKey)
+ {
+ super(dir, watcher);
this.fileKey = fileKey;
}
@@ -405,7 +408,7 @@
WindowsWatchKey watchKey;
if (existing == null) {
// not registered so create new watch key
- watchKey = new WindowsWatchKey(watcher, fk)
+ watchKey = new WindowsWatchKey(dir, watcher, fk)
.init(handle, events, watchSubtree, buffer, countAddress,
overlappedAddress, completionKey);
// map file key to watch key
--- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Tue Feb 08 14:25:33 2011 -0800
@@ -220,19 +220,19 @@
/*we estimate the max length of memory needed as
"currentDir. length + pathname.length"
*/
- int len = wcslen(path);
+ int len = (int)wcslen(path);
len += currentDirLength(path, len);
if (len > MAX_PATH_LENGTH - 1) {
WCHAR *cp = (WCHAR*)malloc(len * sizeof(WCHAR));
if (cp != NULL) {
if (wcanonicalize(path, cp, len) >= 0) {
- rv = (*env)->NewString(env, cp, wcslen(cp));
+ rv = (*env)->NewString(env, cp, (jsize)wcslen(cp));
}
free(cp);
}
} else
if (wcanonicalize(path, canonicalPath, MAX_PATH_LENGTH) >= 0) {
- rv = (*env)->NewString(env, canonicalPath, wcslen(canonicalPath));
+ rv = (*env)->NewString(env, canonicalPath, (jsize)wcslen(canonicalPath));
}
} END_UNICODE_STRING(env, path);
if (rv == NULL) {
@@ -251,14 +251,14 @@
WCHAR canonicalPath[MAX_PATH_LENGTH];
WITH_UNICODE_STRING(env, canonicalPrefixString, canonicalPrefix) {
WITH_UNICODE_STRING(env, pathWithCanonicalPrefixString, pathWithCanonicalPrefix) {
- int len = wcslen(canonicalPrefix) + MAX_PATH;
+ int len = (int)wcslen(canonicalPrefix) + MAX_PATH;
if (len > MAX_PATH_LENGTH) {
WCHAR *cp = (WCHAR*)malloc(len * sizeof(WCHAR));
if (cp != NULL) {
if (wcanonicalizeWithPrefix(canonicalPrefix,
pathWithCanonicalPrefix,
cp, len) >= 0) {
- rv = (*env)->NewString(env, cp, wcslen(cp));
+ rv = (*env)->NewString(env, cp, (jsize)wcslen(cp));
}
free(cp);
}
@@ -266,7 +266,7 @@
if (wcanonicalizeWithPrefix(canonicalPrefix,
pathWithCanonicalPrefix,
canonicalPath, MAX_PATH_LENGTH) >= 0) {
- rv = (*env)->NewString(env, canonicalPath, wcslen(canonicalPath));
+ rv = (*env)->NewString(env, canonicalPath, (jsize)wcslen(canonicalPath));
}
} END_UNICODE_STRING(env, pathWithCanonicalPrefix);
} END_UNICODE_STRING(env, canonicalPrefix);
@@ -358,7 +358,7 @@
} else { /* pagefile.sys is a special case */
if (GetLastError() == ERROR_SHARING_VIOLATION) {
rv = java_io_FileSystem_BA_EXISTS;
- if ((pathlen = wcslen(pathbuf)) >= SPECIALFILE_NAMELEN &&
+ if ((pathlen = (jint)wcslen(pathbuf)) >= SPECIALFILE_NAMELEN &&
(_wcsicmp(pathbuf + pathlen - SPECIALFILE_NAMELEN,
L"pagefile.sys") == 0) ||
(_wcsicmp(pathbuf + pathlen - SPECIALFILE_NAMELEN,
@@ -625,7 +625,7 @@
}
/* Remove trailing space chars from directory name */
- len = wcslen(search_path);
+ len = (int)wcslen(search_path);
while (search_path[len-1] == ' ') {
len--;
}
@@ -668,7 +668,7 @@
|| !wcscmp(find_data.cFileName, L".."))
continue;
name = (*env)->NewString(env, find_data.cFileName,
- wcslen(find_data.cFileName));
+ (jsize)wcslen(find_data.cFileName));
if (name == NULL)
return NULL; // error;
if (len == maxlen) {
@@ -819,7 +819,7 @@
jchar *pf = p;
if (p == NULL) return NULL;
if (iswalpha(*p) && (p[1] == L':')) p += 2;
- ret = (*env)->NewString(env, p, wcslen(p));
+ ret = (*env)->NewString(env, p, (jsize)wcslen(p));
free (pf);
return ret;
}
--- a/jdk/src/windows/native/java/io/canonicalize_md.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/native/java/io/canonicalize_md.c Tue Feb 08 14:25:33 2011 -0800
@@ -479,7 +479,7 @@
assert(*src == L'\\'); /* Invariant */
*p = L'\0'; /* Temporarily clear separator */
- if ((pathlen = wcslen(path)) > MAX_PATH - 1) {
+ if ((pathlen = (int)wcslen(path)) > MAX_PATH - 1) {
pathbuf = getPrefixed(path, pathlen);
h = FindFirstFileW(pathbuf, &fd); /* Look up prefix */
free(pathbuf);
@@ -538,7 +538,7 @@
dend = dst + size; /* Don't go to or past here */
- if ((pathlen=wcslen(pathWithCanonicalPrefix)) > MAX_PATH - 1) {
+ if ((pathlen=(int)wcslen(pathWithCanonicalPrefix)) > MAX_PATH - 1) {
pathbuf = getPrefixed(pathWithCanonicalPrefix, pathlen);
h = FindFirstFileW(pathbuf, &fd); /* Look up prefix */
free(pathbuf);
--- a/jdk/src/windows/native/java/io/io_util_md.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/native/java/io/io_util_md.c Tue Feb 08 14:25:33 2011 -0800
@@ -104,7 +104,7 @@
else return 0; /* invalid drive name. */
dir = currentDir(di);
if (dir != NULL){
- dirlen = wcslen(dir);
+ dirlen = (int)wcslen(dir);
free(dir);
}
return dirlen;
@@ -115,7 +115,7 @@
int dirlen = -1;
dir = _wgetcwd(NULL, MAX_PATH);
if (dir != NULL) {
- curDirLenCached = wcslen(dir);
+ curDirLenCached = (int)wcslen(dir);
free(dir);
}
}
@@ -165,7 +165,7 @@
int max_path = 248; /* CreateDirectoryW() has the limit of 248 */
WITH_UNICODE_STRING(env, path, ps) {
- pathlen = wcslen(ps);
+ pathlen = (int)wcslen(ps);
if (pathlen != 0) {
if (pathlen > 2 &&
(ps[0] == L'\\' && ps[1] == L'\\' || //UNC
--- a/jdk/src/windows/native/sun/nio/ch/Iocp.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/native/sun/nio/ch/Iocp.c Tue Feb 08 14:25:33 2011 -0800
@@ -72,9 +72,10 @@
Java_sun_nio_ch_Iocp_createIoCompletionPort(JNIEnv* env, jclass this,
jlong handle, jlong existingPort, jint completionKey, jint concurrency)
{
+ ULONG_PTR ck = completionKey;
HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(handle),
(HANDLE)jlong_to_ptr(existingPort),
- (DWORD)completionKey,
+ ck,
(DWORD)concurrency);
if (port == NULL) {
JNU_ThrowIOExceptionWithLastError(env, "CreateIoCompletionPort failed");
@@ -96,7 +97,7 @@
jlong completionPort, jobject obj)
{
DWORD bytesTransferred;
- DWORD completionKey;
+ ULONG_PTR completionKey;
OVERLAPPED *lpOverlapped;
BOOL res;
--- a/jdk/src/windows/native/sun/nio/fs/RegistryFileTypeDetector.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/native/sun/nio/fs/RegistryFileTypeDetector.c Tue Feb 08 14:25:33 2011 -0800
@@ -51,7 +51,7 @@
res = RegQueryValueExW(hKey, lpValueName, NULL, &type, (LPBYTE)&data, &size);
if (res == ERROR_SUCCESS) {
if (type == REG_SZ) {
- jsize len = wcslen((WCHAR*)data);
+ jsize len = (jsize)wcslen((WCHAR*)data);
result = (*env)->NewString(env, (const jchar*)&data, len);
}
}
--- a/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Tue Feb 08 14:25:33 2011 -0800
@@ -368,7 +368,7 @@
HANDLE handle = FindFirstFileW(lpFileName, &data);
if (handle != INVALID_HANDLE_VALUE) {
- jstring name = (*env)->NewString(env, data.cFileName, wcslen(data.cFileName));
+ jstring name = (*env)->NewString(env, data.cFileName, (jsize)wcslen(data.cFileName));
if (name == NULL)
return;
(*env)->SetLongField(env, obj, findFirst_handle, ptr_to_jlong(handle));
@@ -401,7 +401,7 @@
WIN32_FIND_DATAW* data = (WIN32_FIND_DATAW*)jlong_to_ptr(dataAddress);
if (FindNextFileW(h, data) != 0) {
- return (*env)->NewString(env, data->cFileName, wcslen(data->cFileName));
+ return (*env)->NewString(env, data->cFileName, (jsize)wcslen(data->cFileName));
} else {
if (GetLastError() != ERROR_NO_MORE_FILES)
throwWindowsException(env, GetLastError());
@@ -424,7 +424,7 @@
handle = (*FindFirstStream_func)(lpFileName, FindStreamInfoStandard, &data, 0);
if (handle != INVALID_HANDLE_VALUE) {
- jstring name = (*env)->NewString(env, data.cStreamName, wcslen(data.cStreamName));
+ jstring name = (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
if (name == NULL)
return;
(*env)->SetLongField(env, obj, findStream_handle, ptr_to_jlong(handle));
@@ -452,7 +452,7 @@
}
if ((*FindNextStream_func)(h, &data) != 0) {
- return (*env)->NewString(env, data.cStreamName, wcslen(data.cStreamName));
+ return (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
} else {
if (GetLastError() != ERROR_HANDLE_EOF)
throwWindowsException(env, GetLastError());
@@ -1224,9 +1224,10 @@
Java_sun_nio_fs_WindowsNativeDispatcher_CreateIoCompletionPort(JNIEnv* env, jclass this,
jlong fileHandle, jlong existingPort, jint completionKey)
{
+ ULONG_PTR ck = completionKey;
HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(fileHandle),
(HANDLE)jlong_to_ptr(existingPort),
- (DWORD)completionKey,
+ ck,
0);
if (port == NULL) {
throwWindowsException(env, GetLastError());
@@ -1239,7 +1240,7 @@
jlong completionPort, jobject obj)
{
DWORD bytesTransferred;
- DWORD completionKey;
+ ULONG_PTR completionKey;
OVERLAPPED *lpOverlapped;
BOOL res;
--- a/jdk/test/com/sun/jndi/ldap/LdapName/Case.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/com/sun/jndi/ldap/LdapName/Case.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/*
* @test
* @bug 4278094
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jndi/ldap/LdapName/EmptyNameSearch.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6997561
+ * @summary A request for better error handling in JNDI
+ */
+
+import java.net.Socket;
+import java.net.ServerSocket;
+import java.io.*;
+import javax.naming.*;
+import javax.naming.directory.*;
+import javax.naming.ldap.*;
+import java.util.Collections;
+import java.util.Hashtable;
+
+public class EmptyNameSearch {
+
+ public static void main(String[] args) throws Exception {
+
+ // Start the LDAP server
+ Server s = new Server();
+ s.start();
+ Thread.sleep(3000);
+
+ // Setup JNDI parameters
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, "ldap://localhost:" + s.getPortNumber());
+
+ try {
+
+ // Create initial context
+ System.out.println("Client: connecting...");
+ DirContext ctx = new InitialDirContext(env);
+
+ System.out.println("Client: performing search...");
+ ctx.search(new LdapName(Collections.EMPTY_LIST), "cn=*", null);
+ ctx.close();
+
+ // Exit
+ throw new RuntimeException();
+
+ } catch (NamingException e) {
+ System.err.println("Passed: caught the expected Exception - " + e);
+
+ } catch (Exception e) {
+ System.err.println("Failed: caught an unexpected Exception - " + e);
+ throw e;
+ }
+ }
+
+ static class Server extends Thread {
+
+ private int serverPort = 0;
+ private byte[] bindResponse = {
+ 0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A,
+ 0x01, 0x00, 0x04, 0x00, 0x04, 0x00
+ };
+ private byte[] searchResponse = {
+ 0x30, 0x0C, 0x02, 0x01, 0x02, 0x65, 0x07, 0x0A,
+ 0x01, 0x02, 0x04, 0x00, 0x04, 0x00
+ };
+
+ Server() {
+ }
+
+ public int getPortNumber() {
+ return serverPort;
+ }
+
+ public void run() {
+ try {
+ ServerSocket serverSock = new ServerSocket(0);
+ serverPort = serverSock.getLocalPort();
+ System.out.println("Server: listening on port " + serverPort);
+
+ Socket socket = serverSock.accept();
+ System.out.println("Server: connection accepted");
+
+ InputStream in = socket.getInputStream();
+ OutputStream out = socket.getOutputStream();
+
+ // Read the LDAP BindRequest
+ System.out.println("Server: reading request...");
+ while (in.read() != -1) {
+ in.skip(in.available());
+ break;
+ }
+
+ // Write an LDAP BindResponse
+ System.out.println("Server: writing response...");
+ out.write(bindResponse);
+ out.flush();
+
+ // Read the LDAP SearchRequest
+ System.out.println("Server: reading request...");
+ while (in.read() != -1) {
+ in.skip(in.available());
+ break;
+ }
+
+ // Write an LDAP SearchResponse
+ System.out.println("Server: writing response...");
+ out.write(searchResponse);
+ out.flush();
+
+ in.close();
+ out.close();
+ socket.close();
+ serverSock.close();
+
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+}
--- a/jdk/test/com/sun/jndi/ldap/LdapName/UnescapeTest.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/com/sun/jndi/ldap/LdapName/UnescapeTest.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/*
* @test
* @bug 4892070
--- a/jdk/test/com/sun/jndi/ldap/ReadTimeoutTest.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/com/sun/jndi/ldap/ReadTimeoutTest.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/**
* @test
* @bug 6176036
--- a/jdk/test/demo/zipfs/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/demo/zipfs/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -48,9 +48,9 @@
if (!found)
throw new RuntimeException("'jar' provider not installed");
- // Test: FileSystems#newFileSystem(FileRef)
+ // Test: FileSystems#newFileSystem(Path)
Map<String,?> env = new HashMap<String,Object>();
- FileSystems.newFileSystem(zipfile, env, null).close();
+ FileSystems.newFileSystem(zipfile, null).close();
// Test: FileSystems#newFileSystem(URI)
URI uri = new URI("jar", zipfile.toUri().toString(), null);
@@ -69,14 +69,11 @@
// Test: DirectoryStream
found = false;
- DirectoryStream<Path> stream = fs.getPath("/").newDirectoryStream();
- try {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(fs.getPath("/"))) {
for (Path entry: stream) {
found = entry.toString().equals("/META-INF/");
if (found) break;
}
- } finally {
- stream.close();
}
if (!found)
@@ -84,21 +81,21 @@
// Test: copy file from zip file to current (scratch) directory
Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider");
- if (source.exists()) {
- Path target = Paths.get(source.getName().toString());
- source.copyTo(target, StandardCopyOption.REPLACE_EXISTING);
+ if (Files.exists(source)) {
+ Path target = Paths.get(source.getFileName().toString());
+ Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
try {
- long s1 = Attributes.readBasicFileAttributes(source).size();
- long s2 = Attributes.readBasicFileAttributes(target).size();
+ long s1 = Files.readAttributes(source, BasicFileAttributes.class).size();
+ long s2 = Files.readAttributes(target, BasicFileAttributes.class).size();
if (s2 != s1)
throw new RuntimeException("target size != source size");
} finally {
- target.delete();
+ Files.delete(target);
}
}
// Test: FileStore
- FileStore store = fs.getPath("/").getFileStore();
+ FileStore store = Files.getFileStore(fs.getPath("/"));
if (!store.supportsFileAttributeView("basic"))
throw new RuntimeException("BasicFileAttributeView should be supported");
@@ -107,7 +104,7 @@
if (fs.isOpen())
throw new RuntimeException("FileSystem should be closed");
try {
- fs.getPath("/missing").checkAccess(AccessMode.READ);
+ fs.provider().checkAccess(fs.getPath("/missing"), AccessMode.READ);
} catch (ClosedFileSystemException x) { }
}
@@ -125,9 +122,9 @@
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs)
{
- if (dir.getName() != null) {
+ if (dir.getFileName() != null) {
indent();
- System.out.println(dir.getName() + "/");
+ System.out.println(dir.getFileName() + "/");
indent++;
}
return FileVisitResult.CONTINUE;
@@ -138,7 +135,7 @@
BasicFileAttributes attrs)
{
indent();
- System.out.print(file.getName());
+ System.out.print(file.getFileName());
if (attrs.isRegularFile())
System.out.format(" (%d)", attrs.size());
System.out.println();
@@ -151,7 +148,7 @@
{
if (exc != null)
super.postVisitDirectory(dir, exc);
- if (dir.getName() != null)
+ if (dir.getFileName() != null)
indent--;
return FileVisitResult.CONTINUE;
}
--- a/jdk/test/demo/zipfs/PathOps.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/demo/zipfs/PathOps.java Tue Feb 08 14:25:33 2011 -0800
@@ -100,7 +100,7 @@
PathOps name(String expected) {
out.println("check name");
checkPath();
- check(path.getName(), expected);
+ check(path.getFileName(), expected);
return this;
}
@@ -197,7 +197,7 @@
try {
out.println("check two paths are same");
checkPath();
- check(path.isSameFile(test(target).path()), true);
+ check(Files.isSameFile(path, test(target).path()), true);
} catch (IOException ioe) {
fail();
}
@@ -252,31 +252,41 @@
.name("foo");
// startsWith
+ test("")
+ .starts("")
+ .notStarts("/");
test("/")
.starts("/")
.notStarts("/foo");
test("/foo")
.starts("/")
.starts("/foo")
- .notStarts("/f");
+ .notStarts("/f")
+ .notStarts("");
test("/foo/bar")
.starts("/")
.starts("/foo")
+ .starts("/foo/")
.starts("/foo/bar")
.notStarts("/f")
.notStarts("foo")
- .notStarts("foo/bar");
+ .notStarts("foo/bar")
+ .notStarts("");
test("foo")
.starts("foo")
.notStarts("f");
test("foo/bar")
.starts("foo")
+ .starts("foo/")
.starts("foo/bar")
.notStarts("f")
.notStarts("/foo")
.notStarts("/foo/bar");
// endsWith
+ test("")
+ .ends("")
+ .notEnds("/");
test("/")
.ends("/")
.notEnds("foo")
@@ -288,14 +298,24 @@
test("/foo/bar")
.ends("bar")
.ends("foo/bar")
+ .ends("foo/bar/")
+ .ends("/foo/bar")
+ .notEnds("/bar");
+ test("/foo/bar/")
+ .ends("bar")
+ .ends("foo/bar")
+ .ends("foo/bar/")
.ends("/foo/bar")
.notEnds("/bar");
test("foo")
.ends("foo");
test("foo/bar")
.ends("bar")
+ .ends("bar/")
+ .ends("foo/bar/")
.ends("foo/bar");
+
// elements
test("a/b/c")
.element(0,"a")
@@ -309,6 +329,8 @@
.absolute();
test("tmp")
.notAbsolute();
+ test("")
+ .notAbsolute();
// resolve
test("/tmp")
@@ -320,7 +342,7 @@
// relativize
test("/a/b/c")
- .relativize("/a/b/c", null)
+ .relativize("/a/b/c", "")
.relativize("/a/b/c/d/e", "d/e")
.relativize("/a/x", "../../x");
@@ -332,7 +354,7 @@
test("/foo")
.normalize("/foo");
test(".")
- .normalize(null);
+ .normalize("");
test("..")
.normalize("..");
test("/..")
@@ -344,7 +366,7 @@
test("./foo")
.normalize("foo");
test("foo/..")
- .normalize(null);
+ .normalize("");
test("../foo")
.normalize("../foo");
test("../../foo")
@@ -411,13 +433,13 @@
}
try {
- path.startsWith(null);
+ path.startsWith((Path)null);
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException npe) {
}
try {
- path.endsWith(null);
+ path.endsWith((Path)null);
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException npe) {
}
@@ -427,8 +449,7 @@
public static void main(String[] args) throws Throwable {
Path zipfile = Paths.get(args[0]);
- Map<String,?> env = new HashMap<String,Object>();
- fs = FileSystems.newFileSystem(zipfile, env, null);
+ fs = FileSystems.newFileSystem(zipfile, null);
npes();
doPathOpTests();
fs.close();
--- a/jdk/test/demo/zipfs/ZipFSTester.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/demo/zipfs/ZipFSTester.java Tue Feb 08 14:25:33 2011 -0800
@@ -25,6 +25,7 @@
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
+import java.nio.file.spi.*;
import java.nio.file.attribute.*;
import java.net.*;
import java.util.*;
@@ -40,15 +41,13 @@
public class ZipFSTester {
public static void main(String[] args) throws Throwable {
- FileSystem fs = null;
- try {
- fs = newZipFileSystem(Paths.get(args[0]), new HashMap<String, Object>());
+
+ try (FileSystem fs = newZipFileSystem(Paths.get(args[0]),
+ new HashMap<String, Object>()))
+ {
test0(fs);
test1(fs);
test2(fs); // more tests
- } finally {
- if (fs != null)
- fs.close();
}
}
@@ -63,17 +62,17 @@
}
for (String pname : list) {
Path path = fs.getPath(pname);
- if (!path.exists())
+ if (!Files.exists(path))
throw new RuntimeException("path existence check failed!");
while ((path = path.getParent()) != null) {
- if (!path.exists())
+ if (!Files.exists(path))
throw new RuntimeException("parent existence check failed!");
}
}
}
}
- static void test1(FileSystem fs)
+ static void test1(FileSystem fs0)
throws Exception
{
Random rdm = new Random();
@@ -81,16 +80,26 @@
Path tmpfsPath = getTempPath();
Map<String, Object> env = new HashMap<String, Object>();
env.put("create", "true");
- FileSystem fs0 = newZipFileSystem(tmpfsPath, env);
- z2zcopy(fs, fs0, "/", 0);
- fs0.close(); // sync to file
+ try (FileSystem copy = newZipFileSystem(tmpfsPath, env)) {
+ z2zcopy(fs0, copy, "/", 0);
+ }
+
+ try (FileSystem fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>())) {
- fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>());
- try {
+ FileSystemProvider provider = fs.provider();
+ // newFileSystem(path...) should not throw exception
+ try (FileSystem fsPath = provider.newFileSystem(tmpfsPath, new HashMap<String, Object>())){}
+ try (FileSystem fsUri = provider.newFileSystem(
+ new URI("jar", tmpfsPath.toUri().toString(), null),
+ new HashMap<String, Object>()))
+ {
+ throw new RuntimeException("newFileSystem(uri...) does not throw exception");
+ } catch (FileSystemAlreadyExistsException fsaee) {}
+
// prepare a src
Path src = getTempPath();
String tmpName = src.toString();
- OutputStream os = src.newOutputStream();
+ OutputStream os = Files.newOutputStream(src);
byte[] bits = new byte[12345];
rdm.nextBytes(bits);
os.write(bits);
@@ -98,37 +107,37 @@
// copyin
Path dst = getPathWithParents(fs, tmpName);
- src.copyTo(dst);
+ Files.copy(src, dst);
checkEqual(src, dst);
// copy
Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) +
"/efg" + rdm.nextInt(100) + "/foo.class");
- dst.copyTo(dst2);
+ Files.copy(dst, dst2);
//dst.moveTo(dst2);
checkEqual(src, dst2);
// delete
- dst.delete();
- if (dst.exists())
+ Files.delete(dst);
+ if (Files.exists(dst))
throw new RuntimeException("Failed!");
// moveout
Path dst3 = Paths.get(tmpName + "_Tmp");
- dst2.moveTo(dst3);
+ Files.move(dst2, dst3);
checkEqual(src, dst3);
// delete
- if (dst2.exists())
+ if (Files.exists(dst2))
throw new RuntimeException("Failed!");
- dst3.delete();
- if (dst3.exists())
+ Files.delete(dst3);
+ if (Files.exists(dst3))
throw new RuntimeException("Failed!");
// newInputStream on dir
Path parent = dst2.getParent();
try {
- parent.newInputStream();
+ Files.newInputStream(parent);
throw new RuntimeException("Failed");
} catch (FileSystemException e) {
e.printStackTrace(); // expected fse
@@ -147,17 +156,15 @@
Path tmp = Paths.get(tmpName + "_Tmp");
fchCopy(dst, tmp); // out
checkEqual(src, tmp);
- tmp.delete();
+ Files.delete(tmp);
// test channels
channel(fs, dst);
- dst.delete();
- src.delete();
+ Files.delete(dst);
+ Files.delete(src);
} finally {
- if (fs != null)
- fs.close();
- if (tmpfsPath.exists())
- tmpfsPath.delete();
+ if (Files.exists(tmpfsPath))
+ Files.delete(tmpfsPath);
}
}
@@ -242,7 +249,7 @@
while (itr.hasNext()) {
String path = itr.next();
try {
- if (fs2.getPath(path).exists()) {
+ if (Files.exists(fs2.getPath(path))) {
z2zmove(fs2, fs3, path);
itr.remove();
}
@@ -296,15 +303,16 @@
fs4.close();
System.out.printf("failed=%d%n", failed);
- fs1Path.delete();
- fs2Path.delete();
- fs3Path.delete();
+ Files.delete(fs1Path);
+ Files.delete(fs2Path);
+ Files.delete(fs3Path);
}
private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
- throws IOException
+ throws Exception
{
- return FileSystems.newFileSystem(path, env, null);
+ return FileSystems.newFileSystem(
+ new URI("jar", path.toUri().toString(), null), env, null);
}
private static Path getTempPath() throws IOException
@@ -317,11 +325,11 @@
private static void list(Path path, List<String> files, List<String> dirs )
throws IOException
{
- if (Attributes.readBasicFileAttributes(path).isDirectory()) {
- DirectoryStream<Path> ds = path.newDirectoryStream();
- for (Path child : ds)
- list(child, files, dirs);
- ds.close();
+ if (Files.isDirectory(path)) {
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
+ for (Path child : ds)
+ list(child, files, dirs);
+ }
dirs.add(path.toString());
} else {
files.add(path.toString());
@@ -335,26 +343,26 @@
Path srcPath = src.getPath(path);
Path dstPath = dst.getPath(path);
- if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
- if (!dstPath.exists()) {
+ if (Files.isDirectory(srcPath)) {
+ if (!Files.exists(dstPath)) {
try {
mkdirs(dstPath);
} catch (FileAlreadyExistsException x) {}
}
- DirectoryStream<Path> ds = srcPath.newDirectoryStream();
- for (Path child : ds) {
- z2zcopy(src, dst,
- path + (path.endsWith("/")?"":"/") + child.getName(),
- method);
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(srcPath)) {
+ for (Path child : ds) {
+ z2zcopy(src, dst,
+ path + (path.endsWith("/")?"":"/") + child.getFileName(),
+ method);
+ }
}
- ds.close();
} else {
try {
- if (dstPath.exists())
+ if (Files.exists(dstPath))
return;
switch (method) {
case 0:
- srcPath.copyTo(dstPath);
+ Files.copy(srcPath, dstPath);
break;
case 1:
chCopy(srcPath, dstPath);
@@ -374,21 +382,21 @@
Path srcPath = src.getPath(path);
Path dstPath = dst.getPath(path);
- if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
- if (!dstPath.exists())
+ if (Files.isDirectory(srcPath)) {
+ if (!Files.exists(dstPath))
mkdirs(dstPath);
- DirectoryStream<Path> ds = srcPath.newDirectoryStream();
- for (Path child : ds) {
- z2zmove(src, dst,
- path + (path.endsWith("/")?"":"/") + child.getName());
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(srcPath)) {
+ for (Path child : ds) {
+ z2zmove(src, dst,
+ path + (path.endsWith("/")?"":"/") + child.getFileName());
+ }
}
- ds.close();
} else {
//System.out.println("moving..." + path);
Path parent = dstPath.getParent();
- if (parent != null && parent.notExists())
+ if (parent != null && Files.notExists(parent))
mkdirs(parent);
- srcPath.moveTo(dstPath);
+ Files.move(srcPath, dstPath);
}
}
@@ -409,7 +417,7 @@
BasicFileAttributes attrs)
{
indent();
- System.out.printf("%s%n", file.getName().toString());
+ System.out.printf("%s%n", file.getFileName().toString());
return FileVisitResult.CONTINUE;
}
@@ -435,20 +443,20 @@
}
private static void mkdirs(Path path) throws IOException {
- if (path.exists())
+ if (Files.exists(path))
return;
path = path.toAbsolutePath();
Path parent = path.getParent();
if (parent != null) {
- if (parent.notExists())
+ if (Files.notExists(parent))
mkdirs(parent);
}
- path.createDirectory();
+ Files.createDirectory(path);
}
private static void rmdirs(Path path) throws IOException {
while (path != null && path.getNameCount() != 0) {
- path.delete();
+ Files.delete(path);
path = path.getParent();
}
}
@@ -460,12 +468,11 @@
// src.toString(), dst.toString());
//streams
- InputStream isSrc = src.newInputStream();
- InputStream isDst = dst.newInputStream();
byte[] bufSrc = new byte[8192];
byte[] bufDst = new byte[8192];
-
- try {
+ try (InputStream isSrc = Files.newInputStream(src);
+ InputStream isDst = Files.newInputStream(dst))
+ {
int nSrc = 0;
while ((nSrc = isSrc.read(bufSrc)) != -1) {
int nDst = 0;
@@ -487,24 +494,21 @@
nSrc--;
}
}
- } finally {
- isSrc.close();
- isDst.close();
}
// channels
- SeekableByteChannel chSrc = src.newByteChannel();
- SeekableByteChannel chDst = dst.newByteChannel();
- if (chSrc.size() != chDst.size()) {
- System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
- chSrc.toString(), chSrc.size(),
- chDst.toString(), chDst.size());
- throw new RuntimeException("CHECK FAILED!");
- }
- ByteBuffer bbSrc = ByteBuffer.allocate(8192);
- ByteBuffer bbDst = ByteBuffer.allocate(8192);
+ try (SeekableByteChannel chSrc = Files.newByteChannel(src);
+ SeekableByteChannel chDst = Files.newByteChannel(dst))
+ {
+ if (chSrc.size() != chDst.size()) {
+ System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
+ chSrc.toString(), chSrc.size(),
+ chDst.toString(), chDst.size());
+ throw new RuntimeException("CHECK FAILED!");
+ }
+ ByteBuffer bbSrc = ByteBuffer.allocate(8192);
+ ByteBuffer bbDst = ByteBuffer.allocate(8192);
- try {
int nSrc = 0;
while ((nSrc = chSrc.read(bbSrc)) != -1) {
int nDst = chDst.read(bbDst);
@@ -526,9 +530,6 @@
}
} catch (IOException x) {
x.printStackTrace();
- } finally {
- chSrc.close();
- chDst.close();
}
}
@@ -540,23 +541,19 @@
openwrite.add(CREATE_NEW);
openwrite.add(WRITE);
- FileChannel srcFc = src.getFileSystem()
- .provider()
- .newFileChannel(src, read);
- FileChannel dstFc = dst.getFileSystem()
- .provider()
- .newFileChannel(dst, openwrite);
-
- try {
+ try (FileChannel srcFc = src.getFileSystem()
+ .provider()
+ .newFileChannel(src, read);
+ FileChannel dstFc = dst.getFileSystem()
+ .provider()
+ .newFileChannel(dst, openwrite))
+ {
ByteBuffer bb = ByteBuffer.allocate(8192);
while (srcFc.read(bb) >= 0) {
bb.flip();
dstFc.write(bb);
bb.clear();
}
- } finally {
- srcFc.close();
- dstFc.close();
}
}
@@ -568,35 +565,29 @@
openwrite.add(CREATE_NEW);
openwrite.add(WRITE);
- SeekableByteChannel srcCh = src.newByteChannel(read);
- SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
+ try (SeekableByteChannel srcCh = Files.newByteChannel(src, read);
+ SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite))
+ {
- try {
ByteBuffer bb = ByteBuffer.allocate(8192);
while (srcCh.read(bb) >= 0) {
bb.flip();
dstCh.write(bb);
bb.clear();
}
- } finally {
- srcCh.close();
- dstCh.close();
}
}
private static void streamCopy(Path src, Path dst) throws IOException
{
- InputStream isSrc = src.newInputStream();
- OutputStream osDst = dst.newOutputStream();
byte[] buf = new byte[8192];
- try {
+ try (InputStream isSrc = Files.newInputStream(src);
+ OutputStream osDst = Files.newOutputStream(dst))
+ {
int n = 0;
while ((n = isSrc.read(buf)) != -1) {
osDst.write(buf, 0, n);
}
- } finally {
- isSrc.close();
- osDst.close();
}
}
@@ -604,31 +595,35 @@
throws Exception
{
System.out.println("test ByteChannel...");
- SeekableByteChannel sbc = path.newByteChannel();
Set<OpenOption> read = new HashSet<>();
read.add(READ);
- System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size());
- ByteBuffer bb = ByteBuffer.allocate((int)sbc.size());
- int n = sbc.read(bb);
- System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n",
- n, sbc.position(), sbc.size());
- ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size());
+ int n = 0;
+ ByteBuffer bb = null;
+ ByteBuffer bb2 = null;
int N = 120;
- sbc.close();
+
+ try (SeekableByteChannel sbc = Files.newByteChannel(path)) {
+ System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size());
+ bb = ByteBuffer.allocate((int)sbc.size());
+ n = sbc.read(bb);
+ System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n",
+ n, sbc.position(), sbc.size());
+ bb2 = ByteBuffer.allocate((int)sbc.size());
+ }
// sbc.position(pos) is not supported in current version
// try the FileChannel
- sbc = fs.provider().newFileChannel(path, read);
- sbc.position(N);
- System.out.printf(" sbc[2]: pos=%d, size=%d%n",
- sbc.position(), sbc.size());
- bb2.limit(100);
- n = sbc.read(bb2);
- System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n",
- n, sbc.position(), sbc.size());
- System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n",
- N, bb.get(N) & 0xff, bb2.get(0) & 0xff);
- sbc.close();
+ try (SeekableByteChannel sbc = fs.provider().newFileChannel(path, read)) {
+ sbc.position(N);
+ System.out.printf(" sbc[2]: pos=%d, size=%d%n",
+ sbc.position(), sbc.size());
+ bb2.limit(100);
+ n = sbc.read(bb2);
+ System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n",
+ n, sbc.position(), sbc.size());
+ System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n",
+ N, bb.get(N) & 0xff, bb2.get(0) & 0xff);
+ }
}
// create parents if does not exist
@@ -637,7 +632,7 @@
{
Path path = fs.getPath(name);
Path parent = path.getParent();
- if (parent != null && parent.notExists())
+ if (parent != null && Files.notExists(parent))
mkdirs(parent);
return path;
}
--- a/jdk/test/demo/zipfs/basic.sh Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/demo/zipfs/basic.sh Tue Feb 08 14:25:33 2011 -0800
@@ -21,7 +21,7 @@
# questions.
#
# @test
-# @bug 6990846 7009092 7009085
+# @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840
# @summary Test ZipFileSystem demo
# @build Basic PathOps ZipFSTester
# @run shell basic.sh
--- a/jdk/test/java/io/File/IsHidden.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/io/File/IsHidden.java Tue Feb 08 14:25:33 2011 -0800
@@ -27,6 +27,7 @@
*/
import java.io.*;
+import java.nio.file.Files;
import java.nio.file.attribute.DosFileAttributeView;
public class IsHidden {
@@ -42,7 +43,7 @@
}
private static void setHidden(File f, boolean value) throws IOException {
- f.toPath().getFileAttributeView(DosFileAttributeView.class).setHidden(value);
+ Files.getFileAttributeView(f.toPath(), DosFileAttributeView.class).setHidden(value);
}
private static void testWin32() throws Exception {
--- a/jdk/test/java/io/File/SetAccess.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/io/File/SetAccess.java Tue Feb 08 14:25:33 2011 -0800
@@ -27,6 +27,7 @@
*/
import java.io.*;
+import java.nio.file.*;
import java.nio.file.attribute.*;
public class SetAccess {
@@ -178,7 +179,7 @@
}
private static String permission(File f) throws Exception {
- PosixFileAttributes attrs = Attributes.readPosixFileAttributes(f.toPath());
+ PosixFileAttributes attrs = Files.readAttributes(f.toPath(), PosixFileAttributes.class);
String type = attrs.isDirectory() ? "d" : " ";
return type + PosixFilePermissions.toString(attrs.permissions());
}
--- a/jdk/test/java/io/File/SymLinks.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/io/File/SymLinks.java Tue Feb 08 14:25:33 2011 -0800
@@ -27,7 +27,7 @@
*/
import java.io.*;
-import java.nio.file.Path;
+import java.nio.file.*;
import java.nio.file.attribute.*;
import static java.nio.file.LinkOption.*;
@@ -80,39 +80,33 @@
if (file != null)
file.delete();
if (link2file != null)
- link2file.toPath().deleteIfExists();
+ Files.deleteIfExists(link2file.toPath());
if (link2link2file != null)
- link2link2file.toPath().deleteIfExists();
+ Files.deleteIfExists(link2link2file.toPath());
if (dir != null)
dir.delete();
if (link2dir != null)
- link2dir.toPath().deleteIfExists();
+ Files.deleteIfExists(link2dir.toPath());
if (link2link2dir != null)
- link2link2dir.toPath().deleteIfExists();
+ Files.deleteIfExists(link2link2dir.toPath());
if (link2nobody != null)
- link2nobody.toPath().deleteIfExists();
+ Files.deleteIfExists(link2nobody.toPath());
if (link2link2nobody != null)
- link2link2nobody.toPath().deleteIfExists();
+ Files.deleteIfExists(link2link2nobody.toPath());
}
/**
* Creates a sym link source->target
*/
static void mklink(File source, File target) throws IOException {
- source.toPath().createSymbolicLink(target.toPath());
+ Files.createSymbolicLink(source.toPath(), target.toPath());
}
/**
* Returns true if the "link" exists and is a sym link.
*/
static boolean isSymLink(File link) {
- try {
- BasicFileAttributes attrs =
- Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS);
- return attrs.isSymbolicLink();
- } catch (IOException x) {
- return false;
- }
+ return Files.isSymbolicLink(link.toPath());
}
/**
@@ -120,7 +114,7 @@
*/
static long lastModifiedOfSymLink(File link) throws IOException {
BasicFileAttributes attrs =
- Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS);
+ Files.readAttributes(link.toPath(), BasicFileAttributes.class, NOFOLLOW_LINKS);
assertTrue(attrs.isSymbolicLink());
return attrs.lastModifiedTime().toMillis();
}
@@ -133,8 +127,8 @@
Path link = dir.toPath().resolve("link");
Path target = dir.toPath().resolve("target");
try {
- link.createSymbolicLink(target);
- link.delete();
+ Files.createSymbolicLink(link, target);
+ Files.delete(link);
return true;
} catch (UnsupportedOperationException x) {
return false;
@@ -224,7 +218,7 @@
assertTrue(isSymLink(link2nobody));
} finally {
- link.toPath().deleteIfExists();
+ Files.deleteIfExists(link.toPath());
}
header("renameTo");
@@ -287,8 +281,8 @@
// on Windows we test with the DOS hidden attribute set
if (System.getProperty("os.name").startsWith("Windows")) {
- DosFileAttributeView view = file.toPath()
- .getFileAttributeView(DosFileAttributeView.class);
+ DosFileAttributeView view = Files
+ .getFileAttributeView(file.toPath(), DosFileAttributeView.class);
view.setHidden(true);
try {
assertTrue(file.isHidden());
--- a/jdk/test/java/io/FileInputStream/LargeFileAvailable.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/io/FileInputStream/LargeFileAvailable.java Tue Feb 08 14:25:33 2011 -0800
@@ -31,6 +31,7 @@
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
+import java.nio.file.Files;
import static java.nio.file.StandardOpenOption.*;
public class LargeFileAvailable {
@@ -85,7 +86,7 @@
// Create a large file as a sparse file if possible
File largefile = File.createTempFile("largefile", null);
// re-create as a sparse file
- largefile.toPath().delete();
+ Files.delete(largefile.toPath());
try (FileChannel fc =
FileChannel.open(largefile.toPath(),
CREATE_NEW, WRITE, SPARSE)) {
--- a/jdk/test/java/lang/Double/ParseDouble.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/lang/Double/ParseDouble.java Tue Feb 08 14:25:33 2011 -0800
@@ -23,11 +23,12 @@
/*
* @test
- * @bug 4160406 4705734 4707389 4826774 4895911
+ * @bug 4160406 4705734 4707389 4826774 4895911 4421494
* @summary Test for Double.parseDouble method and acceptance regex
*/
import java.util.regex.*;
+import java.math.BigDecimal;
public class ParseDouble {
@@ -416,7 +417,15 @@
"0x00100p1",
"0x00.100p1",
- "0x001.100p1"
+ "0x001.100p1",
+
+ // Limits
+
+ "1.7976931348623157E308", // Double.MAX_VALUE
+ "4.9e-324", // Double.MIN_VALUE
+ "2.2250738585072014e-308", // Double.MIN_NORMAL
+
+ "2.2250738585072012e-308", // near Double.MIN_NORMAL
};
static String paddedBadStrings[];
@@ -546,6 +555,32 @@
}
+ /**
+ * For each subnormal power of two, test at boundaries of
+ * region that should convert to that value.
+ */
+ private static void testSubnormalPowers() {
+ BigDecimal TWO = BigDecimal.valueOf(2);
+ // An ulp is the same for all subnormal values
+ BigDecimal ulp_BD = new BigDecimal(Double.MIN_VALUE);
+
+ // Test subnormal powers of two
+ for(int i = -1074; i <= -1022; i++) {
+ double d = Math.scalb(1.0, i);
+
+ /*
+ * The region [d - ulp/2, d + ulp/2] should round to d.
+ */
+ BigDecimal d_BD = new BigDecimal(d);
+
+ BigDecimal lowerBound = d_BD.subtract(ulp_BD.divide(TWO));
+ BigDecimal upperBound = d_BD.add(ulp_BD.divide(TWO));
+
+ double convertedLowerBound = Double.parseDouble(lowerBound.toString());
+ double convertedUpperBound = Double.parseDouble(upperBound.toString());
+ }
+ }
+
public static void main(String[] args) throws Exception {
rudimentaryTest();
@@ -558,5 +593,7 @@
testRegex(paddedGoodStrings, false);
testRegex(badStrings, true);
testRegex(paddedBadStrings, true);
+
+ testSubnormalPowers();
}
}
--- a/jdk/test/java/lang/Runtime/exec/Duped.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/lang/Runtime/exec/Duped.java Tue Feb 08 14:25:33 2011 -0800
@@ -38,8 +38,7 @@
public static void main(String args[]) throws Exception {
StringBuffer s = new StringBuffer();
int c;
- while ((System.in.available() != 0)
- && ((c = System.in.read()) != -1))
+ while ((c = System.in.read()) != -1)
s.append((char)c);
System.out.println(s);
}
--- a/jdk/test/java/net/Socks/SocksProxyVersion.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/net/Socks/SocksProxyVersion.java Tue Feb 08 14:25:33 2011 -0800
@@ -36,15 +36,22 @@
import java.io.IOException;
public class SocksProxyVersion implements Runnable {
- ServerSocket ss;
+ final ServerSocket ss;
volatile boolean failed;
public static void main(String[] args) throws Exception {
new SocksProxyVersion();
}
+ @SuppressWarnings("try")
public SocksProxyVersion() throws Exception {
ss = new ServerSocket(0);
+ try (ServerSocket socket = ss) {
+ runTest();
+ }
+ }
+
+ void runTest() throws Exception {
int port = ss.getLocalPort();
Thread serverThread = new Thread(this);
serverThread.start();
@@ -75,22 +82,21 @@
}
public void run() {
- try (ss) {
- Socket s = ss.accept();
- int version = (s.getInputStream()).read();
- if (version != 4) {
- System.out.println("Got " + version + ", expected 4");
- failed = true;
+ try {
+ try (Socket s = ss.accept()) {
+ int version = (s.getInputStream()).read();
+ if (version != 4) {
+ System.out.println("Got " + version + ", expected 4");
+ failed = true;
+ }
}
- s.close();
-
- s = ss.accept();
- version = (s.getInputStream()).read();
- if (version != 5) {
- System.out.println("Got " + version + ", expected 5");
- failed = true;
+ try (Socket s = ss.accept()) {
+ int version = (s.getInputStream()).read();
+ if (version != 5) {
+ System.out.println("Got " + version + ", expected 5");
+ failed = true;
+ }
}
- s.close();
} catch (IOException e) {
e.printStackTrace();
}
--- a/jdk/test/java/nio/MappedByteBuffer/Force.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/MappedByteBuffer/Force.java Tue Feb 08 14:25:33 2011 -0800
@@ -37,14 +37,17 @@
Random random = new Random();
long filesize = random.nextInt(3*1024*1024);
int cut = random.nextInt((int)filesize);
- File file = new File("Blah");
- RandomAccessFile raf = new RandomAccessFile(file, "rw");
- raf.setLength(filesize);
- FileChannel fc = raf.getChannel();
- MappedByteBuffer buf1 = fc.map(
- FileChannel.MapMode.READ_WRITE, cut, filesize-cut);
- buf1.force();
- fc.close();
- raf.close();
+ File file = File.createTempFile("Blah", null);
+ file.deleteOnExit();
+ try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
+ raf.setLength(filesize);
+ FileChannel fc = raf.getChannel();
+ MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, cut, filesize-cut);
+ mbb.force();
+ }
+
+ // improve chance that mapped buffer will be unmapped
+ System.gc();
+ Thread.sleep(500);
}
}
--- a/jdk/test/java/nio/MappedByteBuffer/ZeroMap.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/MappedByteBuffer/ZeroMap.java Tue Feb 08 14:25:33 2011 -0800
@@ -37,16 +37,19 @@
Random random = new Random();
long filesize = random.nextInt(1024*1024);
int cut = random.nextInt((int)filesize);
- File file = new File("Blah");
- RandomAccessFile raf = new RandomAccessFile(file, "rw");
- raf.setLength(filesize);
- FileChannel fc = raf.getChannel();
- MappedByteBuffer buf1 = fc.map(
- FileChannel.MapMode.READ_WRITE, cut, 0);
- buf1.force();
- buf1.load();
- buf1.isLoaded();
- fc.close();
- raf.close();
+ File file = File.createTempFile("Blah", null);
+ file.deleteOnExit();
+ try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
+ raf.setLength(filesize);
+ FileChannel fc = raf.getChannel();
+ MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, cut, 0);
+ mbb.force();
+ mbb.load();
+ mbb.isLoaded();
+ }
+
+ // improve chance that mapped buffer will be unmapped
+ System.gc();
+ Thread.sleep(500);
}
}
--- a/jdk/test/java/nio/channels/FileChannel/AtomicAppend.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/channels/FileChannel/AtomicAppend.java Tue Feb 08 14:25:33 2011 -0800
@@ -36,6 +36,7 @@
import java.util.concurrent.TimeUnit;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import java.nio.file.Files;
import static java.nio.file.StandardOpenOption.*;
public class AtomicAppend {
@@ -55,7 +56,7 @@
if (rand.nextBoolean()) {
return new FileOutputStream(file, true);
} else {
- return file.toPath().newOutputStream(APPEND);
+ return Files.newOutputStream(file.toPath(), APPEND);
}
}
--- a/jdk/test/java/nio/channels/FileChannel/Transfer.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/channels/FileChannel/Transfer.java Tue Feb 08 14:25:33 2011 -0800
@@ -276,7 +276,7 @@
while (fc == null) {
sink = File.createTempFile("sink", null);
// re-create as a sparse file
- sink.toPath().delete();
+ sink.delete();
try {
fc = FileChannel.open(sink.toPath(),
StandardOpenOption.CREATE_NEW,
--- a/jdk/test/java/nio/channels/FileChannel/Truncate.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/channels/FileChannel/Truncate.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,30 +58,31 @@
for(int i=0; i<100; i++) {
long testSize = generator.nextInt(1000) + 10;
initTestFile(blah, testSize);
- FileChannel fc = (i < 50) ?
- new RandomAccessFile(blah, "rw").getChannel() :
- FileChannel.open(blah.toPath(), READ, WRITE);
- try (fc) {
- if (fc.size() != testSize)
- throw new RuntimeException("Size failed");
- long position = generator.nextInt((int)testSize);
- fc.position(position);
+ try (FileChannel fc = (i < 50) ?
+ new RandomAccessFile(blah, "rw").getChannel() :
+ FileChannel.open(blah.toPath(), READ, WRITE))
+ {
+ if (fc.size() != testSize)
+ throw new RuntimeException("Size failed");
+
+ long position = generator.nextInt((int)testSize);
+ fc.position(position);
- long newSize = generator.nextInt((int)testSize);
- fc.truncate(newSize);
+ long newSize = generator.nextInt((int)testSize);
+ fc.truncate(newSize);
- if (fc.size() != newSize)
- throw new RuntimeException("Truncate failed");
+ if (fc.size() != newSize)
+ throw new RuntimeException("Truncate failed");
- if (position > newSize) {
- if (fc.position() != newSize)
- throw new RuntimeException("Position greater than size");
- } else {
- if (fc.position() != position)
- throw new RuntimeException("Truncate changed position");
- };
- }
+ if (position > newSize) {
+ if (fc.position() != newSize)
+ throw new RuntimeException("Position greater than size");
+ } else {
+ if (fc.position() != position)
+ throw new RuntimeException("Truncate changed position");
+ };
+ }
}
}
@@ -92,24 +93,24 @@
for (int i=0; i<10; i++) {
long testSize = generator.nextInt(1000) + 10;
initTestFile(blah, testSize);
- FileChannel fc = (i < 5) ?
- new FileOutputStream(blah, true).getChannel() :
- FileChannel.open(blah.toPath(), APPEND);
- try (fc) {
- // truncate file
- long newSize = generator.nextInt((int)testSize);
- fc.truncate(newSize);
- if (fc.size() != newSize)
- throw new RuntimeException("Truncate failed");
+ try (FileChannel fc = (i < 5) ?
+ new FileOutputStream(blah, true).getChannel() :
+ FileChannel.open(blah.toPath(), APPEND))
+ {
+ // truncate file
+ long newSize = generator.nextInt((int)testSize);
+ fc.truncate(newSize);
+ if (fc.size() != newSize)
+ throw new RuntimeException("Truncate failed");
- // write one byte
- ByteBuffer buf = ByteBuffer.allocate(1);
- buf.put((byte)'x');
- buf.flip();
- fc.write(buf);
- if (fc.size() != (newSize+1))
- throw new RuntimeException("Unexpected size");
- }
+ // write one byte
+ ByteBuffer buf = ByteBuffer.allocate(1);
+ buf.put((byte)'x');
+ buf.flip();
+ fc.write(buf);
+ if (fc.size() != (newSize+1))
+ throw new RuntimeException("Unexpected size");
+ }
}
}
--- a/jdk/test/java/nio/file/DirectoryStream/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/DirectoryStream/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -28,6 +28,7 @@
*/
import java.nio.file.*;
+import static java.nio.file.Files.*;
import java.util.*;
import java.io.IOException;
@@ -38,29 +39,26 @@
DirectoryStream<Path> stream;
// test that directory is empty
- stream = dir.newDirectoryStream();
- try {
- if (stream.iterator().hasNext())
+ try (DirectoryStream<Path> ds = newDirectoryStream(dir)) {
+ if (ds.iterator().hasNext())
throw new RuntimeException("directory not empty");
- } finally {
- stream.close();
}
// create file in directory
final Path foo = Paths.get("foo");
- dir.resolve(foo).createFile();
+ createFile(dir.resolve(foo));
// iterate over directory and check there is one entry
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
found = false;
try {
for (Path entry: stream) {
- if (entry.getName().equals(foo)) {
+ if (entry.getFileName().equals(foo)) {
if (found)
throw new RuntimeException("entry already found");
found = true;
} else {
- throw new RuntimeException("entry " + entry.getName() +
+ throw new RuntimeException("entry " + entry.getFileName() +
" not expected");
}
}
@@ -71,21 +69,18 @@
throw new RuntimeException("entry not found");
// check filtering: f* should match foo
- DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<>() {
private PathMatcher matcher =
dir.getFileSystem().getPathMatcher("glob:f*");
public boolean accept(Path file) {
return matcher.matches(file);
}
};
- stream = dir.newDirectoryStream(filter);
- try {
- for (Path entry: stream) {
- if (!entry.getName().equals(foo))
+ try (DirectoryStream<Path> ds = newDirectoryStream(dir, filter)) {
+ for (Path entry: ds) {
+ if (!entry.getFileName().equals(foo))
throw new RuntimeException("entry not expected");
}
- } finally {
- stream.close();
}
// check filtering: z* should not match any files
@@ -96,12 +91,9 @@
return matcher.matches(file);
}
};
- stream = dir.newDirectoryStream(filter);
- try {
- if (stream.iterator().hasNext())
+ try (DirectoryStream<Path> ds = newDirectoryStream(dir, filter)) {
+ if (ds.iterator().hasNext())
throw new RuntimeException("no matching entries expected");
- } finally {
- stream.close();
}
// check that an IOException thrown by a filter is propagated
@@ -110,7 +102,7 @@
throw new java.util.zip.ZipException();
}
};
- stream = dir.newDirectoryStream(filter);
+ stream = newDirectoryStream(dir, filter);
try {
stream.iterator().hasNext();
throw new RuntimeException("DirectoryIteratorException expected");
@@ -124,7 +116,7 @@
// check that exception or error thrown by filter is not thrown
// by newDirectoryStream or iterator method.
- stream = dir.newDirectoryStream(new DirectoryStream.Filter<Path>() {
+ stream = newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
public boolean accept(Path file) {
throw new RuntimeException("Should not be visible");
}
@@ -137,13 +129,13 @@
// test NotDirectoryException
try {
- dir.resolve(foo).newDirectoryStream();
+ newDirectoryStream(dir.resolve(foo));
throw new RuntimeException("NotDirectoryException not thrown");
} catch (NotDirectoryException x) {
}
// test UnsupportedOperationException
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
Iterator<Path> i = stream.iterator();
i.next();
try {
@@ -153,7 +145,7 @@
}
// test IllegalStateException
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
stream.iterator();
try {
// attempt to obtain second iterator
@@ -163,7 +155,7 @@
}
stream.close();
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
stream.close();
try {
// attempt to obtain iterator after stream is closed
@@ -173,13 +165,13 @@
}
// test that iterator reads to end of stream when closed
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
i = stream.iterator();
stream.close();
while (i.hasNext())
i.next();
- stream = dir.newDirectoryStream();
+ stream = newDirectoryStream(dir);
i = stream.iterator();
stream.close();
try {
--- a/jdk/test/java/nio/file/DirectoryStream/DriveLetter.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/DirectoryStream/DriveLetter.java Tue Feb 08 14:25:33 2011 -0800
@@ -52,16 +52,14 @@
Path expected = Paths.get(drive).resolve(tempFile.getName());
boolean found = false;
- DirectoryStream<Path> stream = Paths.get(drive).newDirectoryStream();
- try {
+ Path dir = Paths.get(drive);
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path file : stream) {
if (file.equals(expected)) {
found = true;
break;
}
}
- } finally {
- stream.close();
}
if (!found)
throw new RuntimeException("Temporary file not found???");
--- a/jdk/test/java/nio/file/DirectoryStream/SecureDS.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/DirectoryStream/SecureDS.java Tue Feb 08 14:25:33 2011 -0800
@@ -28,6 +28,7 @@
*/
import java.nio.file.*;
+import static java.nio.file.Files.*;
import static java.nio.file.StandardOpenOption.*;
import static java.nio.file.LinkOption.*;
import java.nio.file.attribute.*;
@@ -41,7 +42,7 @@
public static void main(String[] args) throws IOException {
Path dir = TestUtil.createTemporaryDirectory();
try {
- DirectoryStream<Path> stream = dir.newDirectoryStream();
+ DirectoryStream<Path> stream = newDirectoryStream(dir);
stream.close();
if (!(stream instanceof SecureDirectoryStream)) {
System.out.println("SecureDirectoryStream not supported.");
@@ -62,28 +63,28 @@
// Exercise each of SecureDirectoryStream's method (except move)
static void doBasicTests(Path dir) throws IOException {
- Path dir1 = dir.resolve("dir1").createDirectory();
+ Path dir1 = createDirectory(dir.resolve("dir1"));
Path dir2 = dir.resolve("dir2");
// create a file, directory, and two sym links in the directory
Path fileEntry = Paths.get("myfile");
- dir1.resolve(fileEntry).createFile();
+ createFile(dir1.resolve(fileEntry));
Path dirEntry = Paths.get("mydir");
- dir1.resolve(dirEntry).createDirectory();
+ createDirectory(dir1.resolve(dirEntry));
// myfilelink -> myfile
Path link1Entry = Paths.get("myfilelink");
if (supportsLinks)
- dir1.resolve(link1Entry).createSymbolicLink(fileEntry);
+ createSymbolicLink(dir1.resolve(link1Entry), fileEntry);
// mydirlink -> mydir
Path link2Entry = Paths.get("mydirlink");
if (supportsLinks)
- dir1.resolve(link2Entry).createSymbolicLink(dirEntry);
+ createSymbolicLink(dir1.resolve(link2Entry), dirEntry);
// open directory and then move it so that it is no longer accessible
// via its original path.
SecureDirectoryStream<Path> stream =
- (SecureDirectoryStream<Path>)dir1.newDirectoryStream();
- dir1.moveTo(dir2);
+ (SecureDirectoryStream<Path>)newDirectoryStream(dir1);
+ move(dir1, dir2);
// Test: iterate over all entries
int count = 0;
@@ -138,7 +139,7 @@
if (supportsLinks) {
stream.newByteChannel(link1Entry, opts).close();
try {
- Set<OpenOption> mixed = new HashSet<OpenOption>();
+ Set<OpenOption> mixed = new HashSet<>();
mixed.add(READ);
mixed.add(NOFOLLOW_LINKS);
stream.newByteChannel(link1Entry, mixed).close();
@@ -168,51 +169,48 @@
// clean-up
stream.close();
- dir2.delete();
+ delete(dir2);
}
// Exercise SecureDirectoryStream's move method
static void doMoveTests(Path dir) throws IOException {
- Path dir1 = dir.resolve("dir1").createDirectory();
- Path dir2 = dir.resolve("dir2").createDirectory();
+ Path dir1 = createDirectory(dir.resolve("dir1"));
+ Path dir2 = createDirectory(dir.resolve("dir2"));
// create dir1/myfile, dir1/mydir, dir1/mylink
Path fileEntry = Paths.get("myfile");
- dir1.resolve(fileEntry).createFile();
+ createFile(dir1.resolve(fileEntry));
Path dirEntry = Paths.get("mydir");
- dir1.resolve(dirEntry).createDirectory();
+ createDirectory(dir1.resolve(dirEntry));
Path linkEntry = Paths.get("mylink");
if (supportsLinks)
- dir1.resolve(linkEntry).createSymbolicLink(Paths.get("missing"));
+ createSymbolicLink(dir1.resolve(linkEntry), Paths.get("missing"));
// target name
Path target = Paths.get("newfile");
// open stream to both directories
SecureDirectoryStream<Path> stream1 =
- (SecureDirectoryStream<Path>)dir1.newDirectoryStream();
+ (SecureDirectoryStream<Path>)newDirectoryStream(dir1);
SecureDirectoryStream<Path> stream2 =
- (SecureDirectoryStream<Path>)dir2.newDirectoryStream();
+ (SecureDirectoryStream<Path>)newDirectoryStream(dir2);
// Test: move dir1/myfile -> dir2/newfile
stream1.move(fileEntry, stream2, target);
- assertTrue(dir1.resolve(fileEntry).notExists());
- assertTrue(dir2.resolve(target).exists());
+ assertTrue(notExists(dir1.resolve(fileEntry)));
+ assertTrue(exists(dir2.resolve(target)));
stream2.deleteFile(target);
// Test: move dir1/mydir -> dir2/newfile
stream1.move(dirEntry, stream2, target);
- assertTrue(dir1.resolve(dirEntry).notExists());
- assertTrue(dir2.resolve(target).exists());
+ assertTrue(notExists(dir1.resolve(dirEntry)));
+ assertTrue(exists(dir2.resolve(target)));
stream2.deleteDirectory(target);
// Test: move dir1/mylink -> dir2/newfile
if (supportsLinks) {
stream1.move(linkEntry, stream2, target);
- assertTrue(dir2.resolve(target)
- .getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
- .readAttributes()
- .isSymbolicLink());
+ assertTrue(isSymbolicLink(dir2.resolve(target)));
stream2.deleteFile(target);
}
@@ -220,10 +218,10 @@
String testDirAsString = System.getProperty("test.dir");
if (testDirAsString != null) {
Path testDir = Paths.get(testDirAsString);
- if (!dir1.getFileStore().equals(testDir.getFileStore())) {
+ if (!getFileStore(dir1).equals(getFileStore(testDir))) {
SecureDirectoryStream<Path> ts =
- (SecureDirectoryStream<Path>)testDir.newDirectoryStream();
- dir1.resolve(fileEntry).createFile();
+ (SecureDirectoryStream<Path>)newDirectoryStream(testDir);
+ createFile(dir1.resolve(fileEntry));
try {
stream1.move(fileEntry, ts, target);
shouldNotGetHere();
@@ -234,17 +232,17 @@
}
// clean-up
- dir1.delete();
- dir2.delete();
+ delete(dir1);
+ delete(dir2);
}
// null and ClosedDirectoryStreamException
static void miscTests(Path dir) throws IOException {
Path file = Paths.get("file");
- dir.resolve(file).createFile();
+ createFile(dir.resolve(file));
SecureDirectoryStream<Path> stream =
- (SecureDirectoryStream<Path>)dir.newDirectoryStream();
+ (SecureDirectoryStream<Path>)newDirectoryStream(dir);
// NullPointerException
try {
@@ -319,7 +317,7 @@
} catch (ClosedDirectoryStreamException x) { }
// clean-up
- dir.resolve(file).delete();
+ delete(dir.resolve(file));
}
static void assertTrue(boolean b) {
--- a/jdk/test/java/nio/file/FileStore/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/FileStore/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -22,18 +22,21 @@
*/
/* @test
- * @bug 4313887 6873621 6979526
+ * @bug 4313887 6873621 6979526 7006126
* @summary Unit test for java.nio.file.FileStore
* @library ..
*/
import java.nio.file.*;
import java.nio.file.attribute.*;
+import java.io.File;
import java.io.IOException;
import java.util.*;
public class Basic {
+ static final long G = 1024L * 1024L * 1024L;
+
public static void main(String[] args) throws IOException {
Path dir = TestUtil.createTemporaryDirectory();
try {
@@ -48,17 +51,25 @@
throw new RuntimeException("Assertion failed");
}
+ static void checkWithin1GB(long value1, long value2) {
+ long diff = Math.abs(value1 - value2);
+ if (diff > G)
+ throw new RuntimeException("values differ by more than 1GB");
+ }
+
static void doTests(Path dir) throws IOException {
/**
* Test: Directory should be on FileStore that is writable
*/
- assertTrue(!dir.getFileStore().isReadOnly());
+ assertTrue(!Files.getFileStore(dir).isReadOnly());
/**
* Test: Two files should have the same FileStore
*/
- FileStore store1 = dir.resolve("foo").createFile().getFileStore();
- FileStore store2 = dir.resolve("bar").createFile().getFileStore();
+ Path file1 = Files.createFile(dir.resolve("foo"));
+ Path file2 = Files.createFile(dir.resolve("bar"));
+ FileStore store1 = Files.getFileStore(file1);
+ FileStore store2 = Files.getFileStore(file2);
assertTrue(store1.equals(store2));
assertTrue(store2.equals(store1));
assertTrue(store1.hashCode() == store2.hashCode());
@@ -78,6 +89,24 @@
store1.supportsFileAttributeView(UserDefinedFileAttributeView.class));
/**
+ * Test: Space atributes
+ */
+ File f = file1.toFile();
+ long total = f.getTotalSpace();
+ long free = f.getFreeSpace();
+ long usable = f.getUsableSpace();
+
+ // check values are "close"
+ checkWithin1GB(total, store1.getTotalSpace());
+ checkWithin1GB(free, store1.getUnallocatedSpace());
+ checkWithin1GB(usable, store1.getUsableSpace());
+
+ // get values by name
+ checkWithin1GB(total, (Long)store1.getAttribute("totalSpace"));
+ checkWithin1GB(free, (Long)store1.getAttribute("unallocatedSpace"));
+ checkWithin1GB(usable, (Long)store1.getAttribute("usableSpace"));
+
+ /**
* Test: Enumerate all FileStores
*/
FileStore prev = null;
@@ -85,8 +114,10 @@
System.out.format("%s (name=%s type=%s)\n", store, store.name(),
store.type());
- // check space attributes
- Attributes.readFileStoreSpaceAttributes(store);
+ // check space attributes are accessible
+ store.getTotalSpace();
+ store.getUnallocatedSpace();
+ store.getUsableSpace();
// two distinct FileStores should not be equal
assertTrue(!store.equals(prev));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/BytesAndLines.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 7006126
+ * @summary Unit test for methods for Files readAllBytes, readAllLines and
+ * and write methods.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import java.io.*;
+import java.util.*;
+import java.nio.charset.*;
+
+public class BytesAndLines {
+ static final Random rand = new Random();
+
+ static final Charset US_ASCII = Charset.forName("US-ASCII");
+
+ public static void main(String[] args) throws IOException {
+ testReadAndWriteBytes();
+ testReadLines();
+ testWriteLines();
+ }
+
+ /**
+ * Test readAllBytes(Path) and write(Path, byte[], OpenOption...)
+ */
+ static void testReadAndWriteBytes() throws IOException {
+ // exercise methods with various sizes
+ testReadAndWriteBytes(0);
+ for (int i=0; i<100; i++) {
+ testReadAndWriteBytes(rand.nextInt(32000));
+ }
+
+ // NullPointerException
+ Path file = Paths.get("foo");
+ List<String> lines = Collections.emptyList();
+ try {
+ readAllBytes(null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(null, lines, Charset.defaultCharset());
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(file, null, Charset.defaultCharset());
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(file, lines, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(file, lines, Charset.defaultCharset(), (OpenOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ OpenOption[] opts = { null };
+ write(file, lines, Charset.defaultCharset(), opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ }
+
+
+ static void testReadAndWriteBytes(int size) throws IOException {
+ Path path = createTempFile("blah", null);
+ try {
+ boolean append = rand.nextBoolean();
+
+ byte[] b1 = new byte[size];
+ rand.nextBytes(b1);
+
+ byte[] b2 = (append) ? new byte[size] : new byte[0];
+ rand.nextBytes(b2);
+
+ // write method should create file if it doesn't exist
+ if (rand.nextBoolean())
+ delete(path);
+
+ // write bytes to file
+ Path target = write(path, b1);
+ assertTrue(target==path, "Unexpected path");
+ assertTrue(size(path) == b1.length, "Unexpected file size");
+
+ // append bytes to file (might be 0 bytes)
+ write(path, b2, StandardOpenOption.APPEND);
+ assertTrue(size(path) == b1.length + b2.length, "Unexpected file size");
+
+ // read entire file
+ byte[] read = readAllBytes(path);
+
+ // check bytes are correct
+ byte[] expected;
+ if (append) {
+ expected = new byte[b1.length + b2.length];
+ System.arraycopy(b1, 0, expected, 0, b1.length);
+ System.arraycopy(b2, 0, expected, b1.length, b2.length);
+ } else {
+ expected = b1;
+ }
+ assertTrue(Arrays.equals(read, expected),
+ "Bytes read not the same as bytes written");
+ } finally {
+ deleteIfExists(path);
+ }
+ }
+
+ /**
+ * Test readAllLines(Path,Charset)
+ */
+ static void testReadLines() throws IOException {
+ Path tmpfile = createTempFile("blah", "txt");
+ try {
+ List<String> lines;
+
+ // zero lines
+ assertTrue(size(tmpfile) == 0, "File should be empty");
+ lines = readAllLines(tmpfile, US_ASCII);
+ assertTrue(lines.isEmpty(), "No line expected");
+
+ // one line
+ byte[] hi = { (byte)'h', (byte)'i' };
+ write(tmpfile, hi);
+ lines = readAllLines(tmpfile, US_ASCII);
+ assertTrue(lines.size() == 1, "One line expected");
+ assertTrue(lines.get(0).equals("hi"), "'Hi' expected");
+
+ // two lines using platform's line separator
+ List<String> expected = Arrays.asList("hi", "there");
+ write(tmpfile, expected, US_ASCII);
+ assertTrue(size(tmpfile) > 0, "File is empty");
+ lines = readAllLines(tmpfile, US_ASCII);
+ assertTrue(lines.equals(expected), "Unexpected lines");
+
+ // MalformedInputException
+ byte[] bad = { (byte)0xff, (byte)0xff };
+ write(tmpfile, bad);
+ try {
+ readAllLines(tmpfile, US_ASCII);
+ throw new RuntimeException("MalformedInputException expected");
+ } catch (MalformedInputException ignore) { }
+
+
+ // NullPointerException
+ try {
+ readAllLines(null, US_ASCII);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ readAllLines(tmpfile, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+
+ } finally {
+ delete(tmpfile);
+ }
+ }
+
+ /**
+ * Test write(Path,Iterable<? extends CharSequence>,Charset,OpenOption...)
+ */
+ static void testWriteLines() throws IOException {
+ Path tmpfile = createTempFile("blah", "txt");
+ try {
+ // write method should create file if it doesn't exist
+ if (rand.nextBoolean())
+ delete(tmpfile);
+
+ // zero lines
+ Path result = write(tmpfile, Collections.<String>emptyList(), US_ASCII);
+ assert(size(tmpfile) == 0);
+ assert(result == tmpfile);
+
+ // two lines
+ List<String> lines = Arrays.asList("hi", "there");
+ write(tmpfile, lines, US_ASCII);
+ List<String> actual = readAllLines(tmpfile, US_ASCII);
+ assertTrue(actual.equals(lines), "Unexpected lines");
+
+ // append two lines
+ write(tmpfile, lines, US_ASCII, StandardOpenOption.APPEND);
+ List<String> expected = new ArrayList<String>();
+ expected.addAll(lines);
+ expected.addAll(lines);
+ assertTrue(expected.size() == 4, "List should have 4 elements");
+ actual = readAllLines(tmpfile, US_ASCII);
+ assertTrue(actual.equals(expected), "Unexpected lines");
+
+ // UnmappableCharacterException
+ try {
+ String s = "\u00A0\u00A1";
+ write(tmpfile, Arrays.asList(s), US_ASCII);
+ throw new RuntimeException("UnmappableCharacterException expected");
+ } catch (UnmappableCharacterException ignore) { }
+
+ // NullPointerException
+ try {
+ write(null, lines, US_ASCII);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(tmpfile, null, US_ASCII);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(tmpfile, lines, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ write(tmpfile, lines, US_ASCII, (OpenOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ OpenOption[] opts = { (OpenOption)null };
+ write(tmpfile, lines, US_ASCII, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+
+ } finally {
+ delete(tmpfile);
+ }
+
+ }
+
+ static void assertTrue(boolean expr, String errmsg) {
+ if (!expr)
+ throw new RuntimeException(errmsg);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/CheckPermissions.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,723 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6866804 7006126
+ * @summary Unit test for java.nio.file.Files
+ * @library ..
+ * @build CheckPermissions
+ * @run main/othervm CheckPermissions
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.security.Permission;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Checks each method that accesses the file system does the right permission
+ * check when there is a security manager set.
+ */
+
+public class CheckPermissions {
+
+ static class Checks {
+ private List<Permission> permissionsChecked = new ArrayList<>();
+ private Set<String> propertiesChecked = new HashSet<>();
+ private List<String> readsChecked = new ArrayList<>();
+ private List<String> writesChecked = new ArrayList<>();
+ private List<String> deletesChecked = new ArrayList<>();
+ private List<String> execsChecked = new ArrayList<>();
+
+ List<Permission> permissionsChecked() { return permissionsChecked; }
+ Set<String> propertiesChecked() { return propertiesChecked; }
+ List<String> readsChecked() { return readsChecked; }
+ List<String> writesChecked() { return writesChecked; }
+ List<String> deletesChecked() { return deletesChecked; }
+ List<String> execsChecked() { return execsChecked; }
+ }
+
+ static ThreadLocal<Checks> myChecks =
+ new ThreadLocal<Checks>() {
+ @Override protected Checks initialValue() {
+ return null;
+ }
+ };
+
+ static void prepare() {
+ myChecks.set(new Checks());
+ }
+
+ static void assertCheckPermission(Class<? extends Permission> type,
+ String name)
+ {
+ for (Permission perm: myChecks.get().permissionsChecked()) {
+ if (type.isInstance(perm) && perm.getName().equals(name))
+ return;
+ }
+ throw new RuntimeException(type.getName() + "(\"" + name + "\") not checked");
+ }
+
+ static void assertCheckPropertyAccess(String key) {
+ if (!myChecks.get().propertiesChecked().contains(key))
+ throw new RuntimeException("Property " + key + " not checked");
+ }
+
+ static void assertChecked(Path file, List<String> list) {
+ String s = file.toString();
+ for (String f: list) {
+ if (f.endsWith(s))
+ return;
+ }
+ throw new RuntimeException("Access not checked");
+ }
+
+ static void assertCheckRead(Path file) {
+ assertChecked(file, myChecks.get().readsChecked());
+ }
+
+ static void assertCheckWrite(Path file) {
+ assertChecked(file, myChecks.get().writesChecked());
+ }
+
+ static void assertCheckWriteToDirectory(Path dir) {
+ String s = dir.toString();
+ List<String> list = myChecks.get().writesChecked();
+ for (String f: list) {
+ if (f.startsWith(s)) {
+ return;
+ }
+ }
+ throw new RuntimeException("Access not checked");
+ }
+
+ static void assertCheckDelete(Path file) {
+ assertChecked(file, myChecks.get().deletesChecked());
+ }
+
+ static void assertCheckExec(Path file) {
+ assertChecked(file, myChecks.get().execsChecked());
+ }
+
+ static class LoggingSecurityManager extends SecurityManager {
+ static void install() {
+ System.setSecurityManager(new LoggingSecurityManager());
+ }
+
+ @Override
+ public void checkPermission(Permission perm) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.permissionsChecked().add(perm);
+ }
+
+ @Override
+ public void checkPropertyAccess(String key) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.propertiesChecked().add(key);
+ }
+
+ @Override
+ public void checkRead(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.readsChecked().add(file);
+ }
+
+ @Override
+ public void checkWrite(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.writesChecked().add(file);
+ }
+
+ @Override
+ public void checkDelete(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.deletesChecked().add(file);
+ }
+
+ @Override
+ public void checkExec(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.execsChecked().add(file);
+ }
+ }
+
+ static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
+ throws IOException
+ {
+ prepare();
+ view.readAttributes();
+ assertCheckRead(file);
+
+ prepare();
+ FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+ view.setTimes(null, now, now);
+ assertCheckWrite(file);
+ }
+
+ static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
+ throws IOException
+ {
+ prepare();
+ PosixFileAttributes attrs = view.readAttributes();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setPermissions(attrs.permissions());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(attrs.owner());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(attrs.owner());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ }
+
+ public static void main(String[] args) throws IOException {
+ final Path testdir = Paths.get(System.getProperty("test.dir", ".")).toAbsolutePath();
+ final Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
+
+ Path file = createFile(testdir.resolve("file1234"));
+ try {
+ LoggingSecurityManager.install();
+
+ // -- check access --
+
+ prepare();
+ exists(file);
+ assertCheckRead(file);
+
+ prepare();
+ isReadable(file);
+ assertCheckRead(file);
+
+ prepare();
+ isWritable(file);
+ assertCheckWrite(file);
+
+ prepare();
+ isExecutable(file);
+ assertCheckExec(file);
+
+ // -- copy --
+
+ Path target = testdir.resolve("target1234");
+ prepare();
+ copy(file, target);
+ try {
+ assertCheckRead(file);
+ assertCheckWrite(target);
+ } finally {
+ delete(target);
+ }
+
+ if (TestUtil.supportsLinks(testdir)) {
+ Path link = testdir.resolve("link1234");
+ createSymbolicLink(link, file);
+ try {
+ prepare();
+ copy(link, target, LinkOption.NOFOLLOW_LINKS);
+ try {
+ assertCheckRead(link);
+ assertCheckWrite(target);
+ assertCheckPermission(LinkPermission.class, "symbolic");
+ } finally {
+ delete(target);
+ }
+ } finally {
+ delete(link);
+ }
+ }
+
+ // -- createDirectory --
+
+ Path subdir = testdir.resolve("subdir1234");
+ prepare();
+ createDirectory(subdir);
+ try {
+ assertCheckWrite(subdir);
+ } finally {
+ delete(subdir);
+ }
+
+ // -- createFile --
+
+ Path fileToCreate = testdir.resolve("file7890");
+ prepare();
+ createFile(fileToCreate);
+ try {
+ assertCheckWrite(fileToCreate);
+ } finally {
+ delete(fileToCreate);
+ }
+
+ // -- createSymbolicLink --
+
+ if (TestUtil.supportsLinks(testdir)) {
+ prepare();
+ Path link = testdir.resolve("link1234");
+ createSymbolicLink(link, file);
+ try {
+ assertCheckWrite(link);
+ assertCheckPermission(LinkPermission.class, "symbolic");
+ } finally {
+ delete(link);
+ }
+ }
+
+ // -- createLink --
+
+ if (TestUtil.supportsLinks(testdir)) {
+ prepare();
+ Path link = testdir.resolve("entry234");
+ createLink(link, file);
+ try {
+ assertCheckWrite(link);
+ assertCheckPermission(LinkPermission.class, "hard");
+ } finally {
+ delete(link);
+ }
+ }
+
+ // -- createTempFile --
+
+ prepare();
+ Path tmpfile1 = createTempFile("foo", null);
+ try {
+ assertCheckWriteToDirectory(tmpdir);
+ } finally {
+ delete(tmpfile1);
+ }
+ prepare();
+ Path tmpfile2 = createTempFile(testdir, "foo", ".tmp");
+ try {
+ assertCheckWriteToDirectory(testdir);
+ } finally {
+ delete(tmpfile2);
+ }
+
+ // -- createTempDirectory --
+
+ prepare();
+ Path tmpdir1 = createTempDirectory("foo");
+ try {
+ assertCheckWriteToDirectory(tmpdir);
+ } finally {
+ delete(tmpdir1);
+ }
+ prepare();
+ Path tmpdir2 = createTempDirectory(testdir, "foo");
+ try {
+ assertCheckWriteToDirectory(testdir);
+ } finally {
+ delete(tmpdir2);
+ }
+
+ // -- delete/deleteIfExists --
+
+ Path fileToDelete = testdir.resolve("file7890");
+
+ createFile(fileToDelete);
+ prepare();
+ delete(fileToDelete);
+ assertCheckDelete(fileToDelete);
+
+ createFile(fileToDelete);
+ prepare();
+ deleteIfExists(fileToDelete); // file exists
+ assertCheckDelete(fileToDelete);
+
+ prepare();
+ deleteIfExists(fileToDelete); // file does not exist
+ assertCheckDelete(fileToDelete);
+
+ // -- exists/notExists --
+
+ prepare();
+ exists(file);
+ assertCheckRead(file);
+
+ prepare();
+ notExists(file);
+ assertCheckRead(file);
+
+ // -- getFileStore --
+
+ prepare();
+ getFileStore(file);
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
+
+ // -- isSameFile --
+
+ prepare();
+ isSameFile(file, testdir);
+ assertCheckRead(file);
+ assertCheckRead(testdir);
+
+ // -- move --
+
+ Path target2 = testdir.resolve("target1234");
+ prepare();
+ move(file, target2);
+ try {
+ assertCheckWrite(file);
+ assertCheckWrite(target2);
+ } finally {
+ // restore file
+ move(target2, file);
+ }
+
+ // -- newByteChannel --
+
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file)) {
+ assertCheckRead(file);
+ }
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file, WRITE)) {
+ assertCheckWrite(file);
+ }
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file, READ, WRITE)) {
+ assertCheckRead(file);
+ assertCheckWrite(file);
+ }
+
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file, DELETE_ON_CLOSE)) {
+ assertCheckRead(file);
+ assertCheckDelete(file);
+ }
+ createFile(file); // restore file
+
+
+ // -- newInputStream/newOutptuStream --
+
+ prepare();
+ try (InputStream in = newInputStream(file)) {
+ assertCheckRead(file);
+ }
+ prepare();
+ try (OutputStream out = newOutputStream(file)) {
+ assertCheckWrite(file);
+ }
+
+ // -- newDirectoryStream --
+
+ prepare();
+ try (DirectoryStream<Path> stream = newDirectoryStream(testdir)) {
+ assertCheckRead(testdir);
+
+ if (stream instanceof SecureDirectoryStream<?>) {
+ Path entry;
+ SecureDirectoryStream<Path> sds =
+ (SecureDirectoryStream<Path>)stream;
+
+ // newByteChannel
+ entry = file.getFileName();
+ prepare();
+ try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(READ))) {
+ assertCheckRead(file);
+ }
+ prepare();
+ try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(WRITE))) {
+ assertCheckWrite(file);
+ }
+
+ // deleteFile
+ entry = file.getFileName();
+ prepare();
+ sds.deleteFile(entry);
+ assertCheckDelete(file);
+ createFile(testdir.resolve(entry)); // restore file
+
+ // deleteDirectory
+ entry = Paths.get("subdir1234");
+ createDirectory(testdir.resolve(entry));
+ prepare();
+ sds.deleteDirectory(entry);
+ assertCheckDelete(testdir.resolve(entry));
+
+ // move
+ entry = Paths.get("tempname1234");
+ prepare();
+ sds.move(file.getFileName(), sds, entry);
+ assertCheckWrite(file);
+ assertCheckWrite(testdir.resolve(entry));
+ sds.move(entry, sds, file.getFileName()); // restore file
+
+ // newDirectoryStream
+ entry = Paths.get("subdir1234");
+ createDirectory(testdir.resolve(entry));
+ try {
+ prepare();
+ sds.newDirectoryStream(entry).close();
+ assertCheckRead(testdir.resolve(entry));
+ } finally {
+ delete(testdir.resolve(entry));
+ }
+
+ // getFileAttributeView to access attributes of directory
+ testBasicFileAttributeView(sds
+ .getFileAttributeView(BasicFileAttributeView.class), testdir);
+ testPosixFileAttributeView(sds
+ .getFileAttributeView(PosixFileAttributeView.class), testdir);
+
+ // getFileAttributeView to access attributes of entry
+ entry = file.getFileName();
+ testBasicFileAttributeView(sds
+ .getFileAttributeView(entry, BasicFileAttributeView.class), file);
+ testPosixFileAttributeView(sds
+ .getFileAttributeView(entry, PosixFileAttributeView.class), file);
+
+ } else {
+ System.out.println("SecureDirectoryStream not tested");
+ }
+ }
+
+ // -- toAbsolutePath --
+
+ prepare();
+ file.getFileName().toAbsolutePath();
+ assertCheckPropertyAccess("user.dir");
+
+ // -- toRealPath --
+
+ prepare();
+ file.toRealPath(true);
+ assertCheckRead(file);
+
+ prepare();
+ file.toRealPath(false);
+ assertCheckRead(file);
+
+ prepare();
+ Paths.get(".").toRealPath(true);
+ assertCheckPropertyAccess("user.dir");
+
+ prepare();
+ Paths.get(".").toRealPath(false);
+ assertCheckPropertyAccess("user.dir");
+
+ // -- register --
+
+ try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
+ prepare();
+ testdir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
+ assertCheckRead(testdir);
+ }
+
+ // -- getAttribute/setAttribute/readAttributes --
+
+ prepare();
+ getAttribute(file, "size");
+ assertCheckRead(file);
+
+ prepare();
+ setAttribute(file, "lastModifiedTime",
+ FileTime.fromMillis(System.currentTimeMillis()));
+ assertCheckWrite(file);
+
+ prepare();
+ readAttributes(file, "*");
+ assertCheckRead(file);
+
+ // -- BasicFileAttributeView --
+ testBasicFileAttributeView(
+ getFileAttributeView(file, BasicFileAttributeView.class), file);
+
+ // -- PosixFileAttributeView --
+
+ {
+ PosixFileAttributeView view =
+ getFileAttributeView(file, PosixFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(PosixFileAttributeView.class))
+ {
+ testPosixFileAttributeView(view, file);
+ } else {
+ System.out.println("PosixFileAttributeView not tested");
+ }
+ }
+
+ // -- DosFileAttributeView --
+
+ {
+ DosFileAttributeView view =
+ getFileAttributeView(file, DosFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(DosFileAttributeView.class))
+ {
+ prepare();
+ view.readAttributes();
+ assertCheckRead(file);
+
+ prepare();
+ view.setArchive(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setHidden(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setReadOnly(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setSystem(false);
+ assertCheckWrite(file);
+ } else {
+ System.out.println("DosFileAttributeView not tested");
+ }
+ }
+
+ // -- FileOwnerAttributeView --
+
+ {
+ FileOwnerAttributeView view =
+ getFileAttributeView(file, FileOwnerAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(FileOwnerAttributeView.class))
+ {
+ prepare();
+ UserPrincipal owner = view.getOwner();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(owner);
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ } else {
+ System.out.println("FileOwnerAttributeView not tested");
+ }
+ }
+
+ // -- UserDefinedFileAttributeView --
+
+ {
+ UserDefinedFileAttributeView view =
+ getFileAttributeView(file, UserDefinedFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(UserDefinedFileAttributeView.class))
+ {
+ prepare();
+ view.write("test", ByteBuffer.wrap(new byte[100]));
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.read("test", ByteBuffer.allocate(100));
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.size("test");
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.list();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.delete("test");
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+ } else {
+ System.out.println("UserDefinedFileAttributeView not tested");
+ }
+ }
+
+ // -- AclFileAttributeView --
+ {
+ AclFileAttributeView view =
+ getFileAttributeView(file, AclFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(AclFileAttributeView.class))
+ {
+ prepare();
+ List<AclEntry> acl = view.getAcl();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ prepare();
+ view.setAcl(acl);
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ } else {
+ System.out.println("AclFileAttributeView not tested");
+ }
+ }
+
+ // -- UserPrincipalLookupService
+
+ UserPrincipalLookupService lookupService =
+ FileSystems.getDefault().getUserPrincipalLookupService();
+ UserPrincipal owner = getOwner(file);
+
+ prepare();
+ lookupService.lookupPrincipalByName(owner.getName());
+ assertCheckPermission(RuntimePermission.class,
+ "lookupUserInformation");
+
+ try {
+ UserPrincipal group = readAttributes(file, PosixFileAttributes.class).group();
+ prepare();
+ lookupService.lookupPrincipalByGroupName(group.getName());
+ assertCheckPermission(RuntimePermission.class,
+ "lookupUserInformation");
+ } catch (UnsupportedOperationException ignore) {
+ System.out.println("lookupPrincipalByGroupName not tested");
+ }
+
+
+ } finally {
+ deleteIfExists(file);
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/ContentType.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887
- * @summary Unit test for probeContentType method
- * @library ..
- * @build ContentType SimpleFileTypeDetector
- * @run main/othervm ContentType
- */
-
-import java.nio.file.*;
-import java.io.*;
-
-/**
- * Uses Files.probeContentType to probe html file and custom file type.
- */
-
-public class ContentType {
-
- static Path createHtmlFile() throws IOException {
- Path file = File.createTempFile("foo", ".html").toPath();
- OutputStream out = file.newOutputStream();
- try {
- out.write("<html><body>foo</body></html>".getBytes());
- } finally {
- out.close();
- }
-
- return file;
- }
-
- static Path createGrapeFile() throws IOException {
- return File.createTempFile("red", ".grape").toPath();
- }
-
- public static void main(String[] args) throws IOException {
-
- // exercise default file type detector
- Path file = createHtmlFile();
- try {
- String type = Files.probeContentType(file);
- if (type == null) {
- System.err.println("Content type cannot be determined - test skipped");
- } else {
- if (!type.equals("text/html"))
- throw new RuntimeException("Unexpected type: " + type);
- }
- } finally {
- file.delete();
- }
-
- // exercise custom file type detector
- file = createGrapeFile();
- try {
- String type = Files.probeContentType(file);
- if (type == null)
- throw new RuntimeException("Custom file type detector not installed?");
- if (!type.equals("grape/unknown"))
- throw new RuntimeException("Unexpected type: " + type);
- } finally {
- file.delete();
- }
-
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/CopyAndMove.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,1194 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333 6917021 7006126
+ * @summary Unit test for java.nio.file.Files copy and move methods
+ * @library ..
+ * @build CopyAndMove PassThroughFileSystem
+ * @run main/othervm CopyAndMove
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import static java.nio.file.StandardCopyOption.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+import java.util.*;
+
+public class CopyAndMove {
+ static final Random rand = new Random();
+ static boolean heads() { return rand.nextBoolean(); }
+
+ public static void main(String[] args) throws Exception {
+ Path dir1 = TestUtil.createTemporaryDirectory();
+ try {
+
+ // Same directory
+ testCopyFileToFile(dir1, dir1, TestUtil.supportsLinks(dir1));
+ testMove(dir1, dir1, TestUtil.supportsLinks(dir1));
+
+ // Different directories. Use test.dir if possible as it might be
+ // a different volume/file system and so improve test coverage.
+ String testDir = System.getProperty("test.dir", ".");
+ Path dir2 = TestUtil.createTemporaryDirectory(testDir);
+ try {
+ boolean testSymbolicLinks =
+ TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);
+ testCopyFileToFile(dir1, dir2, testSymbolicLinks);
+ testMove(dir1, dir2, testSymbolicLinks);
+ } finally {
+ TestUtil.removeAll(dir2);
+ }
+
+ // Target is location associated with custom provider
+ Path dir3 = PassThroughFileSystem.create().getPath(dir1.toString());
+ testCopyFileToFile(dir1, dir3, false);
+ testMove(dir1, dir3, false);
+
+ // Test copy(InputStream,Path) and copy(Path,OutputStream)
+ testCopyInputStreamToFile();
+ testCopyFileToOuputStream();
+
+ } finally {
+ TestUtil.removeAll(dir1);
+ }
+ }
+
+ static void checkBasicAttributes(BasicFileAttributes attrs1,
+ BasicFileAttributes attrs2)
+ {
+ // check file type
+ assertTrue(attrs1.isRegularFile() == attrs2.isRegularFile());
+ assertTrue(attrs1.isDirectory() == attrs2.isDirectory());
+ assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());
+ assertTrue(attrs1.isOther() == attrs2.isOther());
+
+ // check last modified time
+ long time1 = attrs1.lastModifiedTime().toMillis();
+ long time2 = attrs2.lastModifiedTime().toMillis();
+ assertTrue(time1 == time2);
+
+ // check size
+ if (attrs1.isRegularFile())
+ assertTrue(attrs1.size() == attrs2.size());
+ }
+
+ static void checkPosixAttributes(PosixFileAttributes attrs1,
+ PosixFileAttributes attrs2)
+ {
+ assertTrue(attrs1.permissions().equals(attrs2.permissions()));
+ assertTrue(attrs1.owner().equals(attrs2.owner()));
+ assertTrue(attrs1.group().equals(attrs2.group()));
+ }
+
+ static void checkDosAttributes(DosFileAttributes attrs1,
+ DosFileAttributes attrs2)
+ {
+ assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());
+ assertTrue(attrs1.isHidden() == attrs2.isHidden());
+ assertTrue(attrs1.isSystem() == attrs2.isSystem());
+ }
+
+ static void checkUserDefinedFileAttributes(Map<String,ByteBuffer> attrs1,
+ Map<String,ByteBuffer> attrs2)
+ {
+ assert attrs1.size() == attrs2.size();
+ for (String name: attrs1.keySet()) {
+ ByteBuffer bb1 = attrs1.get(name);
+ ByteBuffer bb2 = attrs2.get(name);
+ assertTrue(bb2 != null);
+ assertTrue(bb1.equals(bb2));
+ }
+ }
+
+ static Map<String,ByteBuffer> readUserDefinedFileAttributes(Path file)
+ throws IOException
+ {
+ UserDefinedFileAttributeView view =
+ getFileAttributeView(file, UserDefinedFileAttributeView.class);
+ Map<String,ByteBuffer> result = new HashMap<>();
+ for (String name: view.list()) {
+ int size = view.size(name);
+ ByteBuffer bb = ByteBuffer.allocate(size);
+ int n = view.read(name, bb);
+ assertTrue(n == size);
+ bb.flip();
+ result.put(name, bb);
+ }
+ return result;
+ }
+
+ // move source to target with verification
+ static void moveAndVerify(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ // read attributes before file is moved
+ BasicFileAttributes basicAttributes = null;
+ PosixFileAttributes posixAttributes = null;
+ DosFileAttributes dosAttributes = null;
+ Map<String,ByteBuffer> namedAttributes = null;
+
+ // get file attributes of source file
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS") || os.equals("Linux")) {
+ posixAttributes = readAttributes(source, PosixFileAttributes.class, NOFOLLOW_LINKS);
+ basicAttributes = posixAttributes;
+ }
+ if (os.startsWith("Windows")) {
+ dosAttributes = readAttributes(source, DosFileAttributes.class, NOFOLLOW_LINKS);
+ basicAttributes = dosAttributes;
+ }
+ if (basicAttributes == null)
+ basicAttributes = readAttributes(source, BasicFileAttributes.class, NOFOLLOW_LINKS);
+
+ // hash file contents if regular file
+ int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;
+
+ // record link target if symbolic link
+ Path linkTarget = null;
+ if (basicAttributes.isSymbolicLink())
+ linkTarget = readSymbolicLink(source);
+
+ // read named attributes if available (and file is not a sym link)
+ if (!basicAttributes.isSymbolicLink() &&
+ getFileStore(source).supportsFileAttributeView("xattr"))
+ {
+ namedAttributes = readUserDefinedFileAttributes(source);
+ }
+
+ // move file
+ Path result = move(source, target, options);
+ assertTrue(result == target);
+
+ // verify source does not exist
+ assertTrue(notExists(source));
+
+ // verify file contents
+ if (basicAttributes.isRegularFile()) {
+ if (computeHash(target) != hash)
+ throw new RuntimeException("Failed to verify move of regular file");
+ }
+
+ // verify link target
+ if (basicAttributes.isSymbolicLink()) {
+ if (!readSymbolicLink(target).equals(linkTarget))
+ throw new RuntimeException("Failed to verify move of symbolic link");
+ }
+
+ // verify basic attributes
+ checkBasicAttributes(basicAttributes,
+ readAttributes(target, BasicFileAttributes.class, NOFOLLOW_LINKS));
+
+ // verify other attributes when same provider
+ if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
+
+ // verify POSIX attributes
+ if (posixAttributes != null && !basicAttributes.isSymbolicLink()) {
+ checkPosixAttributes(posixAttributes,
+ readAttributes(target, PosixFileAttributes.class, NOFOLLOW_LINKS));
+ }
+
+ // verify DOS attributes
+ if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {
+ DosFileAttributes attrs =
+ readAttributes(target, DosFileAttributes.class, NOFOLLOW_LINKS);
+ checkDosAttributes(dosAttributes, attrs);
+ }
+
+ // verify named attributes
+ if (namedAttributes != null &&
+ getFileStore(target).supportsFileAttributeView("xattr"))
+ {
+ checkUserDefinedFileAttributes(namedAttributes,
+ readUserDefinedFileAttributes(target));
+ }
+ }
+ }
+
+ /**
+ * Tests all possible ways to invoke move
+ */
+ static void testMove(Path dir1, Path dir2, boolean supportsLinks)
+ throws IOException
+ {
+ Path source, target, entry;
+
+ boolean sameDevice = getFileStore(dir1).equals(getFileStore(dir2));
+
+ // -- regular file --
+
+ /**
+ * Test: move regular file, target does not exist
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+
+ /**
+ * Test: move regular file, target exists
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(target);
+ createDirectory(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: move regular file, target does not exist
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move regular file, target exists
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move regular file, target exists and is empty directory
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move regular file, target exists and is non-empty directory
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test atomic move of regular file (same file store)
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir1);
+ moveAndVerify(source, target, ATOMIC_MOVE);
+ delete(target);
+
+ /**
+ * Test atomic move of regular file (different file store)
+ */
+ if (!sameDevice) {
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ moveAndVerify(source, target, ATOMIC_MOVE);
+ throw new RuntimeException("AtomicMoveNotSupportedException expected");
+ } catch (AtomicMoveNotSupportedException x) {
+ }
+ delete(source);
+ }
+
+ // -- directories --
+
+ /*
+ * Test: move empty directory, target does not exist
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+
+ /**
+ * Test: move empty directory, target exists
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(target);
+ createDirectory(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: move empty directory, target does not exist
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move empty directory, target exists
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move empty, target exists and is empty directory
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+
+ /**
+ * Test: move empty directory, target exists and is non-empty directory
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ throw new RuntimeException("DirectoryNotEmptyException expected");
+ } catch (DirectoryNotEmptyException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: move non-empty directory (same file system)
+ */
+ source = createSourceDirectory(dir1);
+ createFile(source.resolve("foo"));
+ target = getTargetFile(dir1);
+ moveAndVerify(source, target);
+ delete(target.resolve("foo"));
+ delete(target);
+
+ /**
+ * Test: move non-empty directory (different file store)
+ */
+ if (!sameDevice) {
+ source = createSourceDirectory(dir1);
+ createFile(source.resolve("foo"));
+ target = getTargetFile(dir2);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("IOException expected");
+ } catch (IOException x) {
+ }
+ delete(source.resolve("foo"));
+ delete(source);
+ }
+
+ /**
+ * Test atomic move of directory (same file store)
+ */
+ source = createSourceDirectory(dir1);
+ createFile(source.resolve("foo"));
+ target = getTargetFile(dir1);
+ moveAndVerify(source, target, ATOMIC_MOVE);
+ delete(target.resolve("foo"));
+ delete(target);
+
+ // -- symbolic links --
+
+ /**
+ * Test: Move symbolic link to file, target does not exist
+ */
+ if (supportsLinks) {
+ Path tmp = createSourceFile(dir1);
+ source = dir1.resolve("link");
+ createSymbolicLink(source, tmp);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+ delete(tmp);
+ }
+
+ /**
+ * Test: Move symbolic link to directory, target does not exist
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+ }
+
+ /**
+ * Test: Move broken symbolic link, target does not exists
+ */
+ if (supportsLinks) {
+ Path tmp = Paths.get("doesnotexist");
+ source = dir1.resolve("link");
+ createSymbolicLink(source, tmp);
+ target = getTargetFile(dir2);
+ moveAndVerify(source, target);
+ delete(target);
+ }
+
+ /**
+ * Test: Move symbolic link, target exists
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+ }
+
+ /**
+ * Test: Move regular file, target exists
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ createFile(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+ }
+
+ /**
+ * Test: move symbolic link, target exists and is empty directory
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+ }
+
+ /**
+ * Test: symbolic link, target exists and is non-empty directory
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir2);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ moveAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+ }
+
+ /**
+ * Test atomic move of symbolic link (same file store)
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("link");
+ createSymbolicLink(source, dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ moveAndVerify(source, target, REPLACE_EXISTING);
+ delete(target);
+ }
+
+ // -- misc. tests --
+
+ /**
+ * Test nulls
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ move(null, target);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ move(source, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ move(source, target, (CopyOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ CopyOption[] opts = { REPLACE_EXISTING, null };
+ move(source, target, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ delete(source);
+
+ /**
+ * Test UOE
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ move(source, target, new CopyOption() { });
+ } catch (UnsupportedOperationException x) { }
+ try {
+ move(source, target, REPLACE_EXISTING, new CopyOption() { });
+ } catch (UnsupportedOperationException x) { }
+ delete(source);
+ }
+
+ // copy source to target with verification
+ static void copyAndVerify(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ Path result = copy(source, target, options);
+ assertTrue(result == target);
+
+ // get attributes of source and target file to verify copy
+ boolean followLinks = true;
+ LinkOption[] linkOptions = new LinkOption[0];
+ boolean copyAttributes = false;
+ for (CopyOption opt : options) {
+ if (opt == NOFOLLOW_LINKS) {
+ followLinks = false;
+ linkOptions = new LinkOption[] { NOFOLLOW_LINKS };
+ }
+ if (opt == COPY_ATTRIBUTES)
+ copyAttributes = true;
+ }
+ BasicFileAttributes basicAttributes =
+ readAttributes(source, BasicFileAttributes.class, linkOptions);
+
+ // check hash if regular file
+ if (basicAttributes.isRegularFile())
+ assertTrue(computeHash(source) == computeHash(target));
+
+ // check link target if symbolic link
+ if (basicAttributes.isSymbolicLink())
+ assert(readSymbolicLink(source).equals(readSymbolicLink(target)));
+
+ // check that attributes are copied
+ if (copyAttributes && followLinks) {
+ checkBasicAttributes(basicAttributes,
+ readAttributes(source, BasicFileAttributes.class, linkOptions));
+
+ // verify other attributes when same provider
+ if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
+
+ // check POSIX attributes are copied
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS") || os.equals("Linux")) {
+ checkPosixAttributes(
+ readAttributes(source, PosixFileAttributes.class, linkOptions),
+ readAttributes(target, PosixFileAttributes.class, linkOptions));
+ }
+
+ // check DOS attributes are copied
+ if (os.startsWith("Windows")) {
+ checkDosAttributes(
+ readAttributes(source, DosFileAttributes.class, linkOptions),
+ readAttributes(target, DosFileAttributes.class, linkOptions));
+ }
+
+ // check named attributes are copied
+ if (followLinks &&
+ getFileStore(source).supportsFileAttributeView("xattr") &&
+ getFileStore(target).supportsFileAttributeView("xattr"))
+ {
+ checkUserDefinedFileAttributes(readUserDefinedFileAttributes(source),
+ readUserDefinedFileAttributes(target));
+ }
+ }
+ }
+ }
+
+ /**
+ * Tests all possible ways to invoke copy to copy a file to a file
+ */
+ static void testCopyFileToFile(Path dir1, Path dir2, boolean supportsLinks)
+ throws IOException
+ {
+ Path source, target, link, entry;
+
+ // -- regular file --
+
+ /**
+ * Test: move regular file, target does not exist
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target exists
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(target);
+ createDirectory(target);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target does not exist
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target exists
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target exists and is empty directory
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file, target exists and is non-empty directory
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy regular file + attributes
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target, COPY_ATTRIBUTES);
+ delete(source);
+ delete(target);
+
+
+ // -- directory --
+
+ /*
+ * Test: copy directory, target does not exist
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target exists
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(target);
+ createDirectory(target);
+ try {
+ copyAndVerify(source, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException x) {
+ }
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target does not exist
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target exists
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createFile(target);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target exists and is empty directory
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ delete(source);
+ delete(target);
+
+ /**
+ * Test: copy directory, target exists and is non-empty directory
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ createDirectory(target);
+ entry = target.resolve("foo");
+ createFile(entry);
+ try {
+ copyAndVerify(source, target, REPLACE_EXISTING);
+ throw new RuntimeException("DirectoryNotEmptyException expected");
+ } catch (DirectoryNotEmptyException x) {
+ }
+ delete(entry);
+ delete(source);
+ delete(target);
+
+ /*
+ * Test: copy directory + attributes
+ */
+ source = createSourceDirectory(dir1);
+ target = getTargetFile(dir2);
+ copyAndVerify(source, target, COPY_ATTRIBUTES);
+ delete(source);
+ delete(target);
+
+ // -- symbolic links --
+
+ /**
+ * Test: Follow link
+ */
+ if (supportsLinks) {
+ source = createSourceFile(dir1);
+ link = dir1.resolve("link");
+ createSymbolicLink(link, source);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target);
+ delete(link);
+ delete(source);
+ }
+
+ /**
+ * Test: Copy link (to file)
+ */
+ if (supportsLinks) {
+ source = createSourceFile(dir1);
+ link = dir1.resolve("link");
+ createSymbolicLink(link, source);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target, NOFOLLOW_LINKS);
+ delete(link);
+ delete(source);
+ }
+
+ /**
+ * Test: Copy link (to directory)
+ */
+ if (supportsLinks) {
+ source = dir1.resolve("mydir");
+ createDirectory(source);
+ link = dir1.resolve("link");
+ createSymbolicLink(link, source);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target, NOFOLLOW_LINKS);
+ delete(link);
+ delete(source);
+ }
+
+ /**
+ * Test: Copy broken link
+ */
+ if (supportsLinks) {
+ assertTrue(notExists(source));
+ link = dir1.resolve("link");
+ createSymbolicLink(link, source);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target, NOFOLLOW_LINKS);
+ delete(link);
+ }
+
+ /**
+ * Test: Copy link to UNC (Windows only)
+ */
+ if (supportsLinks &&
+ System.getProperty("os.name").startsWith("Windows"))
+ {
+ Path unc = Paths.get("\\\\rialto\\share\\file");
+ link = dir1.resolve("link");
+ createSymbolicLink(link, unc);
+ target = getTargetFile(dir2);
+ copyAndVerify(link, target, NOFOLLOW_LINKS);
+ delete(link);
+ }
+
+ // -- misc. tests --
+
+ /**
+ * Test nulls
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ copy(source, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ copy(source, target, (CopyOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ try {
+ CopyOption[] opts = { REPLACE_EXISTING, null };
+ copy(source, target, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ delete(source);
+
+ /**
+ * Test UOE
+ */
+ source = createSourceFile(dir1);
+ target = getTargetFile(dir2);
+ try {
+ copy(source, target, new CopyOption() { });
+ } catch (UnsupportedOperationException x) { }
+ try {
+ copy(source, target, REPLACE_EXISTING, new CopyOption() { });
+ } catch (UnsupportedOperationException x) { }
+ delete(source);
+ }
+
+ /**
+ * Test copy from an input stream to a file
+ */
+ static void testCopyInputStreamToFile() throws IOException {
+ testCopyInputStreamToFile(0);
+ for (int i=0; i<100; i++) {
+ testCopyInputStreamToFile(rand.nextInt(32000));
+ }
+
+ // FileAlreadyExistsException
+ Path target = createTempFile("blah", null);
+ try {
+ InputStream in = new ByteArrayInputStream(new byte[0]);
+ try {
+ copy(in, target);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException ignore) { }
+ } finally {
+ delete(target);
+ }
+ Path tmpdir = createTempDirectory("blah");
+ try {
+ if (TestUtil.supportsLinks(tmpdir)) {
+ Path link = createSymbolicLink(tmpdir.resolve("link"),
+ tmpdir.resolve("target"));
+ try {
+ InputStream in = new ByteArrayInputStream(new byte[0]);
+ try {
+ copy(in, link);
+ throw new RuntimeException("FileAlreadyExistsException expected");
+ } catch (FileAlreadyExistsException ignore) { }
+ } finally {
+ delete(link);
+ }
+ }
+ } finally {
+ delete(tmpdir);
+ }
+
+
+ // nulls
+ try {
+ copy((InputStream)null, target);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ copy(new ByteArrayInputStream(new byte[0]), (Path)null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ }
+
+ static void testCopyInputStreamToFile(int size) throws IOException {
+ Path tmpdir = createTempDirectory("blah");
+ Path source = tmpdir.resolve("source");
+ Path target = tmpdir.resolve("target");
+ try {
+ boolean testReplaceExisting = rand.nextBoolean();
+
+ // create source file
+ byte[] b = new byte[size];
+ rand.nextBytes(b);
+ write(source, b);
+
+ // target file might already exist
+ if (testReplaceExisting && rand.nextBoolean()) {
+ write(target, new byte[rand.nextInt(512)]);
+ }
+
+ // copy from stream to file
+ InputStream in = new FileInputStream(source.toFile());
+ try {
+ long n;
+ if (testReplaceExisting) {
+ n = copy(in, target, StandardCopyOption.REPLACE_EXISTING);
+ } else {
+ n = copy(in, target);
+ }
+ assertTrue(in.read() == -1); // EOF
+ assertTrue(n == size);
+ assertTrue(size(target) == size);
+ } finally {
+ in.close();
+ }
+
+ // check file
+ byte[] read = readAllBytes(target);
+ assertTrue(Arrays.equals(read, b));
+
+ } finally {
+ deleteIfExists(source);
+ deleteIfExists(target);
+ delete(tmpdir);
+ }
+ }
+
+ /**
+ * Test copy from file to output stream
+ */
+ static void testCopyFileToOuputStream() throws IOException {
+ testCopyFileToOuputStream(0);
+ for (int i=0; i<100; i++) {
+ testCopyFileToOuputStream(rand.nextInt(32000));
+ }
+
+ // nulls
+ try {
+ copy((Path)null, new ByteArrayOutputStream());
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ Path source = createTempFile("blah", null);
+ delete(source);
+ copy(source, (OutputStream)null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ }
+
+ static void testCopyFileToOuputStream(int size) throws IOException {
+ Path source = createTempFile("blah", null);
+ try {
+ byte[] b = new byte[size];
+ rand.nextBytes(b);
+ write(source, b);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ long n = copy(source, out);
+ assertTrue(n == size);
+ assertTrue(out.size() == size);
+
+ byte[] read = out.toByteArray();
+ assertTrue(Arrays.equals(read, b));
+
+ // check output stream is open
+ out.write(0);
+ assertTrue(out.size() == size+1);
+ } finally {
+ delete(source);
+ }
+ }
+
+ static void assertTrue(boolean value) {
+ if (!value)
+ throw new RuntimeException("Assertion failed");
+ }
+
+ // computes simple hash of the given file
+ static int computeHash(Path file) throws IOException {
+ int h = 0;
+
+ try (InputStream in = newInputStream(file)) {
+ byte[] buf = new byte[1024];
+ int n;
+ do {
+ n = in.read(buf);
+ for (int i=0; i<n; i++) {
+ h = 31*h + (buf[i] & 0xff);
+ }
+ } while (n > 0);
+ }
+ return h;
+ }
+
+ // create file of random size in given directory
+ static Path createSourceFile(Path dir) throws IOException {
+ String name = "source" + Integer.toString(rand.nextInt());
+ Path file = dir.resolve(name);
+ createFile(file);
+ byte[] bytes = new byte[rand.nextInt(128*1024)];
+ rand.nextBytes(bytes);
+ try (OutputStream out = newOutputStream(file)) {
+ out.write(bytes);
+ }
+ randomizeAttributes(file);
+ return file;
+ }
+
+ // create directory in the given directory
+ static Path createSourceDirectory(Path dir) throws IOException {
+ String name = "sourcedir" + Integer.toString(rand.nextInt());
+ Path subdir = dir.resolve(name);
+ createDirectory(subdir);
+ randomizeAttributes(subdir);
+ return subdir;
+ }
+
+ // "randomize" the file attributes of the given file.
+ static void randomizeAttributes(Path file) throws IOException {
+ String os = System.getProperty("os.name");
+ boolean isWindows = os.startsWith("Windows");
+ boolean isUnix = os.equals("SunOS") || os.equals("Linux");
+ boolean isDirectory = isDirectory(file, NOFOLLOW_LINKS);
+
+ if (isUnix) {
+ Set<PosixFilePermission> perms =
+ getPosixFilePermissions(file, NOFOLLOW_LINKS);
+ PosixFilePermission[] toChange = {
+ PosixFilePermission.GROUP_READ,
+ PosixFilePermission.GROUP_WRITE,
+ PosixFilePermission.GROUP_EXECUTE,
+ PosixFilePermission.OTHERS_READ,
+ PosixFilePermission.OTHERS_WRITE,
+ PosixFilePermission.OTHERS_EXECUTE
+ };
+ for (PosixFilePermission perm: toChange) {
+ if (heads()) {
+ perms.add(perm);
+ } else {
+ perms.remove(perm);
+ }
+ }
+ setPosixFilePermissions(file, perms);
+ }
+
+ if (isWindows) {
+ DosFileAttributeView view =
+ getFileAttributeView(file, DosFileAttributeView.class, NOFOLLOW_LINKS);
+ // only set or unset the hidden attribute
+ view.setHidden(heads());
+ }
+
+ boolean addUserDefinedFileAttributes = heads() &&
+ getFileStore(file).supportsFileAttributeView("xattr");
+
+ // remove this when copying a direcory copies its named streams
+ if (isWindows && isDirectory) addUserDefinedFileAttributes = false;
+
+ if (addUserDefinedFileAttributes) {
+ UserDefinedFileAttributeView view =
+ getFileAttributeView(file, UserDefinedFileAttributeView.class);
+ int n = rand.nextInt(16);
+ while (n > 0) {
+ byte[] value = new byte[1 + rand.nextInt(100)];
+ view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));
+ n--;
+ }
+ }
+ }
+
+ // create name for file in given directory
+ static Path getTargetFile(Path dir) throws IOException {
+ String name = "target" + Integer.toString(rand.nextInt());
+ return dir.resolve(name);
+ }
+ }
--- a/jdk/test/java/nio/file/Files/CreateFileTree.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Creates a file tree with possible cycles caused by symbolic links
- * to ancestor directories.
- */
-
-public class CreateFileTree {
-
- static final Random rand = new Random();
-
- public static Path createTemporaryDirectory() throws IOException {
- Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
- Path dir;
- do {
- dir = tmpdir.resolve("name" + rand.nextInt());
- } while (dir.exists());
- dir.createDirectory();
- return dir;
- }
-
- public static void main(String[] args) throws IOException {
- Path top = createTemporaryDirectory();
- if (!top.isAbsolute())
- top = top.toAbsolutePath();
-
- List<Path> dirs = new ArrayList<Path>();
-
- // create tree
- Queue<Path> queue = new ArrayDeque<Path>();
- queue.add(top);
- int total = 1 + rand.nextInt(20);
- int n = 0;
- Path dir;
- while (((dir = queue.poll()) != null) && (n < total)) {
- int r = Math.min((total-n), (1+rand.nextInt(3)));
- for (int i=0; i<r; i++) {
- String name = "dir" + (++n);
- Path subdir = dir.resolve(name).createDirectory();
- queue.offer(subdir);
- dirs.add(subdir);
- }
- }
- assert dirs.size() >= 2;
-
- // create a few regular files in the file tree
- int files = dirs.size() * 3;
- for (int i=0; i<files; i++) {
- String name = "file" + (i+1);
- int x = rand.nextInt(dirs.size());
- dirs.get(x).resolve(name).createFile();
- }
-
- // create a few sym links in the file tree so as to create cycles
- int links = 1 + rand.nextInt(5);
- for (int i=0; i<links; i++) {
- int x = rand.nextInt(dirs.size());
- int y;
- do {
- y = rand.nextInt(dirs.size());
- } while (y != x);
- String name = "link" + (i+1);
- Path link = dirs.get(x).resolve(name);
- Path target = dirs.get(y);
- link.createSymbolicLink(target);
- }
-
- // done
- System.out.println(top);
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/DeleteOnClose.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.io.*;
+import java.util.*;
+
+public class DeleteOnClose {
+
+ public static void main(String[] args) throws IOException {
+ // open file but do not close it. Its existance will be checked by
+ // the calling script.
+ Files.newByteChannel(Paths.get(args[0]), READ, WRITE, DELETE_ON_CLOSE);
+
+ // check temporary file has been deleted after closing it
+ Path file = Files.createTempFile("blah", "tmp");
+ Files.newByteChannel(file, READ, WRITE, DELETE_ON_CLOSE).close();
+ if (Files.exists(file))
+ throw new RuntimeException("Temporary file was not deleted");
+
+ Path dir = Files.createTempDirectory("blah");
+ try {
+ // check that DELETE_ON_CLOSE fails when file is a sym link
+ if (TestUtil.supportsLinks(dir)) {
+ file = dir.resolve("foo");
+ Files.createFile(file);
+ Path link = dir.resolve("link");
+ Files.createSymbolicLink(link, file);
+ try {
+ Files.newByteChannel(link, READ, WRITE, DELETE_ON_CLOSE);
+ throw new RuntimeException("IOException expected");
+ } catch (IOException ignore) { }
+ }
+
+ // check that DELETE_ON_CLOSE works with files created via open
+ // directories
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
+ if (stream instanceof SecureDirectoryStream) {
+ SecureDirectoryStream<Path> secure = (SecureDirectoryStream<Path>)stream;
+ file = Paths.get("foo");
+
+ Set<OpenOption> opts = new HashSet<>();
+ opts.add(WRITE);
+ opts.add(DELETE_ON_CLOSE);
+ secure.newByteChannel(file, opts).close();
+
+ if (Files.exists(dir.resolve(file)))
+ throw new RuntimeException("File not deleted");
+ }
+ }
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/FileAttributes.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333
+ * @summary Unit test for java.nio.file.Files
+ * @library ..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Exercises getAttribute/setAttribute/readAttributes methods.
+ */
+
+public class FileAttributes {
+
+ static void assertTrue(boolean okay) {
+ if (!okay)
+ throw new RuntimeException("Assertion Failed");
+ }
+
+ static void checkEqual(Object o1, Object o2) {
+ if (o1 == null) {
+ assertTrue(o2 == null);
+ } else {
+ assertTrue (o1.equals(o2));
+ }
+ }
+
+ // checks that two time values are within 1s of each other
+ static void checkNearEqual(FileTime t1, FileTime t2) {
+ long diff = Math.abs(t1.toMillis() - t2.toMillis());
+ assertTrue(diff <= 1000);
+ }
+
+ // Exercise getAttribute/setAttribute/readAttributes on basic attributes
+ static void checkBasicAttributes(Path file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ // getAttribute
+ checkEqual(attrs.size(), Files.getAttribute(file, "size"));
+ checkEqual(attrs.lastModifiedTime(), Files.getAttribute(file, "basic:lastModifiedTime"));
+ checkEqual(attrs.lastAccessTime(), Files.getAttribute(file, "lastAccessTime"));
+ checkEqual(attrs.creationTime(), Files.getAttribute(file, "basic:creationTime"));
+ assertTrue((Boolean)Files.getAttribute(file, "isRegularFile"));
+ assertTrue(!(Boolean)Files.getAttribute(file, "basic:isDirectory"));
+ assertTrue(!(Boolean)Files.getAttribute(file, "isSymbolicLink"));
+ assertTrue(!(Boolean)Files.getAttribute(file, "basic:isOther"));
+ checkEqual(attrs.fileKey(), Files.getAttribute(file, "basic:fileKey"));
+
+ // setAttribute
+ FileTime modTime = attrs.lastModifiedTime();
+ Files.setAttribute(file, "basic:lastModifiedTime", FileTime.fromMillis(0L));
+ checkEqual(Files.getLastModifiedTime(file),
+ FileTime.fromMillis(0L));
+ Files.setAttribute(file, "lastModifiedTime", modTime);
+ checkEqual(Files.getLastModifiedTime(file), modTime);
+
+ Map<String,Object> map;
+ map = Files.readAttributes(file, "*");
+ assertTrue(map.size() >= 9);
+ checkEqual(attrs.isRegularFile(), map.get("isRegularFile")); // check one
+
+ map = Files.readAttributes(file, "basic:*");
+ assertTrue(map.size() >= 9);
+ checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime")); // check one
+
+ map = Files.readAttributes(file, "size,lastModifiedTime");
+ assertTrue(map.size() == 2);
+ checkEqual(attrs.size(), map.get("size"));
+ checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
+
+ map = Files.readAttributes(file,
+ "basic:lastModifiedTime,lastAccessTime,ShouldNotExist");
+ assertTrue(map.size() == 2);
+ checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
+ checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime"));
+ }
+
+ // Exercise getAttribute/setAttribute/readAttributes on posix attributes
+ static void checkPosixAttributes(Path file, PosixFileAttributes attrs)
+ throws IOException
+ {
+ checkBasicAttributes(file, attrs);
+
+ // getAttribute
+ checkEqual(attrs.permissions(), Files.getAttribute(file, "posix:permissions"));
+ checkEqual(attrs.owner(), Files.getAttribute(file, "posix:owner"));
+ checkEqual(attrs.group(), Files.getAttribute(file, "posix:group"));
+
+ // setAttribute
+ Set<PosixFilePermission> orig = attrs.permissions();
+ Set<PosixFilePermission> newPerms = new HashSet<>(orig);
+ newPerms.remove(PosixFilePermission.OTHERS_READ);
+ newPerms.remove(PosixFilePermission.OTHERS_WRITE);
+ newPerms.remove(PosixFilePermission.OTHERS_EXECUTE);
+ Files.setAttribute(file, "posix:permissions", newPerms);
+ checkEqual(Files.getPosixFilePermissions(file), newPerms);
+ Files.setAttribute(file, "posix:permissions", orig);
+ checkEqual(Files.getPosixFilePermissions(file), orig);
+ Files.setAttribute(file, "posix:owner", attrs.owner());
+ Files.setAttribute(file, "posix:group", attrs.group());
+
+ // readAttributes
+ Map<String,Object> map;
+ map = Files.readAttributes(file, "posix:*");
+ assertTrue(map.size() >= 12);
+ checkEqual(attrs.permissions(), map.get("permissions")); // check one
+
+ map = Files.readAttributes(file, "posix:size,owner,ShouldNotExist");
+ assertTrue(map.size() == 2);
+ checkEqual(attrs.size(), map.get("size"));
+ checkEqual(attrs.owner(), map.get("owner"));
+ }
+
+ // Exercise getAttribute/readAttributes on unix attributes
+ static void checkUnixAttributes(Path file) throws IOException {
+ // getAttribute
+ int mode = (Integer)Files.getAttribute(file, "unix:mode");
+ long ino = (Long)Files.getAttribute(file, "unix:ino");
+ long dev = (Long)Files.getAttribute(file, "unix:dev");
+ long rdev = (Long)Files.getAttribute(file, "unix:rdev");
+ int nlink = (Integer)Files.getAttribute(file, "unix:nlink");
+ int uid = (Integer)Files.getAttribute(file, "unix:uid");
+ int gid = (Integer)Files.getAttribute(file, "unix:gid");
+ FileTime ctime = (FileTime)Files.getAttribute(file, "unix:ctime");
+
+ // readAttributes
+ Map<String,Object> map;
+ map = Files.readAttributes(file, "unix:*");
+ assertTrue(map.size() >= 20);
+
+ map = Files.readAttributes(file, "unix:size,uid,gid,ShouldNotExist");
+ assertTrue(map.size() == 3);
+ checkEqual(map.get("size"),
+ Files.readAttributes(file, BasicFileAttributes.class).size());
+ }
+
+ // Exercise getAttribute/setAttribute on dos attributes
+ static void checkDosAttributes(Path file, DosFileAttributes attrs)
+ throws IOException
+ {
+ checkBasicAttributes(file, attrs);
+
+ // getAttribute
+ checkEqual(attrs.isReadOnly(), Files.getAttribute(file, "dos:readonly"));
+ checkEqual(attrs.isHidden(), Files.getAttribute(file, "dos:hidden"));
+ checkEqual(attrs.isSystem(), Files.getAttribute(file, "dos:system"));
+ checkEqual(attrs.isArchive(), Files.getAttribute(file, "dos:archive"));
+
+ // setAttribute
+ boolean value;
+
+ value = attrs.isReadOnly();
+ Files.setAttribute(file, "dos:readonly", !value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isReadOnly(), !value);
+ Files.setAttribute(file, "dos:readonly", value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isReadOnly(), value);
+
+ value = attrs.isHidden();
+ Files.setAttribute(file, "dos:hidden", !value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isHidden(), !value);
+ Files.setAttribute(file, "dos:hidden", value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isHidden(), value);
+
+ value = attrs.isSystem();
+ Files.setAttribute(file, "dos:system", !value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isSystem(), !value);
+ Files.setAttribute(file, "dos:system", value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isSystem(), value);
+
+ value = attrs.isArchive();
+ Files.setAttribute(file, "dos:archive", !value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isArchive(), !value);
+ Files.setAttribute(file, "dos:archive", value);
+ checkEqual(Files.readAttributes(file, DosFileAttributes.class).isArchive(), value);
+
+ // readAttributes
+ Map<String,Object> map;
+ map = Files.readAttributes(file, "dos:*");
+ assertTrue(map.size() >= 13);
+ checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
+
+ map = Files.readAttributes(file, "dos:size,hidden,ShouldNotExist");
+ assertTrue(map.size() == 2);
+ checkEqual(attrs.size(), map.get("size"));
+ checkEqual(attrs.isHidden(), map.get("hidden"));
+ }
+
+ static void miscTests(Path file) throws IOException {
+ // NPE tests
+ try {
+ Files.getAttribute(file, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException npe) { }
+ try {
+ Files.getAttribute(file, "isRegularFile", (LinkOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException npe) { }
+ try {
+ Files.setAttribute(file, null, 0L);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException npe) { }
+ }
+
+ static void doTests(Path dir) throws IOException {
+ Path file = dir.resolve("foo");
+ Files.createFile(file);
+ FileStore store = Files.getFileStore(file);
+ try {
+ checkBasicAttributes(file,
+ Files.readAttributes(file, BasicFileAttributes.class));
+
+ if (store.supportsFileAttributeView("posix"))
+ checkPosixAttributes(file,
+ Files.readAttributes(file, PosixFileAttributes.class));
+
+ if (store.supportsFileAttributeView("unix"))
+ checkUnixAttributes(file);
+
+ if (store.supportsFileAttributeView("dos"))
+ checkDosAttributes(file,
+ Files.readAttributes(file, DosFileAttributes.class));
+
+ miscTests(file);
+ } finally {
+ Files.delete(file);
+ }
+ }
+
+
+ public static void main(String[] args) throws IOException {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+ doTests(dir);
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/ForceLoad.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887
- * @summary Test library dependencies by invoking Files.probeContentType
- * before other methods that would cause nio.dll to be loaded.
- */
-
-import java.nio.file.*;
-import java.io.IOException;
-
-public class ForceLoad {
-
- public static void main(String[] args) throws IOException {
- Files.probeContentType(Paths.get("."));
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/InterruptCopy.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6993267
+ * @summary Unit test for Sun-specific ExtendedCopyOption.INTERRUPTIBLE option
+ * @library ..
+ * @run main/othervm -XX:-UseVMInterruptibleIO InterruptCopy
+ */
+
+import java.nio.file.*;
+import java.io.*;
+import java.util.concurrent.*;
+import com.sun.nio.file.ExtendedCopyOption;
+
+public class InterruptCopy {
+
+ private static final long FILE_SIZE_TO_COPY = 512L * 1024L * 1024L;
+ private static final int DELAY_IN_MS = 500;
+ private static final int DURATION_MAX_IN_MS = 5000;
+
+ public static void main(String[] args) throws Exception {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+ FileStore store = Files.getFileStore(dir);
+ System.out.format("Checking space (%s)\n", store);
+ long usableSpace = store.getUsableSpace();
+ if (usableSpace < 2*FILE_SIZE_TO_COPY) {
+ System.out.println("Insufficient disk space to run test.");
+ return;
+ }
+ doTest(dir);
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+
+ static void doTest(Path dir) throws Exception {
+ final Path source = dir.resolve("foo");
+ final Path target = dir.resolve("bar");
+
+ // create source file (don't create it as sparse file because we
+ // require the copy to take a long time)
+ System.out.println("Creating source file...");
+ byte[] buf = new byte[32*1024];
+ long total = 0;
+ try (OutputStream out = Files.newOutputStream(source)) {
+ do {
+ out.write(buf);
+ total += buf.length;
+ } while (total < FILE_SIZE_TO_COPY);
+ }
+ System.out.println("Source file created.");
+
+ ScheduledExecutorService pool =
+ Executors.newSingleThreadScheduledExecutor();
+ try {
+ // copy source to target in main thread, interrupting it after a delay
+ final Thread me = Thread.currentThread();
+ Future<?> wakeup = pool.schedule(new Runnable() {
+ public void run() {
+ me.interrupt();
+ }}, DELAY_IN_MS, TimeUnit.MILLISECONDS);
+ System.out.println("Copying file...");
+ try {
+ long start = System.currentTimeMillis();
+ Files.copy(source, target, ExtendedCopyOption.INTERRUPTIBLE);
+ long duration = System.currentTimeMillis() - start;
+ if (duration > DURATION_MAX_IN_MS)
+ throw new RuntimeException("Copy was not interrupted");
+ } catch (IOException e) {
+ boolean interrupted = Thread.interrupted();
+ if (!interrupted)
+ throw new RuntimeException("Interrupt status was not set");
+ System.out.println("Copy failed (this is expected)");
+ }
+ try {
+ wakeup.get();
+ } catch (InterruptedException ignore) { }
+ Thread.interrupted();
+
+ // copy source to target via task in thread pool, interrupting it after
+ // a delay using cancel(true)
+ Future<Void> result = pool.submit(new Callable<Void>() {
+ public Void call() throws IOException {
+ System.out.println("Copying file...");
+ Files.copy(source, target, ExtendedCopyOption.INTERRUPTIBLE,
+ StandardCopyOption.REPLACE_EXISTING);
+ return null;
+ }
+ });
+ Thread.sleep(DELAY_IN_MS);
+ boolean cancelled = result.cancel(true);
+ if (!cancelled)
+ result.get();
+ System.out.println("Copy cancelled.");
+ } finally {
+ pool.shutdown();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/Links.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333 6863864
+ * @summary Unit test for java.nio.file.Files createSymbolicLink,
+ * readSymbolicLink, and createLink methods
+ * @library ..
+ * @build Links
+ * @run main/othervm Links
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+
+public class Links {
+
+ static final boolean isWindows =
+ System.getProperty("os.name").startsWith("Windows");
+
+ static void assertTrue(boolean okay) {
+ if (!okay)
+ throw new RuntimeException("Assertion failed");
+ }
+
+ /**
+ * Exercise createSymbolicLink and readLink methods
+ */
+ static void testSymLinks(Path dir) throws IOException {
+ final Path link = dir.resolve("link");
+
+ // Check if sym links are supported
+ try {
+ Files.createSymbolicLink(link, Paths.get("foo"));
+ Files.delete(link);
+ } catch (UnsupportedOperationException x) {
+ // sym links not supported
+ return;
+ } catch (IOException x) {
+ // probably insufficient privileges to create sym links (Windows)
+ return;
+ }
+
+ // Test links to various targets
+ String[] windowsTargets =
+ { "foo", "C:\\foo", "\\foo", "\\\\server\\share\\foo" };
+ String[] otherTargets = { "relative", "/absolute" };
+
+ String[] targets = (isWindows) ? windowsTargets : otherTargets;
+ for (String s: targets) {
+ Path target = Paths.get(s);
+ Files.createSymbolicLink(link, target);
+ try {
+ assertTrue(Files.readSymbolicLink(link).equals(target));
+ } finally {
+ Files.delete(link);
+ }
+ }
+
+ // Test links to directory
+ Path mydir = dir.resolve("mydir");
+ Path myfile = mydir.resolve("myfile");
+ try {
+ Files.createDirectory(mydir);
+ Files.createFile(myfile);
+
+ // link -> "mydir"
+ Files.createSymbolicLink(link, mydir.getFileName());
+ assertTrue(Files.readSymbolicLink(link).equals(mydir.getFileName()));
+
+ // Test access to directory via link
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(link)) {
+ boolean found = false;
+ for (Path entry: stream) {
+ if (entry.getFileName().equals(myfile.getFileName())) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found);
+ }
+
+ // Test link2 -> link -> mydir
+ final Path link2 = dir.resolve("link2");
+ Path target2 = link.getFileName();
+ Files.createSymbolicLink(link2, target2);
+ try {
+ assertTrue(Files.readSymbolicLink(link2).equals(target2));
+ Files.newDirectoryStream(link2).close();
+ } finally {
+ Files.delete(link2);
+ }
+
+ // Remove mydir and re-create link2 before re-creating mydir
+ // (This is a useful test on Windows to ensure that creating a
+ // sym link to a directory sym link creates the right type of link).
+ Files.delete(myfile);
+ Files.delete(mydir);
+ Files.createSymbolicLink(link2, target2);
+ try {
+ assertTrue(Files.readSymbolicLink(link2).equals(target2));
+ Files.createDirectory(mydir);
+ Files.newDirectoryStream(link2).close();
+ } finally {
+ Files.delete(link2);
+ }
+
+ } finally {
+ Files.deleteIfExists(myfile);
+ Files.deleteIfExists(mydir);
+ Files.deleteIfExists(link);
+ }
+ }
+
+ /**
+ * Exercise createLink method
+ */
+ static void testHardLinks(Path dir) throws IOException {
+ Path foo = dir.resolve("foo");
+ Files.createFile(foo);
+ try {
+ Path bar = dir.resolve("bar");
+ try {
+ Files.createLink(bar, foo);
+ } catch (UnsupportedOperationException x) {
+ return;
+ } catch (IOException x) {
+ // probably insufficient privileges (Windows)
+ return;
+ }
+ try {
+ Object key1 = Files.readAttributes(foo, BasicFileAttributes.class).fileKey();
+ Object key2 = Files.readAttributes(bar, BasicFileAttributes.class).fileKey();
+ assertTrue((key1 == null) || (key1.equals(key2)));
+ } finally {
+ Files.delete(bar);
+ }
+
+
+ } finally {
+ Files.delete(foo);
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+ testSymLinks(dir);
+ testHardLinks(dir);
+
+ // repeat tests on Windows with long path
+ if (isWindows) {
+ Path dirWithLongPath = null;
+ try {
+ dirWithLongPath = TestUtil.createDirectoryWithLongPath(dir);
+ } catch (IOException x) {
+ System.out.println("Unable to create long path: " + x);
+ }
+ if (dirWithLongPath != null) {
+ System.out.println("");
+ System.out.println("** REPEAT TESTS WITH LONG PATH **");
+ testSymLinks(dirWithLongPath);
+ testHardLinks(dirWithLongPath);
+ }
+ }
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/META-INF/services/java.nio.file.spi.FileTypeDetector Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-SimpleFileTypeDetector
--- a/jdk/test/java/nio/file/Files/MaxDepth.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Unit test for Files.walkFileTree to test maxDepth parameter
- */
-
-public class MaxDepth {
- public static void main(String[] args) throws Exception {
- final Path top = Paths.get(args[0]);
-
- for (int i=0; i<5; i++) {
- Set<FileVisitOption> opts = Collections.emptySet();
- final int maxDepth = i;
- Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
- // compute depth based on relative path to top directory
- private int depth(Path file) {
- Path rp = file.relativize(top);
- return (rp == null) ? 0 : rp.getNameCount();
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- int d = depth(dir);
- if (d == maxDepth)
- throw new RuntimeException("Should not open directories at maxDepth");
- if (d > maxDepth)
- throw new RuntimeException("Too deep");
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- int d = depth(file);
- if (d > maxDepth)
- throw new RuntimeException("Too deep");
- return FileVisitResult.CONTINUE;
- }
- });
- }
- }
-}
--- a/jdk/test/java/nio/file/Files/Misc.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/Files/Misc.java Tue Feb 08 14:25:33 2011 -0800
@@ -22,122 +22,335 @@
*/
/* @test
- * @bug 4313887 6838333 6865748
- * @summary Unit test for java.nio.file.Files for miscellenous cases not
- * covered by other tests
+ * @bug 4313887 6838333
+ * @summary Unit test for miscellenous methods in java.nio.file.Files
* @library ..
*/
import java.nio.file.*;
-import java.nio.file.attribute.Attributes;
-import java.nio.file.attribute.BasicFileAttributes;
+import static java.nio.file.Files.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.*;
public class Misc {
- static void npeExpected() {
- throw new RuntimeException("NullPointerException expected");
- }
-
public static void main(String[] args) throws IOException {
-
- // -- Files.createDirectories --
-
Path dir = TestUtil.createTemporaryDirectory();
try {
- // no-op
- Files.createDirectories(dir);
+ testCreateDirectories(dir);
+ testIsHidden(dir);
+ testIsSameFile(dir);
+ testFileTypeMethods(dir);
+ testAccessMethods(dir);
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
- // create one directory
- Path subdir = dir.resolve("a");
- Files.createDirectories(subdir);
- if (!subdir.exists())
- throw new RuntimeException("directory not created");
+ /**
+ * Tests createDirectories
+ */
+ static void testCreateDirectories(Path tmpdir) throws IOException {
+ // a no-op
+ createDirectories(tmpdir);
+
+ // create one directory
+ Path subdir = tmpdir.resolve("a");
+ createDirectories(subdir);
+ assertTrue(exists(subdir));
- // create parents
- subdir = subdir.resolve("b/c/d");
- Files.createDirectories(subdir);
- if (!subdir.exists())
- throw new RuntimeException("directory not created");
+ // create parents
+ subdir = subdir.resolve("b/c/d");
+ createDirectories(subdir);
+ assertTrue(exists(subdir));
- // existing file is not a directory
- Path file = dir.resolve("x").createFile();
+ // existing file is not a directory
+ Path file = createFile(tmpdir.resolve("x"));
+ try {
+ createDirectories(file);
+ throw new RuntimeException("failure expected");
+ } catch (FileAlreadyExistsException x) { }
+ try {
+ createDirectories(file.resolve("y"));
+ throw new RuntimeException("failure expected");
+ } catch (IOException x) { }
+ }
+
+ /**
+ * Tests isHidden
+ */
+ static void testIsHidden(Path tmpdir) throws IOException {
+ assertTrue(!isHidden(tmpdir));
+
+ Path file = tmpdir.resolve(".foo");
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ createFile(file);
try {
- Files.createDirectories(file);
- throw new RuntimeException("failure expected");
- } catch (FileAlreadyExistsException x) { }
- try {
- Files.createDirectories(file.resolve("y"));
- throw new RuntimeException("failure expected");
- } catch (IOException x) { }
+ setAttribute(file, "dos:hidden", true);
+ try {
+ assertTrue(isHidden(file));
+ } finally {
+ setAttribute(file, "dos:hidden", false);
+ }
+ } finally {
+ delete(file);
+ }
+ } else {
+ assertTrue(isHidden(file));
+ }
+ }
- } finally {
- TestUtil.removeAll(dir);
- }
+ /**
+ * Tests isSameFile
+ */
+ static void testIsSameFile(Path tmpdir) throws IOException {
+ Path thisFile = tmpdir.resolve("thisFile");
+ Path thatFile = tmpdir.resolve("thatFile");
- // --- NullPointerException --
+ /**
+ * Test: isSameFile for self
+ */
+ assertTrue(isSameFile(thisFile, thisFile));
+ /**
+ * Test: Neither files exist
+ */
try {
- Files.probeContentType(null);
- npeExpected();
- } catch (NullPointerException e) {
+ isSameFile(thisFile, thatFile);
+ throw new RuntimeException("IOException not thrown");
+ } catch (IOException x) {
}
try {
- Files.walkFileTree(null, EnumSet.noneOf(FileVisitOption.class),
- Integer.MAX_VALUE, new SimpleFileVisitor<Path>(){});
- npeExpected();
- } catch (NullPointerException e) {
+ isSameFile(thatFile, thisFile);
+ throw new RuntimeException("IOException not thrown");
+ } catch (IOException x) {
}
- try {
- Files.walkFileTree(Paths.get("."), null, Integer.MAX_VALUE,
- new SimpleFileVisitor<Path>(){});
- npeExpected();
- } catch (NullPointerException e) {
- }
+
+ createFile(thisFile);
try {
- Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
- -1, new SimpleFileVisitor<Path>(){});
- throw new RuntimeException("IllegalArgumentExpected expected");
- } catch (IllegalArgumentException e) {
- }
- try {
- Set<FileVisitOption> opts = new HashSet<FileVisitOption>(1);
- opts.add(null);
- Files.walkFileTree(Paths.get("."), opts, Integer.MAX_VALUE,
- new SimpleFileVisitor<Path>(){});
- npeExpected();
- } catch (NullPointerException e) {
- }
- try {
- Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
- Integer.MAX_VALUE, null);
- npeExpected();
- } catch (NullPointerException e) {
+ /**
+ * Test: One file exists
+ */
+ try {
+ isSameFile(thisFile, thatFile);
+ throw new RuntimeException("IOException not thrown");
+ } catch (IOException x) {
+ }
+ try {
+ isSameFile(thatFile, thisFile);
+ throw new RuntimeException("IOException not thrown");
+ } catch (IOException x) {
+ }
+
+ /**
+ * Test: Both file exists
+ */
+ createFile(thatFile);
+ try {
+ assertTrue(!isSameFile(thisFile, thatFile));
+ assertTrue(!isSameFile(thatFile, thisFile));
+ } finally {
+ delete(thatFile);
+ }
+
+ /**
+ * Test: Symbolic links
+ */
+ if (TestUtil.supportsLinks(tmpdir)) {
+ createSymbolicLink(thatFile, thisFile);
+ try {
+ assertTrue(isSameFile(thisFile, thatFile));
+ assertTrue(isSameFile(thatFile, thisFile));
+ } finally {
+ TestUtil.deleteUnchecked(thatFile);
+ }
+ }
+ } finally {
+ delete(thisFile);
}
- SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
- boolean ranTheGauntlet = false;
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get("."));
+ // nulls
+ try {
+ isSameFile(thisFile, null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ try {
+ isSameFile(null, thatFile);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException ignore) { }
+ }
+
+ /**
+ * Exercise isRegularFile, isDirectory, isSymbolicLink
+ */
+ static void testFileTypeMethods(Path tmpdir) throws IOException {
+ assertTrue(!isRegularFile(tmpdir));
+ assertTrue(!isRegularFile(tmpdir, NOFOLLOW_LINKS));
+ assertTrue(isDirectory(tmpdir));
+ assertTrue(isDirectory(tmpdir, NOFOLLOW_LINKS));
+ assertTrue(!isSymbolicLink(tmpdir));
+
+ Path file = createFile(tmpdir.resolve("foo"));
+ try {
+ assertTrue(isRegularFile(file));
+ assertTrue(isRegularFile(file, NOFOLLOW_LINKS));
+ assertTrue(!isDirectory(file));
+ assertTrue(!isDirectory(file, NOFOLLOW_LINKS));
+ assertTrue(!isSymbolicLink(file));
+
+ if (TestUtil.supportsLinks(tmpdir)) {
+ Path link = tmpdir.resolve("link");
+
+ createSymbolicLink(link, tmpdir);
+ try {
+ assertTrue(!isRegularFile(link));
+ assertTrue(!isRegularFile(link, NOFOLLOW_LINKS));
+ assertTrue(isDirectory(link));
+ assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
+ assertTrue(isSymbolicLink(link));
+ } finally {
+ delete(link);
+ }
+
+ createSymbolicLink(link, file);
+ try {
+ assertTrue(isRegularFile(link));
+ assertTrue(!isRegularFile(link, NOFOLLOW_LINKS));
+ assertTrue(!isDirectory(link));
+ assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
+ assertTrue(isSymbolicLink(link));
+ } finally {
+ delete(link);
+ }
+
+ createLink(link, file);
+ try {
+ assertTrue(isRegularFile(link));
+ assertTrue(isRegularFile(link, NOFOLLOW_LINKS));
+ assertTrue(!isDirectory(link));
+ assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
+ assertTrue(!isSymbolicLink(link));
+ } finally {
+ delete(link);
+ }
+ }
+
+ } finally {
+ delete(file);
+ }
+ }
+
+ /**
+ * Exercise isReadbale, isWritable, isExecutable, exists, notExists
+ */
+ static void testAccessMethods(Path tmpdir) throws IOException {
+ // should return false when file does not exist
+ Path doesNotExist = tmpdir.resolve("doesNotExist");
+ assertTrue(!isReadable(doesNotExist));
+ assertTrue(!isWritable(doesNotExist));
+ assertTrue(!isExecutable(doesNotExist));
+ assertTrue(!exists(doesNotExist));
+ assertTrue(notExists(doesNotExist));
- try { visitor.preVisitDirectory(null, attrs);
- } catch (NullPointerException x0) {
- try { visitor.preVisitDirectory(dir, null);
- } catch (NullPointerException x1) {
- try { visitor.visitFile(null, attrs);
- } catch (NullPointerException x2) {
- try { visitor.visitFile(dir, null);
- } catch (NullPointerException x3) {
- try { visitor.visitFileFailed(null, new IOException());
- } catch (NullPointerException x4) {
- try { visitor.visitFileFailed(dir, null);
- } catch (NullPointerException x5) {
- try { visitor.postVisitDirectory(null, new IOException());
- } catch (NullPointerException x6) {
- // if we get here then all visit* methods threw NPE as expected
- ranTheGauntlet = true;
- }}}}}}}
- if (!ranTheGauntlet)
- throw new RuntimeException("A visit method did not throw NPE");
+ Path file = createFile(tmpdir.resolve("foo"));
+ try {
+ // files exist
+ assertTrue(isReadable(file));
+ assertTrue(isWritable(file));
+ assertTrue(exists(file));
+ assertTrue(!notExists(file));
+ assertTrue(isReadable(tmpdir));
+ assertTrue(isWritable(tmpdir));
+ assertTrue(exists(tmpdir));
+ assertTrue(!notExists(tmpdir));
+
+
+ // sym link exists
+ if (TestUtil.supportsLinks(tmpdir)) {
+ Path link = tmpdir.resolve("link");
+
+ createSymbolicLink(link, file);
+ try {
+ assertTrue(isReadable(link));
+ assertTrue(isWritable(link));
+ assertTrue(exists(link));
+ assertTrue(!notExists(link));
+ } finally {
+ delete(link);
+ }
+
+ createSymbolicLink(link, doesNotExist);
+ try {
+ assertTrue(!isReadable(link));
+ assertTrue(!isWritable(link));
+ assertTrue(!exists(link));
+ assertTrue(exists(link, NOFOLLOW_LINKS));
+ assertTrue(notExists(link));
+ assertTrue(!notExists(link, NOFOLLOW_LINKS));
+ } finally {
+ delete(link);
+ }
+ }
+
+ /**
+ * Test: Edit ACL to deny WRITE and EXECUTE
+ */
+ if (getFileStore(file).supportsFileAttributeView("acl")) {
+ AclFileAttributeView view =
+ getFileAttributeView(file, AclFileAttributeView.class);
+ UserPrincipal owner = view.getOwner();
+ List<AclEntry> acl = view.getAcl();
+
+ // Insert entry to deny WRITE and EXECUTE
+ AclEntry entry = AclEntry.newBuilder()
+ .setType(AclEntryType.DENY)
+ .setPrincipal(owner)
+ .setPermissions(AclEntryPermission.WRITE_DATA,
+ AclEntryPermission.EXECUTE)
+ .build();
+ acl.add(0, entry);
+ view.setAcl(acl);
+ try {
+ assertTrue(!isWritable(file));
+ assertTrue(!isExecutable(file));
+ } finally {
+ // Restore ACL
+ acl.remove(0);
+ view.setAcl(acl);
+ }
+ }
+
+ /**
+ * Test: Windows DOS read-only attribute
+ */
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ setAttribute(file, "dos:readonly", true);
+ try {
+ assertTrue(!isWritable(file));
+ } finally {
+ setAttribute(file, "dos:readonly", false);
+ }
+
+ // Read-only attribute does not make direcory read-only
+ DosFileAttributeView view =
+ getFileAttributeView(tmpdir, DosFileAttributeView.class);
+ boolean save = view.readAttributes().isReadOnly();
+ view.setReadOnly(true);
+ try {
+ assertTrue(isWritable(file));
+ } finally {
+ view.setReadOnly(save);
+ }
+ }
+ } finally {
+ delete(file);
+ }
+ }
+
+ static void assertTrue(boolean okay) {
+ if (!okay)
+ throw new RuntimeException("Assertion Failed");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/PassThroughFileSystem.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.nio.channels.SeekableByteChannel;
+import java.net.URI;
+import java.util.*;
+import java.io.*;
+
+/**
+ * A "pass through" file system implementation that passes through, or delegates,
+ * everything to the default file system.
+ */
+
+class PassThroughFileSystem extends FileSystem {
+ private final FileSystemProvider provider;
+ private final FileSystem delegate;
+
+ PassThroughFileSystem(FileSystemProvider provider, FileSystem delegate) {
+ this.provider = provider;
+ this.delegate = delegate;
+ }
+
+ /**
+ * Creates a new "pass through" file system. Useful for test environments
+ * where the provider might not be deployed.
+ */
+ static FileSystem create() throws IOException {
+ FileSystemProvider provider = new PassThroughProvider();
+ Map<String,?> env = Collections.emptyMap();
+ URI uri = URI.create("pass:///");
+ return provider.newFileSystem(uri, env);
+ }
+
+ static Path unwrap(Path wrapper) {
+ if (wrapper == null)
+ throw new NullPointerException();
+ if (!(wrapper instanceof PassThroughPath))
+ throw new ProviderMismatchException();
+ return ((PassThroughPath)wrapper).delegate;
+ }
+
+ @Override
+ public FileSystemProvider provider() {
+ return provider;
+ }
+
+ @Override
+ public void close() throws IOException {
+ delegate.close();
+ }
+
+ @Override
+ public boolean isOpen() {
+ return delegate.isOpen();
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return delegate.isReadOnly();
+ }
+
+ @Override
+ public String getSeparator() {
+ return delegate.getSeparator();
+ }
+
+ @Override
+ public Iterable<Path> getRootDirectories() {
+ final Iterable<Path> roots = delegate.getRootDirectories();
+ return new Iterable<Path>() {
+ @Override
+ public Iterator<Path> iterator() {
+ final Iterator<Path> itr = roots.iterator();
+ return new Iterator<Path>() {
+ @Override
+ public boolean hasNext() {
+ return itr.hasNext();
+ }
+ @Override
+ public Path next() {
+ return new PassThroughPath(delegate, itr.next());
+ }
+ @Override
+ public void remove() {
+ itr.remove();
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public Iterable<FileStore> getFileStores() {
+ // assume that unwrapped objects aren't exposed
+ return delegate.getFileStores();
+ }
+
+ @Override
+ public Set<String> supportedFileAttributeViews() {
+ // assume that unwrapped objects aren't exposed
+ return delegate.supportedFileAttributeViews();
+ }
+
+ @Override
+ public Path getPath(String first, String... more) {
+ return new PassThroughPath(this, delegate.getPath(first, more));
+ }
+
+ @Override
+ public PathMatcher getPathMatcher(String syntaxAndPattern) {
+ final PathMatcher matcher = delegate.getPathMatcher(syntaxAndPattern);
+ return new PathMatcher() {
+ @Override
+ public boolean matches(Path path) {
+ return matcher.matches(unwrap(path));
+ }
+ };
+ }
+
+ @Override
+ public UserPrincipalLookupService getUserPrincipalLookupService() {
+ // assume that unwrapped objects aren't exposed
+ return delegate.getUserPrincipalLookupService();
+ }
+
+ @Override
+ public WatchService newWatchService() throws IOException {
+ // to keep it simple
+ throw new UnsupportedOperationException();
+ }
+
+ static class PassThroughProvider extends FileSystemProvider {
+ private static final String SCHEME = "pass";
+ private static volatile PassThroughFileSystem delegate;
+
+ public PassThroughProvider() { }
+
+ @Override
+ public String getScheme() {
+ return SCHEME;
+ }
+
+ private void checkScheme(URI uri) {
+ if (!uri.getScheme().equalsIgnoreCase(SCHEME))
+ throw new IllegalArgumentException();
+ }
+
+ private void checkUri(URI uri) {
+ checkScheme(uri);
+ if (!uri.getSchemeSpecificPart().equals("///"))
+ throw new IllegalArgumentException();
+ }
+
+ @Override
+ public FileSystem newFileSystem(URI uri, Map<String,?> env)
+ throws IOException
+ {
+ checkUri(uri);
+ synchronized (PassThroughProvider.class) {
+ if (delegate != null)
+ throw new FileSystemAlreadyExistsException();
+ PassThroughFileSystem result =
+ new PassThroughFileSystem(this, FileSystems.getDefault());
+ delegate = result;
+ return result;
+ }
+ }
+
+ @Override
+ public FileSystem getFileSystem(URI uri) {
+ checkUri(uri);
+ FileSystem result = delegate;
+ if (result == null)
+ throw new FileSystemNotFoundException();
+ return result;
+ }
+
+ @Override
+ public Path getPath(URI uri) {
+ checkScheme(uri);
+ if (delegate == null)
+ throw new FileSystemNotFoundException();
+ uri = URI.create(delegate.provider().getScheme() + ":" +
+ uri.getSchemeSpecificPart());
+ return new PassThroughPath(delegate, delegate.provider().getPath(uri));
+ }
+
+ @Override
+ public void setAttribute(Path file, String attribute, Object value, LinkOption... options)
+ throws IOException
+ {
+ Files.setAttribute(unwrap(file), attribute, value, options);
+ }
+
+ @Override
+ public Map<String,Object> readAttributes(Path file, String attributes, LinkOption... options)
+ throws IOException
+ {
+ return Files.readAttributes(unwrap(file), attributes, options);
+ }
+
+ @Override
+ public <V extends FileAttributeView> V getFileAttributeView(Path file,
+ Class<V> type,
+ LinkOption... options)
+ {
+ return Files.getFileAttributeView(unwrap(file), type, options);
+ }
+
+ @Override
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ return Files.readAttributes(unwrap(file), type, options);
+ }
+
+ @Override
+ public void delete(Path file) throws IOException {
+ Files.delete(unwrap(file));
+ }
+
+ @Override
+ public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ Files.createSymbolicLink(unwrap(link), unwrap(target), attrs);
+ }
+
+ @Override
+ public void createLink(Path link, Path existing) throws IOException {
+ Files.createLink(unwrap(link), unwrap(existing));
+ }
+
+ @Override
+ public Path readSymbolicLink(Path link) throws IOException {
+ Path target = Files.readSymbolicLink(unwrap(link));
+ return new PassThroughPath(delegate, target);
+ }
+
+
+ @Override
+ public void copy(Path source, Path target, CopyOption... options) throws IOException {
+ Files.copy(unwrap(source), unwrap(target), options);
+ }
+
+ @Override
+ public void move(Path source, Path target, CopyOption... options) throws IOException {
+ Files.move(unwrap(source), unwrap(target), options);
+ }
+
+ private DirectoryStream<Path> wrap(final DirectoryStream<Path> stream) {
+ return new DirectoryStream<Path>() {
+ @Override
+ public Iterator<Path> iterator() {
+ final Iterator<Path> itr = stream.iterator();
+ return new Iterator<Path>() {
+ @Override
+ public boolean hasNext() {
+ return itr.hasNext();
+ }
+ @Override
+ public Path next() {
+ return new PassThroughPath(delegate, itr.next());
+ }
+ @Override
+ public void remove() {
+ itr.remove();
+ }
+ };
+ }
+ @Override
+ public void close() throws IOException {
+ stream.close();
+ }
+ };
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ return wrap(Files.newDirectoryStream(dir, filter));
+ }
+
+ @Override
+ public void createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ Files.createDirectory(unwrap(dir), attrs);
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path file,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return Files.newByteChannel(unwrap(file), options, attrs);
+ }
+
+
+ @Override
+ public boolean isHidden(Path file) throws IOException {
+ return Files.isHidden(unwrap(file));
+ }
+
+ @Override
+ public FileStore getFileStore(Path file) throws IOException {
+ return Files.getFileStore(unwrap(file));
+ }
+
+ @Override
+ public boolean isSameFile(Path file, Path other) throws IOException {
+ return Files.isSameFile(unwrap(file), unwrap(other));
+ }
+
+ @Override
+ public void checkAccess(Path file, AccessMode... modes)
+ throws IOException
+ {
+ // hack
+ if (modes.length == 0) {
+ if (Files.exists(unwrap(file)))
+ return;
+ else
+ throw new NoSuchFileException(file.toString());
+ }
+ throw new RuntimeException("not implemented yet");
+ }
+ }
+
+ static class PassThroughPath implements Path {
+ private final FileSystem fs;
+ private final Path delegate;
+
+ PassThroughPath(FileSystem fs, Path delegate) {
+ this.fs = fs;
+ this.delegate = delegate;
+ }
+
+ private Path wrap(Path path) {
+ return (path != null) ? new PassThroughPath(fs, path) : null;
+ }
+
+ @Override
+ public FileSystem getFileSystem() {
+ return fs;
+ }
+
+ @Override
+ public boolean isAbsolute() {
+ return delegate.isAbsolute();
+ }
+
+ @Override
+ public Path getRoot() {
+ return wrap(delegate.getRoot());
+ }
+
+ @Override
+ public Path getParent() {
+ return wrap(delegate.getParent());
+ }
+
+ @Override
+ public int getNameCount() {
+ return delegate.getNameCount();
+ }
+
+ @Override
+ public Path getFileName() {
+ return wrap(delegate.getFileName());
+ }
+
+ @Override
+ public Path getName(int index) {
+ return wrap(delegate.getName(index));
+ }
+
+ @Override
+ public Path subpath(int beginIndex, int endIndex) {
+ return wrap(delegate.subpath(beginIndex, endIndex));
+ }
+
+ @Override
+ public boolean startsWith(Path other) {
+ return delegate.startsWith(unwrap(other));
+ }
+
+ @Override
+ public boolean startsWith(String other) {
+ return delegate.startsWith(other);
+ }
+
+ @Override
+ public boolean endsWith(Path other) {
+ return delegate.endsWith(unwrap(other));
+ }
+
+ @Override
+ public boolean endsWith(String other) {
+ return delegate.endsWith(other);
+ }
+
+ @Override
+ public Path normalize() {
+ return wrap(delegate.normalize());
+ }
+
+ @Override
+ public Path resolve(Path other) {
+ return wrap(delegate.resolve(unwrap(other)));
+ }
+
+ @Override
+ public Path resolve(String other) {
+ return wrap(delegate.resolve(other));
+ }
+
+ @Override
+ public Path resolveSibling(Path other) {
+ return wrap(delegate.resolveSibling(unwrap(other)));
+ }
+
+ @Override
+ public Path resolveSibling(String other) {
+ return wrap(delegate.resolveSibling(other));
+ }
+
+ @Override
+ public Path relativize(Path other) {
+ return wrap(delegate.relativize(unwrap(other)));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof PassThroughPath))
+ return false;
+ return delegate.equals(unwrap((PassThroughPath)other));
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+
+ @Override
+ public URI toUri() {
+ String ssp = delegate.toUri().getSchemeSpecificPart();
+ return URI.create(fs.provider().getScheme() + ":" + ssp);
+ }
+
+ @Override
+ public Path toAbsolutePath() {
+ return wrap(delegate.toAbsolutePath());
+ }
+
+ @Override
+ public Path toRealPath(boolean resolveLinks) throws IOException {
+ return wrap(delegate.toRealPath(resolveLinks));
+ }
+
+ @Override
+ public File toFile() {
+ return delegate.toFile();
+ }
+
+ @Override
+ public Iterator<Path> iterator() {
+ final Iterator<Path> itr = delegate.iterator();
+ return new Iterator<Path>() {
+ @Override
+ public boolean hasNext() {
+ return itr.hasNext();
+ }
+ @Override
+ public Path next() {
+ return wrap(itr.next());
+ }
+ @Override
+ public void remove() {
+ itr.remove();
+ }
+ };
+ }
+
+ @Override
+ public int compareTo(Path other) {
+ return delegate.compareTo(unwrap(other));
+ }
+
+ @Override
+ public WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>[] events,
+ WatchEvent.Modifier... modifiers)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>... events)
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/PrintFileTree.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Invokes Files.walkFileTree to traverse a file tree and prints
- * each of the directories and files. The -follow option causes symbolic
- * links to be followed and the -printCycles option will print links
- * where the target of the link is an ancestor directory.
- */
-
-public class PrintFileTree {
-
- public static void main(String[] args) throws Exception {
- boolean followLinks = false;
- boolean printCycles = false;
- int i = 0;
- while (i < (args.length-1)) {
- switch (args[i]) {
- case "-follow" : followLinks = true; break;
- case "-printCycles" : printCycles = true; break;
- default:
- throw new RuntimeException(args[i] + " not recognized");
- }
- i++;
- }
- Path dir = Paths.get(args[i]);
-
- Set<FileVisitOption> options = new HashSet<FileVisitOption>();
- if (followLinks)
- options.add(FileVisitOption.FOLLOW_LINKS);
-
- final boolean reportCycles = printCycles;
- Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
- @Override
- public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
- System.out.println(dir);
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
- if (!attrs.isDirectory() || reportCycles)
- System.out.println(file);
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult postVisitDirectory(FileRef dir, IOException exc)
- throws IOException
- {
- if (exc != null)
- throw exc;
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult visitFileFailed(FileRef file, IOException exc)
- throws IOException
- {
- if (reportCycles && (exc instanceof FileSystemLoopException)) {
- System.out.println(file);
- return FileVisitResult.CONTINUE;
- }
- throw exc;
- }
- });
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/SBC.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Files.newByteChannel
+ * @library ..
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import static com.sun.nio.file.ExtendedOpenOption.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.channels.*;
+import java.io.IOException;
+import java.util.*;
+
+public class SBC {
+
+ static boolean supportsLinks;
+
+ public static void main(String[] args) throws Exception {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+ supportsLinks = TestUtil.supportsLinks(dir);
+
+ // open options
+ createTests(dir);
+ appendTests(dir);
+ truncateExistingTests(dir);
+ noFollowLinksTests(dir);
+
+ // SeekableByteChannel methods
+ sizeTruncatePositionTests(dir);
+
+ // platform specific
+ if (System.getProperty("os.name").startsWith("Windows"))
+ dosSharingOptionTests(dir);
+
+ // misc. tests
+ badCombinations(dir);
+ unsupportedOptions(dir);
+ nullTests(dir);
+
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+
+ // test CREATE and CREATE_NEW options
+ static void createTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+
+ // CREATE
+ try {
+ // create file (no existing file)
+ Files.newByteChannel(file, CREATE, WRITE).close();
+ if (Files.notExists(file))
+ throw new RuntimeException("File not created");
+
+ // create file (existing file)
+ Files.newByteChannel(file, CREATE, WRITE).close();
+
+ // create file where existing file is a sym link
+ if (supportsLinks) {
+ Path link = Files.createSymbolicLink(dir.resolve("link"), file);
+ try {
+ // file already exists
+ Files.newByteChannel(link, CREATE, WRITE).close();
+
+ // file does not exist
+ Files.delete(file);
+ Files.newByteChannel(link, CREATE, WRITE).close();
+ if (Files.notExists(file))
+ throw new RuntimeException("File not created");
+
+ } finally {
+ TestUtil.deleteUnchecked(link);
+ }
+ }
+
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+
+ // CREATE_NEW
+ try {
+ // create file
+ Files.newByteChannel(file, CREATE_NEW, WRITE).close();
+ if (Files.notExists(file))
+ throw new RuntimeException("File not created");
+
+ // create should fail
+ try {
+ SeekableByteChannel sbc =
+ Files.newByteChannel(file, CREATE_NEW, WRITE);
+ sbc.close();
+ throw new RuntimeException("FileAlreadyExistsException not thrown");
+ } catch (FileAlreadyExistsException x) { }
+
+ // create should fail
+ if (supportsLinks) {
+ Path link = dir.resolve("link");
+ Path target = dir.resolve("thisDoesNotExist");
+ Files.createSymbolicLink(link, target);
+ try {
+
+ try {
+ SeekableByteChannel sbc =
+ Files.newByteChannel(file, CREATE_NEW, WRITE);
+ sbc.close();
+ throw new RuntimeException("FileAlreadyExistsException not thrown");
+ } catch (FileAlreadyExistsException x) { }
+
+ } finally {
+ TestUtil.deleteUnchecked(link);
+ }
+ }
+
+
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+
+ // CREATE_NEW + SPARSE
+ try {
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, WRITE, SPARSE)) {
+ final long hole = 2L * 1024L * 1024L * 1024L;
+ sbc.position(hole);
+ write(sbc, "hello");
+ long size = sbc.size();
+ if (size != (hole + 5))
+ throw new RuntimeException("Unexpected size");
+ }
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // test APPEND option
+ static void appendTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+ try {
+ // "hello there" should be written to file
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, WRITE, APPEND)) {
+ write(sbc, "hello ");
+ sbc.position(0L);
+ write(sbc, "there");
+ }
+
+ // check file
+ try (Scanner s = new Scanner(file)) {
+ String line = s.nextLine();
+ if (!line.equals("hello there"))
+ throw new RuntimeException("Unexpected file contents");
+ }
+
+ // check that read is not allowed
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, APPEND)) {
+ sbc.read(ByteBuffer.allocate(100));
+ } catch (NonReadableChannelException x) {
+ }
+ } finally {
+ // clean-up
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // test TRUNCATE_EXISTING option
+ static void truncateExistingTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+ try {
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, WRITE)) {
+ write(sbc, "Have a nice day!");
+ }
+
+ // re-open with truncate option
+ // write short message and check
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, WRITE, TRUNCATE_EXISTING)) {
+ write(sbc, "Hello there!");
+ }
+ try (Scanner s = new Scanner(file)) {
+ String line = s.nextLine();
+ if (!line.equals("Hello there!"))
+ throw new RuntimeException("Unexpected file contents");
+ }
+
+ // re-open with create + truncate option
+ // check file is of size 0L
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, WRITE, CREATE, TRUNCATE_EXISTING)) {
+ long size = ((FileChannel)sbc).size();
+ if (size != 0L)
+ throw new RuntimeException("File not truncated");
+ }
+
+ } finally {
+ // clean-up
+ TestUtil.deleteUnchecked(file);
+ }
+
+ }
+
+ // test NOFOLLOW_LINKS option
+ static void noFollowLinksTests(Path dir) throws Exception {
+ if (!supportsLinks)
+ return;
+ Path file = Files.createFile(dir.resolve("foo"));
+ try {
+ // ln -s foo link
+ Path link = dir.resolve("link");
+ Files.createSymbolicLink(link, file);
+
+ // open with NOFOLLOW_LINKS option
+ try {
+ Files.newByteChannel(link, READ, LinkOption.NOFOLLOW_LINKS);
+ throw new RuntimeException();
+ } catch (IOException x) {
+ } finally {
+ TestUtil.deleteUnchecked(link);
+ }
+
+ } finally {
+ // clean-up
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // test size/truncate/position methods
+ static void sizeTruncatePositionTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+ try {
+ try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, READ, WRITE)) {
+ if (sbc.size() != 0L)
+ throw new RuntimeException("Unexpected size");
+
+ // check size
+ write(sbc, "hello");
+ if (sbc.size() != 5L)
+ throw new RuntimeException("Unexpected size");
+
+ // truncate (size and position should change)
+ sbc.truncate(4L);
+ if (sbc.size() != 4L)
+ throw new RuntimeException("Unexpected size");
+ if (sbc.position() != 4L)
+ throw new RuntimeException("Unexpected position");
+
+ // truncate (position should not change)
+ sbc.position(2L).truncate(3L);
+ if (sbc.size() != 3L)
+ throw new RuntimeException("Unexpected size");
+ if (sbc.position() != 2L)
+ throw new RuntimeException("Unexpected position");
+ }
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // Windows specific options for the use by applications that really want
+ // to use legacy DOS sharing options
+ static void dosSharingOptionTests(Path dir) throws Exception {
+ Path file = Files.createFile(dir.resolve("foo"));
+ try {
+ // no sharing
+ try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_READ,
+ NOSHARE_WRITE, NOSHARE_DELETE))
+ {
+ try {
+ Files.newByteChannel(file, READ);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ try {
+ Files.newByteChannel(file, WRITE);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ try {
+ Files.delete(file);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ }
+
+ // read allowed
+ try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_WRITE, NOSHARE_DELETE)) {
+ Files.newByteChannel(file, READ).close();
+ try {
+ Files.newByteChannel(file, WRITE);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ try {
+ Files.delete(file);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ }
+
+ // write allowed
+ try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_READ, NOSHARE_DELETE)) {
+ try {
+ Files.newByteChannel(file, READ);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ Files.newByteChannel(file, WRITE).close();
+ try {
+ Files.delete(file);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ }
+
+ // delete allowed
+ try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_READ, NOSHARE_WRITE)) {
+ try {
+ Files.newByteChannel(file, READ);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ try {
+ Files.newByteChannel(file, WRITE);
+ throw new RuntimeException("Sharing violation expected");
+ } catch (IOException ignore) { }
+ Files.delete(file);
+ }
+
+ } finally {
+ TestUtil.deleteUnchecked(file);
+ }
+ }
+
+ // invalid combinations of options
+ static void badCombinations(Path dir) throws Exception {
+ Path file = dir.resolve("bad");
+
+ try {
+ Files.newByteChannel(file, READ, APPEND);
+ throw new RuntimeException("IllegalArgumentException expected");
+ } catch (IllegalArgumentException x) { }
+
+ try {
+ Files.newByteChannel(file, WRITE, APPEND, TRUNCATE_EXISTING);
+ throw new RuntimeException("IllegalArgumentException expected");
+ } catch (IllegalArgumentException x) { }
+ }
+
+ // unsupported operations
+ static void unsupportedOptions(Path dir) throws Exception {
+ Path file = dir.resolve("bad");
+
+ OpenOption badOption = new OpenOption() { };
+ try {
+ Files.newByteChannel(file, badOption);
+ throw new RuntimeException("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) { }
+ try {
+ Files.newByteChannel(file, READ, WRITE, badOption);
+ throw new RuntimeException("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) { }
+ }
+
+ // null handling
+ static void nullTests(Path dir) throws Exception {
+ Path file = dir.resolve("foo");
+
+ try {
+ OpenOption[] opts = { READ, null };
+ Files.newByteChannel((Path)null, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ Files.newByteChannel(file, (OpenOption[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ OpenOption[] opts = { READ, null };
+ Files.newByteChannel(file, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ Files.newByteChannel(file, (Set<OpenOption>)null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ Set<OpenOption> opts = new HashSet<>();
+ opts.add(READ);
+ opts.add(null);
+ Files.newByteChannel(file, opts);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
+ Files.newByteChannel(file, opts, (FileAttribute[])null);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+
+ try {
+ EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
+ FileAttribute[] attrs = { null };
+ Files.newByteChannel(file, opts, attrs);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException x) { }
+ }
+
+ static void write(WritableByteChannel wbc, String msg) throws IOException {
+ ByteBuffer buf = ByteBuffer.wrap(msg.getBytes());
+ while (buf.hasRemaining())
+ wbc.write(buf);
+ }
+}
--- a/jdk/test/java/nio/file/Files/SimpleFileTypeDetector.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.spi.FileTypeDetector;
-import java.io.*;
-
-
-public class SimpleFileTypeDetector extends FileTypeDetector {
- public SimpleFileTypeDetector() {
- }
-
- public String probeContentType(FileRef file) throws IOException {
-
- System.out.println("probe " + file + "...");
-
- if (file instanceof Path) {
- String name = ((Path)file).toString();
- if (name.endsWith(".grape")) {
- return "grape/unknown";
- }
- }
-
- // unknown
- return null;
- }
-}
--- a/jdk/test/java/nio/file/Files/SkipSiblings.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Unit test for Files.walkFileTree to test SKIP_SIBLINGS return value.
- */
-
-public class SkipSiblings {
-
- static final Random rand = new Random();
- static final Set<Path> skipped = new HashSet<Path>();
-
- // check if this path's directory has been skipped
- static void check(Path path) {
- if (skipped.contains(path.getParent()))
- throw new RuntimeException(path + " should not have been visited");
- }
-
- // indicates if the siblings of this path should be skipped
- static boolean skip(Path path) {
- Path parent = path.getParent();
- if (parent != null && rand.nextBoolean()) {
- skipped.add(parent);
- return true;
- }
- return false;
- }
-
- public static void main(String[] args) throws Exception {
- Path dir = Paths.get(args[0]);
-
- Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- check(dir);
- if (skip(dir))
- return FileVisitResult.SKIP_SIBLINGS;
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- check(file);
- if (skip(file))
- return FileVisitResult.SKIP_SIBLINGS;
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult postVisitDirectory(Path dir, IOException x) {
- if (x != null)
- throw new RuntimeException(x);
- check(dir);
- return FileVisitResult.CONTINUE;
- }
- });
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/TemporaryFiles.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333 7006126
+ * @summary Unit test for Files.createTempXXX
+ * @library ..
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.Set;
+
+public class TemporaryFiles {
+
+ static void checkInDirectory(Path file, Path dir) {
+ if (dir == null)
+ dir = Paths.get(System.getProperty("java.io.tmpdir"));
+ if (!file.getParent().equals(dir))
+ throw new RuntimeException("Not in expected directory");
+ }
+
+ static void testTempFile(String prefix, String suffix, Path dir)
+ throws IOException
+ {
+ Path file = (dir == null) ?
+ Files.createTempFile(prefix, suffix) :
+ Files.createTempFile(dir, prefix, suffix);
+ try {
+ // check file name
+ String name = file.getFileName().toString();
+ if (prefix != null && !name.startsWith(prefix))
+ throw new RuntimeException("Should start with " + prefix);
+ if (suffix == null && !name.endsWith(".tmp"))
+ throw new RuntimeException("Should end with .tmp");
+ if (suffix != null && !name.endsWith(suffix))
+ throw new RuntimeException("Should end with " + suffix);
+
+ // check file is in expected directory
+ checkInDirectory(file, dir);
+
+ // check that file can be opened for reading and writing
+ Files.newByteChannel(file, READ).close();
+ Files.newByteChannel(file, WRITE).close();
+ Files.newByteChannel(file, READ,WRITE).close();
+
+ // check file permissions are 0600 or more secure
+ if (Files.getFileStore(file).supportsFileAttributeView("posix")) {
+ Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
+ perms.remove(PosixFilePermission.OWNER_READ);
+ perms.remove(PosixFilePermission.OWNER_WRITE);
+ if (!perms.isEmpty())
+ throw new RuntimeException("Temporary file is not secure");
+ }
+ } finally {
+ Files.delete(file);
+ }
+ }
+
+ static void testTempFile(String prefix, String suffix)
+ throws IOException
+ {
+ testTempFile(prefix, suffix, null);
+ }
+
+ static void testTempDirectory(String prefix, Path dir) throws IOException {
+ Path subdir = (dir == null) ?
+ Files.createTempDirectory(prefix) :
+ Files.createTempDirectory(dir, prefix);
+ try {
+ // check file name
+ String name = subdir.getFileName().toString();
+ if (prefix != null && !name.startsWith(prefix))
+ throw new RuntimeException("Should start with " + prefix);
+
+ // check directory is in expected directory
+ checkInDirectory(subdir, dir);
+
+ // check directory is empty
+ DirectoryStream<Path> stream = Files.newDirectoryStream(subdir);
+ try {
+ if (stream.iterator().hasNext())
+ throw new RuntimeException("Tempory directory not empty");
+ } finally {
+ stream.close();
+ }
+
+ // check that we can create file in directory
+ Path file = Files.createFile(subdir.resolve("foo"));
+ try {
+ Files.newByteChannel(file, READ,WRITE).close();
+ } finally {
+ Files.delete(file);
+ }
+
+ // check file permissions are 0700 or more secure
+ if (Files.getFileStore(subdir).supportsFileAttributeView("posix")) {
+ Set<PosixFilePermission> perms = Files.getPosixFilePermissions(subdir);
+ perms.remove(PosixFilePermission.OWNER_READ);
+ perms.remove(PosixFilePermission.OWNER_WRITE);
+ perms.remove(PosixFilePermission.OWNER_EXECUTE);
+ if (!perms.isEmpty())
+ throw new RuntimeException("Temporary directory is not secure");
+ }
+ } finally {
+ Files.delete(subdir);
+ }
+ }
+
+ static void testTempDirectory(String prefix) throws IOException {
+ testTempDirectory(prefix, null);
+ }
+
+ static void testInvalidFileTemp(String prefix, String suffix) throws IOException {
+ try {
+ Path file = Files.createTempFile(prefix, suffix);
+ Files.delete(file);
+ throw new RuntimeException("IllegalArgumentException expected");
+ } catch (IllegalArgumentException expected) { }
+ }
+
+ public static void main(String[] args) throws IOException {
+ // temporary-file directory
+ testTempFile("blah", ".dat");
+ testTempFile("blah", null);
+ testTempFile(null, ".dat");
+ testTempFile(null, null);
+ testTempDirectory("blah");
+ testTempDirectory(null);
+
+ // a given directory
+ Path dir = Files.createTempDirectory("tmpdir");
+ try {
+ testTempFile("blah", ".dat", dir);
+ testTempFile("blah", null, dir);
+ testTempFile(null, ".dat", dir);
+ testTempFile(null, null, dir);
+ testTempDirectory("blah", dir);
+ testTempDirectory(null, dir);
+ } finally {
+ Files.delete(dir);
+ }
+
+ // invalid prefix and suffix
+ testInvalidFileTemp("../blah", null);
+ testInvalidFileTemp("dir/blah", null);
+ testInvalidFileTemp("blah", ".dat/foo");
+ }
+}
--- a/jdk/test/java/nio/file/Files/TerminateWalk.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Unit test for Files.walkFileTree to test TERMINATE return value
- */
-
-public class TerminateWalk {
-
- static final Random rand = new Random();
- static boolean terminated;
-
- static FileVisitResult maybeTerminate() {
- if (terminated)
- throw new RuntimeException("FileVisitor invoked after termination");
- if (rand.nextInt(10) == 0) {
- terminated = true;
- return FileVisitResult.TERMINATE;
- } else {
- return FileVisitResult.CONTINUE;
- }
- }
-
- public static void main(String[] args) throws Exception {
- Path dir = Paths.get(args[0]);
-
- Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- return maybeTerminate();
- }
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- return maybeTerminate();
- }
- @Override
- public FileVisitResult postVisitDirectory(Path dir, IOException x) {
- return maybeTerminate();
- }
- });
- }
-}
--- a/jdk/test/java/nio/file/Files/WalkWithSecurity.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 6876541
- * @summary Test Files.walkFileTree in the presence of a security manager
- * @build WalkWithSecurity
- * @run main/othervm WalkWithSecurity grantAll.policy pass
- * @run main/othervm WalkWithSecurity denyAll.policy fail
- * @run main/othervm WalkWithSecurity grantTopOnly.policy top_only
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.io.IOException;
-
-public class WalkWithSecurity {
-
- public static void main(String[] args) throws IOException {
- String policyFile = args[0];
- ExpectedResult expectedResult = ExpectedResult.valueOf(args[1].toUpperCase());
-
- String here = System.getProperty("user.dir");
- String testSrc = System.getProperty("test.src");
- if (testSrc == null)
- throw new RuntimeException("This test must be run by jtreg");
- Path dir = Paths.get(testSrc);
-
- // Sanity check the environment
- if (Paths.get(here).isSameFile(dir))
- throw new RuntimeException("Working directory cannot be " + dir);
- DirectoryStream<Path> stream = dir.newDirectoryStream();
- try {
- if (!stream.iterator().hasNext())
- throw new RuntimeException(testSrc + " is empty");
- } finally {
- stream.close();
- }
-
- // Install security manager with the given policy file
- System.setProperty("java.security.policy",
- dir.resolve(policyFile).toString());
- System.setSecurityManager(new SecurityManager());
-
- // Walk the source tree
- CountingVisitor visitor = new CountingVisitor();
- SecurityException exception = null;
- try {
- Files.walkFileTree(dir, visitor);
- } catch (SecurityException se) {
- exception = se;
- }
-
- // Check result
- switch (expectedResult) {
- case PASS:
- if (exception != null) {
- exception.printStackTrace();
- throw new RuntimeException("SecurityException not expected");
- }
- if (visitor.count() == 0)
- throw new RuntimeException("No files visited");
- break;
- case FAIL:
- if (exception == null)
- throw new RuntimeException("SecurityException expected");
- if (visitor.count() > 0)
- throw new RuntimeException("Files were visited");
- break;
- case TOP_ONLY:
- if (exception != null) {
- exception.printStackTrace();
- throw new RuntimeException("SecurityException not expected");
- }
- if (visitor.count() == 0)
- throw new RuntimeException("Starting file not visited");
- if (visitor.count() > 1)
- throw new RuntimeException("More than starting file visited");
- break;
- default:
- throw new RuntimeException("Should not get here");
- }
- }
-
- static enum ExpectedResult {
- PASS,
- FAIL,
- TOP_ONLY;
- }
-
- static class CountingVisitor extends SimpleFileVisitor<Path> {
- private int count;
-
- int count() {
- return count;
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- System.out.println(dir);
- count++;
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- System.out.println(file);
- count++;
- return FileVisitResult.CONTINUE;
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/delete_on_close.sh Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 4313887
+# @summary Unit test for DELETE_ON_CLOSE open option
+# @library ..
+# @build DeleteOnClose
+# @run shell delete_on_close.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+ TESTSRC=.
+ TESTCLASSES=.
+ JAVA=java
+else
+ JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+ Windows_* | CYGWIN* )
+ CLASSPATH="${TESTCLASSES};${TESTSRC}"
+ ;;
+ * )
+ CLASSPATH=${TESTCLASSES}:${TESTSRC}
+ ;;
+esac
+export CLASSPATH
+
+TMPFILE="$$.tmp"
+touch $TMPFILE
+$JAVA DeleteOnClose $TMPFILE 2>&1
+if [ $? != 0 ]; then exit 1; fi
+if [ -f $TMPFILE ]; then
+ echo "$TMPFILE was not deleted"
+ exit 1
+fi
+
+exit 0
--- a/jdk/test/java/nio/file/Files/denyAll.policy Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-// policy file that does not grant any permissions
-grant {
-};
--- a/jdk/test/java/nio/file/Files/grantAll.policy Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-// policy file that grants read access to source directory and all descendants
-grant {
- permission java.io.FilePermission "${test.src}", "read";
- permission java.io.FilePermission "${test.src}${file.separator}-", "read";
-};
--- a/jdk/test/java/nio/file/Files/grantTopOnly.policy Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-// policy file that grants read access to source directory
-grant {
- permission java.io.FilePermission "${test.src}", "read";
-};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for probeContentType method
+ * @library ../..
+ * @build Basic SimpleFileTypeDetector
+ * @run main/othervm Basic
+ */
+
+import java.nio.file.*;
+import java.io.*;
+
+/**
+ * Uses Files.probeContentType to probe html file and custom file type.
+ */
+
+public class Basic {
+
+ static Path createHtmlFile() throws IOException {
+ Path file = Files.createTempFile("foo", ".html");
+ try (OutputStream out = Files.newOutputStream(file)) {
+ out.write("<html><body>foo</body></html>".getBytes());
+ }
+
+ return file;
+ }
+
+ static Path createGrapeFile() throws IOException {
+ return Files.createTempFile("red", ".grape");
+ }
+
+ public static void main(String[] args) throws IOException {
+
+ // exercise default file type detector
+ Path file = createHtmlFile();
+ try {
+ String type = Files.probeContentType(file);
+ if (type == null) {
+ System.err.println("Content type cannot be determined - test skipped");
+ } else {
+ if (!type.equals("text/html"))
+ throw new RuntimeException("Unexpected type: " + type);
+ }
+ } finally {
+ Files.delete(file);
+ }
+
+ // exercise custom file type detector
+ file = createGrapeFile();
+ try {
+ String type = Files.probeContentType(file);
+ if (type == null)
+ throw new RuntimeException("Custom file type detector not installed?");
+ if (!type.equals("grape/unknown"))
+ throw new RuntimeException("Unexpected type: " + type);
+ } finally {
+ Files.delete(file);
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/ForceLoad.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Test library dependencies by invoking Files.probeContentType
+ * before other methods that would cause nio.dll to be loaded.
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+
+public class ForceLoad {
+
+ public static void main(String[] args) throws IOException {
+ Files.probeContentType(Paths.get("."));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/META-INF/services/java.nio.file.spi.FileTypeDetector Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,1 @@
+SimpleFileTypeDetector
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/SimpleFileTypeDetector.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.spi.FileTypeDetector;
+import java.io.*;
+
+
+public class SimpleFileTypeDetector extends FileTypeDetector {
+ public SimpleFileTypeDetector() {
+ }
+
+ public String probeContentType(Path file) throws IOException {
+ System.out.println("probe " + file + "...");
+ String name = file.toString();
+ return name.endsWith(".grape") ? "grape/unknown" : null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/CreateFileTree.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Creates a file tree with possible cycles caused by symbolic links
+ * to ancestor directories.
+ */
+
+public class CreateFileTree {
+
+ static final Random rand = new Random();
+
+ public static void main(String[] args) throws IOException {
+ Path top = Files.createTempDirectory("tree");
+ List<Path> dirs = new ArrayList<Path>();
+
+ // create tree
+ Queue<Path> queue = new ArrayDeque<Path>();
+ queue.add(top);
+ int total = 1 + rand.nextInt(20);
+ int n = 0;
+ Path dir;
+ while (((dir = queue.poll()) != null) && (n < total)) {
+ int r = Math.min((total-n), (1+rand.nextInt(3)));
+ for (int i=0; i<r; i++) {
+ String name = "dir" + (++n);
+ Path subdir = Files.createDirectory(dir.resolve(name));
+ queue.offer(subdir);
+ dirs.add(subdir);
+ }
+ }
+ assert dirs.size() >= 2;
+
+ // create a few regular files in the file tree
+ int files = dirs.size() * 3;
+ for (int i=0; i<files; i++) {
+ String name = "file" + (i+1);
+ int x = rand.nextInt(dirs.size());
+ Files.createFile(dirs.get(x).resolve(name));
+ }
+
+ // create a few sym links in the file tree so as to create cycles
+ int links = 1 + rand.nextInt(5);
+ for (int i=0; i<links; i++) {
+ int x = rand.nextInt(dirs.size());
+ int y;
+ do {
+ y = rand.nextInt(dirs.size());
+ } while (y != x);
+ String name = "link" + (i+1);
+ Path link = dirs.get(x).resolve(name);
+ Path target = dirs.get(y);
+ Files.createSymbolicLink(link, target);
+ }
+
+ // done
+ System.out.println(top);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/MaxDepth.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test maxDepth parameter
+ */
+
+public class MaxDepth {
+ public static void main(String[] args) throws Exception {
+ final Path top = Paths.get(args[0]);
+
+ for (int i=0; i<5; i++) {
+ Set<FileVisitOption> opts = Collections.emptySet();
+ final int maxDepth = i;
+ Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
+ // compute depth based on relative path to top directory
+ private int depth(Path file) {
+ Path rp = file.relativize(top);
+ return (rp.getFileName().toString().equals("")) ? 0 : rp.getNameCount();
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ int d = depth(dir);
+ if (d == maxDepth)
+ throw new RuntimeException("Should not open directories at maxDepth");
+ if (d > maxDepth)
+ throw new RuntimeException("Too deep");
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ int d = depth(file);
+ if (d > maxDepth)
+ throw new RuntimeException("Too deep");
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/Nulls.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6865748
+ * @summary Unit test for java.nio.file.Files.walkFileTree
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+import java.util.*;
+
+public class Nulls {
+
+ static void npeExpected() {
+ throw new RuntimeException("NullPointerException expected");
+ }
+
+ public static void main(String[] args) throws IOException {
+ try {
+ Files.walkFileTree(null, EnumSet.noneOf(FileVisitOption.class),
+ Integer.MAX_VALUE, new SimpleFileVisitor<Path>(){});
+ npeExpected();
+ } catch (NullPointerException e) {
+ }
+ try {
+ Files.walkFileTree(Paths.get("."), null, Integer.MAX_VALUE,
+ new SimpleFileVisitor<Path>(){});
+ npeExpected();
+ } catch (NullPointerException e) {
+ }
+ try {
+ Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
+ -1, new SimpleFileVisitor<Path>(){});
+ throw new RuntimeException("IllegalArgumentExpected expected");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ Set<FileVisitOption> opts = new HashSet<>(1);
+ opts.add(null);
+ Files.walkFileTree(Paths.get("."), opts, Integer.MAX_VALUE,
+ new SimpleFileVisitor<Path>(){});
+ npeExpected();
+ } catch (NullPointerException e) {
+ }
+ try {
+ Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
+ Integer.MAX_VALUE, null);
+ npeExpected();
+ } catch (NullPointerException e) {
+ }
+
+ SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
+ boolean ranTheGauntlet = false;
+ Path dir = Paths.get(".");
+ BasicFileAttributes attrs = Files.readAttributes(dir, BasicFileAttributes.class);
+
+ try { visitor.preVisitDirectory(null, attrs);
+ } catch (NullPointerException x0) {
+ try { visitor.preVisitDirectory(dir, null);
+ } catch (NullPointerException x1) {
+ try { visitor.visitFile(null, attrs);
+ } catch (NullPointerException x2) {
+ try { visitor.visitFile(dir, null);
+ } catch (NullPointerException x3) {
+ try { visitor.visitFileFailed(null, new IOException());
+ } catch (NullPointerException x4) {
+ try { visitor.visitFileFailed(dir, null);
+ } catch (NullPointerException x5) {
+ try { visitor.postVisitDirectory(null, new IOException());
+ } catch (NullPointerException x6) {
+ // if we get here then all visit* methods threw NPE as expected
+ ranTheGauntlet = true;
+ }}}}}}}
+ if (!ranTheGauntlet)
+ throw new RuntimeException("A visit method did not throw NPE");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/PrintFileTree.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Invokes Files.walkFileTree to traverse a file tree and prints
+ * each of the directories and files. The -follow option causes symbolic
+ * links to be followed and the -printCycles option will print links
+ * where the target of the link is an ancestor directory.
+ */
+
+public class PrintFileTree {
+
+ public static void main(String[] args) throws Exception {
+ boolean followLinks = false;
+ boolean printCycles = false;
+ int i = 0;
+ while (i < (args.length-1)) {
+ switch (args[i]) {
+ case "-follow" : followLinks = true; break;
+ case "-printCycles" : printCycles = true; break;
+ default:
+ throw new RuntimeException(args[i] + " not recognized");
+ }
+ i++;
+ }
+ Path dir = Paths.get(args[i]);
+
+ Set<FileVisitOption> options = new HashSet<FileVisitOption>();
+ if (followLinks)
+ options.add(FileVisitOption.FOLLOW_LINKS);
+
+ final boolean reportCycles = printCycles;
+ Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ System.out.println(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ if (!attrs.isDirectory() || reportCycles)
+ System.out.println(file);
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+ throws IOException
+ {
+ if (exc != null)
+ throw exc;
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult visitFileFailed(Path file, IOException exc)
+ throws IOException
+ {
+ if (reportCycles && (exc instanceof FileSystemLoopException)) {
+ System.out.println(file);
+ return FileVisitResult.CONTINUE;
+ }
+ throw exc;
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/SkipSiblings.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test SKIP_SIBLINGS return value.
+ */
+
+public class SkipSiblings {
+
+ static final Random rand = new Random();
+ static final Set<Path> skipped = new HashSet<Path>();
+
+ // check if this path's directory has been skipped
+ static void check(Path path) {
+ if (skipped.contains(path.getParent()))
+ throw new RuntimeException(path + " should not have been visited");
+ }
+
+ // indicates if the siblings of this path should be skipped
+ static boolean skip(Path path) {
+ Path parent = path.getParent();
+ if (parent != null && rand.nextBoolean()) {
+ skipped.add(parent);
+ return true;
+ }
+ return false;
+ }
+
+ public static void main(String[] args) throws Exception {
+ Path dir = Paths.get(args[0]);
+
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ check(dir);
+ if (skip(dir))
+ return FileVisitResult.SKIP_SIBLINGS;
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ check(file);
+ if (skip(file))
+ return FileVisitResult.SKIP_SIBLINGS;
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException x) {
+ if (x != null)
+ throw new RuntimeException(x);
+ check(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/TerminateWalk.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test TERMINATE return value
+ */
+
+public class TerminateWalk {
+
+ static final Random rand = new Random();
+ static boolean terminated;
+
+ static FileVisitResult maybeTerminate() {
+ if (terminated)
+ throw new RuntimeException("FileVisitor invoked after termination");
+ if (rand.nextInt(10) == 0) {
+ terminated = true;
+ return FileVisitResult.TERMINATE;
+ } else {
+ return FileVisitResult.CONTINUE;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ Path dir = Paths.get(args[0]);
+
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ return maybeTerminate();
+ }
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ return maybeTerminate();
+ }
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException x) {
+ return maybeTerminate();
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/WalkWithSecurity.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6876541
+ * @summary Test Files.walkFileTree in the presence of a security manager
+ * @build WalkWithSecurity
+ * @run main/othervm WalkWithSecurity grantAll.policy pass
+ * @run main/othervm WalkWithSecurity denyAll.policy fail
+ * @run main/othervm WalkWithSecurity grantTopOnly.policy top_only
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+
+public class WalkWithSecurity {
+
+ public static void main(String[] args) throws IOException {
+ String policyFile = args[0];
+ ExpectedResult expectedResult = ExpectedResult.valueOf(args[1].toUpperCase());
+
+ String here = System.getProperty("user.dir");
+ String testSrc = System.getProperty("test.src");
+ if (testSrc == null)
+ throw new RuntimeException("This test must be run by jtreg");
+ Path dir = Paths.get(testSrc);
+
+ // Sanity check the environment
+ if (Files.isSameFile(Paths.get(here), dir))
+ throw new RuntimeException("Working directory cannot be " + dir);
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
+ if (!stream.iterator().hasNext())
+ throw new RuntimeException(testSrc + " is empty");
+ }
+
+ // Install security manager with the given policy file
+ System.setProperty("java.security.policy",
+ dir.resolve(policyFile).toString());
+ System.setSecurityManager(new SecurityManager());
+
+ // Walk the source tree
+ CountingVisitor visitor = new CountingVisitor();
+ SecurityException exception = null;
+ try {
+ Files.walkFileTree(dir, visitor);
+ } catch (SecurityException se) {
+ exception = se;
+ }
+
+ // Check result
+ switch (expectedResult) {
+ case PASS:
+ if (exception != null) {
+ exception.printStackTrace();
+ throw new RuntimeException("SecurityException not expected");
+ }
+ if (visitor.count() == 0)
+ throw new RuntimeException("No files visited");
+ break;
+ case FAIL:
+ if (exception == null)
+ throw new RuntimeException("SecurityException expected");
+ if (visitor.count() > 0)
+ throw new RuntimeException("Files were visited");
+ break;
+ case TOP_ONLY:
+ if (exception != null) {
+ exception.printStackTrace();
+ throw new RuntimeException("SecurityException not expected");
+ }
+ if (visitor.count() == 0)
+ throw new RuntimeException("Starting file not visited");
+ if (visitor.count() > 1)
+ throw new RuntimeException("More than starting file visited");
+ break;
+ default:
+ throw new RuntimeException("Should not get here");
+ }
+ }
+
+ static enum ExpectedResult {
+ PASS,
+ FAIL,
+ TOP_ONLY;
+ }
+
+ static class CountingVisitor extends SimpleFileVisitor<Path> {
+ private int count;
+
+ int count() {
+ return count;
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ System.out.println(dir);
+ count++;
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ System.out.println(file);
+ count++;
+ return FileVisitResult.CONTINUE;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/denyAll.policy Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,3 @@
+// policy file that does not grant any permissions
+grant {
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/grantAll.policy Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,5 @@
+// policy file that grants read access to source directory and all descendants
+grant {
+ permission java.io.FilePermission "${test.src}", "read";
+ permission java.io.FilePermission "${test.src}${file.separator}-", "read";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/grantTopOnly.policy Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,4 @@
+// policy file that grants read access to source directory
+grant {
+ permission java.io.FilePermission "${test.src}", "read";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/walk_file_tree.sh Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,98 @@
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 4313887 6907737
+# @summary Unit test for walkFileTree method
+# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
+# @run shell walk_file_tree.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+ TESTSRC=.
+ TESTCLASSES=.
+ JAVA=java
+else
+ JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+ Windows_* | CYGWIN* )
+ echo "This test does not run on Windows"
+ exit 0
+ ;;
+ * )
+ CLASSPATH=${TESTCLASSES}:${TESTSRC}
+ ;;
+esac
+export CLASSPATH
+
+# create the file tree
+ROOT=`$JAVA CreateFileTree`
+if [ $? != 0 ]; then exit 1; fi
+
+failures=0
+
+# print the file tree and compare output with find(1)
+$JAVA PrintFileTree "$ROOT" > out1
+find "$ROOT" > out2
+diff out1 out2
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# repeat test following links. Some versions of find(1) output
+# cycles (sym links to ancestor directories), other versions do
+# not. For that reason we run PrintFileTree with the -printCycles
+# option when the output without this option differs to find(1).
+find "$ROOT" -follow > out1
+$JAVA PrintFileTree -follow "$ROOT" > out2
+diff out1 out2
+if [ $? != 0 ];
+ then
+ # re-run printing cycles to stdout
+ $JAVA PrintFileTree -follow -printCycles "$ROOT" > out2
+ diff out1 out2
+ if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+ fi
+
+# test SKIP_SIBLINGS
+$JAVA SkipSiblings "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# test TERMINATE
+$JAVA TerminateWalk "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# test maxDepth
+$JAVA MaxDepth "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# clean-up
+rm -r "$ROOT"
+
+echo ''
+if [ $failures -gt 0 ];
+ then echo "$failures test(s) failed";
+ else echo "Test passed"; fi
+exit $failures
--- a/jdk/test/java/nio/file/Files/walk_file_tree.sh Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 4313887 6907737
-# @summary Unit test for walkFileTree method
-# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
-# @run shell walk_file_tree.sh
-
-# if TESTJAVA isn't set then we assume an interactive run.
-
-if [ -z "$TESTJAVA" ]; then
- TESTSRC=.
- TESTCLASSES=.
- JAVA=java
-else
- JAVA="${TESTJAVA}/bin/java"
-fi
-
-OS=`uname -s`
-case "$OS" in
- Windows_* | CYGWIN* )
- echo "This test does not run on Windows"
- exit 0
- ;;
- * )
- CLASSPATH=${TESTCLASSES}:${TESTSRC}
- ;;
-esac
-export CLASSPATH
-
-# create the file tree
-ROOT=`$JAVA CreateFileTree`
-if [ $? != 0 ]; then exit 1; fi
-
-failures=0
-
-# print the file tree and compare output with find(1)
-$JAVA PrintFileTree "$ROOT" > out1
-find "$ROOT" > out2
-diff out1 out2
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# repeat test following links. Some versions of find(1) output
-# cycles (sym links to ancestor directories), other versions do
-# not. For that reason we run PrintFileTree with the -printCycles
-# option when the output without this option differs to find(1).
-find "$ROOT" -follow > out1
-$JAVA PrintFileTree -follow "$ROOT" > out2
-diff out1 out2
-if [ $? != 0 ];
- then
- # re-run printing cycles to stdout
- $JAVA PrintFileTree -follow -printCycles "$ROOT" > out2
- diff out1 out2
- if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
- fi
-
-# test SKIP_SIBLINGS
-$JAVA SkipSiblings "$ROOT"
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# test TERMINATE
-$JAVA TerminateWalk "$ROOT"
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# test maxDepth
-$JAVA MaxDepth "$ROOT"
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# clean-up
-rm -r "$ROOT"
-
-echo ''
-if [ $failures -gt 0 ];
- then echo "$failures test(s) failed";
- else echo "Test passed"; fi
-exit $failures
--- a/jdk/test/java/nio/file/Path/CheckPermissions.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,697 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 6866804
- * @summary Unit test for java.nio.file.Path
- * @library ..
- * @build CheckPermissions
- * @run main/othervm CheckPermissions
- */
-
-import java.nio.ByteBuffer;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.nio.channels.SeekableByteChannel;
-import java.security.Permission;
-import java.io.*;
-import java.util.*;
-
-/**
- * Checks each method that accesses the file system does the right permission
- * check when there is a security manager set.
- */
-
-public class CheckPermissions {
-
- static class Checks {
- private List<Permission> permissionsChecked = new ArrayList<Permission>();
- private Set<String> propertiesChecked = new HashSet<String>();
- private List<String> readsChecked = new ArrayList<String>();
- private List<String> writesChecked = new ArrayList<String>();
- private List<String> deletesChecked = new ArrayList<String>();
- private List<String> execsChecked = new ArrayList<String>();
-
- List<Permission> permissionsChecked() { return permissionsChecked; }
- Set<String> propertiesChecked() { return propertiesChecked; }
- List<String> readsChecked() { return readsChecked; }
- List<String> writesChecked() { return writesChecked; }
- List<String> deletesChecked() { return deletesChecked; }
- List<String> execsChecked() { return execsChecked; }
- }
-
- static ThreadLocal<Checks> myChecks =
- new ThreadLocal<Checks>() {
- @Override protected Checks initialValue() {
- return null;
- }
- };
-
- static void prepare() {
- myChecks.set(new Checks());
- }
-
- static void assertCheckPermission(Class<? extends Permission> type,
- String name)
- {
- for (Permission perm: myChecks.get().permissionsChecked()) {
- if (type.isInstance(perm) && perm.getName().equals(name))
- return;
- }
- throw new RuntimeException(type.getName() + "\"" + name + "\") not checked");
- }
-
- static void assertCheckPropertyAccess(String key) {
- if (!myChecks.get().propertiesChecked().contains(key))
- throw new RuntimeException("Property " + key + " not checked");
- }
-
- static void assertChecked(Path file, List<String> list) {
- String s = file.toString();
- for (String f: list) {
- if (f.endsWith(s))
- return;
- }
- throw new RuntimeException("Access not checked");
- }
-
- static void assertCheckRead(Path file) {
- assertChecked(file, myChecks.get().readsChecked());
- }
-
- static void assertCheckWrite(Path file) {
- assertChecked(file, myChecks.get().writesChecked());
- }
-
- static void assertCheckDelete(Path file) {
- assertChecked(file, myChecks.get().deletesChecked());
- }
-
- static void assertCheckExec(Path file) {
- assertChecked(file, myChecks.get().execsChecked());
- }
-
- static class LoggingSecurityManager extends SecurityManager {
- static void install() {
- System.setSecurityManager(new LoggingSecurityManager());
- }
-
- @Override
- public void checkPermission(Permission perm) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.permissionsChecked().add(perm);
- }
-
- @Override
- public void checkPropertyAccess(String key) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.propertiesChecked().add(key);
- }
-
- @Override
- public void checkRead(String file) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.readsChecked().add(file);
- }
-
- @Override
- public void checkWrite(String file) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.writesChecked().add(file);
- }
-
- @Override
- public void checkDelete(String file) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.deletesChecked().add(file);
- }
-
- @Override
- public void checkExec(String file) {
- Checks checks = myChecks.get();
- if (checks != null)
- checks.execsChecked().add(file);
- }
- }
-
- static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
- throws IOException
- {
- prepare();
- view.readAttributes();
- assertCheckRead(file);
-
- prepare();
- FileTime now = FileTime.fromMillis(System.currentTimeMillis());
- view.setTimes(null, now, now);
- assertCheckWrite(file);
- }
-
- static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
- throws IOException
- {
- prepare();
- PosixFileAttributes attrs = view.readAttributes();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- prepare();
- view.setPermissions(attrs.permissions());
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- prepare();
- view.setOwner(attrs.owner());
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- prepare();
- view.setOwner(attrs.owner());
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
- }
-
- public static void main(String[] args) throws IOException {
- Path dir = Paths.get(System.getProperty("test.dir", "."));
- Path file = dir.resolve("file1234").createFile();
- try {
- LoggingSecurityManager.install();
-
- // -- checkAccess --
-
- prepare();
- file.checkAccess();
- assertCheckRead(file);
-
- prepare();
- file.checkAccess(AccessMode.READ);
- assertCheckRead(file);
-
- prepare();
- file.checkAccess(AccessMode.WRITE);
- assertCheckWrite(file);
-
- prepare();
- try {
- file.checkAccess(AccessMode.EXECUTE);
- } catch (AccessDeniedException x) { }
- assertCheckExec(file);
-
- prepare();
- try {
- file.checkAccess(AccessMode.READ, AccessMode.WRITE, AccessMode.EXECUTE);
- } catch (AccessDeniedException x) { }
- assertCheckRead(file);
- assertCheckWrite(file);
- assertCheckExec(file);
-
- // -- copyTo --
-
- Path target = dir.resolve("target1234");
- prepare();
- file.copyTo(target);
- try {
- assertCheckRead(file);
- assertCheckWrite(target);
- } finally {
- target.delete();
- }
-
- if (TestUtil.supportsLinks(dir)) {
- Path link = dir.resolve("link1234").createSymbolicLink(file);
- try {
- prepare();
- link.copyTo(target, LinkOption.NOFOLLOW_LINKS);
- try {
- assertCheckRead(link);
- assertCheckWrite(target);
- assertCheckPermission(LinkPermission.class, "symbolic");
- } finally {
- target.delete();
- }
- } finally {
- link.delete();
- }
- }
-
- // -- createDirectory --
-
- Path subdir = dir.resolve("subdir1234");
- prepare();
- subdir.createDirectory();
- try {
- assertCheckWrite(subdir);
- } finally {
- subdir.delete();
- }
-
- // -- createFile --
-
- Path fileToCreate = dir.resolve("file7890");
- prepare();
- try {
- fileToCreate.createFile();
- assertCheckWrite(fileToCreate);
- } finally {
- fileToCreate.delete();
- }
-
- // -- createSymbolicLink --
-
- if (TestUtil.supportsLinks(dir)) {
- prepare();
- Path link = dir.resolve("link1234").createSymbolicLink(file);
- try {
- assertCheckWrite(link);
- assertCheckPermission(LinkPermission.class, "symbolic");
- } finally {
- link.delete();
- }
- }
-
- // -- delete/deleteIfExists --
-
- Path fileToDelete = dir.resolve("file7890");
-
- fileToDelete.createFile();
- prepare();
- fileToDelete.delete();
- assertCheckDelete(fileToDelete);
-
- fileToDelete.createFile();
- prepare();
- fileToDelete.deleteIfExists();
- assertCheckDelete(fileToDelete);
-
- // -- exists/notExists --
-
- prepare();
- file.exists();
- assertCheckRead(file);
-
- prepare();
- file.notExists();
- assertCheckRead(file);
-
- // -- getFileStore --
-
- prepare();
- file.getFileStore();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
-
- // -- isSameFile --
-
- prepare();
- file.isSameFile(dir);
- assertCheckRead(file);
- assertCheckRead(dir);
-
- // -- moveTo --
-
- Path target2 = dir.resolve("target1234");
- prepare();
- file.moveTo(target2);
- try {
- assertCheckWrite(file);
- assertCheckWrite(target2);
- } finally {
- // restore file
- target2.moveTo(file);
- }
-
- // -- newByteChannel --
-
- SeekableByteChannel sbc;
-
- prepare();
- sbc = file.newByteChannel();
- try {
- assertCheckRead(file);
- } finally {
- sbc.close();
- }
- prepare();
- sbc = file.newByteChannel(StandardOpenOption.WRITE);
- try {
- assertCheckWrite(file);
- } finally {
- sbc.close();
- }
- prepare();
- sbc = file.newByteChannel(StandardOpenOption.READ, StandardOpenOption.WRITE);
- try {
- assertCheckRead(file);
- assertCheckWrite(file);
- } finally {
- sbc.close();
- }
-
- prepare();
- sbc = file.newByteChannel(StandardOpenOption.DELETE_ON_CLOSE);
- try {
- assertCheckRead(file);
- assertCheckDelete(file);
- } finally {
- sbc.close();
- }
- file.createFile(); // restore file
-
-
- // -- newInputStream/newOutptuStream --
-
- prepare();
- InputStream in = file.newInputStream();
- try {
- assertCheckRead(file);
- } finally {
- in.close();
- }
- prepare();
- OutputStream out = file.newOutputStream();
- try {
- assertCheckWrite(file);
- } finally {
- out.close();
- }
-
- // -- newDirectoryStream --
-
- prepare();
- DirectoryStream<Path> stream = dir.newDirectoryStream();
- try {
- assertCheckRead(dir);
-
- if (stream instanceof SecureDirectoryStream<?>) {
- Path entry;
- SecureDirectoryStream<Path> sds =
- (SecureDirectoryStream<Path>)stream;
-
- // newByteChannel
- entry = file.getName();
- prepare();
- sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.READ));
- try {
- assertCheckRead(file);
- } finally {
- sbc.close();
- }
- prepare();
- sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.WRITE));
- try {
- assertCheckWrite(file);
- } finally {
- sbc.close();
- }
-
- // deleteFile
- entry = file.getName();
- prepare();
- sds.deleteFile(entry);
- assertCheckDelete(file);
- dir.resolve(entry).createFile(); // restore file
-
- // deleteDirectory
- entry = Paths.get("subdir1234");
- dir.resolve(entry).createDirectory();
- prepare();
- sds.deleteDirectory(entry);
- assertCheckDelete(dir.resolve(entry));
-
- // move
- entry = Paths.get("tempname1234");
- prepare();
- sds.move(file.getName(), sds, entry);
- assertCheckWrite(file);
- assertCheckWrite(dir.resolve(entry));
- sds.move(entry, sds, file.getName()); // restore file
-
- // newDirectoryStream
- entry = Paths.get("subdir1234");
- dir.resolve(entry).createDirectory();
- try {
- prepare();
- sds.newDirectoryStream(entry).close();
- assertCheckRead(dir.resolve(entry));
- } finally {
- dir.resolve(entry).delete();
- }
-
- // getFileAttributeView to access attributes of directory
- testBasicFileAttributeView(sds
- .getFileAttributeView(BasicFileAttributeView.class), dir);
- testPosixFileAttributeView(sds
- .getFileAttributeView(PosixFileAttributeView.class), dir);
-
- // getFileAttributeView to access attributes of entry
- entry = file.getName();
- testBasicFileAttributeView(sds
- .getFileAttributeView(entry, BasicFileAttributeView.class), file);
- testPosixFileAttributeView(sds
- .getFileAttributeView(entry, PosixFileAttributeView.class), file);
-
- } else {
- System.out.println("SecureDirectoryStream not tested");
- }
-
- } finally {
- stream.close();
- }
-
- // -- toAbsolutePath --
-
- prepare();
- file.getName().toAbsolutePath();
- assertCheckPropertyAccess("user.dir");
-
- // -- toRealPath --
-
- prepare();
- file.toRealPath(true);
- assertCheckRead(file);
-
- prepare();
- file.toRealPath(false);
- assertCheckRead(file);
-
- prepare();
- Paths.get(".").toRealPath(true);
- assertCheckPropertyAccess("user.dir");
-
- prepare();
- Paths.get(".").toRealPath(false);
- assertCheckPropertyAccess("user.dir");
-
- // -- register --
-
- WatchService watcher = FileSystems.getDefault().newWatchService();
- try {
- prepare();
- dir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
- assertCheckRead(dir);
- } finally {
- watcher.close();
- }
-
- // -- getAttribute/setAttribute/readAttributes --
-
- prepare();
- file.getAttribute("size");
- assertCheckRead(file);
-
- prepare();
- file.setAttribute("lastModifiedTime",
- FileTime.fromMillis(System.currentTimeMillis()));
- assertCheckWrite(file);
-
- prepare();
- file.readAttributes("*");
- assertCheckRead(file);
-
- // -- BasicFileAttributeView --
- testBasicFileAttributeView(file
- .getFileAttributeView(BasicFileAttributeView.class), file);
-
- // -- PosixFileAttributeView --
-
- {
- PosixFileAttributeView view =
- file.getFileAttributeView(PosixFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(PosixFileAttributeView.class))
- {
- testPosixFileAttributeView(view, file);
- } else {
- System.out.println("PosixFileAttributeView not tested");
- }
- }
-
- // -- DosFileAttributeView --
-
- {
- DosFileAttributeView view =
- file.getFileAttributeView(DosFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(DosFileAttributeView.class))
- {
- prepare();
- view.readAttributes();
- assertCheckRead(file);
-
- prepare();
- view.setArchive(false);
- assertCheckWrite(file);
-
- prepare();
- view.setHidden(false);
- assertCheckWrite(file);
-
- prepare();
- view.setReadOnly(false);
- assertCheckWrite(file);
-
- prepare();
- view.setSystem(false);
- assertCheckWrite(file);
- } else {
- System.out.println("DosFileAttributeView not tested");
- }
- }
-
- // -- FileOwnerAttributeView --
-
- {
- FileOwnerAttributeView view =
- file.getFileAttributeView(FileOwnerAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(FileOwnerAttributeView.class))
- {
- prepare();
- UserPrincipal owner = view.getOwner();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- prepare();
- view.setOwner(owner);
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
- } else {
- System.out.println("FileOwnerAttributeView not tested");
- }
- }
-
- // -- UserDefinedFileAttributeView --
-
- {
- UserDefinedFileAttributeView view =
- file.getFileAttributeView(UserDefinedFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(UserDefinedFileAttributeView.class))
- {
- prepare();
- view.write("test", ByteBuffer.wrap(new byte[100]));
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
-
- prepare();
- view.read("test", ByteBuffer.allocate(100));
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
-
- prepare();
- view.size("test");
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
-
- prepare();
- view.list();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
-
- prepare();
- view.delete("test");
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class,
- "accessUserDefinedAttributes");
- } else {
- System.out.println("UserDefinedFileAttributeView not tested");
- }
- }
-
- // -- AclFileAttributeView --
- {
- AclFileAttributeView view =
- file.getFileAttributeView(AclFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView(AclFileAttributeView.class))
- {
- prepare();
- List<AclEntry> acl = view.getAcl();
- assertCheckRead(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
- prepare();
- view.setAcl(acl);
- assertCheckWrite(file);
- assertCheckPermission(RuntimePermission.class, "accessUserInformation");
- } else {
- System.out.println("AclFileAttributeView not tested");
- }
- }
-
- // -- UserPrincipalLookupService
-
- UserPrincipalLookupService lookupService =
- FileSystems.getDefault().getUserPrincipalLookupService();
- UserPrincipal owner = Attributes.getOwner(file);
-
- prepare();
- lookupService.lookupPrincipalByName(owner.getName());
- assertCheckPermission(RuntimePermission.class,
- "lookupUserInformation");
-
- try {
- UserPrincipal group = Attributes.readPosixFileAttributes(file).group();
- prepare();
- lookupService.lookupPrincipalByGroupName(group.getName());
- assertCheckPermission(RuntimePermission.class,
- "lookupUserInformation");
- } catch (UnsupportedOperationException ignore) {
- System.out.println("lookupPrincipalByGroupName not tested");
- }
-
-
- } finally {
- file.deleteIfExists();
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/CopyAndMove.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1006 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333 6917021
- * @summary Unit test for java.nio.file.Path copyTo/moveTo methods
- * @library ..
- * @build CopyAndMove PassThroughFileSystem
- * @run main/othervm CopyAndMove
- */
-
-import java.nio.ByteBuffer;
-import java.nio.file.*;
-import static java.nio.file.StandardCopyOption.*;
-import static java.nio.file.LinkOption.*;
-import java.nio.file.attribute.*;
-import java.io.*;
-import java.util.*;
-
-public class CopyAndMove {
- static final Random rand = new Random();
- static boolean heads() { return rand.nextBoolean(); }
-
- public static void main(String[] args) throws Exception {
- Path dir1 = TestUtil.createTemporaryDirectory();
- try {
- // Same directory
- doCopyTests(dir1, dir1, TestUtil.supportsLinks(dir1));
- doMoveTests(dir1, dir1, TestUtil.supportsLinks(dir1));
-
- // Different directories. Use test.dir if possible as it might be
- // a different volume/file system and so improve test coverage.
- String testDir = System.getProperty("test.dir", ".");
- Path dir2 = TestUtil.createTemporaryDirectory(testDir);
- try {
- boolean testSymbolicLinks =
- TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);
- doCopyTests(dir1, dir2, testSymbolicLinks);
- doMoveTests(dir1, dir2, testSymbolicLinks);
- } finally {
- TestUtil.removeAll(dir2);
- }
-
- // Target is location associated with custom provider
- Path dir3 = PassThroughFileSystem.create().getPath(dir1.toString());
- doCopyTests(dir1, dir3, false);
- doMoveTests(dir1, dir3, false);
-
- } finally {
- TestUtil.removeAll(dir1);
- }
- }
-
- static void checkBasicAttributes(BasicFileAttributes attrs1,
- BasicFileAttributes attrs2)
- {
- // check file type
- assertTrue(attrs1.isRegularFile() == attrs2.isRegularFile());
- assertTrue(attrs1.isDirectory() == attrs2.isDirectory());
- assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());
- assertTrue(attrs1.isOther() == attrs2.isOther());
-
- // check last modified time
- long time1 = attrs1.lastModifiedTime().toMillis();
- long time2 = attrs2.lastModifiedTime().toMillis();
- assertTrue(time1 == time2);
-
- // check size
- if (attrs1.isRegularFile())
- assertTrue(attrs1.size() == attrs2.size());
- }
-
- static void checkPosixAttributes(PosixFileAttributes attrs1,
- PosixFileAttributes attrs2)
- {
- assertTrue(attrs1.permissions().equals(attrs2.permissions()));
- assertTrue(attrs1.owner().equals(attrs2.owner()));
- assertTrue(attrs1.group().equals(attrs2.group()));
- }
-
- static void checkDosAttributes(DosFileAttributes attrs1,
- DosFileAttributes attrs2)
- {
- assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());
- assertTrue(attrs1.isHidden() == attrs2.isHidden());
- assertTrue(attrs1.isSystem() == attrs2.isSystem());
- }
-
- static void checkUserDefinedFileAttributes(Map<String,ByteBuffer> attrs1,
- Map<String,ByteBuffer> attrs2)
- {
- assert attrs1.size() == attrs2.size();
- for (String name: attrs1.keySet()) {
- ByteBuffer bb1 = attrs1.get(name);
- ByteBuffer bb2 = attrs2.get(name);
- assertTrue(bb2 != null);
- assertTrue(bb1.equals(bb2));
- }
- }
-
- static Map<String,ByteBuffer> readUserDefinedFileAttributes(Path file)
- throws IOException
- {
- UserDefinedFileAttributeView view = file
- .getFileAttributeView(UserDefinedFileAttributeView.class);
- Map<String,ByteBuffer> result = new HashMap<String,ByteBuffer>();
- for (String name: view.list()) {
- int size = view.size(name);
- ByteBuffer bb = ByteBuffer.allocate(size);
- int n = view.read(name, bb);
- assertTrue(n == size);
- bb.flip();
- result.put(name, bb);
- }
- return result;
- }
-
- // move source to target with verification
- static void moveAndVerify(Path source, Path target, CopyOption... options)
- throws IOException
- {
- // read attributes before file is moved
- BasicFileAttributes basicAttributes = null;
- PosixFileAttributes posixAttributes = null;
- DosFileAttributes dosAttributes = null;
- Map<String,ByteBuffer> namedAttributes = null;
-
- // get file attributes of source file
- String os = System.getProperty("os.name");
- if (os.equals("SunOS") || os.equals("Linux")) {
- posixAttributes = Attributes.readPosixFileAttributes(source, NOFOLLOW_LINKS);
- basicAttributes = posixAttributes;
- }
- if (os.startsWith("Windows")) {
- dosAttributes = Attributes.readDosFileAttributes(source, NOFOLLOW_LINKS);
- basicAttributes = dosAttributes;
- }
- if (basicAttributes == null)
- basicAttributes = Attributes.readBasicFileAttributes(source, NOFOLLOW_LINKS);
-
- // hash file contents if regular file
- int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;
-
- // record link target if symbolic link
- Path linkTarget = null;
- if (basicAttributes.isSymbolicLink())
- linkTarget = source.readSymbolicLink();
-
- // read named attributes if available (and file is not a sym link)
- if (!basicAttributes.isSymbolicLink() &&
- source.getFileStore().supportsFileAttributeView("xattr"))
- {
- namedAttributes = readUserDefinedFileAttributes(source);
- }
-
- // move file
- source.moveTo(target, options);
-
- // verify source does not exist
- assertTrue(source.notExists());
-
- // verify file contents
- if (basicAttributes.isRegularFile()) {
- if (computeHash(target) != hash)
- throw new RuntimeException("Failed to verify move of regular file");
- }
-
- // verify link target
- if (basicAttributes.isSymbolicLink()) {
- if (!target.readSymbolicLink().equals(linkTarget))
- throw new RuntimeException("Failed to verify move of symbolic link");
- }
-
- // verify basic attributes
- checkBasicAttributes(basicAttributes,
- Attributes.readBasicFileAttributes(target, NOFOLLOW_LINKS));
-
- // verify other attributes when same provider
- if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
-
- // verify POSIX attributes
- if (posixAttributes != null && !basicAttributes.isSymbolicLink()) {
- checkPosixAttributes(posixAttributes,
- Attributes.readPosixFileAttributes(target, NOFOLLOW_LINKS));
- }
-
- // verify DOS attributes
- if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {
- checkDosAttributes(dosAttributes,
- Attributes.readDosFileAttributes(target, NOFOLLOW_LINKS));
- }
-
- // verify named attributes
- if (namedAttributes != null &&
- target.getFileStore().supportsFileAttributeView("xattr"))
- {
- checkUserDefinedFileAttributes(namedAttributes,
- readUserDefinedFileAttributes(target));
- }
- }
- }
-
- /**
- * Tests all possible ways to invoke moveTo
- */
- static void doMoveTests(Path dir1, Path dir2, boolean supportsLinks)
- throws IOException
- {
- Path source, target, entry;
-
- boolean sameDevice = dir1.getFileStore().equals(dir2.getFileStore());
-
- // -- regular file --
-
- /**
- * Test: move regular file, target does not exist
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
-
- /**
- * Test: move regular file, target exists
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- target.delete();
- target.createDirectory();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
-
- /**
- * Test: move regular file, target does not exist
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move regular file, target exists
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createFile();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move regular file, target exists and is empty directory
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createDirectory();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move regular file, target exists and is non-empty directory
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
-
- /**
- * Test atomic move of regular file (same file store)
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir1);
- moveAndVerify(source, target, ATOMIC_MOVE);
- target.delete();
-
- /**
- * Test atomic move of regular file (different file store)
- */
- if (!sameDevice) {
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- moveAndVerify(source, target, ATOMIC_MOVE);
- throw new RuntimeException("AtomicMoveNotSupportedException expected");
- } catch (AtomicMoveNotSupportedException x) {
- }
- source.delete();
- }
-
- // -- directories --
-
- /*
- * Test: move empty directory, target does not exist
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
-
- /**
- * Test: move empty directory, target exists
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- target.delete();
- target.createDirectory();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
-
- /**
- * Test: move empty directory, target does not exist
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move empty directory, target exists
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createFile();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move empty, target exists and is empty directory
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createDirectory();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
-
- /**
- * Test: move empty directory, target exists and is non-empty directory
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- moveAndVerify(source, target, REPLACE_EXISTING);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
-
- /**
- * Test: move non-empty directory (same file system)
- */
- source = createSourceDirectory(dir1);
- source.resolve("foo").createFile();
- target = getTargetFile(dir1);
- moveAndVerify(source, target);
- target.resolve("foo").delete();
- target.delete();
-
- /**
- * Test: move non-empty directory (different file store)
- */
- if (!sameDevice) {
- source = createSourceDirectory(dir1);
- source.resolve("foo").createFile();
- target = getTargetFile(dir2);
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("IOException expected");
- } catch (IOException x) {
- }
- source.resolve("foo").delete();
- source.delete();
- }
-
- /**
- * Test atomic move of directory (same file store)
- */
- source = createSourceDirectory(dir1);
- source.resolve("foo").createFile();
- target = getTargetFile(dir1);
- moveAndVerify(source, target, ATOMIC_MOVE);
- target.resolve("foo").delete();
- target.delete();
-
- // -- symbolic links --
-
- /**
- * Test: Move symbolic link to file, target does not exist
- */
- if (supportsLinks) {
- Path tmp = createSourceFile(dir1);
- source = dir1.resolve("link").createSymbolicLink(tmp);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
- tmp.delete();
- }
-
- /**
- * Test: Move symbolic link to directory, target does not exist
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
- }
-
- /**
- * Test: Move broken symbolic link, target does not exists
- */
- if (supportsLinks) {
- Path tmp = Paths.get("doesnotexist");
- source = dir1.resolve("link").createSymbolicLink(tmp);
- target = getTargetFile(dir2);
- moveAndVerify(source, target);
- target.delete();
- }
-
- /**
- * Test: Move symbolic link, target exists
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2).createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
- }
-
- /**
- * Test: Move regular file, target exists
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2).createFile();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
- }
-
- /**
- * Test: move symbolic link, target exists and is empty directory
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2).createDirectory();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
- }
-
- /**
- * Test: symbolic link, target exists and is non-empty directory
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir2);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- moveAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
- }
-
- /**
- * Test atomic move of symbolic link (same file store)
- */
- if (supportsLinks) {
- source = dir1.resolve("link").createSymbolicLink(dir1);
- target = getTargetFile(dir2).createFile();
- moveAndVerify(source, target, REPLACE_EXISTING);
- target.delete();
- }
-
- // -- misc. tests --
-
- /**
- * Test nulls
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- source.moveTo(null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- try {
- source.moveTo(target, (CopyOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- try {
- CopyOption[] opts = { REPLACE_EXISTING, null };
- source.moveTo(target, opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- source.delete();
-
- /**
- * Test UOE
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- source.moveTo(target, new CopyOption() { });
- } catch (UnsupportedOperationException x) { }
- try {
- source.moveTo(target, REPLACE_EXISTING, new CopyOption() { });
- } catch (UnsupportedOperationException x) { }
- source.delete();
- }
-
- // copy source to target with verification
- static void copyAndVerify(Path source, Path target, CopyOption... options)
- throws IOException
- {
- source.copyTo(target, options);
-
- // get attributes of source and target file to verify copy
- boolean followLinks = true;
- LinkOption[] linkOptions = new LinkOption[0];
- boolean copyAttributes = false;
- for (CopyOption opt : options) {
- if (opt == NOFOLLOW_LINKS) {
- followLinks = false;
- linkOptions = new LinkOption[] { NOFOLLOW_LINKS };
- }
- if (opt == COPY_ATTRIBUTES)
- copyAttributes = true;
- }
- BasicFileAttributes basicAttributes = Attributes
- .readBasicFileAttributes(source, linkOptions);
-
- // check hash if regular file
- if (basicAttributes.isRegularFile())
- assertTrue(computeHash(source) == computeHash(target));
-
- // check link target if symbolic link
- if (basicAttributes.isSymbolicLink())
- assert( source.readSymbolicLink().equals(target.readSymbolicLink()));
-
- // check that attributes are copied
- if (copyAttributes && followLinks) {
- checkBasicAttributes(basicAttributes,
- Attributes.readBasicFileAttributes(source, linkOptions));
-
- // verify other attributes when same provider
- if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
-
- // check POSIX attributes are copied
- String os = System.getProperty("os.name");
- if (os.equals("SunOS") || os.equals("Linux")) {
- checkPosixAttributes(
- Attributes.readPosixFileAttributes(source, linkOptions),
- Attributes.readPosixFileAttributes(target, linkOptions));
- }
-
- // check DOS attributes are copied
- if (os.startsWith("Windows")) {
- checkDosAttributes(
- Attributes.readDosFileAttributes(source, linkOptions),
- Attributes.readDosFileAttributes(target, linkOptions));
- }
-
- // check named attributes are copied
- if (followLinks &&
- source.getFileStore().supportsFileAttributeView("xattr") &&
- target.getFileStore().supportsFileAttributeView("xattr"))
- {
- checkUserDefinedFileAttributes(readUserDefinedFileAttributes(source),
- readUserDefinedFileAttributes(target));
- }
- }
- }
- }
-
- /**
- * Tests all possible ways to invoke copyTo
- */
- static void doCopyTests(Path dir1, Path dir2, boolean supportsLinks)
- throws IOException
- {
- Path source, target, link, entry;
-
- // -- regular file --
-
- /**
- * Test: move regular file, target does not exist
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target);
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target exists
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createFile();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- target.delete();
- target.createDirectory();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target does not exist
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target exists
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createFile();
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target exists and is empty directory
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createDirectory();
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file, target exists and is non-empty directory
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
-
- /**
- * Test: copy regular file + attributes
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target, COPY_ATTRIBUTES);
- source.delete();
- target.delete();
-
-
- // -- directory --
-
- /*
- * Test: copy directory, target does not exist
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target);
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target exists
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createFile();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- target.delete();
- target.createDirectory();
- try {
- copyAndVerify(source, target);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target does not exist
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target exists
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createFile();
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target exists and is empty directory
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createDirectory();
- copyAndVerify(source, target, REPLACE_EXISTING);
- source.delete();
- target.delete();
-
- /**
- * Test: copy directory, target exists and is non-empty directory
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2).createDirectory();
- entry = target.resolve("foo").createFile();
- try {
- copyAndVerify(source, target, REPLACE_EXISTING);
- throw new RuntimeException("FileAlreadyExistsException expected");
- } catch (FileAlreadyExistsException x) {
- }
- entry.delete();
- source.delete();
- target.delete();
-
- /*
- * Test: copy directory + attributes
- */
- source = createSourceDirectory(dir1);
- target = getTargetFile(dir2);
- copyAndVerify(source, target, COPY_ATTRIBUTES);
- source.delete();
- target.delete();
-
- // -- symbolic links --
-
- /**
- * Test: Follow link
- */
- if (supportsLinks) {
- source = createSourceFile(dir1);
- link = dir1.resolve("link").createSymbolicLink(source);
- target = getTargetFile(dir2);
- copyAndVerify(link, target);
- link.delete();
- source.delete();
- }
-
- /**
- * Test: Copy link (to file)
- */
- if (supportsLinks) {
- source = createSourceFile(dir1);
- link = dir1.resolve("link").createSymbolicLink(source);
- target = getTargetFile(dir2);
- copyAndVerify(link, target, NOFOLLOW_LINKS);
- link.delete();
- source.delete();
- }
-
- /**
- * Test: Copy link (to directory)
- */
- if (supportsLinks) {
- source = dir1.resolve("mydir").createDirectory();
- link = dir1.resolve("link").createSymbolicLink(source);
- target = getTargetFile(dir2);
- copyAndVerify(link, target, NOFOLLOW_LINKS);
- link.delete();
- source.delete();
- }
-
- /**
- * Test: Copy broken link
- */
- if (supportsLinks) {
- assertTrue(source.notExists());
- link = dir1.resolve("link").createSymbolicLink(source);
- target = getTargetFile(dir2);
- copyAndVerify(link, target, NOFOLLOW_LINKS);
- link.delete();
- }
-
- /**
- * Test: Copy link to UNC (Windows only)
- */
- if (supportsLinks &&
- System.getProperty("os.name").startsWith("Windows"))
- {
- Path unc = Paths.get("\\\\rialto\\share\\file");
- link = dir1.resolve("link").createSymbolicLink(unc);
- target = getTargetFile(dir2);
- copyAndVerify(link, target, NOFOLLOW_LINKS);
- link.delete();
- }
-
- // -- misc. tests --
-
- /**
- * Test nulls
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- source.copyTo(null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- try {
- source.copyTo(target, (CopyOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- try {
- CopyOption[] opts = { REPLACE_EXISTING, null };
- source.copyTo(target, opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- source.delete();
-
- /**
- * Test UOE
- */
- source = createSourceFile(dir1);
- target = getTargetFile(dir2);
- try {
- source.copyTo(target, new CopyOption() { });
- } catch (UnsupportedOperationException x) { }
- try {
- source.copyTo(target, REPLACE_EXISTING, new CopyOption() { });
- } catch (UnsupportedOperationException x) { }
- source.delete();
- }
-
-
- static void assertTrue(boolean value) {
- if (!value)
- throw new RuntimeException("Assertion failed");
- }
-
- // computes simple hash of the given file
- static int computeHash(Path file) throws IOException {
- int h = 0;
-
- InputStream in = file.newInputStream();
- try {
- byte[] buf = new byte[1024];
- int n;
- do {
- n = in.read(buf);
- for (int i=0; i<n; i++) {
- h = 31*h + (buf[i] & 0xff);
- }
- } while (n > 0);
- } finally {
- in.close();
- }
- return h;
- }
-
- // create file of random size in given directory
- static Path createSourceFile(Path dir) throws IOException {
- String name = "source" + Integer.toString(rand.nextInt());
- Path file = dir.resolve(name).createFile();
- byte[] bytes = new byte[rand.nextInt(128*1024)];
- rand.nextBytes(bytes);
- OutputStream out = file.newOutputStream();
- try {
- out.write(bytes);
- } finally {
- out.close();
- }
- randomizeAttributes(file);
- return file;
- }
-
- // create directory in the given directory
- static Path createSourceDirectory(Path dir) throws IOException {
- String name = "sourcedir" + Integer.toString(rand.nextInt());
- Path subdir = dir.resolve(name).createDirectory();
- randomizeAttributes(subdir);
- return subdir;
- }
-
- // "randomize" the file attributes of the given file.
- static void randomizeAttributes(Path file) throws IOException {
- String os = System.getProperty("os.name");
- boolean isWindows = os.startsWith("Windows");
- boolean isUnix = os.equals("SunOS") || os.equals("Linux");
- boolean isDirectory = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS)
- .isDirectory();
-
- if (isUnix) {
- Set<PosixFilePermission> perms = Attributes
- .readPosixFileAttributes(file, NOFOLLOW_LINKS).permissions();
- PosixFilePermission[] toChange = {
- PosixFilePermission.GROUP_READ,
- PosixFilePermission.GROUP_WRITE,
- PosixFilePermission.GROUP_EXECUTE,
- PosixFilePermission.OTHERS_READ,
- PosixFilePermission.OTHERS_WRITE,
- PosixFilePermission.OTHERS_EXECUTE
- };
- for (PosixFilePermission perm: toChange) {
- if (heads()) {
- perms.add(perm);
- } else {
- perms.remove(perm);
- }
- }
- Attributes.setPosixFilePermissions(file, perms);
- }
-
- if (isWindows) {
- DosFileAttributeView view = file
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS);
- // only set or unset the hidden attribute
- view.setHidden(heads());
- }
-
- boolean addUserDefinedFileAttributes = heads() &&
- file.getFileStore().supportsFileAttributeView("xattr");
-
- // remove this when copying a direcory copies its named streams
- if (isWindows && isDirectory) addUserDefinedFileAttributes = false;
-
- if (addUserDefinedFileAttributes) {
- UserDefinedFileAttributeView view = file
- .getFileAttributeView(UserDefinedFileAttributeView.class);
- int n = rand.nextInt(16);
- while (n > 0) {
- byte[] value = new byte[1 + rand.nextInt(100)];
- view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));
- n--;
- }
- }
- }
-
- // create name for file in given directory
- static Path getTargetFile(Path dir) throws IOException {
- String name = "target" + Integer.toString(rand.nextInt());
- return dir.resolve(name);
- }
- }
--- a/jdk/test/java/nio/file/Path/DeleteOnClose.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import java.io.*;
-import java.util.*;
-
-public class DeleteOnClose {
-
- public static void main(String[] args) throws IOException {
- // open file but do not close it. Its existance will be checked by
- // the calling script.
- Paths.get(args[0]).newByteChannel(READ, WRITE, DELETE_ON_CLOSE);
-
- // check temporary file has been deleted after closing it
- Path file = File.createTempFile("blah", "tmp").toPath();
- file.newByteChannel(READ, WRITE, DELETE_ON_CLOSE).close();
- if (file.exists())
- throw new RuntimeException("Temporary file was not deleted");
-
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- // check that DELETE_ON_CLOSE fails when file is a sym link
- if (TestUtil.supportsLinks(dir)) {
- file = dir.resolve("foo").createFile();
- Path link = dir.resolve("link").createSymbolicLink(file);
- try {
- link.newByteChannel(READ, WRITE, DELETE_ON_CLOSE);
- throw new RuntimeException("IOException expected");
- } catch (IOException ignore) { }
- }
-
- // check that DELETE_ON_CLOSE works with files created via open
- // directories
- DirectoryStream stream = dir.newDirectoryStream();
- try {
- if (stream instanceof SecureDirectoryStream) {
- SecureDirectoryStream secure = (SecureDirectoryStream)stream;
- file = Paths.get("foo");
-
- Set<OpenOption> opts = new HashSet<OpenOption>();
- opts.add(WRITE);
- opts.add(DELETE_ON_CLOSE);
- secure.newByteChannel(file, opts).close();
-
- if (dir.resolve(file).exists())
- throw new RuntimeException("File not deleted");
- }
- } finally {
- stream.close();
- }
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/FileAttributes.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333
- * @summary Unit test for java.nio.file.Path
- * @library ..
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Exercises getAttribute/setAttribute/readAttributes methods.
- */
-
-public class FileAttributes {
-
- static void assertTrue(boolean okay) {
- if (!okay)
- throw new RuntimeException("Assertion Failed");
- }
-
- static void checkEqual(Object o1, Object o2) {
- if (o1 == null) {
- assertTrue(o2 == null);
- } else {
- assertTrue (o1.equals(o2));
- }
- }
-
- // checks that two time values are within 1s of each other
- static void checkNearEqual(FileTime t1, FileTime t2) {
- long diff = Math.abs(t1.toMillis() - t2.toMillis());
- assertTrue(diff <= 1000);
- }
-
- // Exercise getAttribute/setAttribute/readAttributes on basic attributes
- static void checkBasicAttributes(FileRef file, BasicFileAttributes attrs)
- throws IOException
- {
- // getAttribute
- checkEqual(attrs.size(), file.getAttribute("size"));
- checkEqual(attrs.lastModifiedTime(), file.getAttribute("basic:lastModifiedTime"));
- checkEqual(attrs.lastAccessTime(), file.getAttribute("lastAccessTime"));
- checkEqual(attrs.creationTime(), file.getAttribute("basic:creationTime"));
- assertTrue((Boolean)file.getAttribute("isRegularFile"));
- assertTrue(!(Boolean)file.getAttribute("basic:isDirectory"));
- assertTrue(!(Boolean)file.getAttribute("isSymbolicLink"));
- assertTrue(!(Boolean)file.getAttribute("basic:isOther"));
- checkEqual(attrs.fileKey(), file.getAttribute("basic:fileKey"));
-
- // setAttribute
- FileTime modTime = attrs.lastModifiedTime();
- file.setAttribute("basic:lastModifiedTime", FileTime.fromMillis(0L));
- checkEqual(Attributes.readBasicFileAttributes(file).lastModifiedTime(),
- FileTime.fromMillis(0L));
- file.setAttribute("lastModifiedTime", modTime);
- checkEqual(Attributes.readBasicFileAttributes(file).lastModifiedTime(), modTime);
-
- Map<String,?> map;
- map = file.readAttributes("*");
- assertTrue(map.size() >= 9);
- checkEqual(attrs.isRegularFile(), map.get("isRegularFile")); // check one
-
- map = file.readAttributes("basic:*");
- assertTrue(map.size() >= 9);
- checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime")); // check one
-
- map = file.readAttributes("size,lastModifiedTime");
- assertTrue(map.size() == 2);
- checkEqual(attrs.size(), map.get("size"));
- checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
-
- map = file.readAttributes(
- "basic:lastModifiedTime,lastAccessTime,ShouldNotExist");
- assertTrue(map.size() == 2);
- checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
- checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime"));
- }
-
- // Exercise getAttribute/setAttribute/readAttributes on posix attributes
- static void checkPosixAttributes(FileRef file, PosixFileAttributes attrs)
- throws IOException
- {
- checkBasicAttributes(file, attrs);
-
- // getAttribute
- checkEqual(attrs.permissions(), file.getAttribute("posix:permissions"));
- checkEqual(attrs.owner(), file.getAttribute("posix:owner"));
- checkEqual(attrs.group(), file.getAttribute("posix:group"));
-
- // setAttribute
- Set<PosixFilePermission> orig = attrs.permissions();
- Set<PosixFilePermission> newPerms = new HashSet<PosixFilePermission>(orig);
- newPerms.remove(PosixFilePermission.OTHERS_READ);
- newPerms.remove(PosixFilePermission.OTHERS_WRITE);
- newPerms.remove(PosixFilePermission.OTHERS_EXECUTE);
- file.setAttribute("posix:permissions", newPerms);
- checkEqual(Attributes.readPosixFileAttributes(file).permissions(), newPerms);
- file.setAttribute("posix:permissions", orig);
- checkEqual(Attributes.readPosixFileAttributes(file).permissions(), orig);
- file.setAttribute("posix:owner", attrs.owner());
- file.setAttribute("posix:group", attrs.group());
-
- // readAttributes
- Map<String,?> map;
- map = file.readAttributes("posix:*");
- assertTrue(map.size() >= 12);
- checkEqual(attrs.permissions(), map.get("permissions")); // check one
-
- map = file.readAttributes("posix:size,owner,ShouldNotExist");
- assertTrue(map.size() == 2);
- checkEqual(attrs.size(), map.get("size"));
- checkEqual(attrs.owner(), map.get("owner"));
- }
-
- // Exercise getAttribute/readAttributes on unix attributes
- static void checkUnixAttributes(FileRef file) throws IOException {
- // getAttribute
- int mode = (Integer)file.getAttribute("unix:mode");
- long ino = (Long)file.getAttribute("unix:ino");
- long dev = (Long)file.getAttribute("unix:dev");
- long rdev = (Long)file.getAttribute("unix:rdev");
- int nlink = (Integer)file.getAttribute("unix:nlink");
- int uid = (Integer)file.getAttribute("unix:uid");
- int gid = (Integer)file.getAttribute("unix:gid");
- FileTime ctime = (FileTime)file.getAttribute("unix:ctime");
-
- // readAttributes
- Map<String,?> map;
- map = file.readAttributes("unix:*");
- assertTrue(map.size() >= 20);
-
- map = file.readAttributes("unix:size,uid,gid,ShouldNotExist");
- assertTrue(map.size() == 3);
- checkEqual(map.get("size"),
- Attributes.readBasicFileAttributes(file).size());
- }
-
- // Exercise getAttribute/setAttribute on dos attributes
- static void checkDosAttributes(FileRef file, DosFileAttributes attrs)
- throws IOException
- {
- checkBasicAttributes(file, attrs);
-
- // getAttribute
- checkEqual(attrs.isReadOnly(), file.getAttribute("dos:readonly"));
- checkEqual(attrs.isHidden(), file.getAttribute("dos:hidden"));
- checkEqual(attrs.isSystem(), file.getAttribute("dos:system"));
- checkEqual(attrs.isArchive(), file.getAttribute("dos:archive"));
-
- // setAttribute
- boolean value;
-
- value = attrs.isReadOnly();
- file.setAttribute("dos:readonly", !value);
- checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), !value);
- file.setAttribute("dos:readonly", value);
- checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), value);
-
- value = attrs.isHidden();
- file.setAttribute("dos:hidden", !value);
- checkEqual(Attributes.readDosFileAttributes(file).isHidden(), !value);
- file.setAttribute("dos:hidden", value);
- checkEqual(Attributes.readDosFileAttributes(file).isHidden(), value);
-
- value = attrs.isSystem();
- file.setAttribute("dos:system", !value);
- checkEqual(Attributes.readDosFileAttributes(file).isSystem(), !value);
- file.setAttribute("dos:system", value);
- checkEqual(Attributes.readDosFileAttributes(file).isSystem(), value);
-
- value = attrs.isArchive();
- file.setAttribute("dos:archive", !value);
- checkEqual(Attributes.readDosFileAttributes(file).isArchive(), !value);
- file.setAttribute("dos:archive", value);
- checkEqual(Attributes.readDosFileAttributes(file).isArchive(), value);
-
- // readAttributes
- Map<String,?> map;
- map = file.readAttributes("dos:*");
- assertTrue(map.size() >= 13);
- checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
-
- map = file.readAttributes("dos:size,hidden,ShouldNotExist");
- assertTrue(map.size() == 2);
- checkEqual(attrs.size(), map.get("size"));
- checkEqual(attrs.isHidden(), map.get("hidden"));
- }
-
- static void miscTests(Path file) throws IOException {
- // NPE tests
- try {
- file.getAttribute(null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException npe) { }
- try {
- file.getAttribute("isRegularFile", (LinkOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException npe) { }
- try {
- file.setAttribute(null, 0L);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException npe) { }
- }
-
- static void doTests(Path dir) throws IOException {
- Path file = dir.resolve("foo").createFile();
- FileStore store = file.getFileStore();
- try {
- checkBasicAttributes(file,
- Attributes.readBasicFileAttributes(file));
-
- if (store.supportsFileAttributeView("posix"))
- checkPosixAttributes(file,
- Attributes.readPosixFileAttributes(file));
-
- if (store.supportsFileAttributeView("unix"))
- checkUnixAttributes(file);
-
- if (store.supportsFileAttributeView("dos"))
- checkDosAttributes(file,
- Attributes.readDosFileAttributes(file));
-
- miscTests(file);
- } finally {
- file.delete();
- }
- }
-
-
- public static void main(String[] args) throws IOException {
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- doTests(dir);
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/InterruptCopy.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6993267
- * @summary Unit test for Sun-specific ExtendedCopyOption.INTERRUPTIBLE option
- * @library ..
- * @run main/othervm -XX:-UseVMInterruptibleIO InterruptCopy
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.Attributes;
-import java.io.*;
-import java.util.concurrent.*;
-import com.sun.nio.file.ExtendedCopyOption;
-
-public class InterruptCopy {
-
- private static final long FILE_SIZE_TO_COPY = 512L * 1024L * 1024L;
- private static final int DELAY_IN_MS = 500;
- private static final int DURATION_MAX_IN_MS = 5000;
-
- public static void main(String[] args) throws Exception {
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- FileStore store = dir.getFileStore();
- System.out.format("Checking space (%s)\n", store);
- long usableSpace = Attributes
- .readFileStoreSpaceAttributes(store).usableSpace();
- if (usableSpace < 2*FILE_SIZE_TO_COPY) {
- System.out.println("Insufficient disk space to run test.");
- return;
- }
- doTest(dir);
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-
- static void doTest(Path dir) throws Exception {
- final Path source = dir.resolve("foo");
- final Path target = dir.resolve("bar");
-
- // create source file (don't create it as sparse file because we
- // require the copy to take a long time)
- System.out.println("Creating source file...");
- byte[] buf = new byte[32*1024];
- long total = 0;
- OutputStream out = source.newOutputStream();
- try {
- do {
- out.write(buf);
- total += buf.length;
- } while (total < FILE_SIZE_TO_COPY);
- } finally {
- out.close();
- }
- System.out.println("Source file created.");
-
- ScheduledExecutorService pool =
- Executors.newSingleThreadScheduledExecutor();
- try {
- // copy source to target in main thread, interrupting it after a delay
- final Thread me = Thread.currentThread();
- Future<?> wakeup = pool.schedule(new Runnable() {
- public void run() {
- me.interrupt();
- }}, DELAY_IN_MS, TimeUnit.MILLISECONDS);
- System.out.println("Copying file...");
- try {
- long start = System.currentTimeMillis();
- source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE);
- long duration = System.currentTimeMillis() - start;
- if (duration > DURATION_MAX_IN_MS)
- throw new RuntimeException("Copy was not interrupted");
- } catch (IOException e) {
- boolean interrupted = Thread.interrupted();
- if (!interrupted)
- throw new RuntimeException("Interrupt status was not set");
- System.out.println("Copy failed (this is expected)");
- }
- try {
- wakeup.get();
- } catch (InterruptedException ignore) { }
- Thread.interrupted();
-
- // copy source to target via task in thread pool, interrupting it after
- // a delay using cancel(true)
- Future<Void> result = pool.submit(new Callable<Void>() {
- public Void call() throws IOException {
- System.out.println("Copying file...");
- source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE,
- StandardCopyOption.REPLACE_EXISTING);
- return null;
- }
- });
- Thread.sleep(DELAY_IN_MS);
- boolean cancelled = result.cancel(true);
- if (!cancelled)
- result.get();
- System.out.println("Copy cancelled.");
- } finally {
- pool.shutdown();
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/Links.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333 6863864
- * @summary Unit test for java.nio.file.Path createSymbolicLink,
- * readSymbolicLink, and createLink methods
- * @library ..
- * @build Links
- * @run main/othervm Links
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.*;
-
-public class Links {
-
- static final boolean isWindows =
- System.getProperty("os.name").startsWith("Windows");
-
- static void assertTrue(boolean okay) {
- if (!okay)
- throw new RuntimeException("Assertion failed");
- }
-
- /**
- * Exercise createSymbolicLink and readLink methods
- */
- static void testSymLinks(Path dir) throws IOException {
- final Path link = dir.resolve("link");
-
- // Check if sym links are supported
- try {
- link.createSymbolicLink(Paths.get("foo"));
- link.delete();
- } catch (UnsupportedOperationException x) {
- // sym links not supported
- return;
- } catch (IOException x) {
- // probably insufficient privileges to create sym links (Windows)
- return;
- }
-
- // Test links to various targets
- String[] windowsTargets =
- { "foo", "C:\\foo", "\\foo", "\\\\server\\share\\foo" };
- String[] otherTargets = { "relative", "/absolute" };
-
- String[] targets = (isWindows) ? windowsTargets : otherTargets;
- for (String s: targets) {
- Path target = Paths.get(s);
- link.createSymbolicLink(target);
- try {
- assertTrue(link.readSymbolicLink().equals(target));
- } finally {
- link.delete();
- }
- }
-
- // Test links to directory
- Path mydir = dir.resolve("mydir");
- Path myfile = mydir.resolve("myfile");
- try {
- mydir.createDirectory();
- myfile.createFile();
-
- // link -> "mydir"
- link.createSymbolicLink(mydir.getName());
- assertTrue(link.readSymbolicLink().equals(mydir.getName()));
-
- // Test access to directory via link
- DirectoryStream<Path> stream = link.newDirectoryStream();
- try {
- boolean found = false;
- for (Path entry: stream) {
- if (entry.getName().equals(myfile.getName())) {
- found = true;
- break;
- }
- }
- assertTrue(found);
- } finally {
- stream.close();
- }
-
- // Test link2 -> link -> mydir
- final Path link2 = dir.resolve("link2");
- Path target2 = link.getName();
- link2.createSymbolicLink(target2);
- try {
- assertTrue(link2.readSymbolicLink().equals(target2));
- link2.newDirectoryStream().close();
- } finally {
- link2.delete();
- }
-
- // Remove mydir and re-create link2 before re-creating mydir
- // (This is a useful test on Windows to ensure that creating a
- // sym link to a directory sym link creates the right type of link).
- myfile.delete();
- mydir.delete();
- link2.createSymbolicLink(target2);
- try {
- assertTrue(link2.readSymbolicLink().equals(target2));
- mydir.createDirectory();
- link2.newDirectoryStream().close();
- } finally {
- link2.delete();
- }
-
- } finally {
- myfile.deleteIfExists();
- mydir.deleteIfExists();
- link.deleteIfExists();
- }
- }
-
- /**
- * Exercise createLink method
- */
- static void testHardLinks(Path dir) throws IOException {
- Path foo = dir.resolve("foo").createFile();
- try {
- Path bar;
- try {
- bar = dir.resolve("bar").createLink(foo);
- } catch (UnsupportedOperationException x) {
- return;
- } catch (IOException x) {
- // probably insufficient privileges (Windows)
- return;
- }
- try {
- Object key1 = Attributes
- .readBasicFileAttributes(foo).fileKey();
- Object key2 = Attributes
- .readBasicFileAttributes(bar).fileKey();
- assertTrue((key1 == null) || (key1.equals(key2)));
- } finally {
- bar.delete();
- }
-
-
- } finally {
- foo.delete();
- }
- }
-
- public static void main(String[] args) throws IOException {
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- testSymLinks(dir);
- testHardLinks(dir);
-
- // repeat tests on Windows with long path
- if (isWindows) {
- Path dirWithLongPath = null;
- try {
- dirWithLongPath = TestUtil.createDirectoryWithLongPath(dir);
- } catch (IOException x) {
- System.out.println("Unable to create long path: " + x);
- }
- if (dirWithLongPath != null) {
- System.out.println("");
- System.out.println("** REPEAT TESTS WITH LONG PATH **");
- testSymLinks(dirWithLongPath);
- testHardLinks(dirWithLongPath);
- }
- }
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/Misc.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/Path/Misc.java Tue Feb 08 14:25:33 2011 -0800
@@ -22,17 +22,13 @@
*/
/* @test
- * @bug 4313887 6838333 6867101
- * @summary Unit test for java.nio.file.Path for miscellenous methods not
- * covered by other tests
+ * @bug 4313887 6838333
+ * @summary Unit test for miscellenous java.nio.file.Path methods
* @library ..
*/
import java.nio.file.*;
-import static java.nio.file.LinkOption.*;
-import java.nio.file.attribute.*;
import java.io.*;
-import java.util.*;
public class Misc {
static final boolean isWindows =
@@ -45,22 +41,14 @@
supportsLinks = TestUtil.supportsLinks(dir);
// equals and hashCode methods
- equalsAndHashCode();
+ testEqualsAndHashCode();
- // checkAccess method
- checkAccessTests(dir);
-
- // getFileAttributeView methods
- getFileAttributeViewTests(dir);
+ // toFile method
+ testToFile(dir);
// toRealPath method
- toRealPathTests(dir);
+ testToRealPath(dir);
- // isSameFile method
- isSameFileTests(dir);
-
- // isHidden method
- isHiddenTests(dir);
} finally {
TestUtil.removeAll(dir);
@@ -70,8 +58,7 @@
/**
* Exercise equals and hashCode methods
*/
- static void equalsAndHashCode() {
-
+ static void testEqualsAndHashCode() {
Path thisFile = Paths.get("this");
Path thatFile = Paths.get("that");
@@ -93,172 +80,25 @@
}
/**
- * Exercise checkAccess method
+ * Exercise toFile method
*/
- static void checkAccessTests(Path dir) throws IOException {
- final Path file = dir.resolve("foo").createFile();
-
- /**
- * Test: This directory should readable and writable
- */
- dir.checkAccess();
- dir.checkAccess(AccessMode.READ);
- dir.checkAccess(AccessMode.WRITE);
- dir.checkAccess(AccessMode.READ, AccessMode.WRITE);
-
- /**
- * Test: Check access to all files in all root directories.
- * (A useful test on Windows for special files such as pagefile.sys)
- */
- for (Path root: FileSystems.getDefault().getRootDirectories()) {
- DirectoryStream<Path> stream;
- try {
- stream = root.newDirectoryStream();
- } catch (IOException x) {
- continue; // skip root directories that aren't accessible
- }
- try {
- for (Path entry: stream) {
- try {
- entry.checkAccess();
- } catch (AccessDeniedException ignore) { }
- }
- } finally {
- stream.close();
- }
- }
-
- /**
- * Test: File does not exist
- */
- Path doesNotExist = dir.resolve("thisDoesNotExists");
- try {
- doesNotExist.checkAccess();
- throw new RuntimeException("NoSuchFileException expected");
- } catch (NoSuchFileException x) {
- }
- try {
- doesNotExist.checkAccess(AccessMode.READ);
- throw new RuntimeException("NoSuchFileException expected");
- } catch (NoSuchFileException x) {
- }
- try {
- doesNotExist.checkAccess(AccessMode.WRITE);
- throw new RuntimeException("NoSuchFileException expected");
- } catch (NoSuchFileException x) {
- }
- try {
- doesNotExist.checkAccess(AccessMode.EXECUTE);
- throw new RuntimeException("NoSuchFileException expected");
- } catch (NoSuchFileException x) {
- }
-
- /**
- * Test: Edit ACL to deny WRITE and EXECUTE
- */
- AclFileAttributeView view = file
- .getFileAttributeView(AclFileAttributeView.class);
- if (view != null &&
- file.getFileStore().supportsFileAttributeView("acl"))
- {
- UserPrincipal owner = view.getOwner();
- List<AclEntry> acl = view.getAcl();
-
- // Insert entry to deny WRITE and EXECUTE
- AclEntry entry = AclEntry.newBuilder()
- .setType(AclEntryType.DENY)
- .setPrincipal(owner)
- .setPermissions(AclEntryPermission.WRITE_DATA,
- AclEntryPermission.EXECUTE)
- .build();
- acl.add(0, entry);
- view.setAcl(acl);
-
- try {
- file.checkAccess(AccessMode.WRITE);
- throw new RuntimeException("AccessDeniedException expected");
- } catch (AccessDeniedException x) {
- }
-
- try {
- file.checkAccess(AccessMode.EXECUTE);
- throw new RuntimeException("AccessDeniedException expected");
- } catch (AccessDeniedException x) {
- }
-
-
- // Restore ACL
- acl.remove(0);
- view.setAcl(acl);
- }
-
- /**
- * Test: Windows DOS read-only attribute
- */
- if (isWindows) {
- DosFileAttributeView dview =
- file.getFileAttributeView(DosFileAttributeView.class);
- dview.setReadOnly(true);
- try {
- file.checkAccess(AccessMode.WRITE);
- throw new RuntimeException("AccessDeniedException expected");
- } catch (AccessDeniedException x) {
- }
- dview.setReadOnly(false);
-
- // Read-only attribute does not make direcory read-only
- dview = dir.getFileAttributeView(DosFileAttributeView.class);
- boolean save = dview.readAttributes().isReadOnly();
- dview.setReadOnly(true);
- dir.checkAccess(AccessMode.WRITE);
- dview.setReadOnly(save);
- }
-
- /**
- * Test: null
- */
- try {
- file.checkAccess((AccessMode)null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
-
- // clean-up
- file.delete();
+ static void testToFile(Path dir) throws IOException {
+ File d = dir.toFile();
+ assertTrue(d.toString().equals(dir.toString()));
+ assertTrue(d.toPath().equals(dir));
}
/**
- * Exercise getFileAttributeFile methods
- */
- static void getFileAttributeViewTests(Path dir) {
- assertTrue(dir.getFileAttributeView(BasicFileAttributeView.class)
- instanceof BasicFileAttributeView);
- assertTrue(dir.getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
- instanceof BasicFileAttributeView);
- assertTrue(dir.getFileAttributeView(BogusFileAttributeView.class) == null);
- try {
- dir.getFileAttributeView((Class<FileAttributeView>)null);
- } catch (NullPointerException ignore) { }
- try {
- dir.getFileAttributeView(BasicFileAttributeView.class, (LinkOption[])null);
- } catch (NullPointerException ignore) { }
- try {
- dir.getFileAttributeView(BasicFileAttributeView.class, (LinkOption)null);
- } catch (NullPointerException ignore) { }
-
- }
- interface BogusFileAttributeView extends FileAttributeView { }
-
- /**
* Exercise toRealPath method
*/
- static void toRealPathTests(Path dir) throws IOException {
- final Path file = dir.resolve("foo").createFile();
+ static void testToRealPath(Path dir) throws IOException {
+ final Path file = Files.createFile(dir.resolve("foo"));
final Path link = dir.resolve("link");
/**
- * Test: toRealPath(true) will access same file as toRealPath(false)
+ * Test: totRealPath(true) will access same file as toRealPath(false)
*/
- assertTrue(file.toRealPath(true).isSameFile(file.toRealPath(false)));
+ assertTrue(Files.isSameFile(file.toRealPath(true), file.toRealPath(false)));
/**
* Test: toRealPath should fail if file does not exist
@@ -279,29 +119,27 @@
* Test: toRealPath(true) should resolve links
*/
if (supportsLinks) {
- link.createSymbolicLink(file.toAbsolutePath());
+ Files.createSymbolicLink(link, file.toAbsolutePath());
assertTrue(link.toRealPath(true).equals(file.toRealPath(true)));
- link.delete();
+ Files.delete(link);
}
-
/**
* Test: toRealPath(false) should not resolve links
*/
if (supportsLinks) {
- link.createSymbolicLink(file.toAbsolutePath());
- assertTrue(link.toRealPath(false).getName().equals(link.getName()));
- link.delete();
+ Files.createSymbolicLink(link, file.toAbsolutePath());
+ assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
+ Files.delete(link);
}
/**
* Test: toRealPath(false) with broken link
*/
if (supportsLinks) {
- Path broken = dir.resolve("doesNotExist");
- link.createSymbolicLink(broken);
- assertTrue(link.toRealPath(false).getName().equals(link.getName()));
- link.delete();
+ Path broken = Files.createSymbolicLink(link, doesNotExist);
+ assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
+ Files.delete(link);
}
/**
@@ -314,105 +152,13 @@
* Test: toRealPath should eliminate ".." when it doesn't follow a
* symbolic link
*/
- Path subdir = dir.resolve("subdir").createDirectory();
+ Path subdir = Files.createDirectory(dir.resolve("subdir"));
assertTrue(subdir.resolve("..").toRealPath(true).equals(dir.toRealPath(true)));
assertTrue(subdir.resolve("..").toRealPath(false).equals(dir.toRealPath(false)));
- subdir.delete();
+ Files.delete(subdir);
// clean-up
- file.delete();
- }
-
- /**
- * Exercise isSameFile method
- */
- static void isSameFileTests(Path dir) throws IOException {
- Path thisFile = dir.resolve("thisFile");
- Path thatFile = dir.resolve("thatFile");
-
- /**
- * Test: isSameFile for self and null
- */
- assertTrue(thisFile.isSameFile(thisFile));
- assertTrue(!thisFile.isSameFile(null));
-
- /**
- * Test: Neither files exist
- */
- try {
- thisFile.isSameFile(thatFile);
- throw new RuntimeException("IOException not thrown");
- } catch (IOException x) {
- }
- try {
- thatFile.isSameFile(thisFile);
- throw new RuntimeException("IOException not thrown");
- } catch (IOException x) {
- }
-
- thisFile.createFile();
- try {
- /**
- * Test: One file exists
- */
- try {
- thisFile.isSameFile(thatFile);
- throw new RuntimeException("IOException not thrown");
- } catch (IOException x) {
- }
- try {
- thatFile.isSameFile(thisFile);
- throw new RuntimeException("IOException not thrown");
- } catch (IOException x) {
- }
-
- thatFile.createFile();
-
- /**
- * Test: Both file exists
- */
- try {
- assertTrue(!thisFile.isSameFile(thatFile));
- assertTrue(!thatFile.isSameFile(thisFile));
- } finally {
- TestUtil.deleteUnchecked(thatFile);
- }
-
- /**
- * Test: Symbolic links
- */
- if (supportsLinks) {
- thatFile.createSymbolicLink(thisFile);
- try {
- assertTrue(thisFile.isSameFile(thatFile));
- assertTrue(thatFile.isSameFile(thisFile));
- } finally {
- TestUtil.deleteUnchecked(thatFile);
- }
- }
- } finally {
- thisFile.delete();
- }
- }
-
- /**
- * Exercise isHidden method
- */
- static void isHiddenTests(Path dir) throws IOException {
- assertTrue(!dir.isHidden());
-
- Path file = dir.resolve(".foo");
- if (isWindows) {
- file.createFile();
- try {
- file.setAttribute("dos:hidden", true);
- assertTrue(file.isHidden());
- } finally {
- file.delete();
- }
- } else {
- assertTrue(file.isHidden());
- }
+ Files.delete(file);
}
static void assertTrue(boolean okay) {
--- a/jdk/test/java/nio/file/Path/PassThroughFileSystem.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,554 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.nio.file.spi.FileSystemProvider;
-import java.nio.channels.SeekableByteChannel;
-import java.net.URI;
-import java.util.*;
-import java.io.*;
-
-/**
- * A "pass through" file system implementation that passes through, or delegates,
- * everything to the default file system.
- */
-
-class PassThroughFileSystem extends FileSystem {
- private final FileSystemProvider provider;
- private final FileSystem delegate;
-
- PassThroughFileSystem(FileSystemProvider provider, FileSystem delegate) {
- this.provider = provider;
- this.delegate = delegate;
- }
-
- /**
- * Creates a new "pass through" file system. Useful for test environments
- * where the provider might not be deployed.
- */
- static FileSystem create() throws IOException {
- FileSystemProvider provider = new PassThroughProvider();
- Map<String,?> env = Collections.emptyMap();
- URI uri = URI.create("pass:///");
- return provider.newFileSystem(uri, env);
- }
-
- @Override
- public FileSystemProvider provider() {
- return provider;
- }
-
- @Override
- public void close() throws IOException {
- delegate.close();
- }
-
- @Override
- public boolean isOpen() {
- return delegate.isOpen();
- }
-
- @Override
- public boolean isReadOnly() {
- return delegate.isReadOnly();
- }
-
- @Override
- public String getSeparator() {
- return delegate.getSeparator();
- }
-
- @Override
- public Iterable<Path> getRootDirectories() {
- final Iterable<Path> roots = delegate.getRootDirectories();
- return new Iterable<Path>() {
- @Override
- public Iterator<Path> iterator() {
- final Iterator<Path> itr = roots.iterator();
- return new Iterator<Path>() {
- @Override
- public boolean hasNext() {
- return itr.hasNext();
- }
- @Override
- public Path next() {
- return new PassThroughPath(delegate, itr.next());
- }
- @Override
- public void remove() {
- itr.remove();
- }
- };
- }
- };
- }
-
- @Override
- public Iterable<FileStore> getFileStores() {
- // assume that unwrapped objects aren't exposed
- return delegate.getFileStores();
- }
-
- @Override
- public Set<String> supportedFileAttributeViews() {
- // assume that unwrapped objects aren't exposed
- return delegate.supportedFileAttributeViews();
- }
-
- @Override
- public Path getPath(String path) {
- return new PassThroughPath(this, delegate.getPath(path));
- }
-
- @Override
- public PathMatcher getPathMatcher(String syntaxAndPattern) {
- final PathMatcher matcher = delegate.getPathMatcher(syntaxAndPattern);
- return new PathMatcher() {
- @Override
- public boolean matches(Path path) {
- return matcher.matches(PassThroughPath.unwrap(path));
- }
- };
- }
-
- @Override
- public UserPrincipalLookupService getUserPrincipalLookupService() {
- // assume that unwrapped objects aren't exposed
- return delegate.getUserPrincipalLookupService();
- }
-
- @Override
- public WatchService newWatchService() throws IOException {
- // to keep it simple
- throw new UnsupportedOperationException();
- }
-
- static class PassThroughProvider extends FileSystemProvider {
- private static final String SCHEME = "pass";
- private static volatile PassThroughFileSystem delegate;
-
- public PassThroughProvider() { }
-
- @Override
- public String getScheme() {
- return SCHEME;
- }
-
- private void checkScheme(URI uri) {
- if (!uri.getScheme().equalsIgnoreCase(SCHEME))
- throw new IllegalArgumentException();
- }
-
- private void checkUri(URI uri) {
- checkScheme(uri);
- if (!uri.getSchemeSpecificPart().equals("///"))
- throw new IllegalArgumentException();
- }
-
- @Override
- public FileSystem newFileSystem(URI uri, Map<String,?> env)
- throws IOException
- {
- checkUri(uri);
- synchronized (PassThroughProvider.class) {
- if (delegate != null)
- throw new FileSystemAlreadyExistsException();
- PassThroughFileSystem result =
- new PassThroughFileSystem(this, FileSystems.getDefault());
- delegate = result;
- return result;
- }
- }
-
- @Override
- public FileSystem getFileSystem(URI uri) {
- checkUri(uri);
- FileSystem result = delegate;
- if (result == null)
- throw new FileSystemNotFoundException();
- return result;
- }
-
- @Override
- public Path getPath(URI uri) {
- checkScheme(uri);
- if (delegate == null)
- throw new FileSystemNotFoundException();
- uri = URI.create(delegate.provider().getScheme() + ":" +
- uri.getSchemeSpecificPart());
- return new PassThroughPath(delegate, delegate.provider().getPath(uri));
- }
- }
-
- static class PassThroughPath extends Path {
- private final FileSystem fs;
- private final Path delegate;
-
- PassThroughPath(FileSystem fs, Path delegate) {
- this.fs = fs;
- this.delegate = delegate;
- }
-
- private Path wrap(Path path) {
- return (path != null) ? new PassThroughPath(fs, path) : null;
- }
-
- static Path unwrap(Path wrapper) {
- if (!(wrapper instanceof PassThroughPath))
- throw new ProviderMismatchException();
- return ((PassThroughPath)wrapper).delegate;
- }
-
- @Override
- public FileSystem getFileSystem() {
- return fs;
- }
-
- @Override
- public boolean isAbsolute() {
- return delegate.isAbsolute();
- }
-
- @Override
- public Path getRoot() {
- return wrap(delegate.getRoot());
- }
-
-
- @Override
- public Path getName() {
- return wrap(delegate.getName());
- }
-
- @Override
- public Path getParent() {
- return wrap(delegate.getParent());
- }
-
- @Override
- public int getNameCount() {
- return delegate.getNameCount();
- }
-
- @Override
- public Path getName(int index) {
- return wrap(delegate.getName(index));
- }
-
- @Override
- public Path subpath(int beginIndex, int endIndex) {
- return wrap(delegate.subpath(beginIndex, endIndex));
- }
-
- @Override
- public boolean startsWith(Path other) {
- return delegate.startsWith(unwrap(other));
- }
-
- @Override
- public boolean endsWith(Path other) {
- return delegate.endsWith(unwrap(other));
- }
-
- @Override
- public Path normalize() {
- return wrap(delegate.normalize());
- }
-
- @Override
- public Path resolve(Path other) {
- return wrap(delegate.resolve(unwrap(other)));
- }
-
- @Override
- public Path resolve(String other) {
- return wrap(delegate.resolve(other));
- }
-
- @Override
- public Path relativize(Path other) {
- return wrap(delegate.relativize(unwrap(other)));
- }
-
- @Override
- public void setAttribute(String attribute, Object value, LinkOption... options)
- throws IOException
- {
- delegate.setAttribute(attribute, value, options);
- }
-
- @Override
- public Object getAttribute(String attribute, LinkOption... options)
- throws IOException
- {
- // assume that unwrapped objects aren't exposed
- return delegate.getAttribute(attribute, options);
- }
-
- @Override
- public Map<String,?> readAttributes(String attributes, LinkOption... options)
- throws IOException
- {
- // assume that unwrapped objects aren't exposed
- return delegate.readAttributes(attributes, options);
- }
-
- @Override
- public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
- LinkOption... options)
- {
- return delegate.getFileAttributeView(type, options);
- }
-
- @Override
- public void delete() throws IOException {
- delegate.delete();
- }
-
- @Override
- public void deleteIfExists() throws IOException {
- delegate.deleteIfExists();
- }
-
- @Override
- public Path createSymbolicLink(Path target, FileAttribute<?>... attrs)
- throws IOException
- {
- delegate.createSymbolicLink(unwrap(target), attrs);
- return this;
- }
-
- @Override
- public Path createLink(Path existing) throws IOException {
- delegate.createLink(unwrap(existing));
- return this;
- }
-
- @Override
- public Path readSymbolicLink() throws IOException {
- return wrap(delegate.readSymbolicLink());
- }
-
- @Override
- public URI toUri() {
- String ssp = delegate.toUri().getSchemeSpecificPart();
- return URI.create(fs.provider().getScheme() + ":" + ssp);
- }
-
- @Override
- public Path toAbsolutePath() {
- return wrap(delegate.toAbsolutePath());
- }
-
- @Override
- public Path toRealPath(boolean resolveLinks) throws IOException {
- return wrap(delegate.toRealPath(resolveLinks));
- }
-
- @Override
- public Path copyTo(Path target, CopyOption... options) throws IOException {
- return wrap(delegate.copyTo(unwrap(target), options));
- }
-
- @Override
- public Path moveTo(Path target, CopyOption... options) throws IOException {
- return wrap(delegate.copyTo(unwrap(target), options));
- }
-
- private DirectoryStream<Path> wrap(final DirectoryStream<Path> stream) {
- return new DirectoryStream<Path>() {
- @Override
- public Iterator<Path> iterator() {
- final Iterator<Path> itr = stream.iterator();
- return new Iterator<Path>() {
- @Override
- public boolean hasNext() {
- return itr.hasNext();
- }
- @Override
- public Path next() {
- return wrap(itr.next());
- }
- @Override
- public void remove() {
- itr.remove();
- }
- };
- }
- @Override
- public void close() throws IOException {
- stream.close();
- }
- };
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream() throws IOException {
- return wrap(delegate.newDirectoryStream());
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(String glob)
- throws IOException
- {
- return wrap(delegate.newDirectoryStream(glob));
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
- throws IOException
- {
- return wrap(delegate.newDirectoryStream(filter));
- }
-
- @Override
- public Path createFile(FileAttribute<?>... attrs) throws IOException {
- delegate.createFile(attrs);
- return this;
- }
-
- @Override
- public Path createDirectory(FileAttribute<?>... attrs)
- throws IOException
- {
- delegate.createDirectory(attrs);
- return this;
- }
-
- @Override
- public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- return delegate.newByteChannel(options, attrs);
- }
-
- @Override
- public SeekableByteChannel newByteChannel(OpenOption... options)
- throws IOException
- {
- return delegate.newByteChannel(options);
- }
-
- @Override
- public InputStream newInputStream(OpenOption... options) throws IOException {
- return delegate.newInputStream();
- }
-
- @Override
- public OutputStream newOutputStream(OpenOption... options)
- throws IOException
- {
- return delegate.newOutputStream(options);
- }
-
- @Override
- public boolean isHidden() throws IOException {
- return delegate.isHidden();
- }
-
- @Override
- public void checkAccess(AccessMode... modes) throws IOException {
- delegate.checkAccess(modes);
- }
-
- @Override
- public boolean exists() {
- return delegate.exists();
- }
-
- @Override
- public boolean notExists() {
- return delegate.notExists();
- }
-
- @Override
- public FileStore getFileStore() throws IOException {
- return delegate.getFileStore();
- }
-
- @Override
- public WatchKey register(WatchService watcher,
- WatchEvent.Kind<?>[] events,
- WatchEvent.Modifier... modifiers)
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public WatchKey register(WatchService watcher,
- WatchEvent.Kind<?>... events)
- {
- throw new UnsupportedOperationException();
- }
-
-
- @Override
- public Iterator<Path> iterator() {
- final Iterator<Path> itr = delegate.iterator();
- return new Iterator<Path>() {
- @Override
- public boolean hasNext() {
- return itr.hasNext();
- }
- @Override
- public Path next() {
- return wrap(itr.next());
- }
- @Override
- public void remove() {
- itr.remove();
- }
- };
- }
-
- @Override
- public int compareTo(Path other) {
- return delegate.compareTo(unwrap(other));
- }
-
- @Override
- public boolean isSameFile(Path other) throws IOException {
- return delegate.isSameFile(unwrap(other));
- }
-
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof PassThroughPath))
- return false;
- return delegate.equals(unwrap((PassThroughPath)other));
- }
-
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
-
- @Override
- public String toString() {
- return delegate.toString();
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/PathOps.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/Path/PathOps.java Tue Feb 08 14:25:33 2011 -0800
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887 6838333 6925932
+ * @bug 4313887 6838333 6925932 7006126
* @summary Unit test for java.nio.file.Path path operations
*/
@@ -36,15 +36,15 @@
private Path path;
private Exception exc;
- private PathOps(String s) {
+ private PathOps(String first, String... more) {
out.println();
- input = s;
+ input = first;
try {
- path = FileSystems.getDefault().getPath(s);
- out.format("%s -> %s", s, path);
+ path = FileSystems.getDefault().getPath(first, more);
+ out.format("%s -> %s", first, path);
} catch (Exception x) {
exc = x;
- out.format("%s -> %s", s, x);
+ out.format("%s -> %s", first, x);
}
out.println();
}
@@ -97,7 +97,7 @@
PathOps name(String expected) {
out.println("check name");
checkPath();
- check(path.getName(), expected);
+ check(path.getFileName(), expected);
return this;
}
@@ -168,6 +168,13 @@
return this;
}
+ PathOps resolveSibling(String other, String expected) {
+ out.format("test resolveSibling %s\n", other);
+ checkPath();
+ check(path.resolveSibling(other), expected);
+ return this;
+ }
+
PathOps relativize(String other, String expected) {
out.format("test relativize %s\n", other);
checkPath();
@@ -198,8 +205,8 @@
return this;
}
- static PathOps test(String s) {
- return new PathOps(s);
+ static PathOps test(String first, String... more) {
+ return new PathOps(first, more);
}
// -- PathOpss --
@@ -213,6 +220,26 @@
static void doWindowsTests() {
header("Windows specific tests");
+ // construction
+ test("C:\\")
+ .string("C:\\");
+ test("C:\\", "")
+ .string("C:\\");
+ test("C:\\", "foo")
+ .string("C:\\foo");
+ test("C:\\", "\\foo")
+ .string("C:\\foo");
+ test("C:\\", "foo\\")
+ .string("C:\\foo");
+ test("foo", "bar", "gus")
+ .string("foo\\bar\\gus");
+ test("")
+ .string("");
+ test("", "C:\\")
+ .string("C:\\");
+ test("", "foo", "", "bar", "", "\\gus")
+ .string("foo\\bar\\gus");
+
// all components present
test("C:\\a\\b\\c")
.root("C:\\")
@@ -252,17 +279,23 @@
.root(null)
.parent(null)
.name("foo");
+ test("")
+ .root(null)
+ .parent(null)
+ .name("");
// startsWith
test("C:\\")
.starts("C:\\")
.starts("c:\\")
.notStarts("C")
- .notStarts("C:");
+ .notStarts("C:")
+ .notStarts("");
test("C:")
.starts("C:")
.starts("c:")
- .notStarts("C");
+ .notStarts("C")
+ .notStarts("");
test("\\")
.starts("\\");
test("C:\\foo\\bar")
@@ -273,7 +306,8 @@
.starts("C:\\Foo\\Bar")
.notStarts("C:")
.notStarts("C")
- .notStarts("C:foo");
+ .notStarts("C:foo")
+ .notStarts("");
test("\\foo\\bar")
.starts("\\")
.starts("\\foo")
@@ -281,26 +315,35 @@
.starts("\\foo\\bar")
.starts("\\fOo\\BaR")
.notStarts("foo")
- .notStarts("foo\\bar");
+ .notStarts("foo\\bar")
+ .notStarts("");
test("foo\\bar")
.starts("foo")
.starts("foo\\bar")
- .notStarts("\\");
+ .notStarts("\\")
+ .notStarts("");
test("\\\\server\\share")
.starts("\\\\server\\share")
.starts("\\\\server\\share\\")
+ .notStarts("\\")
+ .notStarts("");
+ test("")
+ .starts("")
.notStarts("\\");
// endsWith
test("C:\\")
.ends("C:\\")
.ends("c:\\")
- .notEnds("\\");
+ .notEnds("\\")
+ .notEnds("");
test("C:")
.ends("C:")
- .ends("c:");
+ .ends("c:")
+ .notEnds("");
test("\\")
- .ends("\\");
+ .ends("\\")
+ .notEnds("");
test("C:\\foo\\bar")
.ends("bar")
.ends("BAR")
@@ -309,7 +352,8 @@
.ends("C:\\foo\\bar")
.ends("c:\\foO\\baR")
.notEnds("r")
- .notEnds("\\foo\\bar");
+ .notEnds("\\foo\\bar")
+ .notEnds("");
test("\\foo\\bar")
.ends("bar")
.ends("BaR")
@@ -317,17 +361,23 @@
.ends("foO\\baR")
.ends("\\foo\\bar")
.ends("\\Foo\\Bar")
- .notEnds("oo\\bar");
+ .notEnds("oo\\bar")
+ .notEnds("");
test("foo\\bar")
.ends("bar")
.ends("BAR")
.ends("foo\\bar")
.ends("Foo\\Bar")
- .notEnds("ar");
+ .notEnds("ar")
+ .notEnds("");
test("\\\\server\\share")
.ends("\\\\server\\share")
.ends("\\\\server\\share\\")
.notEnds("shared")
+ .notEnds("\\")
+ .notEnds("");
+ test("")
+ .ends("")
.notEnds("\\");
// elements
@@ -338,6 +388,8 @@
test("foo.bar\\gus.alice")
.element(0, "foo.bar")
.element(1, "gus.alice");
+ test("")
+ .element(0, "");
// subpath
test("C:\\foo")
@@ -355,6 +407,8 @@
.subpath(2, 3, "gus");
test("\\\\server\\share\\foo")
.subpath(0, 1, "foo");
+ test("")
+ .subpath(0, 1, "");
// isAbsolute
test("foo").notAbsolute();
@@ -362,6 +416,7 @@
test("C:\\").absolute();
test("C:\\abc").absolute();
test("\\\\server\\share\\").absolute();
+ test("").notAbsolute();
// resolve
test("C:\\")
@@ -369,42 +424,99 @@
.resolve("D:\\bar", "D:\\bar")
.resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
.resolve("C:foo", "C:\\foo")
- .resolve("D:foo", "D:foo");
+ .resolve("D:foo", "D:foo")
+ .resolve("", "C:\\");
test("\\")
.resolve("foo", "\\foo")
.resolve("D:bar", "D:bar")
.resolve("C:\\bar", "C:\\bar")
.resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
- .resolve("\\foo", "\\foo");
+ .resolve("\\foo", "\\foo")
+ .resolve("", "\\");
test("\\foo")
.resolve("bar", "\\foo\\bar")
.resolve("D:bar", "D:bar")
.resolve("C:\\bar", "C:\\bar")
.resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
- .resolve("\\bar", "\\bar");
+ .resolve("\\bar", "\\bar")
+ .resolve("", "\\foo");
test("foo")
.resolve("bar", "foo\\bar")
.resolve("D:\\bar", "D:\\bar")
.resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
.resolve("C:bar", "C:bar")
- .resolve("D:foo", "D:foo");
+ .resolve("D:foo", "D:foo")
+ .resolve("", "foo");
test("C:")
- .resolve("foo", "C:foo");
+ .resolve("foo", "C:foo")
+ .resolve("", "C:");
test("\\\\server\\share\\foo")
.resolve("bar", "\\\\server\\share\\foo\\bar")
.resolve("\\bar", "\\\\server\\share\\bar")
.resolve("D:\\bar", "D:\\bar")
.resolve("\\\\other\\share\\bar", "\\\\other\\share\\bar")
- .resolve("D:bar", "D:bar");
+ .resolve("D:bar", "D:bar")
+ .resolve("", "\\\\server\\share\\foo");
+ test("")
+ .resolve("", "")
+ .resolve("foo", "foo")
+ .resolve("C:\\", "C:\\")
+ .resolve("C:foo", "C:foo")
+ .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar");
+
+ // resolveSibling
+ test("foo")
+ .resolveSibling("bar", "bar")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("C:bar", "C:bar")
+ .resolveSibling("D:foo", "D:foo")
+ .resolveSibling("", "");
+ test("foo\\bar")
+ .resolveSibling("gus", "foo\\gus")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("C:bar", "C:bar")
+ .resolveSibling("D:foo", "D:foo")
+ .resolveSibling("", "foo");
+ test("C:\\foo")
+ .resolveSibling("gus", "C:\\gus")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("C:bar", "C:\\bar")
+ .resolveSibling("D:foo", "D:foo")
+ .resolveSibling("", "C:\\");
+ test("C:\\foo\\bar")
+ .resolveSibling("gus", "C:\\foo\\gus")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("C:bar", "C:\\foo\\bar")
+ .resolveSibling("D:foo", "D:foo")
+ .resolveSibling("", "C:\\foo");
+ test("\\\\server\\share\\foo")
+ .resolveSibling("bar", "\\\\server\\share\\bar")
+ .resolveSibling("\\bar", "\\\\server\\share\\bar")
+ .resolveSibling("D:\\bar", "D:\\bar")
+ .resolveSibling("\\\\other\\share\\bar", "\\\\other\\share\\bar")
+ .resolveSibling("D:bar", "D:bar")
+ .resolveSibling("", "\\\\server\\share\\");
+ test("")
+ .resolveSibling("", "")
+ .resolveSibling("foo", "foo")
+ .resolveSibling("C:\\", "C:\\");
// relativize
test("foo\\bar")
- .relativize("foo\\bar", null)
+ .relativize("foo\\bar", "")
.relativize("foo", "..");
test("C:\\a\\b\\c")
- .relativize("C:\\a", "..\\..");
+ .relativize("C:\\a", "..\\..")
+ .relativize("C:\\a\\b\\c", "");
test("\\\\server\\share\\foo")
- .relativize("\\\\server\\share\\bar", "..\\bar");
+ .relativize("\\\\server\\share\\bar", "..\\bar")
+ .relativize("\\\\server\\share\\foo", "");
+ test("")
+ .relativize("", "");
// normalize
test("C:\\")
@@ -436,7 +548,7 @@
test("foo\\.")
.normalize("foo");
test("foo\\..")
- .normalize(null);
+ .normalize("");
test("C:\\foo")
.normalize("C:\\foo");
test("C:\\foo\\.")
@@ -478,7 +590,7 @@
test("\\..\\foo")
.normalize("\\foo");
test(".")
- .normalize(null);
+ .normalize("");
test("..")
.normalize("..");
test("\\..\\..")
@@ -493,6 +605,8 @@
.normalize("foo");
test(".\\foo\\.\\bar\\.\\gus\\..\\.\\..")
.normalize("foo");
+ test("")
+ .normalize("");
// UNC corner cases
test("\\\\server\\share\\")
@@ -557,6 +671,26 @@
static void doUnixTests() {
header("Unix specific tests");
+ // construction
+ test("/")
+ .string("/");
+ test("/", "")
+ .string("/");
+ test("/", "foo")
+ .string("/foo");
+ test("/", "/foo")
+ .string("/foo");
+ test("/", "foo/")
+ .string("/foo");
+ test("foo", "bar", "gus")
+ .string("foo/bar/gus");
+ test("")
+ .string("");
+ test("", "/")
+ .string("/");
+ test("", "foo", "", "bar", "", "/gus")
+ .string("foo/bar/gus");
+
// all components
test("/a/b/c")
.root("/")
@@ -580,10 +714,15 @@
.root(null)
.parent(null)
.name("foo");
+ test("")
+ .root(null)
+ .parent(null)
+ .name("");
// startsWith
test("/")
.starts("/")
+ .notStarts("")
.notStarts("/foo");
test("/foo")
.starts("/")
@@ -598,6 +737,7 @@
.notStarts("foo/bar");
test("foo")
.starts("foo")
+ .notStarts("")
.notStarts("f");
test("foo/bar")
.starts("foo")
@@ -605,10 +745,14 @@
.notStarts("f")
.notStarts("/foo")
.notStarts("/foo/bar");
+ test("")
+ .starts("")
+ .notStarts("/");
// endsWith
test("/")
.ends("/")
+ .notEnds("")
.notEnds("foo")
.notEnds("/foo");
test("/foo")
@@ -625,6 +769,7 @@
.notEnds("o/bar");
test("foo")
.ends("foo")
+ .notEnds("")
.notEnds("oo")
.notEnds("oola");
test("foo/bar")
@@ -642,12 +787,47 @@
.notEnds("r/gus")
.notEnds("barack/gus")
.notEnds("bar/gust");
+ test("")
+ .ends("")
+ .notEnds("/");
// elements
test("a/b/c")
- .element(0,"a")
- .element(1,"b")
- .element(2,"c");
+ .element(0, "a")
+ .element(1, "b")
+ .element(2, "c");
+ test("")
+ .element(0, "");
+
+ // subpath
+ test("/foo")
+ .subpath(0, 1, "foo");
+ test("foo")
+ .subpath(0, 1, "foo");
+ test("/foo/bar")
+ .subpath(0, 1, "foo")
+ .subpath(1, 2, "bar")
+ .subpath(0, 2, "foo/bar");
+ test("foo/bar")
+ .subpath(0, 1, "foo")
+ .subpath(1, 2, "bar")
+ .subpath(0, 2, "foo/bar");
+ test("/foo/bar/gus")
+ .subpath(0, 1, "foo")
+ .subpath(1, 2, "bar")
+ .subpath(2, 3, "gus")
+ .subpath(0, 2, "foo/bar")
+ .subpath(1, 3, "bar/gus")
+ .subpath(0, 3, "foo/bar/gus");
+ test("foo/bar/gus")
+ .subpath(0, 1, "foo")
+ .subpath(1, 2, "bar")
+ .subpath(2, 3, "gus")
+ .subpath(0, 2, "foo/bar")
+ .subpath(1, 3, "bar/gus")
+ .subpath(0, 3, "foo/bar/gus");
+ test("")
+ .subpath(0, 1, "");
// isAbsolute
test("/")
@@ -656,20 +836,61 @@
.absolute();
test("tmp")
.notAbsolute();
+ test("")
+ .notAbsolute();
+
// resolve
test("/tmp")
.resolve("foo", "/tmp/foo")
- .resolve("/foo", "/foo");
+ .resolve("/foo", "/foo")
+ .resolve("", "/tmp");
test("tmp")
.resolve("foo", "tmp/foo")
+ .resolve("/foo", "/foo")
+ .resolve("", "tmp");
+ test("")
+ .resolve("", "")
+ .resolve("foo", "foo")
.resolve("/foo", "/foo");
+ // resolveSibling
+ test("foo")
+ .resolveSibling("bar", "bar")
+ .resolveSibling("/bar", "/bar")
+ .resolveSibling("", "");
+ test("foo/bar")
+ .resolveSibling("gus", "foo/gus")
+ .resolveSibling("/gus", "/gus")
+ .resolveSibling("", "foo");
+ test("/foo")
+ .resolveSibling("gus", "/gus")
+ .resolveSibling("/gus", "/gus")
+ .resolveSibling("", "/");
+ test("/foo/bar")
+ .resolveSibling("gus", "/foo/gus")
+ .resolveSibling("/gus", "/gus")
+ .resolveSibling("", "/foo");
+ test("")
+ .resolveSibling("foo", "foo")
+ .resolveSibling("/foo", "/foo")
+ .resolve("", "");
+
// relativize
test("/a/b/c")
- .relativize("/a/b/c", null)
+ .relativize("/a/b/c", "")
.relativize("/a/b/c/d/e", "d/e")
- .relativize("/a/x", "../../x");
+ .relativize("/a/x", "../../x")
+ .relativize("/x", "../../../x");
+ test("a/b/c")
+ .relativize("a/b/c/d", "d")
+ .relativize("a/x", "../../x")
+ .relativize("x", "../../../x")
+ .relativize("", "../../..");
+ test("")
+ .relativize("a", "a")
+ .relativize("a/b/c", "a/b/c")
+ .relativize("", "");
// normalize
test("/")
@@ -679,7 +900,7 @@
test("/foo")
.normalize("/foo");
test(".")
- .normalize(null);
+ .normalize("");
test("..")
.normalize("..");
test("/..")
@@ -691,7 +912,7 @@
test("./foo")
.normalize("foo");
test("foo/..")
- .normalize(null);
+ .normalize("");
test("../foo")
.normalize("../foo");
test("../../foo")
@@ -717,7 +938,7 @@
test("//bar\u0000")
.invalid();
- // normalization
+ // normalization of input
test("//foo//bar")
.string("/foo/bar")
.root("/")
@@ -749,13 +970,13 @@
}
try {
- path.startsWith(null);
+ path.startsWith((Path)null);
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException npe) {
}
try {
- path.endsWith(null);
+ path.endsWith((Path)null);
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException npe) {
}
--- a/jdk/test/java/nio/file/Path/SBC.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887
- * @summary Unit test for java.nio.file.Path.newByteChannel
- * @library ..
- */
-
-import java.nio.ByteBuffer;
-import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import static com.sun.nio.file.ExtendedOpenOption.*;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.channels.*;
-import java.io.IOException;
-import java.util.*;
-
-public class SBC {
-
- static boolean supportsLinks;
-
- public static void main(String[] args) throws Exception {
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- supportsLinks = TestUtil.supportsLinks(dir);
-
- // open options
- createTests(dir);
- appendTests(dir);
- truncateExistingTests(dir);
- noFollowLinksTests(dir);
-
- // SeekableByteChannel methods
- sizeTruncatePositionTests(dir);
-
- // platform specific
- if (System.getProperty("os.name").startsWith("Windows"))
- dosSharingOptionTests(dir);
-
- // misc. tests
- badCombinations(dir);
- unsupportedOptions(dir);
- nullTests(dir);
-
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-
- // test CREATE and CREATE_NEW options
- static void createTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
-
- // CREATE
- try {
- // create file (no existing file)
- file.newByteChannel(CREATE, WRITE).close();
- if (file.notExists())
- throw new RuntimeException("File not created");
-
- // create file (existing file)
- file.newByteChannel(CREATE, WRITE).close();
-
- // create file where existing file is a sym link
- if (supportsLinks) {
- Path link = dir.resolve("link").createSymbolicLink(file);
- try {
- // file already exists
- link.newByteChannel(CREATE, WRITE).close();
-
- // file does not exist
- file.delete();
- link.newByteChannel(CREATE, WRITE).close();
- if (file.notExists())
- throw new RuntimeException("File not created");
-
- } finally {
- TestUtil.deleteUnchecked(link);
- }
- }
-
- } finally {
- TestUtil.deleteUnchecked(file);
- }
-
- // CREATE_NEW
- try {
- // create file
- file.newByteChannel(CREATE_NEW, WRITE).close();
- if (file.notExists())
- throw new RuntimeException("File not created");
-
- // create should fail
- try {
- SeekableByteChannel sbc =
- file.newByteChannel(CREATE_NEW, WRITE);
- sbc.close();
- throw new RuntimeException("FileAlreadyExistsException not thrown");
- } catch (FileAlreadyExistsException x) { }
-
- // create should fail
- if (supportsLinks) {
- Path link = dir.resolve("link");
- Path target = dir.resolve("thisDoesNotExist");
- link.createSymbolicLink(target);
- try {
-
- try {
- SeekableByteChannel sbc =
- file.newByteChannel(CREATE_NEW, WRITE);
- sbc.close();
- throw new RuntimeException("FileAlreadyExistsException not thrown");
- } catch (FileAlreadyExistsException x) { }
-
- } finally {
- TestUtil.deleteUnchecked(link);
- }
- }
-
-
- } finally {
- TestUtil.deleteUnchecked(file);
- }
-
- // CREATE_NEW + SPARSE
- try {
- SeekableByteChannel sbc = file
- .newByteChannel(CREATE_NEW, WRITE, SPARSE);
- try {
- final long hole = 2L * 1024L * 1024L * 1024L;
- sbc.position(hole);
- write(sbc, "hello");
- long size = sbc.size();
- if (size != (hole + 5))
- throw new RuntimeException("Unexpected size");
- } finally {
- sbc.close();
- }
- } finally {
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // test APPEND option
- static void appendTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
- try {
- // "hello there" should be written to file
- SeekableByteChannel sbc = file
- .newByteChannel(CREATE_NEW, WRITE, APPEND);
- try {
- write(sbc, "hello ");
- sbc.position(0L);
- write(sbc, "there");
- } finally {
- sbc.close();
- }
-
- // check file
- Scanner s = new Scanner(file);
- try {
- String line = s.nextLine();
- if (!line.equals("hello there"))
- throw new RuntimeException("Unexpected file contents");
- } finally {
- s.close();
- }
-
- // check that read is not allowed
- sbc = file.newByteChannel(APPEND);
- try {
- sbc.read(ByteBuffer.allocate(100));
- } catch (NonReadableChannelException x) {
- } finally {
- sbc.close();
- }
- } finally {
- // clean-up
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // test TRUNCATE_EXISTING option
- static void truncateExistingTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
- try {
- SeekableByteChannel sbc =
- file.newByteChannel(CREATE_NEW, WRITE);
- try {
- write(sbc, "Have a nice day!");
- } finally {
- sbc.close();
- }
-
- // re-open with truncate option
- // write short message and check
- sbc = file.newByteChannel(WRITE, TRUNCATE_EXISTING);
- try {
- write(sbc, "Hello there!");
- } finally {
- sbc.close();
- }
- Scanner s = new Scanner(file);
- try {
- String line = s.nextLine();
- if (!line.equals("Hello there!"))
- throw new RuntimeException("Unexpected file contents");
- } finally {
- s.close();
- }
-
- // re-open with create + truncate option
- // check file is of size 0L
- sbc = file.newByteChannel(WRITE, CREATE, TRUNCATE_EXISTING);
- try {
- long size = ((FileChannel)sbc).size();
- if (size != 0L)
- throw new RuntimeException("File not truncated");
- } finally {
- sbc.close();
- }
-
- } finally {
- // clean-up
- TestUtil.deleteUnchecked(file);
- }
-
- }
-
- // test NOFOLLOW_LINKS option
- static void noFollowLinksTests(Path dir) throws Exception {
- if (!supportsLinks)
- return;
- Path file = dir.resolve("foo").createFile();
- try {
- // ln -s foo link
- Path link = dir.resolve("link").createSymbolicLink(file);
-
- // open with NOFOLLOW_LINKS option
- try {
- link.newByteChannel(READ, LinkOption.NOFOLLOW_LINKS);
- throw new RuntimeException();
- } catch (IOException x) {
- } finally {
- TestUtil.deleteUnchecked(link);
- }
-
- } finally {
- // clean-up
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // test size/truncate/position methods
- static void sizeTruncatePositionTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
- try {
- SeekableByteChannel sbc = file
- .newByteChannel(CREATE_NEW, READ, WRITE);
- try {
- if (sbc.size() != 0L)
- throw new RuntimeException("Unexpected size");
-
- // check size
- write(sbc, "hello");
- if (sbc.size() != 5L)
- throw new RuntimeException("Unexpected size");
-
- // truncate (size and position should change)
- sbc.truncate(4L);
- if (sbc.size() != 4L)
- throw new RuntimeException("Unexpected size");
- if (sbc.position() != 4L)
- throw new RuntimeException("Unexpected position");
-
- // truncate (position should not change)
- sbc.position(2L).truncate(3L);
- if (sbc.size() != 3L)
- throw new RuntimeException("Unexpected size");
- if (sbc.position() != 2L)
- throw new RuntimeException("Unexpected position");
- } finally {
- sbc.close();
- }
- } finally {
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // Windows specific options for the use by applications that really want
- // to use legacy DOS sharing options
- static void dosSharingOptionTests(Path dir) throws Exception {
- Path file = dir.resolve("foo").createFile();
- try {
- SeekableByteChannel ch;
-
- // no sharing
- ch = file.newByteChannel(READ,
- NOSHARE_READ, NOSHARE_WRITE, NOSHARE_DELETE);
- try {
- try {
- file.newByteChannel(READ);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- try {
- file.newByteChannel(WRITE);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- try {
- file.delete();
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- } finally {
- ch.close();
- }
-
- // read allowed
- ch = file.newByteChannel(READ, NOSHARE_WRITE, NOSHARE_DELETE);
- try {
- file.newByteChannel(READ).close();
- try {
- file.newByteChannel(WRITE);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- try {
- file.delete();
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- } finally {
- ch.close();
- }
-
- // write allowed
- ch = file.newByteChannel(READ, NOSHARE_READ, NOSHARE_DELETE);
- try {
- try {
- file.newByteChannel(READ);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- file.newByteChannel(WRITE).close();
- try {
- file.delete();
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- } finally {
- ch.close();
- }
-
- // delete allowed
- ch = file.newByteChannel(READ, NOSHARE_READ, NOSHARE_WRITE);
- try {
- try {
- file.newByteChannel(READ);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- try {
- file.newByteChannel(WRITE);
- throw new RuntimeException("Sharing violation expected");
- } catch (IOException ignore) { }
- file.delete();
- } finally {
- ch.close();
- }
-
- } finally {
- TestUtil.deleteUnchecked(file);
- }
- }
-
- // invalid combinations of options
- static void badCombinations(Path dir) throws Exception {
- Path file = dir.resolve("bad");
-
- try {
- file.newByteChannel(READ, APPEND);
- throw new RuntimeException("IllegalArgumentException expected");
- } catch (IllegalArgumentException x) { }
-
- try {
- file.newByteChannel(WRITE, APPEND, TRUNCATE_EXISTING);
- throw new RuntimeException("IllegalArgumentException expected");
- } catch (IllegalArgumentException x) { }
- }
-
- // unsupported operations
- static void unsupportedOptions(Path dir) throws Exception {
- Path file = dir.resolve("bad");
-
- OpenOption badOption = new OpenOption() { };
- try {
- file.newByteChannel(badOption);
- throw new RuntimeException("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) { }
- try {
- file.newByteChannel(READ, WRITE, badOption);
- throw new RuntimeException("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) { }
- }
-
- // null handling
- static void nullTests(Path dir) throws Exception {
- Path file = dir.resolve("foo");
-
- try {
- file.newByteChannel((OpenOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- OpenOption[] opts = { READ, null };
- file.newByteChannel(opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- file.newByteChannel((Set<OpenOption>)null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- Set<OpenOption> opts = new HashSet<OpenOption>();
- opts.add(READ);
- opts.add(null);
- file.newByteChannel(opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
- file.newByteChannel(opts, (FileAttribute[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
-
- try {
- EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
- FileAttribute[] attrs = { null };
- file.newByteChannel(opts, attrs);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException x) { }
- }
-
- static void write(WritableByteChannel wbc, String msg) throws IOException {
- ByteBuffer buf = ByteBuffer.wrap(msg.getBytes());
- while (buf.hasRemaining())
- wbc.write(buf);
- }
-}
--- a/jdk/test/java/nio/file/Path/TemporaryFiles.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333
- * @summary Unit test for File.createTemporaryXXX (to be be moved to test/java/io/File)
- * @library ..
- */
-
-import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import java.nio.file.attribute.*;
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-
-public class TemporaryFiles {
-
- static void checkInTempDirectory(Path file) {
- Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
- if (!file.getParent().equals(tmpdir))
- throw new RuntimeException("Not in temporary directory");
- }
-
- static void checkFile(Path file) throws IOException {
- // check file is in temporary directory
- checkInTempDirectory(file);
-
- // check that file can be opened for reading and writing
- file.newByteChannel(READ).close();
- file.newByteChannel(WRITE).close();
- file.newByteChannel(READ,WRITE).close();
-
- // check file permissions are 0600 or more secure
- if (file.getFileStore().supportsFileAttributeView("posix")) {
- Set<PosixFilePermission> perms = Attributes
- .readPosixFileAttributes(file).permissions();
- perms.remove(PosixFilePermission.OWNER_READ);
- perms.remove(PosixFilePermission.OWNER_WRITE);
- if (!perms.isEmpty())
- throw new RuntimeException("Temporary file is not secure");
- }
- }
-
- static void checkDirectory(Path dir) throws IOException {
- // check directory is in temporary directory
- checkInTempDirectory(dir);
-
- // check directory is empty
- DirectoryStream<Path> stream = dir.newDirectoryStream();
- try {
- if (stream.iterator().hasNext())
- throw new RuntimeException("Tempory directory not empty");
- } finally {
- stream.close();
- }
-
- // check file permissions are 0700 or more secure
- if (dir.getFileStore().supportsFileAttributeView("posix")) {
- Set<PosixFilePermission> perms = Attributes
- .readPosixFileAttributes(dir).permissions();
- perms.remove(PosixFilePermission.OWNER_READ);
- perms.remove(PosixFilePermission.OWNER_WRITE);
- perms.remove(PosixFilePermission.OWNER_EXECUTE);
- if (!perms.isEmpty())
- throw new RuntimeException("Temporary directory is not secure");
- }
- }
-
- public static void main(String[] args) throws IOException {
- Path file = File.createTemporaryFile("blah", null).toPath();
- try {
- checkFile(file);
- } finally {
- TestUtil.deleteUnchecked(file);
- }
- }
-}
--- a/jdk/test/java/nio/file/Path/UriImportExport.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/Path/UriImportExport.java Tue Feb 08 14:25:33 2011 -0800
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887
+ * @bug 4313887 7003155
* @summary Unit test for java.nio.file.Path
*/
@@ -36,42 +36,105 @@
static final PrintStream log = System.out;
static int failures = 0;
- static void test(String fn, String expected) {
+ /**
+ * Test Path -> URI -> Path
+ */
+ static void testPath(String s) {
+ Path path = Paths.get(s);
+ log.println(path);
+ URI uri = path.toUri();
+ log.println(" --> " + uri);
+ Path result = Paths.get(uri);
+ log.println(" --> " + result);
+ if (!result.equals(path.toAbsolutePath())) {
+ log.println("FAIL: Expected " + path + ", got " + result);
+ failures++;
+ }
log.println();
- Path p = Paths.get(fn);
- log.println(p);
- URI u = p.toUri();
- log.println(" --> " + u);
- if (expected != null && !(u.toString().equals(expected))) {
- log.println("FAIL: Expected " + expected);
- failures++;
- return;
- }
- Path q = Paths.get(u);
- log.println(" --> " + q);
- if (!p.toAbsolutePath().equals(q)) {
- log.println("FAIL: Expected " + p + ", got " + q);
+ }
+
+ /**
+ * Test Path -> (expected) URI -> Path
+ */
+ static void testPath(String s, String expectedUri) {
+ Path path = Paths.get(s);
+ log.println(path);
+ URI uri = path.toUri();
+ log.println(" --> " + uri);
+ if (!uri.toString().equals(expectedUri)) {
+ log.println("FAILED: Expected " + expectedUri + ", got " + uri);
failures++;
return;
}
+ Path result = Paths.get(uri);
+ log.println(" --> " + result);
+ if (!result.equals(path.toAbsolutePath())) {
+ log.println("FAIL: Expected " + path + ", got " + result);
+ failures++;
+ }
+ log.println();
}
- static void test(String fn) {
- test(fn, null);
+ /**
+ * Test URI -> Path -> URI
+ */
+ static void testUri(String s) throws Exception {
+ URI uri = URI.create(s);
+ log.println(uri);
+ Path path = Paths.get(uri);
+ log.println(" --> " + path);
+ URI result = path.toUri();
+ log.println(" --> " + result);
+ if (!result.equals(uri)) {
+ log.println("FAIL: Expected " + uri + ", got " + result);
+ failures++;
+ }
+ log.println();
+ }
+
+ /**
+ * Test URI -> Path fails with IllegalArgumentException
+ */
+ static void testBadUri(String s) throws Exception {
+ URI uri = URI.create(s);
+ log.println(uri);
+ try {
+ Path path = Paths.get(uri);
+ log.format(" --> %s FAIL: Expected IllegalArgumentException\n", path);
+ failures++;
+ } catch (IllegalArgumentException expected) {
+ log.println(" --> IllegalArgumentException (expected)");
+ }
+ log.println();
}
public static void main(String[] args) throws Exception {
- test("foo");
- test("/foo");
- test("/foo bar");
+ testBadUri("file:foo");
+ testBadUri("file:/foo?q");
+ testBadUri("file:/foo#f");
String osname = System.getProperty("os.name");
if (osname.startsWith("Windows")) {
- test("C:\\foo");
- test("C:foo");
- test("\\\\rialto.dublin.com\\share\\");
- test("\\\\fe80--203-baff-fe5a-749ds1.ipv6-literal.net\\share\\missing",
+ testPath("C:\\doesnotexist");
+ testPath("C:doesnotexist");
+ testPath("\\\\server.nowhere.oracle.com\\share\\");
+ testPath("\\\\fe80--203-baff-fe5a-749ds1.ipv6-literal.net\\share\\missing",
"file://[fe80::203:baff:fe5a:749d%1]/share/missing");
+ } else {
+ testPath("doesnotexist");
+ testPath("/doesnotexist");
+ testPath("/does not exist");
+ testUri("file:///");
+ testUri("file:///foo/bar/doesnotexist");
+ testUri("file:/foo/bar/doesnotexist");
+
+ // file:///foo/bar/\u0440\u0443\u0441\u0441\u043A\u0438\u0439 (Russian)
+ testUri("file:///foo/bar/%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9");
+
+ // invalid
+ testBadUri("file:foo");
+ testBadUri("file://server/foo");
+ testBadUri("file:///foo%00");
}
if (failures > 0)
--- a/jdk/test/java/nio/file/Path/delete_on_close.sh Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 4313887
-# @summary Unit test for DELETE_ON_CLOSE open option
-# @library ..
-# @build DeleteOnClose
-# @run shell delete_on_close.sh
-
-# if TESTJAVA isn't set then we assume an interactive run.
-
-if [ -z "$TESTJAVA" ]; then
- TESTSRC=.
- TESTCLASSES=.
- JAVA=java
-else
- JAVA="${TESTJAVA}/bin/java"
-fi
-
-OS=`uname -s`
-case "$OS" in
- Windows_* | CYGWIN* )
- CLASSPATH="${TESTCLASSES};${TESTSRC}"
- ;;
- * )
- CLASSPATH=${TESTCLASSES}:${TESTSRC}
- ;;
-esac
-export CLASSPATH
-
-TMPFILE="$$.tmp"
-touch $TMPFILE
-$JAVA DeleteOnClose $TMPFILE 2>&1
-if [ $? != 0 ]; then exit 1; fi
-if [ -f $TMPFILE ]; then
- echo "$TMPFILE was not deleted"
- exit 1
-fi
-
-exit 0
--- a/jdk/test/java/nio/file/TestUtil.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/TestUtil.java Tue Feb 08 14:25:33 2011 -0800
@@ -31,17 +31,12 @@
}
static Path createTemporaryDirectory(String where) throws IOException {
- Path top = FileSystems.getDefault().getPath(where);
- Random r = new Random();
- Path dir;
- do {
- dir = top.resolve("name" + r.nextInt());
- } while (dir.exists());
- return dir.createDirectory();
+ Path dir = FileSystems.getDefault().getPath(where);
+ return Files.createTempDirectory(dir, "name");
}
static Path createTemporaryDirectory() throws IOException {
- return createTemporaryDirectory(System.getProperty("java.io.tmpdir"));
+ return Files.createTempDirectory("name");
}
static void removeAll(Path dir) throws IOException {
@@ -53,7 +48,7 @@
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
try {
- file.delete();
+ Files.delete(file);
} catch (IOException x) {
System.err.format("Unable to delete %s: %s\n", file, x);
}
@@ -62,7 +57,7 @@
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
try {
- dir.delete();
+ Files.delete(dir);
} catch (IOException x) {
System.err.format("Unable to delete %s: %s\n", dir, x);
}
@@ -78,7 +73,7 @@
static void deleteUnchecked(Path file) {
try {
- file.delete();
+ Files.delete(file);
} catch (IOException exc) {
System.err.format("Unable to delete %s: %s\n", file, exc);
}
@@ -99,7 +94,7 @@
String name = sb.toString();
do {
dir = dir.resolve(name).resolve(".");
- dir.createDirectory();
+ Files.createDirectory(dir);
} while (dir.toString().length() < 2048);
return dir;
}
@@ -111,8 +106,8 @@
Path link = dir.resolve("testlink");
Path target = dir.resolve("testtarget");
try {
- link.createSymbolicLink(target);
- link.delete();
+ Files.createSymbolicLink(link, target);
+ Files.delete(link);
return true;
} catch (UnsupportedOperationException x) {
return false;
--- a/jdk/test/java/nio/file/WatchService/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -41,8 +41,9 @@
public class Basic {
- static void createFile(Path file) throws IOException {
- file.newOutputStream().close();
+ static void checkKey(WatchKey key, Path dir) {
+ if (!key.isValid())
+ throw new RuntimeException("Key is not valid");
}
static void takeExpectedKey(WatchService watcher, WatchKey expected) {
@@ -80,19 +81,19 @@
FileSystem fs = FileSystems.getDefault();
Path name = fs.getPath("foo");
- WatchService watcher = fs.newWatchService();
- try {
+ try (WatchService watcher = fs.newWatchService()) {
// --- ENTRY_CREATE ---
// register for event
System.out.format("register %s for ENTRY_CREATE\n", dir);
WatchKey myKey = dir.register(watcher,
new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+ checkKey(myKey, dir);
// create file
Path file = dir.resolve("foo");
System.out.format("create %s\n", file);
- createFile(file);
+ Files.createFile(file);
// remove key and check that we got the ENTRY_CREATE event
takeExpectedKey(watcher, myKey);
@@ -112,9 +113,10 @@
new WatchEvent.Kind<?>[]{ ENTRY_DELETE });
if (deleteKey != myKey)
throw new RuntimeException("register did not return existing key");
+ checkKey(deleteKey, dir);
System.out.format("delete %s\n", file);
- file.delete();
+ Files.delete(file);
takeExpectedKey(watcher, myKey);
checkExpectedEvent(myKey.pollEvents(),
StandardWatchEventKind.ENTRY_DELETE, name);
@@ -126,7 +128,7 @@
System.out.println("OKAY");
// create the file for the next test
- createFile(file);
+ Files.createFile(file);
// --- ENTRY_MODIFY ---
@@ -135,13 +137,11 @@
new WatchEvent.Kind<?>[]{ ENTRY_MODIFY });
if (newKey != myKey)
throw new RuntimeException("register did not return existing key");
+ checkKey(newKey, dir);
System.out.format("update: %s\n", file);
- OutputStream out = file.newOutputStream(StandardOpenOption.APPEND);
- try {
+ try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.APPEND)) {
out.write("I am a small file".getBytes("UTF-8"));
- } finally {
- out.close();
}
// remove key and check that we got the ENTRY_MODIFY event
@@ -151,10 +151,7 @@
System.out.println("OKAY");
// done
- file.delete();
-
- } finally {
- watcher.close();
+ Files.delete(file);
}
}
@@ -164,12 +161,12 @@
static void testCancel(Path dir) throws IOException {
System.out.println("-- Cancel --");
- WatchService watcher = FileSystems.getDefault().newWatchService();
- try {
+ try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
System.out.format("register %s for events\n", dir);
WatchKey myKey = dir.register(watcher,
new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+ checkKey(myKey, dir);
System.out.println("cancel key");
myKey.cancel();
@@ -177,7 +174,7 @@
// create a file in the directory
Path file = dir.resolve("mars");
System.out.format("create: %s\n", file);
- createFile(file);
+ Files.createFile(file);
// poll for keys - there will be none
System.out.println("poll...");
@@ -190,12 +187,9 @@
}
// done
- file.delete();
+ Files.delete(file);
System.out.println("OKAY");
-
- } finally {
- watcher.close();
}
}
@@ -206,17 +200,16 @@
static void testAutomaticCancel(Path dir) throws IOException {
System.out.println("-- Automatic Cancel --");
- Path subdir = dir.resolve("bar").createDirectory();
+ Path subdir = Files.createDirectory(dir.resolve("bar"));
- WatchService watcher = FileSystems.getDefault().newWatchService();
- try {
+ try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
System.out.format("register %s for events\n", subdir);
WatchKey myKey = subdir.register(watcher,
new WatchEvent.Kind<?>[]{ ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY });
System.out.format("delete: %s\n", subdir);
- subdir.delete();
+ Files.delete(subdir);
takeExpectedKey(watcher, myKey);
System.out.println("reset key");
@@ -227,8 +220,6 @@
System.out.println("OKAY");
- } finally {
- watcher.close();
}
}
@@ -411,7 +402,7 @@
// create gus1
Path file1 = dir.resolve(name1);
System.out.format("create %s\n", file1);
- createFile(file1);
+ Files.createFile(file1);
// register with both watch services (different events)
System.out.println("register for different events");
@@ -426,7 +417,7 @@
// create gus2
Path file2 = dir.resolve(name2);
System.out.format("create %s\n", file2);
- createFile(file2);
+ Files.createFile(file2);
// check that key1 got ENTRY_CREATE
takeExpectedKey(watcher1, key1);
@@ -439,7 +430,7 @@
throw new RuntimeException("key not expected");
// delete gus1
- file1.delete();
+ Files.delete(file1);
// check that key2 got ENTRY_DELETE
takeExpectedKey(watcher2, key2);
@@ -462,7 +453,7 @@
// create file and key2 should be queued
System.out.format("create %s\n", file1);
- createFile(file1);
+ Files.createFile(file1);
takeExpectedKey(watcher2, key2);
checkExpectedEvent(key2.pollEvents(),
StandardWatchEventKind.ENTRY_CREATE, name1);
--- a/jdk/test/java/nio/file/WatchService/FileTreeModifier.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/FileTreeModifier.java Tue Feb 08 14:25:33 2011 -0800
@@ -62,10 +62,7 @@
WatchService watcher = fs.newWatchService();
// create directories
- Path subdir = top
- .resolve("a").createDirectory()
- .resolve("b").createDirectory()
- .resolve("c").createDirectory();
+ Path subdir = Files.createDirectories(top.resolve("a").resolve("b").resolve("c"));
// Test ENTRY_CREATE with FILE_TREE modifier.
@@ -73,7 +70,7 @@
new WatchEvent.Kind<?>[]{ ENTRY_CREATE }, FILE_TREE);
// create file in a/b/c and check we get create event
- Path file = subdir.resolve("foo").createFile();
+ Path file = Files.createFile(subdir.resolve("foo"));
checkExpectedEvent(watcher, ENTRY_CREATE, top.relativize(file));
key.reset();
@@ -85,7 +82,7 @@
throw new RuntimeException("Existing key not returned");
// delete a/b/c/foo and check we get delete event
- file.delete();
+ Files.delete(file);
checkExpectedEvent(watcher, ENTRY_DELETE, top.relativize(file));
key.reset();
@@ -96,19 +93,20 @@
throw new RuntimeException("Existing key not returned");
// create a/b/c/foo
- file.createFile();
+ Files.createFile(file);
// check that key is not queued
+ WatchKey nextKey;
try {
- k = watcher.poll(3, TimeUnit.SECONDS);
+ nextKey = watcher.poll(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException();
}
- if (k != null)
+ if (nextKey != null)
throw new RuntimeException("WatchKey not expected to be polled");
// create bar and check we get create event
- file = top.resolve("bar").createFile();
+ file = Files.createFile(top.resolve("bar"));
checkExpectedEvent(watcher, ENTRY_CREATE, top.relativize(file));
key.reset();
@@ -121,11 +119,8 @@
throw new RuntimeException("Existing key not returned");
// modify bar and check we get modify event
- OutputStream out = file.newOutputStream();
- try {
+ try (OutputStream out = Files.newOutputStream(file)) {
out.write("Double shot expresso please".getBytes("UTF-8"));
- } finally {
- out.close();
}
checkExpectedEvent(watcher, ENTRY_MODIFY, top.relativize(file));
key.reset();
--- a/jdk/test/java/nio/file/WatchService/LotsOfEvents.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/LotsOfEvents.java Tue Feb 08 14:25:33 2011 -0800
@@ -55,15 +55,14 @@
static void testOverflowEvent(Path dir)
throws IOException, InterruptedException
{
- WatchService watcher = dir.getFileSystem().newWatchService();
- try {
+ try (WatchService watcher = dir.getFileSystem().newWatchService()) {
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE);
// create a lot of files
int n = 1024;
Path[] files = new Path[n];
for (int i=0; i<n; i++) {
- files[i] = dir.resolve("foo" + i).createFile();
+ files[i] = Files.createFile(dir.resolve("foo" + i));
}
// give time for events to accumulate (improve chance of overflow)
@@ -74,7 +73,7 @@
// delete the files
for (int i=0; i<n; i++) {
- files[i].delete();
+ Files.delete(files[i]);
}
// give time for events to accumulate (improve chance of overflow)
@@ -82,8 +81,6 @@
// check that we see the delete events (or overflow)
drainAndCheckOverflowEvents(watcher, ENTRY_DELETE, n);
- } finally {
- watcher.close();
}
}
@@ -147,8 +144,7 @@
entries[i].create();
}
- WatchService watcher = dir.getFileSystem().newWatchService();
- try {
+ try (WatchService watcher = dir.getFileSystem().newWatchService()) {
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
// do several rounds of noise and test
@@ -169,7 +165,7 @@
// events for the same file.
WatchKey key = watcher.poll(15, TimeUnit.SECONDS);
while (key != null) {
- Set<Path> modified = new HashSet<Path>();
+ Set<Path> modified = new HashSet<>();
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
Path file = (kind == OVERFLOW) ? null : (Path)event.context();
@@ -188,9 +184,6 @@
key = watcher.poll(2, TimeUnit.SECONDS);
}
}
-
- } finally {
- watcher.close();
}
}
@@ -200,20 +193,17 @@
this.file = file;
}
void create() throws IOException {
- if (file.notExists())
- file.createFile();
+ if (Files.notExists(file))
+ Files.createFile(file);
}
void deleteIfExists() throws IOException {
- file.deleteIfExists();
+ Files.deleteIfExists(file);
}
void modifyIfExists() throws IOException {
- if (file.exists()) {
- OutputStream out = file.newOutputStream(StandardOpenOption.APPEND);
- try {
+ if (Files.exists(file)) {
+ try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.APPEND)) {
out.write("message".getBytes());
- } finally {
- out.close();
}
}
}
--- a/jdk/test/java/nio/file/WatchService/SensitivityModifier.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java Tue Feb 08 14:25:33 2011 -0800
@@ -51,6 +51,7 @@
}
}
+ @SuppressWarnings("unchecked")
static void doTest(Path top) throws Exception {
FileSystem fs = top.getFileSystem();
WatchService watcher = fs.newWatchService();
@@ -61,11 +62,11 @@
Path[] dirs = new Path[nDirs];
Path[] files = new Path[nFiles];
for (int i=0; i<nDirs; i++) {
- dirs[i] = top.resolve("dir" + i).createDirectory();
+ dirs[i] = Files.createDirectory(top.resolve("dir" + i));
}
for (int i=0; i<nFiles; i++) {
Path dir = dirs[rand.nextInt(nDirs)];
- files[i] = dir.resolve("file" + i).createFile();
+ files[i] = Files.createFile(dir.resolve("file" + i));
}
// register the directories (random sensitivity)
@@ -80,11 +81,8 @@
for (int i=0; i<10; i++) {
Path file = files[rand.nextInt(nFiles)];
System.out.println("Modify: " + file);
- OutputStream out = file.newOutputStream();
- try {
+ try (OutputStream out = Files.newOutputStream(file)) {
out.write(new byte[100]);
- } finally {
- out.close();
}
System.out.println("Waiting for event...");
WatchKey key = watcher.take();
@@ -92,7 +90,7 @@
if (event.kind() != ENTRY_MODIFY)
throw new RuntimeException("Unexpected event: " + event);
Path name = ((WatchEvent<Path>)event).context();
- if (!name.equals(file.getName()))
+ if (!name.equals(file.getFileName()))
throw new RuntimeException("Unexpected context: " + name);
System.out.println("Event OK");
--- a/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -47,11 +47,11 @@
// sanity check read and writing ACL
static void testReadWrite(Path dir) throws IOException {
Path file = dir.resolve("foo");
- if (file.notExists())
- file.createFile();
+ if (Files.notExists(file))
+ Files.createFile(file);
- AclFileAttributeView view = file
- .getFileAttributeView(AclFileAttributeView.class);
+ AclFileAttributeView view =
+ Files.getFileAttributeView(file, AclFileAttributeView.class);
// print existing ACL
List<AclEntry> acl = view.getAcl();
@@ -79,7 +79,7 @@
}
// if PosixFileAttributeView then repeat test with OWNER@
- if (file.getFileStore().supportsFileAttributeView("posix")) {
+ if (Files.getFileStore(file).supportsFileAttributeView("posix")) {
owner = file.getFileSystem().getUserPrincipalLookupService()
.lookupPrincipalByName("OWNER@");
entry = AclEntry.newBuilder(entry).setPrincipal(owner).build();
@@ -115,7 +115,8 @@
// sanity check create a file or directory with initial ACL
static void testCreateFile(Path dir) throws IOException {
- UserPrincipal user = Attributes.getOwner(dir);
+ UserPrincipal user = Files.getOwner(dir);
+ AclFileAttributeView view;
// create file with initial ACL
System.out.println("-- create file with initial ACL --");
@@ -127,8 +128,9 @@
.setPermissions(SYNCHRONIZE, READ_DATA, WRITE_DATA,
READ_ATTRIBUTES, READ_ACL, WRITE_ATTRIBUTES, DELETE)
.build());
- file.createFile(asAclAttribute(fileAcl));
- assertEquals(Attributes.getAcl(file), fileAcl);
+ Files.createFile(file, asAclAttribute(fileAcl));
+ view = Files.getFileAttributeView(file, AclFileAttributeView.class);
+ assertEquals(view.getAcl(), fileAcl);
// create directory with initial ACL
System.out.println("-- create directory with initial ACL --");
@@ -142,17 +144,18 @@
AclEntry.newBuilder(fileAcl.get(0))
.setFlags(FILE_INHERIT)
.build());
- subdir.createDirectory(asAclAttribute(dirAcl));
- assertEquals(Attributes.getAcl(subdir), dirAcl);
+ Files.createDirectory(subdir, asAclAttribute(dirAcl));
+ view = Files.getFileAttributeView(subdir, AclFileAttributeView.class);
+ assertEquals(view.getAcl(), dirAcl);
}
public static void main(String[] args) throws IOException {
// use work directory rather than system temporary directory to
// improve chances that ACLs are supported
- Path dir = Paths.get("./work" + new Random().nextInt())
- .createDirectory();
+ Path dir = Paths.get("./work" + new Random().nextInt());
+ Files.createDirectory(dir);
try {
- if (!dir.getFileStore().supportsFileAttributeView("acl")) {
+ if (!Files.getFileStore(dir).supportsFileAttributeView("acl")) {
System.out.println("ACLs not supported - test skipped!");
return;
}
--- a/jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -43,7 +43,7 @@
static void checkAttributesOfDirectory(Path dir)
throws IOException
{
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
+ BasicFileAttributes attrs = Files.readAttributes(dir, BasicFileAttributes.class);
check(attrs.isDirectory(), "is a directory");
check(!attrs.isRegularFile(), "is not a regular file");
check(!attrs.isSymbolicLink(), "is not a link");
@@ -58,7 +58,7 @@
static void checkAttributesOfFile(Path dir, Path file)
throws IOException
{
- BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
check(attrs.isRegularFile(), "is a regular file");
check(!attrs.isDirectory(), "is not a directory");
check(!attrs.isSymbolicLink(), "is not a link");
@@ -73,8 +73,8 @@
// copy last-modified time and file create time from directory to file,
// re-read attribtues, and check they match
BasicFileAttributeView view =
- file.getFileAttributeView(BasicFileAttributeView.class);
- BasicFileAttributes dirAttrs = Attributes.readBasicFileAttributes(dir);
+ Files.getFileAttributeView(file, BasicFileAttributeView.class);
+ BasicFileAttributes dirAttrs = Files.readAttributes(dir, BasicFileAttributes.class);
view.setTimes(dirAttrs.lastModifiedTime(), null, null);
if (dirAttrs.creationTime() != null) {
view.setTimes(null, null, dirAttrs.creationTime());
@@ -95,8 +95,8 @@
static void checkAttributesOfLink(Path link)
throws IOException
{
- BasicFileAttributes attrs = Attributes
- .readBasicFileAttributes(link, LinkOption.NOFOLLOW_LINKS);
+ BasicFileAttributes attrs =
+ Files.readAttributes(link, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
check(attrs.isSymbolicLink(), "is a link");
check(!attrs.isDirectory(), "is a directory");
check(!attrs.isRegularFile(), "is not a regular file");
@@ -108,11 +108,8 @@
{
// create file
Path file = dir.resolve("foo");
- OutputStream out = file.newOutputStream();
- try {
+ try (OutputStream out = Files.newOutputStream(file)) {
out.write("this is not an empty file".getBytes("UTF-8"));
- } finally {
- out.close();
}
// check attributes of directory and file
@@ -122,7 +119,7 @@
// symbolic links may be supported
Path link = dir.resolve("link");
try {
- link.createSymbolicLink( file );
+ Files.createSymbolicLink(link, file);
} catch (UnsupportedOperationException x) {
return;
} catch (IOException x) {
--- a/jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -74,27 +74,25 @@
static void readWriteTests(Path dir) throws IOException {
// create "foo" and test that we can read/write each FAT attribute
- Path file = dir.resolve("foo");
- file.createFile();
+ Path file = Files.createFile(dir.resolve("foo"));
try {
- testAttributes(file
- .getFileAttributeView(DosFileAttributeView.class));
+ testAttributes(Files.getFileAttributeView(file, DosFileAttributeView.class));
// Following tests use a symbolic link so skip if not supported
if (!TestUtil.supportsLinks(dir))
return;
- Path link = dir.resolve("link").createSymbolicLink(file);
+ Path link = dir.resolve("link");
+ Files.createSymbolicLink(link, file);
// test following links
- testAttributes(link
- .getFileAttributeView(DosFileAttributeView.class));
+ testAttributes(Files.getFileAttributeView(link, DosFileAttributeView.class));
// test not following links
try {
try {
- testAttributes(link
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
+ testAttributes(Files
+ .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS));
} catch (IOException x) {
// access to link attributes not supported
return;
@@ -103,32 +101,32 @@
// set all attributes on link
// run test on target of link (which leaves them all un-set)
// check that attributes of link remain all set
- setAll(link
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), true);
- testAttributes(link
- .getFileAttributeView(DosFileAttributeView.class));
- DosFileAttributes attrs = Attributes.readDosFileAttributes(link, NOFOLLOW_LINKS);
+ setAll(Files
+ .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS), true);
+ testAttributes(Files
+ .getFileAttributeView(link, DosFileAttributeView.class));
+ DosFileAttributes attrs =
+ Files.getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS)
+ .readAttributes();
check(attrs.isReadOnly());
check(attrs.isHidden());
check(attrs.isArchive());
check(attrs.isSystem());
- setAll(link
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), false);
+ setAll(Files
+ .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS), false);
// set all attributes on target
// run test on link (which leaves them all un-set)
// check that attributes of target remain all set
- setAll(link
- .getFileAttributeView(DosFileAttributeView.class), true);
- testAttributes(link
- .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
- attrs = Attributes.readDosFileAttributes(link);
+ setAll(Files.getFileAttributeView(link, DosFileAttributeView.class), true);
+ testAttributes(Files
+ .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS));
+ attrs = Files.getFileAttributeView(link, DosFileAttributeView.class).readAttributes();
check(attrs.isReadOnly());
check(attrs.isHidden());
check(attrs.isArchive());
check(attrs.isSystem());
- setAll(link
- .getFileAttributeView(DosFileAttributeView.class), false);
+ setAll(Files.getFileAttributeView(link, DosFileAttributeView.class), false);
} finally {
TestUtil.deleteUnchecked(link);
}
@@ -143,7 +141,7 @@
try {
// skip test if DOS file attributes not supported
- if (!dir.getFileStore().supportsFileAttributeView("dos")) {
+ if (!Files.getFileStore(dir).supportsFileAttributeView("dos")) {
System.out.println("DOS file attribute not supported.");
return;
}
--- a/jdk/test/java/nio/file/attribute/FileStoreAttributeView/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333
- * @summary Unit test for java.nio.file.attribute.FileStoreAttributeView
- * @library ../..
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Simple unit test for FileStoreAttributeView that checks that the disk space
- * attribtues are "close" to the equivalent values reported by java.io.File.
- */
-
-public class Basic {
-
- static final long K = 1024L;
- static final long G = 1024L * 1024L * 1024L;
-
- /**
- * Print out the disk space information for the given file system
- */
- static void printFileStore(FileStore fs) throws IOException {
- FileStoreSpaceAttributeView view =
- fs.getFileStoreAttributeView(FileStoreSpaceAttributeView.class);
- FileStoreSpaceAttributes attrs = view.readAttributes();
-
- long total = attrs.totalSpace() / K;
- long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / K;
- long avail = attrs.usableSpace() / K;
-
- String s = fs.toString();
- if (s.length() > 20) {
- System.out.println(s);
- s = "";
- }
- System.out.format("%-20s %12d %12d %12d\n", s, total, used, avail);
- }
-
- /**
- * Check that two values are within 1GB of each other
- */
- static void checkWithin1GB(long value1, long value2) {
- long diff = Math.abs(value1 - value2);
- if (diff > G)
- throw new RuntimeException("values differ by more than 1GB");
- }
-
- /**
- * Check disk space on the file system of the given file
- */
- static void checkSpace(Path file) throws IOException {
- System.out.println(" -- check space -- ");
- System.out.println(file);
-
- FileStore fs = file.getFileStore();
- System.out.format("Filesystem: %s\n", fs);
-
- // get values reported by java.io.File
- File f = new File(file.toString());
- long total = f.getTotalSpace();
- long free = f.getFreeSpace();
- long usable = f.getUsableSpace();
- System.out.println("java.io.File");
- System.out.format(" Total: %d\n", total);
- System.out.format(" Free: %d\n", free);
- System.out.format(" Usable: %d\n", usable);
-
- // get values reported by the FileStoreSpaceAttributeView
- FileStoreSpaceAttributes attrs = fs
- .getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
- .readAttributes();
- System.out.println("java.nio.file.FileStoreSpaceAttributeView:");
- System.out.format(" Total: %d\n", attrs.totalSpace());
- System.out.format(" Free: %d\n", attrs.unallocatedSpace());
- System.out.format(" Usable: %d\n", attrs.usableSpace());
-
- // check values are "close"
- checkWithin1GB(total, attrs.totalSpace());
- checkWithin1GB(free, attrs.unallocatedSpace());
- checkWithin1GB(usable, attrs.usableSpace());
-
- // get values by name
- checkWithin1GB(total, (Long)fs.getAttribute("space:totalSpace"));
- checkWithin1GB(free, (Long)fs.getAttribute("space:unallocatedSpace"));
- checkWithin1GB(usable, (Long)fs.getAttribute("space:usableSpace"));
- }
-
- public static void main(String[] args) throws IOException {
- // print out the disk space information for all file systems
- FileSystem fs = FileSystems.getDefault();
- for (FileStore store: fs.getFileStores()) {
- printFileStore(store);
- }
-
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- // check space using directory
- checkSpace(dir);
-
- // check space using file
- Path file = dir.resolve("foo").createFile();
- checkSpace(file);
-
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-}
--- a/jdk/test/java/nio/file/attribute/FileTime/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/FileTime/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -29,13 +29,16 @@
import java.nio.file.attribute.FileTime;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.*;
-import java.io.IOException;
+import java.util.Random;
public class Basic {
- public static void main(String[] args) throws IOException {
+ static final Random rand = new Random();
+
+ public static void main(String[] args) {
long now = System.currentTimeMillis();
long tomorrowInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) + 1;
+ long yesterdayInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) - 1;
// equals
eq(now, MILLISECONDS, now, MILLISECONDS);
@@ -50,6 +53,29 @@
cmp(now, MILLISECONDS, now+1234, MILLISECONDS, -1);
cmp(tomorrowInDays, DAYS, now, MILLISECONDS, 1);
cmp(now, MILLISECONDS, tomorrowInDays, DAYS, -1);
+ cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
+ cmp(now, MILLISECONDS, yesterdayInDays, DAYS, 1);
+ cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
+ cmp(Long.MAX_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, 1);
+ cmp(Long.MAX_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, 1);
+ cmp(Long.MIN_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, -1);
+ cmp(Long.MIN_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, -1);
+
+ // to(TimeUnit)
+ to(MILLISECONDS.convert(1, DAYS) - 1, MILLISECONDS);
+ to(MILLISECONDS.convert(1, DAYS) + 0, MILLISECONDS);
+ to(MILLISECONDS.convert(1, DAYS) + 1, MILLISECONDS);
+ to(1, MILLISECONDS);
+ to(0, MILLISECONDS);
+ to(1, MILLISECONDS);
+ to(MILLISECONDS.convert(-1, DAYS) - 1, MILLISECONDS);
+ to(MILLISECONDS.convert(-1, DAYS) + 0, MILLISECONDS);
+ to(MILLISECONDS.convert(-1, DAYS) + 1, MILLISECONDS);
+ for (TimeUnit unit: TimeUnit.values()) {
+ for (int i=0; i<100; i++) { to(rand.nextLong(), unit); }
+ to(Long.MIN_VALUE, unit);
+ to(Long.MAX_VALUE, unit);
+ }
// toString
ts(1L, DAYS, "1970-01-02T00:00:00Z");
@@ -59,6 +85,8 @@
ts(1L, MILLISECONDS, "1970-01-01T00:00:00.001Z");
ts(1L, MICROSECONDS, "1970-01-01T00:00:00.000001Z");
ts(1L, NANOSECONDS, "1970-01-01T00:00:00.000000001Z");
+ ts(999999999L, NANOSECONDS, "1970-01-01T00:00:00.999999999Z");
+ ts(9999999999L, NANOSECONDS, "1970-01-01T00:00:09.999999999Z");
ts(-1L, DAYS, "1969-12-31T00:00:00Z");
ts(-1L, HOURS, "1969-12-31T23:00:00Z");
@@ -67,6 +95,8 @@
ts(-1L, MILLISECONDS, "1969-12-31T23:59:59.999Z");
ts(-1L, MICROSECONDS, "1969-12-31T23:59:59.999999Z");
ts(-1L, NANOSECONDS, "1969-12-31T23:59:59.999999999Z");
+ ts(-999999999L, NANOSECONDS, "1969-12-31T23:59:59.000000001Z");
+ ts(-9999999999L, NANOSECONDS, "1969-12-31T23:59:50.000000001Z");
ts(-62135596799999L, MILLISECONDS, "0001-01-01T00:00:00.001Z");
ts(-62135596800000L, MILLISECONDS, "0001-01-01T00:00:00Z");
@@ -114,9 +144,24 @@
throw new RuntimeException("should not be equal");
}
- static void ts(long v, TimeUnit y, String expected) {
- String s = FileTime.from(v, y).toString();
- if (!s.equals(expected))
- throw new RuntimeException("unexpected format");
+ static void to(long v, TimeUnit unit) {
+ FileTime t = FileTime.from(v, unit);
+ for (TimeUnit u: TimeUnit.values()) {
+ long result = t.to(u);
+ long expected = u.convert(v, unit);
+ if (result != expected) {
+ throw new RuntimeException("unexpected result");
+ }
+ }
+ }
+
+ static void ts(long v, TimeUnit unit, String expected) {
+ String result = FileTime.from(v, unit).toString();
+ if (!result.equals(expected)) {
+ System.err.format("FileTime.from(%d, %s).toString() failed\n", v, unit);
+ System.err.format("Expected: %s\n", expected);
+ System.err.format(" Got: %s\n", result);
+ throw new RuntimeException();
+ }
}
}
--- a/jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -49,9 +49,8 @@
Set<PosixFilePermission> perms = PosixFilePermissions.fromString(mode);
// change permissions and re-read them.
- Attributes.setPosixFilePermissions(file, perms);
- Set<PosixFilePermission> current = Attributes
- .readPosixFileAttributes(file).permissions();
+ Files.setPosixFilePermissions(file, perms);
+ Set<PosixFilePermission> current = Files.getPosixFilePermissions(file);
if (!current.equals(perms)) {
throw new RuntimeException("Actual permissions: " +
PosixFilePermissions.toString(current) + ", expected: " +
@@ -59,8 +58,8 @@
}
// repeat test using setAttribute/getAttribute
- file.setAttribute("posix:permissions", perms);
- current = (Set<PosixFilePermission>)file.getAttribute("posix:permissions");
+ Files.setAttribute(file, "posix:permissions", perms);
+ current = (Set<PosixFilePermission>)Files.getAttribute(file, "posix:permissions");
if (!current.equals(perms)) {
throw new RuntimeException("Actual permissions: " +
PosixFilePermissions.toString(current) + ", expected: " +
@@ -97,25 +96,25 @@
FileAttribute<Set<PosixFilePermission>> attr =
PosixFilePermissions.asFileAttribute(requested);
System.out.format("create file with mode: %s\n", mode);
- file.createFile(attr);
+ Files.createFile(file, attr);
try {
- checkSecure(requested, file
- .getFileAttributeView(PosixFileAttributeView.class)
- .readAttributes()
- .permissions());
+ checkSecure(requested,
+ Files.getFileAttributeView(file, PosixFileAttributeView.class)
+ .readAttributes()
+ .permissions());
} finally {
- file.delete();
+ Files.delete(file);
}
System.out.format("create directory with mode: %s\n", mode);
- file.createDirectory(attr);
+ Files.createDirectory(file, attr);
try {
- checkSecure(requested, file
- .getFileAttributeView(PosixFileAttributeView.class)
- .readAttributes()
- .permissions());
+ checkSecure(requested,
+ Files.getFileAttributeView(file, PosixFileAttributeView.class)
+ .readAttributes()
+ .permissions());
} finally {
- file.delete();
+ Files.delete(file);
}
}
@@ -130,11 +129,11 @@
// create file and test updating and reading its permissions
Path file = dir.resolve("foo");
System.out.format("create %s\n", file);
- file.createFile();
+ Files.createFile(file);
try {
// get initial permissions so that we can restore them later
- PosixFileAttributeView view = file
- .getFileAttributeView(PosixFileAttributeView.class);
+ PosixFileAttributeView view =
+ Files.getFileAttributeView(file, PosixFileAttributeView.class);
Set<PosixFilePermission> save = view.readAttributes()
.permissions();
@@ -165,7 +164,7 @@
view.setPermissions(save);
}
} finally {
- file.delete();
+ Files.delete(file);
}
// create link (to file that doesn't exist) and test reading of
@@ -173,15 +172,18 @@
if (TestUtil.supportsLinks(dir)) {
Path link = dir.resolve("link");
System.out.format("create link %s\n", link);
- link.createSymbolicLink(file);
+ Files.createSymbolicLink(link, file);
try {
- PosixFileAttributes attrs = Attributes
- .readPosixFileAttributes(link, NOFOLLOW_LINKS);
+ PosixFileAttributes attrs =
+ Files.getFileAttributeView(link,
+ PosixFileAttributeView.class,
+ NOFOLLOW_LINKS)
+ .readAttributes();
if (!attrs.isSymbolicLink()) {
throw new RuntimeException("not a link");
}
} finally {
- link.delete();
+ Files.delete(link);
}
}
@@ -235,12 +237,12 @@
Path file = dir.resolve("gus");
System.out.format("create %s\n", file);
- file.createFile();
+ Files.createFile(file);
try {
// read attributes of directory to get owner/group
- PosixFileAttributeView view = file
- .getFileAttributeView(PosixFileAttributeView.class);
+ PosixFileAttributeView view =
+ Files.getFileAttributeView(file, PosixFileAttributeView.class);
PosixFileAttributes attrs = view.readAttributes();
// set to existing owner/group
@@ -248,13 +250,13 @@
view.setGroup(attrs.group());
// repeat test using set/getAttribute
- UserPrincipal owner = (UserPrincipal)file.getAttribute("posix:owner");
- file.setAttribute("posix:owner", owner);
- UserPrincipal group = (UserPrincipal)file.getAttribute("posix:group");
- file.setAttribute("posix:group", group);
+ UserPrincipal owner = (UserPrincipal)Files.getAttribute(file, "posix:owner");
+ Files.setAttribute(file, "posix:owner", owner);
+ UserPrincipal group = (UserPrincipal)Files.getAttribute(file, "posix:group");
+ Files.setAttribute(file, "posix:group", group);
} finally {
- file.delete();
+ Files.delete(file);
}
System.out.println("OKAY");
@@ -272,7 +274,7 @@
.getUserPrincipalLookupService();
// read attributes of directory to get owner/group
- PosixFileAttributes attrs = Attributes.readPosixFileAttributes(dir);
+ PosixFileAttributes attrs = Files.readAttributes(dir, PosixFileAttributes.class);
// lookup owner and check it matches file's owner
System.out.format("lookup: %s\n", attrs.owner().getName());
@@ -322,8 +324,8 @@
{
System.out.println("-- Exceptions --");
- PosixFileAttributeView view = dir
- .getFileAttributeView(PosixFileAttributeView.class);
+ PosixFileAttributeView view =
+ Files.getFileAttributeView(dir,PosixFileAttributeView.class);
// NullPointerException
try {
@@ -355,7 +357,7 @@
} catch (NullPointerException x) {
}
try {
- Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
+ Set<PosixFilePermission> perms = new HashSet<>();
perms.add(null);
view.setPermissions(perms);
throw new RuntimeException("NullPointerException not thrown");
@@ -377,7 +379,7 @@
public static void main(String[] args) throws IOException {
Path dir = TestUtil.createTemporaryDirectory();
try {
- if (!dir.getFileStore().supportsFileAttributeView("posix")) {
+ if (!Files.getFileStore(dir).supportsFileAttributeView("posix")) {
System.out.println("PosixFileAttributeView not supported");
return;
}
--- a/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -79,8 +79,8 @@
}
static void test(Path file, LinkOption... options) throws IOException {
- final UserDefinedFileAttributeView view = file
- .getFileAttributeView(UserDefinedFileAttributeView.class, options);
+ final UserDefinedFileAttributeView view =
+ Files.getFileAttributeView(file, UserDefinedFileAttributeView.class, options);
ByteBuffer buf = rand.nextBoolean() ?
ByteBuffer.allocate(100) : ByteBuffer.allocateDirect(100);
@@ -131,24 +131,24 @@
// Test: dynamic access
String name = "user:" + ATTR_NAME;
byte[] valueAsBytes = ATTR_VALUE.getBytes();
- file.setAttribute(name, valueAsBytes);
- byte[] actualAsBytes = (byte[])file.getAttribute(name);
+ Files.setAttribute(file, name, valueAsBytes);
+ byte[] actualAsBytes = (byte[])Files.getAttribute(file, name);
if (!Arrays.equals(valueAsBytes, actualAsBytes))
throw new RuntimeException("Unexpected attribute value");
- Map<String,?> map = file.readAttributes(name);
+ Map<String,?> map = Files.readAttributes(file, name);
if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
throw new RuntimeException("Unexpected attribute value");
- map = file.readAttributes("user:*");
+ map = Files.readAttributes(file, "user:*");
if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
throw new RuntimeException("Unexpected attribute value");
- map = file.readAttributes("user:DoesNotExist");
+ map = Files.readAttributes(file, "user:DoesNotExist");
if (!map.isEmpty())
throw new RuntimeException("Map expected to be empty");
}
static void miscTests(final Path file) throws IOException {
- final UserDefinedFileAttributeView view = file
- .getFileAttributeView(UserDefinedFileAttributeView.class);
+ final UserDefinedFileAttributeView view =
+ Files.getFileAttributeView(file, UserDefinedFileAttributeView.class);
view.write(ATTR_NAME, ByteBuffer.wrap(ATTR_VALUE.getBytes()));
// NullPointerException
@@ -180,31 +180,31 @@
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.getAttribute(null);
+ Files.getAttribute(file, null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.getAttribute("user:" + ATTR_NAME, (LinkOption[])null);
+ Files.getAttribute(file, "user:" + ATTR_NAME, (LinkOption[])null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.setAttribute("user:" + ATTR_NAME, null);
+ Files.setAttribute(file, "user:" + ATTR_NAME, null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.setAttribute(null, new byte[0]);
+ Files.setAttribute(file, null, new byte[0]);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.setAttribute("user: " + ATTR_NAME, new byte[0], (LinkOption[])null);
+ Files.setAttribute(file, "user: " + ATTR_NAME, new byte[0], (LinkOption[])null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.readAttributes((String)null);
+ Files.readAttributes(file, (String)null);
}});
expectNullPointerException(new Task() {
public void run() throws IOException {
- file.readAttributes("*", (LinkOption[])null);
+ Files.readAttributes(file, "*", (LinkOption[])null);
}});
// Read-only buffer
@@ -229,46 +229,50 @@
// create temporary directory to run tests
Path dir = TestUtil.createTemporaryDirectory();
try {
- if (!dir.getFileStore().supportsFileAttributeView("user")) {
+ if (!Files.getFileStore(dir).supportsFileAttributeView("user")) {
System.out.println("UserDefinedFileAttributeView not supported - skip test");
return;
}
// test access to user defined attributes of regular file
- Path file = dir.resolve("foo.html").createFile();
+ Path file = dir.resolve("foo.html");
+ Files.createFile(file);
try {
test(file);
} finally {
- file.delete();
+ Files.delete(file);
}
- // test access to user define attributes of directory
- file = dir.resolve("foo").createDirectory();
+ // test access to user defined attributes of directory
+ Path subdir = dir.resolve("foo");
+ Files.createDirectory(subdir);
try {
- test(file);
+ test(subdir);
} finally {
- file.delete();
+ Files.delete(subdir);
}
// test access to user defined attributes of sym link
if (TestUtil.supportsLinks(dir)) {
Path target = dir.resolve("doesnotexist");
- Path link = dir.resolve("link").createSymbolicLink(target);
+ Path link = dir.resolve("link");
+ Files.createSymbolicLink(link, target);
try {
test(link, NOFOLLOW_LINKS);
} catch (IOException x) {
// access to attributes of sym link may not be supported
} finally {
- link.delete();
+ Files.delete(link);
}
}
// misc. tests
try {
- file = dir.resolve("foo.txt").createFile();
+ file = dir.resolve("foo.txt");
+ Files.createFile(file);
miscTests(dir);
} finally {
- file.delete();
+ Files.delete(file);
}
} finally {
--- a/jdk/test/java/nio/file/spi/SetDefaultProvider.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/spi/SetDefaultProvider.java Tue Feb 08 14:25:33 2011 -0800
@@ -22,14 +22,13 @@
*/
/* @test
- * @bug 4313887
+ * @bug 4313887 7006126
* @summary Unit test for java.nio.file.spi.FileSystemProvider
* @build TestProvider SetDefaultProvider
* @run main/othervm -Djava.nio.file.spi.DefaultFileSystemProvider=TestProvider SetDefaultProvider
*/
import java.nio.file.*;
-import java.nio.file.spi.*;
public class SetDefaultProvider {
public static void main(String[] args) throws Exception {
--- a/jdk/test/java/nio/file/spi/TestProvider.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/nio/file/spi/TestProvider.java Tue Feb 08 14:25:33 2011 -0800
@@ -24,6 +24,7 @@
import java.nio.file.spi.FileSystemProvider;
import java.nio.file.*;
import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
import java.net.URI;
import java.util.*;
import java.io.IOException;
@@ -34,7 +35,6 @@
public TestProvider(FileSystemProvider defaultProvider) {
theFileSystem = new TestFileSystem(this);
-
}
@Override
@@ -57,6 +57,124 @@
throw new RuntimeException("not implemented");
}
+ @Override
+ public void setAttribute(Path file, String attribute, Object value,
+ LinkOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public Map<String,Object> readAttributes(Path file, String attributes,
+ LinkOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public <A extends BasicFileAttributes> A readAttributes(Path file,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public <V extends FileAttributeView> V getFileAttributeView(Path file,
+ Class<V> type,
+ LinkOption... options)
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+
+ @Override
+ public void delete(Path file) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void createLink(Path link, Path existing) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public Path readSymbolicLink(Path link) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+
+ @Override
+ public void copy(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void move(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Path dir,
+ DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path file,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
+
+ @Override
+ public boolean isHidden(Path file) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public FileStore getFileStore(Path file) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public boolean isSameFile(Path file, Path other) throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public void checkAccess(Path file, AccessMode... modes)
+ throws IOException
+ {
+ throw new RuntimeException("not implemented");
+ }
+
static class TestFileSystem extends FileSystem {
private final TestProvider provider;
@@ -105,7 +223,7 @@
}
@Override
- public Path getPath(String path) {
+ public Path getPath(String first, String... more) {
throw new RuntimeException("not implemented");
}
@@ -124,5 +242,4 @@
throw new RuntimeException("not implemented");
}
}
-
}
--- a/jdk/test/java/util/Arrays/Sorting.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/util/Arrays/Sorting.java Tue Feb 08 14:25:33 2011 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6880672 6896573 6899694 6976036
+ * @bug 6880672 6896573 6899694 6976036 7013585
* @summary Exercise Arrays.sort
* @build Sorting
* @run main Sorting -shortrun
@@ -546,13 +546,19 @@
private static void prepareSubArray(int[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- a[i] = 0xBABA;
+ a[i] = 0xDEDA;
}
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = -i + m;
+ int middle = (fromIndex + toIndex) >>> 1;
+ int k = 0;
+
+ for (int i = fromIndex; i < middle; i++) {
+ a[i] = k++;
+ }
+ for (int i = middle; i < toIndex; i++) {
+ a[i] = k--;
}
for (int i = toIndex; i < a.length; i++) {
- a[i] = 0xDEDA;
+ a[i] = 0xBABA;
}
}
@@ -1518,9 +1524,9 @@
private static void checkSubArray(Integer[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i].intValue() != 0xBABA) {
+ if (a[i].intValue() != 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1531,18 +1537,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i].intValue() != 0xDEDA) {
+ if (a[i].intValue() != 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(int[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != 0xBABA) {
+ if (a[i] != 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1553,18 +1559,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != 0xDEDA) {
+ if (a[i] != 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(byte[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (byte) 0xBABA) {
+ if (a[i] != (byte) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1575,18 +1581,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (byte) 0xDEDA) {
+ if (a[i] != (byte) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(long[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (long) 0xBABA) {
+ if (a[i] != (long) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1597,18 +1603,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (long) 0xDEDA) {
+ if (a[i] != (long) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(char[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (char) 0xBABA) {
+ if (a[i] != (char) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1619,18 +1625,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (char) 0xDEDA) {
+ if (a[i] != (char) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(short[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (short) 0xBABA) {
+ if (a[i] != (short) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1641,18 +1647,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (short) 0xDEDA) {
+ if (a[i] != (short) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(float[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (float) 0xBABA) {
+ if (a[i] != (float) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1663,18 +1669,18 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (float) 0xDEDA) {
+ if (a[i] != (float) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
private static void checkSubArray(double[] a, int fromIndex, int toIndex, int m) {
for (int i = 0; i < fromIndex; i++) {
- if (a[i] != (double) 0xBABA) {
+ if (a[i] != (double) 0xDEDA) {
failed("Range sort changes left element on position " + i +
- ": " + a[i] + ", must be " + 0xBABA);
+ ": " + a[i] + ", must be " + 0xDEDA);
}
}
@@ -1685,9 +1691,9 @@
}
for (int i = toIndex; i < a.length; i++) {
- if (a[i] != (double) 0xDEDA) {
+ if (a[i] != (double) 0xBABA) {
failed("Range sort changes right element on position " + i +
- ": " + a[i] + ", must be " + 0xDEDA);
+ ": " + a[i] + ", must be " + 0xBABA);
}
}
}
--- a/jdk/test/java/util/Objects/BasicObjectsTest.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/util/Objects/BasicObjectsTest.java Tue Feb 08 14:25:33 2011 -0800
@@ -164,7 +164,7 @@
// Test 1-arg variant
try {
- s = Objects.nonNull("pants");
+ s = Objects.requireNonNull("pants");
if (s != "pants") {
System.err.printf("1-arg non-null failed to return its arg");
errors++;
@@ -175,7 +175,7 @@
}
try {
- s = Objects.nonNull(null);
+ s = Objects.requireNonNull(null);
System.err.printf("1-arg nonNull failed to throw NPE");
errors++;
} catch (NullPointerException e) {
@@ -184,7 +184,7 @@
// Test 2-arg variant
try {
- s = Objects.nonNull("pants", "trousers");
+ s = Objects.requireNonNull("pants", "trousers");
if (s != "pants") {
System.err.printf("2-arg nonNull failed to return its arg");
errors++;
@@ -195,7 +195,7 @@
}
try {
- s = Objects.nonNull(null, "pantaloons");
+ s = Objects.requireNonNull(null, "pantaloons");
System.err.printf("2-arg nonNull failed to throw NPE");
errors++;
} catch (NullPointerException e) {
--- a/jdk/test/java/util/regex/RegExTest.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/java/util/regex/RegExTest.java Tue Feb 08 14:25:33 2011 -0800
@@ -32,7 +32,7 @@
* 4872664 4803179 4892980 4900747 4945394 4938995 4979006 4994840 4997476
* 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
* 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
- * 6350801 6676425 6878475 6919132 6931676 6948903
+ * 6350801 6676425 6878475 6919132 6931676 6948903 7014645
*/
import java.util.regex.*;
@@ -136,6 +136,7 @@
namedGroupCaptureTest();
nonBmpClassComplementTest();
unicodePropertiesTest();
+ unicodeHexNotationTest();
if (failure)
throw new RuntimeException("Failure in the RE handling.");
else
@@ -161,18 +162,19 @@
private static void check(Matcher m, String result, boolean expected) {
m.find();
- if (m.group().equals(result))
- failCount += (expected) ? 0 : 1;
- else
- failCount += (expected) ? 1 : 0;
+ if (m.group().equals(result) != expected)
+ failCount++;
}
private static void check(Pattern p, String s, boolean expected) {
- Matcher matcher = p.matcher(s);
- if (matcher.find())
- failCount += (expected) ? 0 : 1;
- else
- failCount += (expected) ? 1 : 0;
+ if (p.matcher(s).find() != expected)
+ failCount++;
+ }
+
+ private static void check(String p, String s, boolean expected) {
+ Matcher matcher = Pattern.compile(p).matcher(s);
+ if (matcher.find() != expected)
+ failCount++;
}
private static void check(String p, char c, boolean expected) {
@@ -3614,4 +3616,45 @@
}
report("unicodeProperties");
}
+
+ private static void unicodeHexNotationTest() throws Exception {
+
+ // negative
+ checkExpectedFail("\\x{-23}");
+ checkExpectedFail("\\x{110000}");
+ checkExpectedFail("\\x{}");
+ checkExpectedFail("\\x{AB[ef]");
+
+ // codepoint
+ check("^\\x{1033c}$", "\uD800\uDF3C", true);
+ check("^\\xF0\\x90\\x8C\\xBC$", "\uD800\uDF3C", false);
+ check("^\\x{D800}\\x{DF3c}+$", "\uD800\uDF3C", false);
+ check("^\\xF0\\x90\\x8C\\xBC$", "\uD800\uDF3C", false);
+
+ // in class
+ check("^[\\x{D800}\\x{DF3c}]+$", "\uD800\uDF3C", false);
+ check("^[\\xF0\\x90\\x8C\\xBC]+$", "\uD800\uDF3C", false);
+ check("^[\\x{D800}\\x{DF3C}]+$", "\uD800\uDF3C", false);
+ check("^[\\x{DF3C}\\x{D800}]+$", "\uD800\uDF3C", false);
+ check("^[\\x{D800}\\x{DF3C}]+$", "\uDF3C\uD800", true);
+ check("^[\\x{DF3C}\\x{D800}]+$", "\uDF3C\uD800", true);
+
+ for (int cp = 0; cp <= 0x10FFFF; cp++) {
+ String s = "A" + new String(Character.toChars(cp)) + "B";
+ String hexUTF16 = (cp <= 0xFFFF)? String.format("\\u%04x", cp)
+ : String.format("\\u%04x\\u%04x",
+ (int) Character.toChars(cp)[0],
+ (int) Character.toChars(cp)[1]);
+ String hexCodePoint = "\\x{" + Integer.toHexString(cp) + "}";
+ if (!Pattern.matches("A" + hexUTF16 + "B", s))
+ failCount++;
+ if (!Pattern.matches("A[" + hexUTF16 + "]B", s))
+ failCount++;
+ if (!Pattern.matches("A" + hexCodePoint + "B", s))
+ failCount++;
+ if (!Pattern.matches("A[" + hexCodePoint + "]B", s))
+ failCount++;
+ }
+ report("unicodeHexNotation");
+ }
}
--- a/jdk/test/javax/script/CauseExceptionTest.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/javax/script/CauseExceptionTest.java Tue Feb 08 14:25:33 2011 -0800
@@ -34,6 +34,10 @@
public static void main(String[] args) throws ScriptException, NoSuchMethodException {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("js");
+ if (engine == null) {
+ System.out.println("Warning: No js engine found; test vacuously passes.");
+ return;
+ }
engine.eval("function hello_world() { println('hello world'); throw 'out of here'; } ");
Invocable invocable = (Invocable) engine;
try {
--- a/jdk/test/javax/script/StringWriterPrintTest.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/javax/script/StringWriterPrintTest.java Tue Feb 08 14:25:33 2011 -0800
@@ -34,6 +34,10 @@
public static void main(String[] args) throws ScriptException {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("js");
+ if (engine == null) {
+ System.out.println("Warning: No js engine found; test vacuously passes.");
+ return;
+ }
StringWriter sw = new StringWriter();
engine.eval("print(\"hello world 1\\n\")");
engine.getContext().setWriter(sw);
--- a/jdk/test/javax/script/UnescapedBracketRegExTest.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/javax/script/UnescapedBracketRegExTest.java Tue Feb 08 14:25:33 2011 -0800
@@ -34,6 +34,10 @@
public static void main(String[] args) throws ScriptException {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("js");
+ if (engine == null) {
+ System.out.println("Warning: No js engine found; test vacuously passes.");
+ return;
+ }
// the following throws exception
engine.eval("var x = /[a-zA-Z+/=]/;");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/Basic.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6887710
+ * @summary Verify the impact of sun.misc.JarIndex.metaInfFilenames on Service loaders
+ * @run main/othervm Basic
+ */
+
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import com.sun.net.httpserver.Headers;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+/**
+ * Verifies the impact of sun.misc.JarIndex.metaInfFilenames on service loaders
+ * (sun.misc.Service & java.util.ServiceLoader), as well as finding resources
+ * through Class.getResouce.
+ *
+ * 1) Compile the test sources:
+ * jarA:
+ * META-INF/services/my.happy.land
+ * com/message/spi/MessageService.java
+ * a/A.java
+ * jarB:
+ * META-INF/JAVA2.DS
+ * META-INF/services/no.name.service
+ * b/B.java
+ * jarC:
+ * META-INF/fonts.mf
+ * META-INF/fonts/Company-corporate.ttf
+ * META-INF/fonts/kidpr.ttf
+ * META-INF/services/com.message.spi.MessageService
+ * my/impl/StandardMessageService.java
+ *
+ * 2) Build three jar files a.jar, b.jar, c.jar
+ *
+ * 3) Create an index in a.jar (jar -i a.jar b.jar c.jar)
+ * with sun.misc.JarIndex.metaInfFilenames=true
+ *
+ * 4) Start a HTTP server serving out the three jars.
+ *
+ * The test then tries to locate services/resources within the jars using
+ * URLClassLoader. Each request to the HTTP server is recorded to ensure
+ * only the correct amount of requests are being made.
+ *
+ * Note: Needs jdk/lib/tools.jar in the classpath to compile and run.
+ */
+
+public class Basic {
+ static final String slash = File.separator;
+ static final String[] testSources = {
+ "jarA" + slash + "a" + slash + "A.java",
+ "jarA" + slash + "com" + slash + "message" + slash + "spi" + slash + "MessageService.java",
+ "jarB" + slash + "b" + slash + "B.java",
+ "jarC" + slash + "my" + slash + "impl" + slash + "StandardMessageService.java"};
+
+ static final String testSrc = System.getProperty("test.src");
+ static final String testSrcDir = testSrc != null ? testSrc : ".";
+ static final String testClasses = System.getProperty("test.classes");
+ static final String testClassesDir = testClasses != null ? testClasses : ".";
+
+ static JarHttpServer httpServer;
+
+ public static void main(String[] args) throws Exception {
+
+ // Set global url cache to false so that we can track every jar request.
+ (new URL("http://localhost/")).openConnection().setDefaultUseCaches(false);
+
+ buildTest();
+
+ try {
+ httpServer = new JarHttpServer(testClassesDir);
+ httpServer.start();
+
+ doTest(httpServer.getAddress());
+
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } finally {
+ if (httpServer != null) { httpServer.stop(2); }
+ }
+ }
+
+ static void buildTest() {
+ /* compile the source that will be used to generate the jars */
+ for (int i=0; i<testSources.length; i++)
+ testSources[i] = testSrcDir + slash + testSources[i];
+
+ compile("-d" , testClassesDir,
+ "-sourcepath", testSrcDir,
+ testSources[0], testSources[1], testSources[2], testSources[3]);
+
+ /* build the 3 jar files */
+ jar("-cf", testClassesDir + slash + "a.jar",
+ "-C", testClassesDir, "a",
+ "-C", testClassesDir, "com",
+ "-C", testSrcDir + slash + "jarA", "META-INF");
+ jar("-cf", testClassesDir + slash + "b.jar",
+ "-C", testClassesDir, "b",
+ "-C", testSrcDir + slash + "jarB", "META-INF");
+ jar("-cf", testClassesDir + slash + "c.jar",
+ "-C", testClassesDir, "my",
+ "-C", testSrcDir + slash + "jarC", "META-INF");
+
+ /* Create an index in a.jar for b.jar and c.jar */
+ createIndex(testClassesDir);
+ }
+
+ /* run jar <args> */
+ static void jar(String... args) {
+ debug("Running: jar " + Arrays.toString(args));
+ sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");
+ if (!jar.run(args)) {
+ throw new RuntimeException("jar failed: args=" + Arrays.toString(args));
+ }
+ }
+
+ /* run javac <args> */
+ static void compile(String... args) {
+ debug("Running: javac " + Arrays.toString(args));
+ com.sun.tools.javac.main.Main compiler = new com.sun.tools.javac.main.Main("javac");
+ if (compiler.compile(args) != 0) {
+ throw new RuntimeException("javac failed: args=" + Arrays.toString(args));
+ }
+ }
+
+ static String jar;
+ static {
+ String javaHome = System.getProperty("java.home");
+ if (javaHome.endsWith("jre")) {
+ int index = javaHome.lastIndexOf(slash);
+ if (index != -1)
+ javaHome = javaHome.substring(0, index);
+ }
+
+ jar = javaHome + slash+ "bin" + slash + "jar";
+ }
+
+ /* create the index */
+ static void createIndex(String workingDir) {
+ // ProcessBuilder is used so that the current directory can be set
+ // to the directory that directly contains the jars.
+ debug("Running jar to create the index");
+ ProcessBuilder pb = new ProcessBuilder(
+ jar, "-J-Dsun.misc.JarIndex.metaInfFilenames=true", "-i", "a.jar", "b.jar", "c.jar");
+ pb.directory(new File(workingDir));
+ //pd.inheritIO();
+ try {
+ Process p = pb.start();
+ if(p.waitFor() != 0)
+ throw new RuntimeException("jar indexing failed");
+
+ if(debug && p != null) {
+ String line = null;
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(p.getInputStream()));
+ while((line = reader.readLine()) != null)
+ debug(line);
+ reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+ while((line = reader.readLine()) != null)
+ debug(line);
+ }
+ } catch(InterruptedException ie) { throw new RuntimeException(ie);
+ } catch(IOException e) { throw new RuntimeException(e); }
+ }
+
+ static final boolean debug = true;
+
+ static void debug(Object message) { if (debug) System.out.println(message); }
+
+ /* service define in c.jar */
+ static final String messageService = "com.message.spi.MessageService";
+
+ /* a service that is not defined in any of the jars */
+ static final String unknownService = "java.lang.Object";
+
+ static void doTest(InetSocketAddress serverAddress) throws IOException {
+ URL baseURL = new URL("http://localhost:" + serverAddress.getPort() + "/");
+
+ int failed = 0;
+
+ // Tests using sun.misc.Service
+ if (!sunMiscServiceTest(baseURL, messageService, true, false, true)) {
+ System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
+ failed++;
+ }
+ if (!sunMiscServiceTest(baseURL, unknownService, false, false, false)) {
+ System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
+ failed++;
+ }
+
+ // Tests using java.util.SerivceLoader
+ if (!javaUtilServiceLoaderTest(baseURL, messageService, true, false, true)) {
+ System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
+ failed++;
+ }
+ if (!javaUtilServiceLoaderTest(baseURL, unknownService, false, false, false)) {
+ System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
+ failed++;
+ }
+
+ // Tests using java.lang.Class (similar to the FontManager in javafx)
+ if (!klassLoader(baseURL, "/META-INF/fonts.mf", true, false, true)) {
+ System.out.println("Test: klassLoader looking for /META-INF/fonts.mf failed");
+ failed++;
+ }
+ if (!klassLoader(baseURL, "/META-INF/unknown.mf", false, false, false)) {
+ System.out.println("Test: klassLoader looking for /META-INF/unknown.mf failed");
+ failed++;
+ }
+
+ if (failed > 0)
+ throw new RuntimeException("Failed: " + failed + " tests");
+ }
+
+ static boolean sunMiscServiceTest(URL baseURL,
+ String serviceClass,
+ boolean expectToFind,
+ boolean expectbDotJar,
+ boolean expectcDotJar) throws IOException {
+ debug("----------------------------------");
+ debug("Running test with sun.misc.Service looking for " + serviceClass);
+ URLClassLoader loader = getLoader(baseURL);
+ httpServer.reset();
+
+ Class messageServiceClass = null;
+ try {
+ messageServiceClass = loader.loadClass(serviceClass);
+ } catch (ClassNotFoundException cnfe) {
+ System.err.println(cnfe);
+ throw new RuntimeException("Error in test: " + cnfe);
+ }
+
+ Iterator<Class<?>> iterator = sun.misc.Service.providers(messageServiceClass, loader);
+ if (expectToFind && !iterator.hasNext()) {
+ debug(messageServiceClass + " NOT found.");
+ return false;
+ }
+
+ while (iterator.hasNext()) {
+ debug("found " + iterator.next() + " " + messageService);
+ }
+
+ debug("HttpServer: " + httpServer);
+
+ if (!expectbDotJar && httpServer.bDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for b.jar");
+ return false;
+ }
+ if (!expectcDotJar && httpServer.cDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for c.jar");
+ return false;
+ }
+
+ return true;
+ }
+
+ static boolean javaUtilServiceLoaderTest(URL baseURL,
+ String serviceClass,
+ boolean expectToFind,
+ boolean expectbDotJar,
+ boolean expectcDotJar) throws IOException {
+ debug("----------------------------------");
+ debug("Running test with java.util.ServiceLoader looking for " + serviceClass);
+ URLClassLoader loader = getLoader(baseURL);
+ httpServer.reset();
+
+ Class messageServiceClass = null;
+ try {
+ messageServiceClass = loader.loadClass(serviceClass);
+ } catch (ClassNotFoundException cnfe) {
+ System.err.println(cnfe);
+ throw new RuntimeException("Error in test: " + cnfe);
+ }
+
+ Iterator<Class<?>> iterator = (ServiceLoader.load(messageServiceClass, loader)).iterator();
+ if (expectToFind && !iterator.hasNext()) {
+ debug(messageServiceClass + " NOT found.");
+ return false;
+ }
+
+ while (iterator.hasNext()) {
+ debug("found " + iterator.next() + " " + messageService);
+ }
+
+ debug("HttpServer: " + httpServer);
+
+ if (!expectbDotJar && httpServer.bDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for b.jar");
+ return false;
+ }
+ if (!expectcDotJar && httpServer.cDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for c.jar");
+ return false;
+ }
+
+ return true;
+ }
+
+ /* Tries to find a resource in a similar way to the font manager in javafx
+ * com.sun.javafx.scene.text.FontManager */
+ static boolean klassLoader(URL baseURL,
+ String resource,
+ boolean expectToFind,
+ boolean expectbDotJar,
+ boolean expectcDotJar) throws IOException {
+ debug("----------------------------------");
+ debug("Running test looking for " + resource);
+ URLClassLoader loader = getLoader(baseURL);
+ httpServer.reset();
+
+ Class ADotAKlass = null;
+ try {
+ ADotAKlass = loader.loadClass("a.A");
+ } catch (ClassNotFoundException cnfe) {
+ System.err.println(cnfe);
+ throw new RuntimeException("Error in test: " + cnfe);
+ }
+
+ URL u = ADotAKlass.getResource(resource);
+ if (expectToFind && u == null) {
+ System.out.println("Expected to find " + resource + " but didn't");
+ return false;
+ }
+
+ debug("HttpServer: " + httpServer);
+
+ if (!expectbDotJar && httpServer.bDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for b.jar");
+ return false;
+ }
+ if (!expectcDotJar && httpServer.cDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for c.jar");
+ return false;
+ }
+
+ return true;
+ }
+
+ static URLClassLoader getLoader(URL baseURL) throws IOException {
+ ClassLoader loader = Basic.class.getClassLoader();
+
+ while (loader.getParent() != null)
+ loader = loader.getParent();
+
+ return new URLClassLoader( new URL[]{
+ new URL(baseURL, "a.jar"),
+ new URL(baseURL, "b.jar"),
+ new URL(baseURL, "c.jar")}, loader );
+ }
+
+ /**
+ * HTTP Server to server the jar files.
+ */
+ static class JarHttpServer implements HttpHandler {
+ final String docsDir;
+ final HttpServer httpServer;
+ int aDotJar, bDotJar, cDotJar;
+
+ JarHttpServer(String docsDir) throws IOException {
+ this.docsDir = docsDir;
+
+ httpServer = HttpServer.create(new InetSocketAddress(0), 0);
+ httpServer.createContext("/", this);
+ }
+
+ void start() throws IOException {
+ httpServer.start();
+ }
+
+ void stop(int delay) {
+ httpServer.stop(delay);
+ }
+
+ InetSocketAddress getAddress() {
+ return httpServer.getAddress();
+ }
+
+ void reset() {
+ aDotJar = bDotJar = cDotJar = 0;
+ }
+
+ @Override
+ public String toString() {
+ return "aDotJar=" + aDotJar + ", bDotJar=" + bDotJar + ", cDotJar=" + cDotJar;
+ }
+
+ public void handle(HttpExchange t) throws IOException {
+ InputStream is = t.getRequestBody();
+ Headers map = t.getRequestHeaders();
+ Headers rmap = t.getResponseHeaders();
+ URI uri = t.getRequestURI();
+
+ debug("Server: received request for " + uri);
+ String path = uri.getPath();
+ if (path.endsWith("a.jar"))
+ aDotJar++;
+ else if (path.endsWith("b.jar"))
+ bDotJar++;
+ else if (path.endsWith("c.jar"))
+ cDotJar++;
+ else
+ System.out.println("Unexpected resource request" + path);
+
+ while (is.read() != -1);
+ is.close();
+
+ File file = new File(docsDir, path);
+ if (!file.exists())
+ throw new RuntimeException("Error: request for " + file);
+ long clen = file.length();
+ t.sendResponseHeaders (200, clen);
+ OutputStream os = t.getResponseBody();
+ FileInputStream fis = new FileInputStream(file);
+ try {
+ byte[] buf = new byte [16 * 1024];
+ int len;
+ while ((len=fis.read(buf)) != -1) {
+ os.write (buf, 0, len);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ fis.close();
+ os.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarA/META-INF/services/my.happy.land Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# The contents of this file do not matter. It exists
+# simply to have a service defined in META-INF/services.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarA/a/A.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package a;
+
+public class A {
+ public static void hello() throws Exception {
+ System.out.println("Hello from a.A");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarA/com/message/spi/MessageService.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.message.spi;
+
+public interface MessageService {
+ String message();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarB/META-INF/JAVA2.DS Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# The contents of this file do not matter. It exists
+# simply to have a file under META-INF.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarB/META-INF/services/no.name.service Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# The contents of this file do not matter. It exists
+# simply to have a service defined in META-INF/services.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarB/b/B.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package b;
+
+public class B {
+ public static void hello() {
+ System.out.println("Hello from b.B");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/fonts.mf Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+corporate=/fonts/Company-corporate.ttf
+crazy-looking=/fonts/kidpr.ttf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/fonts/Company-corporate.ttf Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+This is not a real font.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/fonts/kidpr.ttf Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+This is not a real font.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/services/com.message.spi.MessageService Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+my.impl.StandardMessageService
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/my/impl/StandardMessageService.java Tue Feb 08 14:25:33 2011 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package my.impl;
+
+public class StandardMessageService implements com.message.spi.MessageService {
+ @Override
+ public String message() {
+ return "This is a message from the standard message service";
+ }
+}
--- a/jdk/test/sun/security/provider/SeedGenerator/SeedGeneratorChoice.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/sun/security/provider/SeedGenerator/SeedGeneratorChoice.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
--- a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,10 @@
/**
* @test
*
- * @bug 6861062
- * @summary Disable MD2 support
+ * @bug 6861062 7011497
+ * @summary Disable MD2 support.
+ * New CertPathValidatorException.BasicReason enum constant for
+ * constrained algorithm.
*
* @author Xuelei Fan
*/
@@ -35,6 +37,7 @@
import java.util.*;
import java.security.Security;
import java.security.cert.*;
+import java.security.cert.CertPathValidatorException.*;
public class CPValidatorEndEntity {
@@ -329,6 +332,13 @@
intermediate_SHA1withRSA_1024_1024);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
@@ -337,6 +347,13 @@
intermediate_SHA1withRSA_512_1024);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
}
--- a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,10 @@
/**
* @test
*
- * @bug 6861062
+ * @bug 6861062 7011497
* @summary Disable MD2 support
+ * new CertPathValidatorException.BasicReason enum constant for
+ * constrained algorithm
*
* @author Xuelei Fan
*/
@@ -35,6 +37,7 @@
import java.util.*;
import java.security.Security;
import java.security.cert.*;
+import java.security.cert.CertPathValidatorException.*;
public class CPValidatorIntermediate {
@@ -223,6 +226,13 @@
validate(intermediate_MD2withRSA_1024_1024);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
@@ -230,6 +240,13 @@
validate(intermediate_MD2withRSA_1024_512);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
}
--- a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java Tue Feb 08 14:25:33 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,10 @@
/**
* @test
*
- * @bug 6861062
+ * @bug 6861062 7011497
* @summary Disable MD2 support
+ * new CertPathValidatorException.BasicReason enum constant for
+ * constrained algorithm
*
* @author Xuelei Fan
*/
@@ -35,6 +37,7 @@
import java.util.*;
import java.security.Security;
import java.security.cert.*;
+import java.security.cert.CertPathValidatorException.*;
public class CPValidatorTrustAnchor {
@@ -142,6 +145,13 @@
validate(trustAnchor_MD2withRSA_2048);
throw new Exception("expected algorithm disabled exception");
} catch (CertPathValidatorException cpve) {
+ // we may get ClassCastException here
+ BasicReason reason = (BasicReason)cpve.getReason();
+ if (reason != BasicReason.ALGORITHM_CONSTRAINED) {
+ throw new Exception(
+ "Expect to get ALGORITHM_CONSTRAINED CPVE", cpve);
+ }
+
System.out.println("Get the expected exception " + cpve);
}
}
--- a/jdk/test/tools/launcher/Arrrghs.java Tue Feb 08 14:19:54 2011 -0800
+++ b/jdk/test/tools/launcher/Arrrghs.java Tue Feb 08 14:25:33 2011 -0800
@@ -24,7 +24,7 @@
/**
* @test
* @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938
- * 6894719
+ * 6894719 6968053
* @summary Argument parsing validation.
* @compile -XDignore.symbol.file Arrrghs.java TestHelper.java
* @run main Arrrghs
@@ -250,13 +250,11 @@
TestHelper.createJar("MIA", new File("some.jar"), new File("Foo"),
(String[])null);
tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar");
- tr.contains("Error: Could not find main class MIA");
- tr.contains("java.lang.NoClassDefFoundError: MIA");
+ tr.contains("Error: Could not find or load main class MIA");
System.out.println(tr);
// use classpath to check
tr = TestHelper.doExec(TestHelper.javaCmd, "-cp", "some.jar", "MIA");
- tr.contains("Error: Could not find main class MIA");
- tr.contains("java.lang.NoClassDefFoundError: MIA");
+ tr.contains("Error: Could not find or load main class MIA");
System.out.println(tr);
// incorrect method access
@@ -305,12 +303,12 @@
// amongst a potpourri of kindred main methods, is the right one chosen ?
TestHelper.createJar(new File("some.jar"), new File("Foo"),
- "void main(Object[] args){}",
- "int main(Float[] args){return 1;}",
- "private void main() {}",
- "private static void main(int x) {}",
- "public int main(int argc, String[] argv) {return 1;}",
- "public static void main(String[] args) {System.out.println(\"THE_CHOSEN_ONE\");}");
+ "void main(Object[] args){}",
+ "int main(Float[] args){return 1;}",
+ "private void main() {}",
+ "private static void main(int x) {}",
+ "public int main(int argc, String[] argv) {return 1;}",
+ "public static void main(String[] args) {System.out.println(\"THE_CHOSEN_ONE\");}");
tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar");
tr.contains("THE_CHOSEN_ONE");
System.out.println(tr);
@@ -326,6 +324,30 @@
tr.checkPositive();
System.out.println(tr);
}
+ // tests 6968053, ie. we turn on the -Xdiag (for now) flag and check if
+ // the suppressed stack traces are exposed.
+ static void runDiagOptionTests() throws FileNotFoundException {
+ TestHelper.TestResult tr = null;
+ // a missing class
+ TestHelper.createJar("MIA", new File("some.jar"), new File("Foo"),
+ (String[])null);
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "-jar", "some.jar");
+ tr.contains("Error: Could not find or load main class MIA");
+ tr.contains("java.lang.ClassNotFoundException: MIA");
+ System.out.println(tr);
+
+ // use classpath to check
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "-cp", "some.jar", "MIA");
+ tr.contains("Error: Could not find or load main class MIA");
+ tr.contains("java.lang.ClassNotFoundException: MIA");
+ System.out.println(tr);
+
+ // a missing class on the classpath
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "NonExistentClass");
+ tr.contains("Error: Could not find or load main class NonExistentClass");
+ tr.contains("java.lang.ClassNotFoundException: NonExistentClass");
+ System.out.println(tr);
+ }
static void test6894719() {
// test both arguments to ensure they exist
@@ -352,6 +374,7 @@
runBasicErrorMessageTests();
runMainMethodTests();
test6894719();
+ runDiagOptionTests();
if (TestHelper.testExitValue > 0) {
System.out.println("Total of " + TestHelper.testExitValue + " failed");
System.exit(1);