1/*
2 * Copyright (c) 2007, 2017, 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
26package java.nio.file.spi;
27
28import java.nio.file.*;
29import java.nio.file.attribute.*;
30import java.nio.channels.*;
31import java.net.URI;
32import java.io.InputStream;
33import java.io.OutputStream;
34import java.io.IOException;
35import java.util.*;
36import java.util.concurrent.ExecutorService;
37import java.security.AccessController;
38import 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
77public 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 class="striped">
923     * <caption style="display:none">Access Modes</caption>
924     * <thead>
925     * <tr> <th>Value</th> <th>Description</th> </tr>
926     * </thead>
927     * <tbody>
928     * <tr>
929     *   <td> {@link AccessMode#READ READ} </td>
930     *   <td> Checks that the file exists and that the Java virtual machine has
931     *     permission to read the file. </td>
932     * </tr>
933     * <tr>
934     *   <td> {@link AccessMode#WRITE WRITE} </td>
935     *   <td> Checks that the file exists and that the Java virtual machine has
936     *     permission to write to the file, </td>
937     * </tr>
938     * <tr>
939     *   <td> {@link AccessMode#EXECUTE EXECUTE} </td>
940     *   <td> Checks that the file exists and that the Java virtual machine has
941     *     permission to {@link Runtime#exec execute} the file. The semantics
942     *     may differ when checking access to a directory. For example, on UNIX
943     *     systems, checking for {@code EXECUTE} access checks that the Java
944     *     virtual machine has permission to search the directory in order to
945     *     access file or subdirectories. </td>
946     * </tr>
947     * </tbody>
948     * </table>
949     *
950     * <p> If the {@code modes} parameter is of length zero, then the existence
951     * of the file is checked.
952     *
953     * <p> This method follows symbolic links if the file referenced by this
954     * object is a symbolic link. Depending on the implementation, this method
955     * may require to read file permissions, access control lists, or other
956     * file attributes in order to check the effective access to the file. To
957     * determine the effective access to a file may require access to several
958     * attributes and so in some implementations this method may not be atomic
959     * with respect to other file system operations.
960     *
961     * @param   path
962     *          the path to the file to check
963     * @param   modes
964     *          The access modes to check; may have zero elements
965     *
966     * @throws  UnsupportedOperationException
967     *          an implementation is required to support checking for
968     *          {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
969     *          exception is specified to allow for the {@code Access} enum to
970     *          be extended in future releases.
971     * @throws  NoSuchFileException
972     *          if a file does not exist <i>(optional specific exception)</i>
973     * @throws  AccessDeniedException
974     *          the requested access would be denied or the access cannot be
975     *          determined because the Java virtual machine has insufficient
976     *          privileges or other reasons. <i>(optional specific exception)</i>
977     * @throws  IOException
978     *          if an I/O error occurs
979     * @throws  SecurityException
980     *          In the case of the default provider, and a security manager is
981     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
982     *          is invoked when checking read access to the file or only the
983     *          existence of the file, the {@link SecurityManager#checkWrite(String)
984     *          checkWrite} is invoked when checking write access to the file,
985     *          and {@link SecurityManager#checkExec(String) checkExec} is invoked
986     *          when checking execute access.
987     */
988    public abstract void checkAccess(Path path, AccessMode... modes)
989        throws IOException;
990
991    /**
992     * Returns a file attribute view of a given type. This method works in
993     * exactly the manner specified by the {@link Files#getFileAttributeView}
994     * method.
995     *
996     * @param   <V>
997     *          The {@code FileAttributeView} type
998     * @param   path
999     *          the path to the file
1000     * @param   type
1001     *          the {@code Class} object corresponding to the file attribute view
1002     * @param   options
1003     *          options indicating how symbolic links are handled
1004     *
1005     * @return  a file attribute view of the specified type, or {@code null} if
1006     *          the attribute view type is not available
1007     */
1008    public abstract <V extends FileAttributeView> V
1009        getFileAttributeView(Path path, Class<V> type, LinkOption... options);
1010
1011    /**
1012     * Reads a file's attributes as a bulk operation. This method works in
1013     * exactly the manner specified by the {@link
1014     * Files#readAttributes(Path,Class,LinkOption[])} method.
1015     *
1016     * @param   <A>
1017     *          The {@code BasicFileAttributes} type
1018     * @param   path
1019     *          the path to the file
1020     * @param   type
1021     *          the {@code Class} of the file attributes required
1022     *          to read
1023     * @param   options
1024     *          options indicating how symbolic links are handled
1025     *
1026     * @return  the file attributes
1027     *
1028     * @throws  UnsupportedOperationException
1029     *          if an attributes of the given type are not supported
1030     * @throws  IOException
1031     *          if an I/O error occurs
1032     * @throws  SecurityException
1033     *          In the case of the default provider, a security manager is
1034     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
1035     *          method is invoked to check read access to the file
1036     */
1037    public abstract <A extends BasicFileAttributes> A
1038        readAttributes(Path path, Class<A> type, LinkOption... options) throws IOException;
1039
1040    /**
1041     * Reads a set of file attributes as a bulk operation. This method works in
1042     * exactly the manner specified by the {@link
1043     * Files#readAttributes(Path,String,LinkOption[])} method.
1044     *
1045     * @param   path
1046     *          the path to the file
1047     * @param   attributes
1048     *          the attributes to read
1049     * @param   options
1050     *          options indicating how symbolic links are handled
1051     *
1052     * @return  a map of the attributes returned; may be empty. The map's keys
1053     *          are the attribute names, its values are the attribute values
1054     *
1055     * @throws  UnsupportedOperationException
1056     *          if the attribute view is not available
1057     * @throws  IllegalArgumentException
1058     *          if no attributes are specified or an unrecognized attributes is
1059     *          specified
1060     * @throws  IOException
1061     *          If an I/O error occurs
1062     * @throws  SecurityException
1063     *          In the case of the default provider, and a security manager is
1064     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
1065     *          method denies read access to the file. If this method is invoked
1066     *          to read security sensitive attributes then the security manager
1067     *          may be invoke to check for additional permissions.
1068     */
1069    public abstract Map<String,Object> readAttributes(Path path, String attributes,
1070                                                      LinkOption... options)
1071        throws IOException;
1072
1073    /**
1074     * Sets the value of a file attribute. This method works in exactly the
1075     * manner specified by the {@link Files#setAttribute} method.
1076     *
1077     * @param   path
1078     *          the path to the file
1079     * @param   attribute
1080     *          the attribute to set
1081     * @param   value
1082     *          the attribute value
1083     * @param   options
1084     *          options indicating how symbolic links are handled
1085     *
1086     * @throws  UnsupportedOperationException
1087     *          if the attribute view is not available
1088     * @throws  IllegalArgumentException
1089     *          if the attribute name is not specified, or is not recognized, or
1090     *          the attribute value is of the correct type but has an
1091     *          inappropriate value
1092     * @throws  ClassCastException
1093     *          If the attribute value is not of the expected type or is a
1094     *          collection containing elements that are not of the expected
1095     *          type
1096     * @throws  IOException
1097     *          If an I/O error occurs
1098     * @throws  SecurityException
1099     *          In the case of the default provider, and a security manager is
1100     *          installed, its {@link SecurityManager#checkWrite(String) checkWrite}
1101     *          method denies write access to the file. If this method is invoked
1102     *          to set security sensitive attributes then the security manager
1103     *          may be invoked to check for additional permissions.
1104     */
1105    public abstract void setAttribute(Path path, String attribute,
1106                                      Object value, LinkOption... options)
1107        throws IOException;
1108}
1109