mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-12 04:05:26 +00:00
7017446: (fs) Updates to file system API (3/2011)
Reviewed-by: sherman
This commit is contained in:
parent
49f0232c39
commit
8dfe1d556a
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user