1 /*
   2  * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.nio.file.spi;
  27 
  28 import java.nio.file.*;
  29 import java.nio.file.attribute.*;
  30 import java.nio.channels.*;
  31 import java.net.URI;
  32 import java.io.InputStream;
  33 import java.io.OutputStream;
  34 import java.io.IOException;
  35 import java.util.*;
  36 import java.util.concurrent.ExecutorService;
  37 import java.security.AccessController;
  38 import java.security.PrivilegedAction;
  39 
  40 /**
  41  * Service-provider class for file systems. The methods defined by the {@link
  42  * java.nio.file.Files} class will typically delegate to an instance of this
  43  * class.
  44  *
  45  * <p> A file system provider is a concrete implementation of this class that
  46  * implements the abstract methods defined by this class. A provider is
  47  * identified by a {@code URI} {@link #getScheme() scheme}. The default provider
  48  * is identified by the URI scheme "file". It creates the {@link FileSystem} that
  49  * provides access to the file systems accessible to the Java virtual machine.
  50  * The {@link FileSystems} class defines how file system providers are located
  51  * and loaded. The default provider is typically a system-default provider but
  52  * may be overridden if the system property {@code
  53  * java.nio.file.spi.DefaultFileSystemProvider} is set. In that case, the
  54  * provider has a one argument constructor whose formal parameter type is {@code
  55  * FileSystemProvider}. All other providers have a zero argument constructor
  56  * that initializes the provider.
  57  *
  58  * <p> A provider is a factory for one or more {@link FileSystem} instances. Each
  59  * file system is identified by a {@code URI} where the URI's scheme matches
  60  * the provider's {@link #getScheme scheme}. The default file system, for example,
  61  * is identified by the URI {@code "file:///"}. A memory-based file system,
  62  * for example, may be identified by a URI such as {@code "memory:///?name=logfs"}.
  63  * The {@link #newFileSystem newFileSystem} method may be used to create a file
  64  * system, and the {@link #getFileSystem getFileSystem} method may be used to
  65  * obtain a reference to an existing file system created by the provider. Where
  66  * a provider is the factory for a single file system then it is provider dependent
  67  * if the file system is created when the provider is initialized, or later when
  68  * the {@code newFileSystem} method is invoked. In the case of the default
  69  * provider, the {@code FileSystem} is created when the provider is initialized.
  70  *
  71  * <p> All of the methods in this class are safe for use by multiple concurrent
  72  * threads.
  73  *
  74  * @since 1.7
  75  */
  76 
  77 public abstract class FileSystemProvider {
  78     // lock using when loading providers
  79     private static final Object lock = new Object();
  80 
  81     // installed providers
  82     private static volatile List<FileSystemProvider> installedProviders;
  83 
  84     // used to avoid recursive loading of installed providers
  85     private static boolean loadingProviders  = false;
  86 
  87     private static Void checkPermission() {
  88         SecurityManager sm = System.getSecurityManager();
  89         if (sm != null)
  90             sm.checkPermission(new RuntimePermission("fileSystemProvider"));
  91         return null;
  92     }
  93     private FileSystemProvider(Void ignore) { }
  94 
  95     /**
  96      * Initializes a new instance of this class.
  97      *
  98      * <p> During construction a provider may safely access files associated
  99      * with the default provider but care needs to be taken to avoid circular
 100      * loading of other installed providers. If circular loading of installed
 101      * providers is detected then an unspecified error is thrown.
 102      *
 103      * @throws  SecurityException
 104      *          If a security manager has been installed and it denies
 105      *          {@link RuntimePermission}{@code ("fileSystemProvider")}
 106      */
 107     protected FileSystemProvider() {
 108         this(checkPermission());
 109     }
 110 
 111     // loads all installed providers
 112     private static List<FileSystemProvider> loadInstalledProviders() {
 113         List<FileSystemProvider> list = new ArrayList<>();
 114 
 115         ServiceLoader<FileSystemProvider> sl = ServiceLoader
 116             .load(FileSystemProvider.class, ClassLoader.getSystemClassLoader());
 117 
 118         // ServiceConfigurationError may be throw here
 119         for (FileSystemProvider provider: sl) {
 120             String scheme = provider.getScheme();
 121 
 122             // add to list if the provider is not "file" and isn't a duplicate
 123             if (!scheme.equalsIgnoreCase("file")) {
 124                 boolean found = false;
 125                 for (FileSystemProvider p: list) {
 126                     if (p.getScheme().equalsIgnoreCase(scheme)) {
 127                         found = true;
 128                         break;
 129                     }
 130                 }
 131                 if (!found) {
 132                     list.add(provider);
 133                 }
 134             }
 135         }
 136         return list;
 137     }
 138 
 139     /**
 140      * Returns a list of the installed file system providers.
 141      *
 142      * <p> The first invocation of this method causes the default provider to be
 143      * initialized (if not already initialized) and loads any other installed
 144      * providers as described by the {@link FileSystems} class.
 145      *
 146      * @return  An unmodifiable list of the installed file system providers. The
 147      *          list contains at least one element, that is the default file
 148      *          system provider
 149      *
 150      * @throws  ServiceConfigurationError
 151      *          When an error occurs while loading a service provider
 152      */
 153     public static List<FileSystemProvider> installedProviders() {
 154         if (installedProviders == null) {
 155             // ensure default provider is initialized
 156             FileSystemProvider defaultProvider = FileSystems.getDefault().provider();
 157 
 158             synchronized (lock) {
 159                 if (installedProviders == null) {
 160                     if (loadingProviders) {
 161                         throw new Error("Circular loading of installed providers detected");
 162                     }
 163                     loadingProviders = true;
 164 
 165                     List<FileSystemProvider> list = AccessController
 166                         .doPrivileged(new PrivilegedAction<>() {
 167                             @Override
 168                             public List<FileSystemProvider> run() {
 169                                 return loadInstalledProviders();
 170                         }});
 171 
 172                     // insert the default provider at the start of the list
 173                     list.add(0, defaultProvider);
 174 
 175                     installedProviders = Collections.unmodifiableList(list);
 176                 }
 177             }
 178         }
 179         return installedProviders;
 180     }
 181 
 182     /**
 183      * Returns the URI scheme that identifies this provider.
 184      *
 185      * @return  The URI scheme
 186      */
 187     public abstract String getScheme();
 188 
 189     /**
 190      * Constructs a new {@code FileSystem} object identified by a URI. This
 191      * method is invoked by the {@link FileSystems#newFileSystem(URI,Map)}
 192      * method to open a new file system identified by a URI.
 193      *
 194      * <p> The {@code uri} parameter is an absolute, hierarchical URI, with a
 195      * scheme equal (without regard to case) to the scheme supported by this
 196      * provider. The exact form of the URI is highly provider dependent. The
 197      * {@code env} parameter is a map of provider specific properties to configure
 198      * the file system.
 199      *
 200      * <p> This method throws {@link FileSystemAlreadyExistsException} if the
 201      * file system already exists because it was previously created by an
 202      * invocation of this method. Once a file system is {@link
 203      * java.nio.file.FileSystem#close closed} it is provider-dependent if the
 204      * provider allows a new file system to be created with the same URI as a
 205      * file system it previously created.
 206      *
 207      * @param   uri
 208      *          URI reference
 209      * @param   env
 210      *          A map of provider specific properties to configure the file system;
 211      *          may be empty
 212      *
 213      * @return  A new file system
 214      *
 215      * @throws  IllegalArgumentException
 216      *          If the pre-conditions for the {@code uri} parameter aren't met,
 217      *          or the {@code env} parameter does not contain properties required
 218      *          by the provider, or a property value is invalid
 219      * @throws  IOException
 220      *          An I/O error occurs creating the file system
 221      * @throws  SecurityException
 222      *          If a security manager is installed and it denies an unspecified
 223      *          permission required by the file system provider implementation
 224      * @throws  FileSystemAlreadyExistsException
 225      *          If the file system has already been created
 226      */
 227     public abstract FileSystem newFileSystem(URI uri, Map<String,?> env)
 228         throws IOException;
 229 
 230     /**
 231      * Returns an existing {@code FileSystem} created by this provider.
 232      *
 233      * <p> This method returns a reference to a {@code FileSystem} that was
 234      * created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
 235      * method. File systems created the {@link #newFileSystem(Path,Map)
 236      * newFileSystem(Path,Map)} method are not returned by this method.
 237      * The file system is identified by its {@code URI}. Its exact form
 238      * is highly provider dependent. In the case of the default provider the URI's
 239      * path component is {@code "/"} and the authority, query and fragment components
 240      * are undefined (Undefined components are represented by {@code null}).
 241      *
 242      * <p> Once a file system created by this provider is {@link
 243      * java.nio.file.FileSystem#close closed} it is provider-dependent if this
 244      * method returns a reference to the closed file system or throws {@link
 245      * FileSystemNotFoundException}. If the provider allows a new file system to
 246      * be created with the same URI as a file system it previously created then
 247      * this method throws the exception if invoked after the file system is
 248      * closed (and before a new instance is created by the {@link #newFileSystem
 249      * newFileSystem} method).
 250      *
 251      * <p> If a security manager is installed then a provider implementation
 252      * may require to check a permission before returning a reference to an
 253      * existing file system. In the case of the {@link FileSystems#getDefault
 254      * default} file system, no permission check is required.
 255      *
 256      * @param   uri
 257      *          URI reference
 258      *
 259      * @return  The file system
 260      *
 261      * @throws  IllegalArgumentException
 262      *          If the pre-conditions for the {@code uri} parameter aren't met
 263      * @throws  FileSystemNotFoundException
 264      *          If the file system does not exist
 265      * @throws  SecurityException
 266      *          If a security manager is installed and it denies an unspecified
 267      *          permission.
 268      */
 269     public abstract FileSystem getFileSystem(URI uri);
 270 
 271     /**
 272      * Return a {@code Path} object by converting the given {@link URI}. The
 273      * resulting {@code Path} is associated with a {@link FileSystem} that
 274      * already exists or is constructed automatically.
 275      *
 276      * <p> The exact form of the URI is file system provider dependent. In the
 277      * case of the default provider, the URI scheme is {@code "file"} and the
 278      * given URI has a non-empty path component, and undefined query, and
 279      * fragment components. The resulting {@code Path} is associated with the
 280      * default {@link FileSystems#getDefault default} {@code FileSystem}.
 281      *
 282      * <p> If a security manager is installed then a provider implementation
 283      * may require to check a permission. In the case of the {@link
 284      * FileSystems#getDefault default} file system, no permission check is
 285      * required.
 286      *
 287      * @param   uri
 288      *          The URI to convert
 289      *
 290      * @return  The resulting {@code Path}
 291      *
 292      * @throws  IllegalArgumentException
 293      *          If the URI scheme does not identify this provider or other
 294      *          preconditions on the uri parameter do not hold
 295      * @throws  FileSystemNotFoundException
 296      *          The file system, identified by the URI, does not exist and
 297      *          cannot be created automatically
 298      * @throws  SecurityException
 299      *          If a security manager is installed and it denies an unspecified
 300      *          permission.
 301      */
 302     public abstract Path getPath(URI uri);
 303 
 304     /**
 305      * Constructs a new {@code FileSystem} to access the contents of a file as a
 306      * file system.
 307      *
 308      * <p> This method is intended for specialized providers of pseudo file
 309      * systems where the contents of one or more files is treated as a file
 310      * system. The {@code env} parameter is a map of provider specific properties
 311      * to configure the file system.
 312      *
 313      * <p> If this provider does not support the creation of such file systems
 314      * or if the provider does not recognize the file type of the given file then
 315      * it throws {@code UnsupportedOperationException}. The default implementation
 316      * of this method throws {@code UnsupportedOperationException}.
 317      *
 318      * @param   path
 319      *          The path to the file
 320      * @param   env
 321      *          A map of provider specific properties to configure the file system;
 322      *          may be empty
 323      *
 324      * @return  A new file system
 325      *
 326      * @throws  UnsupportedOperationException
 327      *          If this provider does not support access to the contents as a
 328      *          file system or it does not recognize the file type of the
 329      *          given file
 330      * @throws  IllegalArgumentException
 331      *          If the {@code env} parameter does not contain properties required
 332      *          by the provider, or a property value is invalid
 333      * @throws  IOException
 334      *          If an I/O error occurs
 335      * @throws  SecurityException
 336      *          If a security manager is installed and it denies an unspecified
 337      *          permission.
 338      */
 339     public FileSystem newFileSystem(Path path, Map<String,?> env)
 340         throws IOException
 341     {
 342         throw new UnsupportedOperationException();
 343     }
 344 
 345     /**
 346      * Opens a file, returning an input stream to read from the file. This
 347      * method works in exactly the manner specified by the {@link
 348      * Files#newInputStream} method.
 349      *
 350      * <p> The default implementation of this method opens a channel to the file
 351      * as if by invoking the {@link #newByteChannel} method and constructs a
 352      * stream that reads bytes from the channel. This method should be overridden
 353      * where appropriate.
 354      *
 355      * @param   path
 356      *          the path to the file to open
 357      * @param   options
 358      *          options specifying how the file is opened
 359      *
 360      * @return  a new input stream
 361      *
 362      * @throws  IllegalArgumentException
 363      *          if an invalid combination of options is specified
 364      * @throws  UnsupportedOperationException
 365      *          if an unsupported option is specified
 366      * @throws  IOException
 367      *          if an I/O error occurs
 368      * @throws  SecurityException
 369      *          In the case of the default provider, and a security manager is
 370      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 371      *          method is invoked to check read access to the file.
 372      */
 373     public InputStream newInputStream(Path path, OpenOption... options)
 374         throws IOException
 375     {
 376         if (options.length > 0) {
 377             for (OpenOption opt: options) {
 378                 // All OpenOption values except for APPEND and WRITE are allowed
 379                 if (opt == StandardOpenOption.APPEND ||
 380                     opt == StandardOpenOption.WRITE)
 381                     throw new UnsupportedOperationException("'" + opt + "' not allowed");
 382             }
 383         }
 384         return Channels.newInputStream(Files.newByteChannel(path, options));
 385     }
 386 
 387     /**
 388      * Opens or creates a file, returning an output stream that may be used to
 389      * write bytes to the file. This method works in exactly the manner
 390      * specified by the {@link Files#newOutputStream} method.
 391      *
 392      * <p> The default implementation of this method opens a channel to the file
 393      * as if by invoking the {@link #newByteChannel} method and constructs a
 394      * stream that writes bytes to the channel. This method should be overridden
 395      * where appropriate.
 396      *
 397      * @param   path
 398      *          the path to the file to open or create
 399      * @param   options
 400      *          options specifying how the file is opened
 401      *
 402      * @return  a new output stream
 403      *
 404      * @throws  IllegalArgumentException
 405      *          if {@code options} contains an invalid combination of options
 406      * @throws  UnsupportedOperationException
 407      *          if an unsupported option is specified
 408      * @throws  IOException
 409      *          if an I/O error occurs
 410      * @throws  SecurityException
 411      *          In the case of the default provider, and a security manager is
 412      *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
 413      *          method is invoked to check write access to the file. The {@link
 414      *          SecurityManager#checkDelete(String) checkDelete} method is
 415      *          invoked to check delete access if the file is opened with the
 416      *          {@code DELETE_ON_CLOSE} option.
 417      */
 418     public OutputStream newOutputStream(Path path, OpenOption... options)
 419         throws IOException
 420     {
 421         int len = options.length;
 422         Set<OpenOption> opts = new HashSet<>(len + 3);
 423         if (len == 0) {
 424             opts.add(StandardOpenOption.CREATE);
 425             opts.add(StandardOpenOption.TRUNCATE_EXISTING);
 426         } else {
 427             for (OpenOption opt: options) {
 428                 if (opt == StandardOpenOption.READ)
 429                     throw new IllegalArgumentException("READ not allowed");
 430                 opts.add(opt);
 431             }
 432         }
 433         opts.add(StandardOpenOption.WRITE);
 434         return Channels.newOutputStream(newByteChannel(path, opts));
 435     }
 436 
 437     /**
 438      * Opens or creates a file for reading and/or writing, returning a file
 439      * channel to access the file. This method works in exactly the manner
 440      * specified by the {@link FileChannel#open(Path,Set,FileAttribute[])
 441      * FileChannel.open} method. A provider that does not support all the
 442      * features required to construct a file channel throws {@code
 443      * UnsupportedOperationException}. The default provider is required to
 444      * support the creation of file channels. When not overridden, the default
 445      * implementation throws {@code UnsupportedOperationException}.
 446      *
 447      * @param   path
 448      *          the path of the file to open or create
 449      * @param   options
 450      *          options specifying how the file is opened
 451      * @param   attrs
 452      *          an optional list of file attributes to set atomically when
 453      *          creating the file
 454      *
 455      * @return  a new file channel
 456      *
 457      * @throws  IllegalArgumentException
 458      *          If the set contains an invalid combination of options
 459      * @throws  UnsupportedOperationException
 460      *          If this provider that does not support creating file channels,
 461      *          or an unsupported open option or file attribute is specified
 462      * @throws  IOException
 463      *          If an I/O error occurs
 464      * @throws  SecurityException
 465      *          In the case of the default file system, the {@link
 466      *          SecurityManager#checkRead(String)} method is invoked to check
 467      *          read access if the file is opened for reading. The {@link
 468      *          SecurityManager#checkWrite(String)} method is invoked to check
 469      *          write access if the file is opened for writing
 470      */
 471     public FileChannel newFileChannel(Path path,
 472                                       Set<? extends OpenOption> options,
 473                                       FileAttribute<?>... attrs)
 474         throws IOException
 475     {
 476         throw new UnsupportedOperationException();
 477     }
 478 
 479     /**
 480      * Opens or creates a file for reading and/or writing, returning an
 481      * asynchronous file channel to access the file. This method works in
 482      * exactly the manner specified by the {@link
 483      * AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
 484      * AsynchronousFileChannel.open} method.
 485      * A provider that does not support all the features required to construct
 486      * an asynchronous file channel throws {@code UnsupportedOperationException}.
 487      * The default provider is required to support the creation of asynchronous
 488      * file channels. When not overridden, the default implementation of this
 489      * method throws {@code UnsupportedOperationException}.
 490      *
 491      * @param   path
 492      *          the path of the file to open or create
 493      * @param   options
 494      *          options specifying how the file is opened
 495      * @param   executor
 496      *          the thread pool or {@code null} to associate the channel with
 497      *          the default thread pool
 498      * @param   attrs
 499      *          an optional list of file attributes to set atomically when
 500      *          creating the file
 501      *
 502      * @return  a new asynchronous file channel
 503      *
 504      * @throws  IllegalArgumentException
 505      *          If the set contains an invalid combination of options
 506      * @throws  UnsupportedOperationException
 507      *          If this provider that does not support creating asynchronous file
 508      *          channels, or an unsupported open option or file attribute is
 509      *          specified
 510      * @throws  IOException
 511      *          If an I/O error occurs
 512      * @throws  SecurityException
 513      *          In the case of the default file system, the {@link
 514      *          SecurityManager#checkRead(String)} method is invoked to check
 515      *          read access if the file is opened for reading. The {@link
 516      *          SecurityManager#checkWrite(String)} method is invoked to check
 517      *          write access if the file is opened for writing
 518      */
 519     public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
 520                                                               Set<? extends OpenOption> options,
 521                                                               ExecutorService executor,
 522                                                               FileAttribute<?>... attrs)
 523         throws IOException
 524     {
 525         throw new UnsupportedOperationException();
 526     }
 527 
 528     /**
 529      * Opens or creates a file, returning a seekable byte channel to access the
 530      * file. This method works in exactly the manner specified by the {@link
 531      * Files#newByteChannel(Path,Set,FileAttribute[])} method.
 532      *
 533      * @param   path
 534      *          the path to the file to open or create
 535      * @param   options
 536      *          options specifying how the file is opened
 537      * @param   attrs
 538      *          an optional list of file attributes to set atomically when
 539      *          creating the file
 540      *
 541      * @return  a new seekable byte channel
 542      *
 543      * @throws  IllegalArgumentException
 544      *          if the set contains an invalid combination of options
 545      * @throws  UnsupportedOperationException
 546      *          if an unsupported open option is specified or the array contains
 547      *          attributes that cannot be set atomically when creating the file
 548      * @throws  FileAlreadyExistsException
 549      *          if a file of that name already exists and the {@link
 550      *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
 551      *          <i>(optional specific exception)</i>
 552      * @throws  IOException
 553      *          if an I/O error occurs
 554      * @throws  SecurityException
 555      *          In the case of the default provider, and a security manager is
 556      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 557      *          method is invoked to check read access to the path if the file is
 558      *          opened for reading. The {@link SecurityManager#checkWrite(String)
 559      *          checkWrite} method is invoked to check write access to the path
 560      *          if the file is opened for writing. The {@link
 561      *          SecurityManager#checkDelete(String) checkDelete} method is
 562      *          invoked to check delete access if the file is opened with the
 563      *          {@code DELETE_ON_CLOSE} option.
 564      */
 565     public abstract SeekableByteChannel newByteChannel(Path path,
 566         Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException;
 567 
 568     /**
 569      * Opens a directory, returning a {@code DirectoryStream} to iterate over
 570      * the entries in the directory. This method works in exactly the manner
 571      * specified by the {@link
 572      * Files#newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter)}
 573      * method.
 574      *
 575      * @param   dir
 576      *          the path to the directory
 577      * @param   filter
 578      *          the directory stream filter
 579      *
 580      * @return  a new and open {@code DirectoryStream} object
 581      *
 582      * @throws  NotDirectoryException
 583      *          if the file could not otherwise be opened because it is not
 584      *          a directory <i>(optional specific exception)</i>
 585      * @throws  IOException
 586      *          if an I/O error occurs
 587      * @throws  SecurityException
 588      *          In the case of the default provider, and a security manager is
 589      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 590      *          method is invoked to check read access to the directory.
 591      */
 592     public abstract DirectoryStream<Path> newDirectoryStream(Path dir,
 593          DirectoryStream.Filter<? super Path> filter) throws IOException;
 594 
 595     /**
 596      * Creates a new directory. This method works in exactly the manner
 597      * specified by the {@link Files#createDirectory} method.
 598      *
 599      * @param   dir
 600      *          the directory to create
 601      * @param   attrs
 602      *          an optional list of file attributes to set atomically when
 603      *          creating the directory
 604      *
 605      * @throws  UnsupportedOperationException
 606      *          if the array contains an attribute that cannot be set atomically
 607      *          when creating the directory
 608      * @throws  FileAlreadyExistsException
 609      *          if a directory could not otherwise be created because a file of
 610      *          that name already exists <i>(optional specific exception)</i>
 611      * @throws  IOException
 612      *          if an I/O error occurs or the parent directory does not exist
 613      * @throws  SecurityException
 614      *          In the case of the default provider, and a security manager is
 615      *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
 616      *          method is invoked to check write access to the new directory.
 617      */
 618     public abstract void createDirectory(Path dir, FileAttribute<?>... attrs)
 619         throws IOException;
 620 
 621     /**
 622      * Creates a symbolic link to a target. This method works in exactly the
 623      * manner specified by the {@link Files#createSymbolicLink} method.
 624      *
 625      * <p> The default implementation of this method throws {@code
 626      * UnsupportedOperationException}.
 627      *
 628      * @param   link
 629      *          the path of the symbolic link to create
 630      * @param   target
 631      *          the target of the symbolic link
 632      * @param   attrs
 633      *          the array of attributes to set atomically when creating the
 634      *          symbolic link
 635      *
 636      * @throws  UnsupportedOperationException
 637      *          if the implementation does not support symbolic links or the
 638      *          array contains an attribute that cannot be set atomically when
 639      *          creating the symbolic link
 640      * @throws  FileAlreadyExistsException
 641      *          if a file with the name already exists <i>(optional specific
 642      *          exception)</i>
 643      * @throws  IOException
 644      *          if an I/O error occurs
 645      * @throws  SecurityException
 646      *          In the case of the default provider, and a security manager
 647      *          is installed, it denies {@link LinkPermission}{@code ("symbolic")}
 648      *          or its {@link SecurityManager#checkWrite(String) checkWrite}
 649      *          method denies write access to the path of the symbolic link.
 650      */
 651     public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
 652         throws IOException
 653     {
 654         throw new UnsupportedOperationException();
 655     }
 656 
 657     /**
 658      * Creates a new link (directory entry) for an existing file. This method
 659      * works in exactly the manner specified by the {@link Files#createLink}
 660      * method.
 661      *
 662      * <p> The default implementation of this method throws {@code
 663      * UnsupportedOperationException}.
 664      *
 665      * @param   link
 666      *          the link (directory entry) to create
 667      * @param   existing
 668      *          a path to an existing file
 669      *
 670      * @throws  UnsupportedOperationException
 671      *          if the implementation does not support adding an existing file
 672      *          to a directory
 673      * @throws  FileAlreadyExistsException
 674      *          if the entry could not otherwise be created because a file of
 675      *          that name already exists <i>(optional specific exception)</i>
 676      * @throws  IOException
 677      *          if an I/O error occurs
 678      * @throws  SecurityException
 679      *          In the case of the default provider, and a security manager
 680      *          is installed, it denies {@link LinkPermission}{@code ("hard")}
 681      *          or its {@link SecurityManager#checkWrite(String) checkWrite}
 682      *          method denies write access to either the  link or the
 683      *          existing file.
 684      */
 685     public void createLink(Path link, Path existing) throws IOException {
 686         throw new UnsupportedOperationException();
 687     }
 688 
 689     /**
 690      * Deletes a file. This method works in exactly the  manner specified by the
 691      * {@link Files#delete} method.
 692      *
 693      * @param   path
 694      *          the path to the file to delete
 695      *
 696      * @throws  NoSuchFileException
 697      *          if the file does not exist <i>(optional specific exception)</i>
 698      * @throws  DirectoryNotEmptyException
 699      *          if the file is a directory and could not otherwise be deleted
 700      *          because the directory is not empty <i>(optional specific
 701      *          exception)</i>
 702      * @throws  IOException
 703      *          if an I/O error occurs
 704      * @throws  SecurityException
 705      *          In the case of the default provider, and a security manager is
 706      *          installed, the {@link SecurityManager#checkDelete(String)} method
 707      *          is invoked to check delete access to the file
 708      */
 709     public abstract void delete(Path path) throws IOException;
 710 
 711     /**
 712      * Deletes a file if it exists. This method works in exactly the manner
 713      * specified by the {@link Files#deleteIfExists} method.
 714      *
 715      * <p> The default implementation of this method simply invokes {@link
 716      * #delete} ignoring the {@code NoSuchFileException} when the file does not
 717      * exist. It may be overridden where appropriate.
 718      *
 719      * @param   path
 720      *          the path to the file to delete
 721      *
 722      * @return  {@code true} if the file was deleted by this method; {@code
 723      *          false} if the file could not be deleted because it did not
 724      *          exist
 725      *
 726      * @throws  DirectoryNotEmptyException
 727      *          if the file is a directory and could not otherwise be deleted
 728      *          because the directory is not empty <i>(optional specific
 729      *          exception)</i>
 730      * @throws  IOException
 731      *          if an I/O error occurs
 732      * @throws  SecurityException
 733      *          In the case of the default provider, and a security manager is
 734      *          installed, the {@link SecurityManager#checkDelete(String)} method
 735      *          is invoked to check delete access to the file
 736      */
 737     public boolean deleteIfExists(Path path) throws IOException {
 738         try {
 739             delete(path);
 740             return true;
 741         } catch (NoSuchFileException ignore) {
 742             return false;
 743         }
 744     }
 745 
 746     /**
 747      * Reads the target of a symbolic link. This method works in exactly the
 748      * manner specified by the {@link Files#readSymbolicLink} method.
 749      *
 750      * <p> The default implementation of this method throws {@code
 751      * UnsupportedOperationException}.
 752      *
 753      * @param   link
 754      *          the path to the symbolic link
 755      *
 756      * @return  The target of the symbolic link
 757      *
 758      * @throws  UnsupportedOperationException
 759      *          if the implementation does not support symbolic links
 760      * @throws  NotLinkException
 761      *          if the target could otherwise not be read because the file
 762      *          is not a symbolic link <i>(optional specific exception)</i>
 763      * @throws  IOException
 764      *          if an I/O error occurs
 765      * @throws  SecurityException
 766      *          In the case of the default provider, and a security manager
 767      *          is installed, it checks that {@code FilePermission} has been
 768      *          granted with the "{@code readlink}" action to read the link.
 769      */
 770     public Path readSymbolicLink(Path link) throws IOException {
 771         throw new UnsupportedOperationException();
 772     }
 773 
 774     /**
 775      * Copy a file to a target file. This method works in exactly the manner
 776      * specified by the {@link Files#copy(Path,Path,CopyOption[])} method
 777      * except that both the source and target paths must be associated with
 778      * this provider.
 779      *
 780      * @param   source
 781      *          the path to the file to copy
 782      * @param   target
 783      *          the path to the target file
 784      * @param   options
 785      *          options specifying how the copy should be done
 786      *
 787      * @throws  UnsupportedOperationException
 788      *          if the array contains a copy option that is not supported
 789      * @throws  FileAlreadyExistsException
 790      *          if the target file exists but cannot be replaced because the
 791      *          {@code REPLACE_EXISTING} option is not specified <i>(optional
 792      *          specific exception)</i>
 793      * @throws  DirectoryNotEmptyException
 794      *          the {@code REPLACE_EXISTING} option is specified but the file
 795      *          cannot be replaced because it is a non-empty directory
 796      *          <i>(optional specific exception)</i>
 797      * @throws  IOException
 798      *          if an I/O error occurs
 799      * @throws  SecurityException
 800      *          In the case of the default provider, and a security manager is
 801      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 802      *          method is invoked to check read access to the source file, the
 803      *          {@link SecurityManager#checkWrite(String) checkWrite} is invoked
 804      *          to check write access to the target file. If a symbolic link is
 805      *          copied the security manager is invoked to check {@link
 806      *          LinkPermission}{@code ("symbolic")}.
 807      */
 808     public abstract void copy(Path source, Path target, CopyOption... options)
 809         throws IOException;
 810 
 811     /**
 812      * Move or rename a file to a target file. This method works in exactly the
 813      * manner specified by the {@link Files#move} method except that both the
 814      * source and target paths must be associated with this provider.
 815      *
 816      * @param   source
 817      *          the path to the file to move
 818      * @param   target
 819      *          the path to the target file
 820      * @param   options
 821      *          options specifying how the move should be done
 822      *
 823      * @throws  UnsupportedOperationException
 824      *          if the array contains a copy option that is not supported
 825      * @throws  FileAlreadyExistsException
 826      *          if the target file exists but cannot be replaced because the
 827      *          {@code REPLACE_EXISTING} option is not specified <i>(optional
 828      *          specific exception)</i>
 829      * @throws  DirectoryNotEmptyException
 830      *          the {@code REPLACE_EXISTING} option is specified but the file
 831      *          cannot be replaced because it is a non-empty directory
 832      *          <i>(optional specific exception)</i>
 833      * @throws  AtomicMoveNotSupportedException
 834      *          if the options array contains the {@code ATOMIC_MOVE} option but
 835      *          the file cannot be moved as an atomic file system operation.
 836      * @throws  IOException
 837      *          if an I/O error occurs
 838      * @throws  SecurityException
 839      *          In the case of the default provider, and a security manager is
 840      *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
 841      *          method is invoked to check write access to both the source and
 842      *          target file.
 843      */
 844     public abstract void move(Path source, Path target, CopyOption... options)
 845         throws IOException;
 846 
 847     /**
 848      * Tests if two paths locate the same file. This method works in exactly the
 849      * manner specified by the {@link Files#isSameFile} method.
 850      *
 851      * @param   path
 852      *          one path to the file
 853      * @param   path2
 854      *          the other path
 855      *
 856      * @return  {@code true} if, and only if, the two paths locate the same file
 857      *
 858      * @throws  IOException
 859      *          if an I/O error occurs
 860      * @throws  SecurityException
 861      *          In the case of the default provider, and a security manager is
 862      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 863      *          method is invoked to check read access to both files.
 864      */
 865     public abstract boolean isSameFile(Path path, Path path2)
 866         throws IOException;
 867 
 868     /**
 869      * Tells whether or not a file is considered <em>hidden</em>. This method
 870      * works in exactly the manner specified by the {@link Files#isHidden}
 871      * method.
 872      *
 873      * <p> This method is invoked by the {@link Files#isHidden isHidden} method.
 874      *
 875      * @param   path
 876      *          the path to the file to test
 877      *
 878      * @return  {@code true} if the file is considered hidden
 879      *
 880      * @throws  IOException
 881      *          if an I/O error occurs
 882      * @throws  SecurityException
 883      *          In the case of the default provider, and a security manager is
 884      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 885      *          method is invoked to check read access to the file.
 886      */
 887     public abstract boolean isHidden(Path path) throws IOException;
 888 
 889     /**
 890      * Returns the {@link FileStore} representing the file store where a file
 891      * is located. This method works in exactly the manner specified by the
 892      * {@link Files#getFileStore} method.
 893      *
 894      * @param   path
 895      *          the path to the file
 896      *
 897      * @return  the file store where the file is stored
 898      *
 899      * @throws  IOException
 900      *          if an I/O error occurs
 901      * @throws  SecurityException
 902      *          In the case of the default provider, and a security manager is
 903      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 904      *          method is invoked to check read access to the file, and in
 905      *          addition it checks
 906      *          {@link RuntimePermission}{@code ("getFileStoreAttributes")}
 907      */
 908     public abstract FileStore getFileStore(Path path) throws IOException;
 909 
 910     /**
 911      * Checks the existence, and optionally the accessibility, of a file.
 912      *
 913      * <p> This method may be used by the {@link Files#isReadable isReadable},
 914      * {@link Files#isWritable isWritable} and {@link Files#isExecutable
 915      * isExecutable} methods to check the accessibility of a file.
 916      *
 917      * <p> This method checks the existence of a file and that this Java virtual
 918      * machine has appropriate privileges that would allow it access the file
 919      * according to all of access modes specified in the {@code modes} parameter
 920      * as follows:
 921      *
 922      * <table border=1 cellpadding=5 summary="">
 923      * <tr> <th>Value</th> <th>Description</th> </tr>
 924      * <tr>
 925      *   <td> {@link AccessMode#READ READ} </td>
 926      *   <td> Checks that the file exists and that the Java virtual machine has
 927      *     permission to read the file. </td>
 928      * </tr>
 929      * <tr>
 930      *   <td> {@link AccessMode#WRITE WRITE} </td>
 931      *   <td> Checks that the file exists and that the Java virtual machine has
 932      *     permission to write to the file, </td>
 933      * </tr>
 934      * <tr>
 935      *   <td> {@link AccessMode#EXECUTE EXECUTE} </td>
 936      *   <td> Checks that the file exists and that the Java virtual machine has
 937      *     permission to {@link Runtime#exec execute} the file. The semantics
 938      *     may differ when checking access to a directory. For example, on UNIX
 939      *     systems, checking for {@code EXECUTE} access checks that the Java
 940      *     virtual machine has permission to search the directory in order to
 941      *     access file or subdirectories. </td>
 942      * </tr>
 943      * </table>
 944      *
 945      * <p> If the {@code modes} parameter is of length zero, then the existence
 946      * of the file is checked.
 947      *
 948      * <p> This method follows symbolic links if the file referenced by this
 949      * object is a symbolic link. Depending on the implementation, this method
 950      * may require to read file permissions, access control lists, or other
 951      * file attributes in order to check the effective access to the file. To
 952      * determine the effective access to a file may require access to several
 953      * attributes and so in some implementations this method may not be atomic
 954      * with respect to other file system operations.
 955      *
 956      * @param   path
 957      *          the path to the file to check
 958      * @param   modes
 959      *          The access modes to check; may have zero elements
 960      *
 961      * @throws  UnsupportedOperationException
 962      *          an implementation is required to support checking for
 963      *          {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
 964      *          exception is specified to allow for the {@code Access} enum to
 965      *          be extended in future releases.
 966      * @throws  NoSuchFileException
 967      *          if a file does not exist <i>(optional specific exception)</i>
 968      * @throws  AccessDeniedException
 969      *          the requested access would be denied or the access cannot be
 970      *          determined because the Java virtual machine has insufficient
 971      *          privileges or other reasons. <i>(optional specific exception)</i>
 972      * @throws  IOException
 973      *          if an I/O error occurs
 974      * @throws  SecurityException
 975      *          In the case of the default provider, and a security manager is
 976      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
 977      *          is invoked when checking read access to the file or only the
 978      *          existence of the file, the {@link SecurityManager#checkWrite(String)
 979      *          checkWrite} is invoked when checking write access to the file,
 980      *          and {@link SecurityManager#checkExec(String) checkExec} is invoked
 981      *          when checking execute access.
 982      */
 983     public abstract void checkAccess(Path path, AccessMode... modes)
 984         throws IOException;
 985 
 986     /**
 987      * Returns a file attribute view of a given type. This method works in
 988      * exactly the manner specified by the {@link Files#getFileAttributeView}
 989      * method.
 990      *
 991      * @param   <V>
 992      *          The {@code FileAttributeView} type
 993      * @param   path
 994      *          the path to the file
 995      * @param   type
 996      *          the {@code Class} object corresponding to the file attribute view
 997      * @param   options
 998      *          options indicating how symbolic links are handled
 999      *
1000      * @return  a file attribute view of the specified type, or {@code null} if
1001      *          the attribute view type is not available
1002      */
1003     public abstract <V extends FileAttributeView> V
1004         getFileAttributeView(Path path, Class<V> type, LinkOption... options);
1005 
1006     /**
1007      * Reads a file's attributes as a bulk operation. This method works in
1008      * exactly the manner specified by the {@link
1009      * Files#readAttributes(Path,Class,LinkOption[])} method.
1010      *
1011      * @param   <A>
1012      *          The {@code BasicFileAttributes} type
1013      * @param   path
1014      *          the path to the file
1015      * @param   type
1016      *          the {@code Class} of the file attributes required
1017      *          to read
1018      * @param   options
1019      *          options indicating how symbolic links are handled
1020      *
1021      * @return  the file attributes
1022      *
1023      * @throws  UnsupportedOperationException
1024      *          if an attributes of the given type are not supported
1025      * @throws  IOException
1026      *          if an I/O error occurs
1027      * @throws  SecurityException
1028      *          In the case of the default provider, a security manager is
1029      *          installed, its {@link SecurityManager#checkRead(String) checkRead}
1030      *          method is invoked to check read access to the file
1031      */
1032     public abstract <A extends BasicFileAttributes> A
1033         readAttributes(Path path, Class<A> type, LinkOption... options) throws IOException;
1034 
1035     /**
1036      * Reads a set of file attributes as a bulk operation. This method works in
1037      * exactly the manner specified by the {@link
1038      * Files#readAttributes(Path,String,LinkOption[])} method.
1039      *
1040      * @param   path
1041      *          the path to the file
1042      * @param   attributes
1043      *          the attributes to read
1044      * @param   options
1045      *          options indicating how symbolic links are handled
1046      *
1047      * @return  a map of the attributes returned; may be empty. The map's keys
1048      *          are the attribute names, its values are the attribute values
1049      *
1050      * @throws  UnsupportedOperationException
1051      *          if the attribute view is not available
1052      * @throws  IllegalArgumentException
1053      *          if no attributes are specified or an unrecognized attributes is
1054      *          specified
1055      * @throws  IOException
1056      *          If an I/O error occurs
1057      * @throws  SecurityException
1058      *          In the case of the default provider, and a security manager is
1059      *          installed, its {@link SecurityManager#checkRead(String) checkRead}
1060      *          method denies read access to the file. If this method is invoked
1061      *          to read security sensitive attributes then the security manager
1062      *          may be invoke to check for additional permissions.
1063      */
1064     public abstract Map<String,Object> readAttributes(Path path, String attributes,
1065                                                       LinkOption... options)
1066         throws IOException;
1067 
1068     /**
1069      * Sets the value of a file attribute. This method works in exactly the
1070      * manner specified by the {@link Files#setAttribute} method.
1071      *
1072      * @param   path
1073      *          the path to the file
1074      * @param   attribute
1075      *          the attribute to set
1076      * @param   value
1077      *          the attribute value
1078      * @param   options
1079      *          options indicating how symbolic links are handled
1080      *
1081      * @throws  UnsupportedOperationException
1082      *          if the attribute view is not available
1083      * @throws  IllegalArgumentException
1084      *          if the attribute name is not specified, or is not recognized, or
1085      *          the attribute value is of the correct type but has an
1086      *          inappropriate value
1087      * @throws  ClassCastException
1088      *          If the attribute value is not of the expected type or is a
1089      *          collection containing elements that are not of the expected
1090      *          type
1091      * @throws  IOException
1092      *          If an I/O error occurs
1093      * @throws  SecurityException
1094      *          In the case of the default provider, and a security manager is
1095      *          installed, its {@link SecurityManager#checkWrite(String) checkWrite}
1096      *          method denies write access to the file. If this method is invoked
1097      *          to set security sensitive attributes then the security manager
1098      *          may be invoked to check for additional permissions.
1099      */
1100     public abstract void setAttribute(Path path, String attribute,
1101                                       Object value, LinkOption... options)
1102         throws IOException;
1103 }