diff --git a/jdk/src/java.base/share/classes/java/nio/file/Path.java b/jdk/src/java.base/share/classes/java/nio/file/Path.java index 9df57c120e0..fdb28cfd716 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/Path.java +++ b/jdk/src/java.base/share/classes/java/nio/file/Path.java @@ -29,6 +29,7 @@ import java.io.File; import java.io.IOException; import java.net.URI; import java.util.Iterator; +import java.util.NoSuchElementException; /** * An object that may be used to locate a file in a file system. It will @@ -246,6 +247,12 @@ public interface Path * "{@code foo/bar}" starts with "{@code foo}" and "{@code foo/bar}". It * does not start with "{@code f}" or "{@code fo}". * + * @implSpec + * The default implementation is equivalent for this path to: + *
{@code
+     *     startsWith(getFileSystem().getPath(other));
+     * }
+ * * @param other * the given path string * @@ -255,7 +262,9 @@ public interface Path * @throws InvalidPathException * If the path string cannot be converted to a Path. */ - boolean startsWith(String other); + default boolean startsWith(String other) { + return startsWith(getFileSystem().getPath(other)); + } /** * Tests if this path ends with the given path. @@ -294,6 +303,12 @@ public interface Path * Path}"{@code foo/bar}" with the {@code String} "{@code bar/}" returns * {@code true}. * + * @implSpec + * The default implementation is equivalent for this path to: + *
{@code
+     *     endsWith(getFileSystem().getPath(other));
+     * }
+ * * @param other * the given path string * @@ -303,7 +318,9 @@ public interface Path * @throws InvalidPathException * If the path string cannot be converted to a Path. */ - boolean endsWith(String other); + default boolean endsWith(String other) { + return endsWith(getFileSystem().getPath(other)); + } /** * Returns a path that is this path with redundant name elements eliminated. @@ -365,6 +382,12 @@ public interface Path * invoking this method with the path string "{@code gus}" will result in * the {@code Path} "{@code foo/bar/gus}". * + * @implSpec + * The default implementation is equivalent for this path to: + *
{@code
+     *     resolve(getFileSystem().getPath(other));
+     * }
+ * * @param other * the path string to resolve against this path * @@ -375,7 +398,9 @@ public interface Path * * @see FileSystem#getPath */ - Path resolve(String other); + default Path resolve(String other) { + return resolve(getFileSystem().getPath(other)); + } /** * Resolves the given path against this path's {@link #getParent parent} @@ -389,6 +414,14 @@ public interface Path * returns this path's parent, or where this path doesn't have a parent, the * empty path. * + * @implSpec + * The default implementation is equivalent for this path to: + *
{@code
+     *     (getParent() == null) ? other : getParent().resolve(other);
+     * }
+ * unless {@code other == null}, in which case a + * {@code NullPointerException} is thrown. + * * @param other * the path to resolve against this path's parent * @@ -396,13 +429,24 @@ public interface Path * * @see #resolve(Path) */ - Path resolveSibling(Path other); + default Path resolveSibling(Path other) { + if (other == null) + throw new NullPointerException(); + Path parent = getParent(); + return (parent == null) ? other : parent.resolve(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. * + * @implSpec + * The default implementation is equivalent for this path to: + *
{@code
+     *     resolveSibling(getFileSystem().getPath(other));
+     * }
+ * * @param other * the path string to resolve against this path's parent * @@ -413,7 +457,9 @@ public interface Path * * @see FileSystem#getPath */ - Path resolveSibling(String other); + default Path resolveSibling(String other) { + return resolveSibling(getFileSystem().getPath(other)); + } /** * Constructs a relative path between this path and a given path. @@ -590,12 +636,28 @@ public interface Path * File} object returned by this method is {@link #equals equal} to the * original {@code File}. * + * @implSpec + * The default implementation is equivalent for this path to: + *
{@code
+     *     new File(toString());
+     * }
+ * if the {@code FileSystem} which created this {@code Path} is the default + * file system; otherwise an {@code UnsupportedOperationException} is + * thrown. + * * @return a {@code File} object representing this path * * @throws UnsupportedOperationException * if this {@code Path} is not associated with the default provider */ - File toFile(); + default File toFile() { + if (getFileSystem() == FileSystems.getDefault()) { + return new File(toString()); + } else { + throw new UnsupportedOperationException("Path not associated with " + + "default file system."); + } + } // -- watchable -- @@ -681,6 +743,13 @@ public interface Path * * WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); * + * + * @implSpec + * The default implementation is equivalent for this path to: + *
{@code
+     *     register(watcher, events, new WatchEvent.Modifier[0]);
+     * }
+ * * @param watcher * The watch service to which this object is to be registered * @param events @@ -706,9 +775,10 @@ public interface Path * method is invoked to check read access to the file. */ @Override - WatchKey register(WatchService watcher, - WatchEvent.Kind... events) - throws IOException; + default WatchKey register(WatchService watcher, + WatchEvent.Kind... events) throws IOException { + return register(watcher, events, new WatchEvent.Modifier[0]); + } // -- Iterable -- @@ -721,10 +791,36 @@ public interface Path * is the name of the file or directory denoted by this path. The {@link * #getRoot root} component, if present, is not returned by the iterator. * + * @implSpec + * The default implementation returns an {@code Iterator} which, for + * this path, traverses the {@code Path}s returned by + * {@code getName(index)}, where {@code index} ranges from zero to + * {@code getNameCount() - 1}, inclusive. + * * @return an iterator over the name elements of this path. */ @Override - Iterator iterator(); + default Iterator iterator() { + return new Iterator() { + 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(); + } + } + }; + } // -- compareTo/equals/hashCode -- diff --git a/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPath.java b/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPath.java deleted file mode 100644 index dd6b3bde9a9..00000000000 --- a/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPath.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2007, 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.io.File; -import java.io.IOException; -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Base implementation class of {@code Path}. - */ - -abstract class AbstractPath implements Path { - protected AbstractPath() { } - - @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 - public final Path resolve(String other) { - return resolve(getFileSystem().getPath(other)); - } - - @Override - 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 Path resolveSibling(String other) { - return resolveSibling(getFileSystem().getPath(other)); - } - - @Override - public final Iterator iterator() { - return new Iterator() { - 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(); - } - }; - } - - @Override - public final File toFile() { - return new File(toString()); - } - - @Override - public final WatchKey register(WatchService watcher, - WatchEvent.Kind... events) - throws IOException - { - return register(watcher, events, new WatchEvent.Modifier[0]); - } -} diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java index 9f45afdab48..b74a393e9b2 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java @@ -40,9 +40,7 @@ import static sun.nio.fs.UnixConstants.*; * Solaris/Linux implementation of java.nio.file.Path */ -class UnixPath - extends AbstractPath -{ +class UnixPath implements Path { private static ThreadLocal> encoder = new ThreadLocal>(); diff --git a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java index e0a6e5be15a..afa24e40cf3 100644 --- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java +++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java @@ -41,7 +41,7 @@ import static sun.nio.fs.WindowsConstants.*; * Windows implementation of Path */ -class WindowsPath extends AbstractPath { +class WindowsPath implements Path { // 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