提交 b977a1ca 编写于 作者: A alanb

7017446: (fs) Updates to file system API (3/2011)

Reviewed-by: sherman
上级 69d4354d
......@@ -1712,10 +1712,10 @@ public final class Files {
* @return the {@code path} parameter
*
* @throws UnsupportedOperationException
* if the attribute view is not available or it does not support
* updating the attribute
* if the attribute view is not available
* @throws IllegalArgumentException
* if the attribute value is of the correct type but has an
* if the attribute name is not specified, or is not recognized, or
* 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
......@@ -1776,9 +1776,12 @@ public final class Files {
* @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
* @return the attribute value
*
* @throws UnsupportedOperationException
* if the attribute view is not available
* @throws IllegalArgumentException
* if the attribute name is not specified or is not recognized
* @throws IOException
* if an I/O error occurs
* @throws SecurityException
......@@ -1794,8 +1797,9 @@ public final class Files {
{
// only one attribute should be read
if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0)
return null;
throw new IllegalArgumentException(attribute);
Map<String,Object> map = readAttributes(path, attribute, options);
assert map.size() == 1;
String name;
int pos = attribute.indexOf(':');
if (pos == -1) {
......@@ -1868,9 +1872,14 @@ public final class Files {
* @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
* @return a map of the attributes returned; The map's keys are the
* attribute names, its values are the attribute values
*
* @throws UnsupportedOperationException
* if the attribute view is not available
* @throws IllegalArgumentException
* if no attributes are specified or an unrecognized attributes is
* specified
* @throws IOException
* if an I/O error occurs
* @throws SecurityException
......
......@@ -228,6 +228,9 @@ public interface Path
* not have a root component and the given path has a root component then
* this path does not start with the given path.
*
* <p> If the given path is associated with a different {@code FileSystem}
* to this path then {@code false} is returned.
*
* @param other
* the given path
*
......@@ -270,6 +273,9 @@ public interface Path
* does not have a root component and the given path has a root component
* then this path does not end with the given path.
*
* <p> If the given path is associated with a different {@code FileSystem}
* to this path then {@code false} is returned.
*
* @param other
* the given path
*
......@@ -283,7 +289,10 @@ public interface Path
* 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}".
* not end with "{@code r}" or "{@code /bar}". Note that trailing separators
* are not taken into account, and so invoking this method on the {@code
* Path}"{@code foo/bar}" with the {@code String} "{@code bar/}" returns
* {@code true}.
*
* @param other
* the given path string
......@@ -724,12 +733,18 @@ public interface Path
* provider, platform specific. This method does not access the file system
* and neither file is required to exist.
*
* <p> This method may not be used to compare paths that are associated
* with different file system providers.
*
* @param other the path compared to this path.
*
* @return zero if the argument is {@link #equals equal} to this path, a
* value less than zero if this path is lexicographically less than
* the argument, or a value greater than zero if this path is
* lexicographically greater than the argument
*
* @throws ClassCastException
* if the paths are associated with different providers
*/
@Override
int compareTo(Path other);
......@@ -738,7 +753,7 @@ public interface Path
* Tests this path for equality with the given object.
*
* <p> If the given object is not a Path, or is a Path associated with a
* different provider, then this method immediately returns {@code false}.
* different {@code FileSystem}, then this method returns {@code false}.
*
* <p> Whether or not two path are equal depends on the file system
* implementation. In some cases the paths are compared without regard
......
......@@ -146,5 +146,5 @@ public interface WatchKey {
*
* @return the object for which this watch key was created
*/
//T watchable();
Watchable watchable();
}
......@@ -216,12 +216,14 @@ public final class FileTime
* "2009-02-13T23:31:30Z"}, and {@code FileTime.fromMillis(1234567890123L).toString()}
* yields {@code "2009-02-13T23:31:30.123Z"}.
*
* <p> A {@code FileTime} is primarly intended to represent the value of a
* <p> A {@code FileTime} is primarily intended to represent the value of a
* file's time stamp. Where used to represent <i>extreme values</i>, where
* the year is less than "{@code 0001}" or greater than "{@code 9999}" then
* the year may be expanded to more than four digits and may be
* negative-signed. If more than four digits then leading zeros are not
* present. The year before "{@code 0001}" is "{@code -0001}".
* this method deviates from ISO 8601 in the same manner as the
* <a href="http://www.w3.org/TR/xmlschema-2/#deviantformats">XML Schema
* language</a>. That is, the year may be expanded to more than four digits
* and may be negative-signed. If more than four digits then leading zeros
* are not present. The year before "{@code 0001}" is "{@code -0001}".
*
* @return the string representation of this file time
*/
......
......@@ -1037,6 +1037,11 @@ public abstract class FileSystemProvider {
* @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 UnsupportedOperationException
* if the attribute view is not available
* @throws IllegalArgumentException
* if no attributes are specified or an unrecognized attributes is
* specified
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
......@@ -1064,10 +1069,10 @@ public abstract class FileSystemProvider {
* options indicating how symbolic links are handled
*
* @throws UnsupportedOperationException
* if the attribute view is not available or it does not support
* updating the attribute
* if the attribute view is not available
* @throws IllegalArgumentException
* if the attribute value is of the correct type but has an
* if the attribute name is not specified, or is not recognized, or
* 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
......
......@@ -57,8 +57,8 @@ abstract class AbstractAclFileAttributeView
setAcl((List<AclEntry>)value);
return;
}
throw new UnsupportedOperationException("'" + name() + ":" +
attribute + "' not supported");
throw new IllegalArgumentException("'" + name() + ":" +
attribute + "' not recognized");
}
@Override
......@@ -81,6 +81,8 @@ abstract class AbstractAclFileAttributeView
owner = true;
continue;
}
throw new IllegalArgumentException("'" + name() + ":" +
attribute + "' not recognized");
}
Map<String,Object> result = new HashMap<>(2);
if (acl)
......
......@@ -46,6 +46,18 @@ abstract class AbstractBasicFileAttributeView
private static final String IS_SYMBOLIC_LINK_NAME = "isSymbolicLink";
private static final String IS_OTHER_NAME = "isOther";
// the names of the basic attributes
static final Set<String> basicAttributeNames =
Util.newSet(SIZE_NAME,
CREATION_TIME_NAME,
LAST_ACCESS_TIME_NAME,
LAST_MODIFIED_TIME_NAME,
FILE_KEY_NAME,
IS_DIRECTORY_NAME,
IS_REGULAR_FILE_NAME,
IS_SYMBOLIC_LINK_NAME,
IS_OTHER_NAME);
protected AbstractBasicFileAttributeView() { }
@Override
......@@ -69,24 +81,26 @@ abstract class AbstractBasicFileAttributeView
setTimes(null, null, (FileTime)value);
return;
}
throw new UnsupportedOperationException("'" + attribute +
"' is unknown or read-only attribute");
throw new IllegalArgumentException("'" + name() + ":" +
attribute + "' not recognized");
}
/**
* Used to build a map of attribute name/values.
*/
static class AttributesBuilder {
private Set<String> set = new HashSet<>();
private Set<String> names = new HashSet<>();
private Map<String,Object> map = new HashMap<>();
private boolean copyAll;
private AttributesBuilder(String[] attributes) {
for (String attribute: attributes) {
if (attribute.equals("*")) {
private AttributesBuilder(Set<String> allowed, String[] requested) {
for (String name: requested) {
if (name.equals("*")) {
copyAll = true;
} else {
set.add(attribute);
if (!allowed.contains(name))
throw new IllegalArgumentException("'" + name + "' not recognized");
names.add(name);
}
}
}
......@@ -94,21 +108,19 @@ abstract class AbstractBasicFileAttributeView
/**
* Creates builder to build up a map of the matching attributes
*/
static AttributesBuilder create(String[] attributes) {
return new AttributesBuilder(attributes);
static AttributesBuilder create(Set<String> allowed, String[] requested) {
return new AttributesBuilder(allowed, requested);
}
/**
* Returns true if the attribute should be returned in the map
*/
boolean match(String attribute) {
if (copyAll)
return true;
return set.contains(attribute);
boolean match(String name) {
return copyAll || names.contains(name);
}
void add(String attribute, Object value) {
map.put(attribute, value);
void add(String name, Object value) {
map.put(name, value);
}
/**
......@@ -124,7 +136,7 @@ abstract class AbstractBasicFileAttributeView
* Invoked by readAttributes or sub-classes to add all matching basic
* attributes to the builder
*/
final void addBasicAttributesToBuilder(BasicFileAttributes attrs,
final void addRequestedBasicAttributes(BasicFileAttributes attrs,
AttributesBuilder builder)
{
if (builder.match(SIZE_NAME))
......@@ -148,9 +160,12 @@ abstract class AbstractBasicFileAttributeView
}
@Override
public Map<String,Object> readAttributes(String[] attributes) throws IOException {
AttributesBuilder builder = AttributesBuilder.create(attributes);
addBasicAttributesToBuilder(readAttributes(), builder);
public Map<String,Object> readAttributes(String[] requested)
throws IOException
{
AttributesBuilder builder =
AttributesBuilder.create(basicAttributeNames, requested);
addRequestedBasicAttributes(readAttributes(), builder);
return builder.unmodifiableMap();
}
}
......@@ -29,7 +29,6 @@ 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
......@@ -72,6 +71,8 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider {
throws IOException
{
String[] s = split(attribute);
if (s[0].length() == 0)
throw new IllegalArgumentException(attribute);
DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
if (view == null)
throw new UnsupportedOperationException("View '" + s[0] + "' not available");
......@@ -83,9 +84,11 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider {
throws IOException
{
String[] s = split(attributes);
if (s[0].length() == 0)
throw new IllegalArgumentException(attributes);
DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
if (view == null)
return Collections.emptyMap();
throw new UnsupportedOperationException("View '" + s[0] + "' not available");
return view.readAttributes(s[1].split(","));
}
......
......@@ -59,22 +59,6 @@ abstract class AbstractUserDefinedFileAttributeView
return "user";
}
private Object getAttribute(String attribute) throws IOException {
int size;
try {
size = size(attribute);
} catch (IOException e) {
// not found or some other I/O error
if (list().contains(attribute))
throw e;
return null;
}
byte[] buf = new byte[size];
int n = read(attribute, ByteBuffer.wrap(buf));
return (n == size) ? buf : Arrays.copyOf(buf, n);
}
@Override
public final void setAttribute(String attribute, Object value)
throws IOException
......@@ -94,12 +78,13 @@ abstract class AbstractUserDefinedFileAttributeView
{
// names of attributes to return
List<String> names = new ArrayList<>();
for (String name: attributes) {
if (name.equals("*")) {
names = list();
break;
} else {
if (name.length() == 0)
throw new IllegalArgumentException();
names.add(name);
}
}
......@@ -107,11 +92,12 @@ abstract class AbstractUserDefinedFileAttributeView
// read each value and return in map
Map<String,Object> result = new HashMap<>();
for (String name: names) {
Object value = getAttribute(name);
if (value != null)
result.put(name, value);
int size = size(name);
byte[] buf = new byte[size];
int n = read(name, ByteBuffer.wrap(buf));
byte[] value = (n == size) ? buf : Arrays.copyOf(buf, n);
result.put(name, value);
}
return result;
}
}
......@@ -81,7 +81,8 @@ abstract class AbstractWatchKey implements WatchKey {
/**
* Return the original watchable (Path)
*/
Path watchable() {
@Override
public Path watchable() {
return dir;
}
......
......@@ -63,10 +63,10 @@ final class FileOwnerAttributeViewImpl
{
if (attribute.equals(OWNER_NAME)) {
setOwner((UserPrincipal)value);
return;
} else {
throw new IllegalArgumentException("'" + name() + ":" +
attribute + "' not recognized");
}
throw new UnsupportedOperationException("'" + name() + ":" +
attribute + "' not supported");
}
@Override
......@@ -75,6 +75,9 @@ final class FileOwnerAttributeViewImpl
for (String attribute: attributes) {
if (attribute.equals("*") || attribute.equals(OWNER_NAME)) {
result.put(OWNER_NAME, getOwner());
} else {
throw new IllegalArgumentException("'" + name() + ":" +
attribute + "' not recognized");
}
}
return result;
......
......@@ -25,6 +25,8 @@
package sun.nio.fs;
import java.util.*;
/**
* Utility methods
*/
......@@ -54,6 +56,28 @@ class Util {
}
result[n] = s.substring(last, s.length());
return result;
}
/**
* Returns a Set containing the given elements.
*/
static <E> Set<E> newSet(E... elements) {
HashSet<E> set = new HashSet<>();
for (E e: elements) {
set.add(e);
}
return set;
}
/**
* Returns a Set containing all the elements of the given Set plus
* the given elements.
*/
static <E> Set<E> newSet(Set<E> other, E... elements) {
HashSet<E> set = new HashSet<>(other);
for (E e: elements) {
set.add(e);
}
return set;
}
}
......@@ -33,8 +33,7 @@ import java.nio.file.*;
import static java.nio.file.StandardWatchEventKind.*;
import static java.nio.file.LinkOption.*;
import java.nio.file.attribute.*;
import java.io.*;
import java.util.*;
import java.io.IOException;
/**
* Example to watch a directory (or tree) for changes to files.
......@@ -43,9 +42,9 @@ import java.util.*;
public class WatchDir {
private final WatchService watcher;
private final Map<WatchKey,Path> keys;
private final boolean recursive;
private boolean trace = false;
private int count;
@SuppressWarnings("unchecked")
static <T> WatchEvent<T> cast(WatchEvent<?> event) {
......@@ -57,17 +56,9 @@ public class WatchDir {
*/
private void register(Path dir) throws IOException {
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
if (trace) {
Path prev = keys.get(key);
if (prev == null) {
System.out.format("register: %s\n", dir);
} else {
if (!dir.equals(prev)) {
System.out.format("update: %s -> %s\n", prev, dir);
}
}
}
keys.put(key, dir);
count++;
if (trace)
System.out.format("register: %s\n", dir);
}
/**
......@@ -92,7 +83,6 @@ public class WatchDir {
*/
WatchDir(Path dir, boolean recursive) throws IOException {
this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<WatchKey,Path>();
this.recursive = recursive;
if (recursive) {
......@@ -121,12 +111,6 @@ public class WatchDir {
return;
}
Path dir = keys.get(key);
if (dir == null) {
System.err.println("WatchKey not recognized!!");
continue;
}
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind kind = event.kind();
......@@ -138,7 +122,7 @@ public class WatchDir {
// Context for directory entry event is the file name of entry
WatchEvent<Path> ev = cast(event);
Path name = ev.context();
Path child = dir.resolve(name);
Path child = ((Path)key.watchable()).resolve(name);
// print out event
System.out.format("%s: %s\n", event.kind().name(), child);
......@@ -156,15 +140,13 @@ public class WatchDir {
}
}
// reset key and remove from set if directory no longer accessible
// reset key
boolean valid = key.reset();
if (!valid) {
keys.remove(key);
// all directories are inaccessible
if (keys.isEmpty()) {
// directory no longer accessible
count--;
if (count == 0)
break;
}
}
}
}
......
......@@ -27,6 +27,7 @@ package sun.nio.fs;
import java.nio.file.attribute.*;
import java.util.Map;
import java.util.Set;
import java.io.IOException;
import sun.misc.Unsafe;
......@@ -57,6 +58,10 @@ class LinuxDosFileAttributeView
private static final int DOS_XATTR_SYSTEM = 0x04;
private static final int DOS_XATTR_ARCHIVE = 0x20;
// the names of the DOS attributes (includes basic)
private static final Set<String> dosAttributeNames =
Util.newSet(basicAttributeNames, READONLY_NAME, ARCHIVE_NAME, SYSTEM_NAME, HIDDEN_NAME);
LinuxDosFileAttributeView(UnixPath file, boolean followLinks) {
super(file, followLinks);
}
......@@ -93,9 +98,10 @@ class LinuxDosFileAttributeView
public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
AttributesBuilder builder =
AttributesBuilder.create(dosAttributeNames, attributes);
DosFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder);
addRequestedBasicAttributes(attrs, builder);
if (builder.match(READONLY_NAME))
builder.add(READONLY_NAME, attrs.isReadOnly());
if (builder.match(ARCHIVE_NAME))
......
......@@ -123,6 +123,10 @@ class UnixFileAttributeViews {
private static final String OWNER_NAME = "owner";
private static final String GROUP_NAME = "group";
// the names of the posix attributes (incudes basic)
static final Set<String> posixAttributeNames =
Util.newSet(basicAttributeNames, PERMISSIONS_NAME, OWNER_NAME, GROUP_NAME);
Posix(UnixPath file, boolean followLinks) {
super(file, followLinks);
}
......@@ -172,9 +176,10 @@ class UnixFileAttributeViews {
* Invoked by readAttributes or sub-classes to add all matching posix
* attributes to the builder
*/
final void addPosixAttributesToBuilder(PosixFileAttributes attrs,
final void addRequestedPosixAttributes(PosixFileAttributes attrs,
AttributesBuilder builder)
{
addRequestedBasicAttributes(attrs, builder);
if (builder.match(PERMISSIONS_NAME))
builder.add(PERMISSIONS_NAME, attrs.permissions());
if (builder.match(OWNER_NAME))
......@@ -184,13 +189,13 @@ class UnixFileAttributeViews {
}
@Override
public Map<String,Object> readAttributes(String[] attributes)
public Map<String,Object> readAttributes(String[] requested)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
AttributesBuilder builder =
AttributesBuilder.create(posixAttributeNames, requested);
PosixFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder);
addPosixAttributesToBuilder(attrs, builder);
addRequestedPosixAttributes(attrs, builder);
return builder.unmodifiableMap();
}
......@@ -287,6 +292,12 @@ class UnixFileAttributeViews {
private static final String GID_NAME = "gid";
private static final String CTIME_NAME = "ctime";
// the names of the unix attributes (including posix)
static final Set<String> unixAttributeNames =
Util.newSet(posixAttributeNames,
MODE_NAME, INO_NAME, DEV_NAME, RDEV_NAME,
NLINK_NAME, UID_NAME, GID_NAME, CTIME_NAME);
Unix(UnixPath file, boolean followLinks) {
super(file, followLinks);
}
......@@ -316,13 +327,13 @@ class UnixFileAttributeViews {
}
@Override
public Map<String,Object> readAttributes(String[] attributes)
public Map<String,Object> readAttributes(String[] requested)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
AttributesBuilder builder =
AttributesBuilder.create(unixAttributeNames, requested);
UnixFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder);
addPosixAttributesToBuilder(attrs, builder);
addRequestedPosixAttributes(attrs, builder);
if (builder.match(MODE_NAME))
builder.add(MODE_NAME, attrs.mode());
if (builder.match(INO_NAME))
......
......@@ -606,7 +606,9 @@ class UnixPath
@Override
public boolean startsWith(Path other) {
UnixPath that = toUnixPath(other);
if (!(Objects.requireNonNull(other) instanceof UnixPath))
return false;
UnixPath that = (UnixPath)other;
// other path is longer
if (that.path.length > path.length)
......@@ -655,7 +657,9 @@ class UnixPath
@Override
public boolean endsWith(Path other) {
UnixPath that = toUnixPath(other);
if (!(Objects.requireNonNull(other) instanceof UnixPath))
return false;
UnixPath that = (UnixPath)other;
int thisLen = path.length;
int thatLen = that.path.length;
......
......@@ -157,6 +157,11 @@ class WindowsFileAttributeViews {
private static final String HIDDEN_NAME = "hidden";
private static final String ATTRIBUTES_NAME = "attributes";
// the names of the DOS attribtues (includes basic)
static final Set<String> dosAttributeNames =
Util.newSet(basicAttributeNames,
READONLY_NAME, ARCHIVE_NAME, SYSTEM_NAME, HIDDEN_NAME, ATTRIBUTES_NAME);
Dos(WindowsPath file, boolean followLinks) {
super(file, followLinks);
}
......@@ -193,9 +198,10 @@ class WindowsFileAttributeViews {
public Map<String,Object> readAttributes(String[] attributes)
throws IOException
{
AttributesBuilder builder = AttributesBuilder.create(attributes);
AttributesBuilder builder =
AttributesBuilder.create(dosAttributeNames, attributes);
WindowsFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder);
addRequestedBasicAttributes(attrs, builder);
if (builder.match(READONLY_NAME))
builder.add(READONLY_NAME, attrs.isReadOnly());
if (builder.match(ARCHIVE_NAME))
......
......@@ -646,7 +646,9 @@ class WindowsPath extends AbstractPath {
@Override
public boolean startsWith(Path obj) {
WindowsPath other = toWindowsPath(obj);
if (!(Objects.requireNonNull(obj) instanceof WindowsPath))
return false;
WindowsPath other = (WindowsPath)obj;
// if this path has a root component the given path's root must match
if (!this.root.equalsIgnoreCase(other.root)) {
......@@ -675,7 +677,9 @@ class WindowsPath extends AbstractPath {
@Override
public boolean endsWith(Path obj) {
WindowsPath other = toWindowsPath(obj);
if (!(Objects.requireNonNull(obj) instanceof WindowsPath))
return false;
WindowsPath other = (WindowsPath)obj;
// other path is longer
if (other.path.length() > this.path.length()) {
......
......@@ -22,7 +22,7 @@
*/
/* @test
* @bug 4313887 6838333
* @bug 4313887 6838333 7017446
* @summary Unit test for java.nio.file.Files
* @library ..
*/
......@@ -94,12 +94,6 @@ public class FileAttributes {
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
......@@ -132,7 +126,7 @@ public class FileAttributes {
assertTrue(map.size() >= 12);
checkEqual(attrs.permissions(), map.get("permissions")); // check one
map = Files.readAttributes(file, "posix:size,owner,ShouldNotExist");
map = Files.readAttributes(file, "posix:size,owner");
assertTrue(map.size() == 2);
checkEqual(attrs.size(), map.get("size"));
checkEqual(attrs.owner(), map.get("owner"));
......@@ -155,7 +149,7 @@ public class FileAttributes {
map = Files.readAttributes(file, "unix:*");
assertTrue(map.size() >= 20);
map = Files.readAttributes(file, "unix:size,uid,gid,ShouldNotExist");
map = Files.readAttributes(file, "unix:size,uid,gid");
assertTrue(map.size() == 3);
checkEqual(map.get("size"),
Files.readAttributes(file, BasicFileAttributes.class).size());
......@@ -206,14 +200,65 @@ public class FileAttributes {
assertTrue(map.size() >= 13);
checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
map = Files.readAttributes(file, "dos:size,hidden,ShouldNotExist");
map = Files.readAttributes(file, "dos:size,hidden");
assertTrue(map.size() == 2);
checkEqual(attrs.size(), map.get("size"));
checkEqual(attrs.isHidden(), map.get("hidden"));
}
static void checkBadSet(Path file, String attribute, Object value)
throws IOException
{
try {
Files.setAttribute(file, attribute, 0);
throw new RuntimeException("IllegalArgumentException expected");
} catch (IllegalArgumentException ignore) { }
}
static void checkBadGet(Path file, String attribute) throws IOException {
try {
Files.getAttribute(file, attribute);
throw new RuntimeException("IllegalArgumentException expected");
} catch (IllegalArgumentException ignore) { }
}
static void checkBadRead(Path file, String attribute) throws IOException {
try {
Files.readAttributes(file, attribute);
throw new RuntimeException("IllegalArgumentException expected");
} catch (IllegalArgumentException ignore) { }
}
static void miscTests(Path file) throws IOException {
// NPE tests
// unsupported views
try {
Files.setAttribute(file, "foo:bar", 0);
throw new RuntimeException("UnsupportedOperationException expected");
} catch (UnsupportedOperationException ignore) { }
try {
Files.getAttribute(file, "foo:bar");
throw new RuntimeException("UnsupportedOperationException expected");
} catch (UnsupportedOperationException ignore) { }
try {
Files.readAttributes(file, "foo:*");
throw new RuntimeException("UnsupportedOperationException expected");
} catch (UnsupportedOperationException ignore) { }
// bad args
checkBadSet(file, "", 0);
checkBadSet(file, "basic:", 0);
checkBadSet(file, "basic:foobar", 0);
checkBadGet(file, "");
checkBadGet(file, "basic:");
checkBadGet(file, "basic:foobar");
checkBadGet(file, "basic:size,lastModifiedTime");
checkBadGet(file, "basic:*");
checkBadRead(file, "");
checkBadRead(file, "basic:");
checkBadRead(file, "basic:foobar");
checkBadRead(file, "basic:size,foobar");
// nulls
try {
Files.getAttribute(file, null);
throw new RuntimeException("NullPointerException expected");
......
......@@ -22,7 +22,7 @@
*/
/* @test
* @bug 4313887 6838333
* @bug 4313887 6838333 7017446
* @summary Unit test for java.nio.file.WatchService
* @library ..
* @run main/timeout=120 Basic
......@@ -44,6 +44,8 @@ public class Basic {
static void checkKey(WatchKey key, Path dir) {
if (!key.isValid())
throw new RuntimeException("Key is not valid");
if (key.watchable() != dir)
throw new RuntimeException("Unexpected watchable");
}
static void takeExpectedKey(WatchService watcher, WatchKey expected) {
......
......@@ -141,9 +141,6 @@ public class Basic {
map = Files.readAttributes(file, "user:*");
if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
throw new RuntimeException("Unexpected attribute value");
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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册