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 instaled providers
85     private static boolean loadingProviders  = false;
86 
checkPermission()87     private static Void checkPermission() {
88         SecurityManager sm = System.getSecurityManager();
89         if (sm != null)
90             sm.checkPermission(new RuntimePermission("fileSystemProvider"));
91         return null;
92     }
FileSystemProvider(Void ignore)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}<tt>("fileSystemProvider")</tt>
106      */
FileSystemProvider()107     protected FileSystemProvider() {
108         this(checkPermission());
109     }
110 
111     // loads all installed providers
loadInstalledProviders()112     private static List<FileSystemProvider> loadInstalledProviders() {
113         List<FileSystemProvider> list = new ArrayList<FileSystemProvider>();
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      */
installedProviders()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<List<FileSystemProvider>>() {
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      */
getScheme()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      */
newFileSystem(URI uri, Map<String,?> env)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      */
getFileSystem(URI uri)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      */
getPath(URI uri)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      */
newFileSystem(Path path, Map<String,?> env)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      */
newInputStream(Path path, OpenOption... options)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      */
newOutputStream(Path path, OpenOption... options)418     public OutputStream newOutputStream(Path path, OpenOption... options)
419         throws IOException
420     {
421         int len = options.length;
422         Set<OpenOption> opts = new HashSet<OpenOption>(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      */
newFileChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs)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      */
newAsynchronousFileChannel(Path path, Set<? extends OpenOption> options, ExecutorService executor, FileAttribute<?>... attrs)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      */
newByteChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs)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      */
newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter)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      */
createDirectory(Path dir, FileAttribute<?>... attrs)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}<tt>("symbolic")</tt>
648      *          or its {@link SecurityManager#checkWrite(String) checkWrite}
649      *          method denies write access to the path of the symbolic link.
650      */
createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)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}<tt>("hard")</tt>
681      *          or its {@link SecurityManager#checkWrite(String) checkWrite}
682      *          method denies write access to either the  link or the
683      *          existing file.
684      */
createLink(Path link, Path existing)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      */
delete(Path path)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      */
deleteIfExists(Path path)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      */
readSymbolicLink(Path link)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      */
copy(Path source, Path target, CopyOption... options)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      */
move(Path source, Path target, CopyOption... options)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      */
isSameFile(Path path, Path path2)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      */
isHidden(Path path)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 {@link RuntimePermission}<tt>
906      *          ("getFileStoreAttributes")</tt>
907      */
getFileStore(Path path)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      */
checkAccess(Path path, AccessMode... modes)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
getFileAttributeView(Path path, Class<V> type, LinkOption... options)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
readAttributes(Path path, Class<A> type, LinkOption... options)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      */
readAttributes(Path path, String attributes, LinkOption... options)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      */
setAttribute(Path path, String attribute, Object value, LinkOption... options)1100     public abstract void setAttribute(Path path, String attribute,
1101                                       Object value, LinkOption... options)
1102         throws IOException;
1103 }
1104