--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java Sun Feb 15 12:25:54 2009 +0000
@@ -0,0 +1,434 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.spi;
+
+import java.nio.file.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.channels.*;
+import java.net.URI;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.io.IOException;
+
+/**
+ * Service-provider class for file systems.
+ *
+ * <p> A file system provider is a concrete implementation of this class that
+ * implements the abstract methods defined by this class. A provider is
+ * identified by a {@code URI} {@link #getScheme() scheme}. The default provider
+ * is identified by the URI scheme "file". It creates the {@link FileSystem} that
+ * provides access to the file systems accessible to the Java virtual machine.
+ * The {@link FileSystems} class defines how file system providers are located
+ * and loaded. The default provider is typically a system-default provider but
+ * may be overridden if the system property {@code
+ * java.nio.file.spi.DefaultFileSystemProvider} is set. In that case, the
+ * provider has a one argument constructor whose formal parameter type is {@code
+ * FileSystemProvider}. All other providers have a zero argument constructor
+ * that initializes the provider.
+ *
+ * <p> A provider is a factory for one or more {@link FileSystem} instances. Each
+ * file system is identified by a {@code URI} where the URI's scheme matches
+ * the provider's {@link #getScheme scheme}. The default file system, for example,
+ * is identified by the URI {@code "file:///"}. A memory-based file system,
+ * for example, may be identified by a URI such as {@code "memory:///?name=logfs"}.
+ * The {@link #newFileSystem newFileSystem} method may be used to create a file
+ * system, and the {@link #getFileSystem getFileSystem} method may be used to
+ * obtain a reference to an existing file system created by the provider. Where
+ * a provider is the factory for a single file system then it is provider dependent
+ * if the file system is created when the provider is initialized, or later when
+ * the {@code newFileSystem} method is invoked. In the case of the default
+ * provider, the {@code FileSystem} is created when the provider is initialized.
+ *
+ * <p> In addition to file systems, a provider is also a factory for {@link
+ * FileChannel} and {@link AsynchronousFileChannel} channels. The {@link
+ * #newFileChannel newFileChannel} and {@link #newAsynchronousFileChannel
+ * AsynchronousFileChannel} methods are defined to open or create files, returning
+ * a channel to access the file. These methods are invoked by static factory
+ * methods defined in the {@link java.nio.channels} package.
+ *
+ * <p> All of the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public abstract class FileSystemProvider {
+ // lock using when loading providers
+ private static final Object lock = new Object();
+
+ // installed providers
+ private static volatile List<FileSystemProvider> installedProviders;
+
+ // used to avoid recursive loading of instaled providers
+ private static boolean loadingProviders = false;
+
+ private static Void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("fileSystemProvider"));
+ return null;
+ }
+ private FileSystemProvider(Void ignore) { }
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * <p> During construction a provider may safely access files associated
+ * with the default provider but care needs to be taken to avoid circular
+ * loading of other installed providers. If circular loading of installed
+ * providers is detected then an unspecified error is thrown.
+ *
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link RuntimePermission}<tt>("fileSystemProvider")</tt>
+ */
+ protected FileSystemProvider() {
+ this(checkPermission());
+ }
+
+ // loads all installed providers
+ private static List<FileSystemProvider> loadInstalledProviders() {
+ List<FileSystemProvider> list = new ArrayList<FileSystemProvider>();
+
+ ServiceLoader<FileSystemProvider> sl = ServiceLoader
+ .load(FileSystemProvider.class, ClassLoader.getSystemClassLoader());
+
+ // ServiceConfigurationError may be throw here
+ for (FileSystemProvider provider: sl) {
+ String scheme = provider.getScheme();
+
+ // add to list if the provider is not "file" and isn't a duplicate
+ if (!scheme.equalsIgnoreCase("file")) {
+ boolean found = false;
+ for (FileSystemProvider p: list) {
+ if (p.getScheme().equalsIgnoreCase(scheme)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ list.add(provider);
+ }
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns a list of the installed file system providers.
+ *
+ * <p> The first invocation of this method causes the default provider to be
+ * initialized (if not already initialized) and loads any other installed
+ * providers as described by the {@link FileSystems} class.
+ *
+ * @return An unmodifiable list of the installed file system providers. The
+ * list contains at least one element, that is the default file
+ * system provider
+ *
+ * @throws ServiceConfigurationError
+ * When an error occurs while loading a service provider
+ */
+ public static List<FileSystemProvider> installedProviders() {
+ if (installedProviders == null) {
+ // ensure default provider is initialized
+ FileSystemProvider defaultProvider = FileSystems.getDefault().provider();
+
+ synchronized (lock) {
+ if (installedProviders == null) {
+ if (loadingProviders) {
+ throw new Error("Circular loading of installed providers detected");
+ }
+ loadingProviders = true;
+
+ List<FileSystemProvider> list = AccessController
+ .doPrivileged(new PrivilegedAction<List<FileSystemProvider>>() {
+ @Override
+ public List<FileSystemProvider> run() {
+ return loadInstalledProviders();
+ }});
+
+ // insert the default provider at the start of the list
+ list.add(0, defaultProvider);
+
+ installedProviders = Collections.unmodifiableList(list);
+ }
+ }
+ }
+ return installedProviders;
+ }
+
+ /**
+ * Returns the URI scheme that identifies this provider.
+ *
+ * @return The URI scheme
+ */
+ public abstract String getScheme();
+
+ /**
+ * Constructs a new {@code FileSystem} object identified by a URI. This
+ * method is invoked by the {@link FileSystems#newFileSystem(URI,Map)}
+ * method to open a new file system identified by a URI.
+ *
+ * <p> The {@code uri} parameter is an absolute, hierarchical URI, with a
+ * scheme equal (without regard to case) to the scheme supported by this
+ * provider. The exact form of the URI is highly provider dependent. The
+ * {@code env} parameter is a map of provider specific properties to configure
+ * the file system.
+ *
+ * <p> This method throws {@link FileSystemAlreadyExistsException} if the
+ * file system already exists because it was previously created by an
+ * invocation of this method. Once a file system is {@link FileSystem#close
+ * closed} it is provider-dependent if the provider allows a new file system
+ * to be created with the same URI as a file system it previously created.
+ *
+ * @param uri
+ * URI reference
+ * @param env
+ * A map of provider specific properties to configure the file system;
+ * may be empty
+ *
+ * @return A new file system
+ *
+ * @throws IllegalArgumentException
+ * If the pre-conditions for the {@code uri} parameter aren't met,
+ * or the {@code env} parameter does not contain properties required
+ * by the provider, or a property value is invalid
+ * @throws IOException
+ * An I/O error occurs creating the file system
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission required by the file system provider implementation
+ * @throws FileSystemAlreadyExistsException
+ * If the file system has already been created
+ */
+ public abstract FileSystem newFileSystem(URI uri, Map<String,?> env)
+ throws IOException;
+
+ /**
+ * Returns an existing {@code FileSystem} created by this provider.
+ *
+ * <p> This method returns a reference to a {@code FileSystem} that was
+ * created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
+ * method. File systems created the {@link #newFileSystem(FileRef,Map)
+ * newFileSystem(FileRef,Map)} method are not returned by this method.
+ * The file system is identified by its {@code URI}. Its exact form
+ * is highly provider dependent. In the case of the default provider the URI's
+ * path component is {@code "/"} and the authority, query and fragment components
+ * are undefined (Undefined components are represented by {@code null}).
+ *
+ * <p> Once a file system created by this provider is {@link FileSystem#close
+ * closed} it is provider-dependent if this method returns a reference to
+ * the closed file system or throws {@link FileSystemNotFoundException}.
+ * If the provider allows a new file system to be created with the same URI
+ * as a file system it previously created then this method throws the
+ * exception if invoked after the file system is closed (and before a new
+ * instance is created by the {@link #newFileSystem newFileSystem} method).
+ *
+ * <p> If a security manager is installed then a provider implementation
+ * may require to check a permission before returning a reference to an
+ * existing file system. In the case of the {@link FileSystems#getDefault
+ * default} file system, no permission check is required.
+ *
+ * @param uri
+ * URI reference
+ *
+ * @return The file system
+ *
+ * @throws IllegalArgumentException
+ * If the pre-conditions for the {@code uri} parameter aren't met
+ * @throws FileSystemNotFoundException
+ * If the file system does not exist
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission.
+ */
+ public abstract FileSystem getFileSystem(URI uri);
+
+ /**
+ * Return a {@code Path} object by converting the given {@link URI}.
+ *
+ * <p> The exact form of the URI is file system provider dependent. In the
+ * case of the default provider, the URI scheme is {@code "file"} and the
+ * given URI has a non-empty path component, and undefined query, and
+ * fragment components. The resulting {@code Path} is associated with the
+ * default {@link FileSystems#getDefault default} {@code FileSystem}.
+ *
+ * <p> If a security manager is installed then a provider implementation
+ * may require to check a permission. In the case of the {@link
+ * FileSystems#getDefault default} file system, no permission check is
+ * required.
+ *
+ * @param uri
+ * The URI to convert
+ *
+ * @throws IllegalArgumentException
+ * If the URI scheme does not identify this provider or other
+ * preconditions on the uri parameter do not hold
+ * @throws FileSystemNotFoundException
+ * The file system, identified by the URI, does not exist
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission.
+ */
+ public abstract Path getPath(URI uri);
+
+ /**
+ * Constructs a new {@code FileSystem} to access the contents of a file as a
+ * file system.
+ *
+ * <p> This method is intended for specialized providers of pseudo file
+ * systems where the contents of one or more files is treated as a file
+ * system. The {@code file} parameter is a reference to an existing file
+ * and the {@code env} parameter is a map of provider specific properties to
+ * configure the file system.
+ *
+ * <p> If this provider does not support the creation of such file systems
+ * or if the provider does not recognize the file type of the given file then
+ * it throws {@code UnsupportedOperationException}. The default implementation
+ * of this method throws {@code UnsupportedOperationException}.
+ *
+ * @param file
+ * The file
+ * @param env
+ * A map of provider specific properties to configure the file system;
+ * may be empty
+ *
+ * @return A new file system
+ *
+ * @throws UnsupportedOperationException
+ * If this provider does not support access to the contents as a
+ * file system or it does not recognize the file type of the
+ * given file
+ * @throws IllegalArgumentException
+ * If the {@code env} parameter does not contain properties required
+ * by the provider, or a property value is invalid
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission.
+ */
+ public FileSystem newFileSystem(FileRef file, Map<String,?> env)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Opens or creates a file for reading and/or writing, returning a file
+ * channel to access the file.
+ *
+ * <p> This method is invoked by the {@link FileChannel#open(Path,Set,FileAttribute[])
+ * FileChannel.open} method to open a file channel. A provider that does not
+ * support all the features required to construct a file channel throws
+ * {@code UnsupportedOperationException}. The default provider is required
+ * to support the creation of file channels. When not overridden, the
+ * default implementation throws {@code UnsupportedOperationException}.
+ *
+ * @param path
+ * The path of the file to open or create
+ * @param options
+ * Options specifying how the file is opened
+ * @param attrs
+ * An optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return A new file channel
+ *
+ * @throws IllegalArgumentException
+ * If the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * If this provider that does not support creating file channels,
+ * or an unsupported open option or file attribute is specified
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default file system, the {@link
+ * SecurityManager#checkRead(String)} method is invoked to check
+ * read access if the file is opened for reading. The {@link
+ * SecurityManager#checkWrite(String)} method is invoked to check
+ * write access if the file is opened for writing
+ */
+ public FileChannel newFileChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Opens or creates a file for reading and/or writing, returning an
+ * asynchronous file channel to access the file.
+ *
+ * <p> This method is invoked by the {@link
+ * AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
+ * AsynchronousFileChannel.open} method to open an asynchronous file channel.
+ * A provider that does not support all the features required to construct
+ * an asynchronous file channel throws {@code UnsupportedOperationException}.
+ * The default provider is required to support the creation of asynchronous
+ * file channels. When not overridden, the default implementation of this
+ * method throws {@code UnsupportedOperationException}.
+ *
+ * @param path
+ * The path of the file to open or create
+ * @param options
+ * Options specifying how the file is opened
+ * @param executor
+ * The thread pool or {@code null} to associate the channel with
+ * the default thread pool
+ * @param attrs
+ * An optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return A new asynchronous file channel
+ *
+ * @throws IllegalArgumentException
+ * If the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * If this provider that does not support creating asynchronous file
+ * channels, or an unsupported open option or file attribute is
+ * specified
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default file system, the {@link
+ * SecurityManager#checkRead(String)} method is invoked to check
+ * read access if the file is opened for reading. The {@link
+ * SecurityManager#checkWrite(String)} method is invoked to check
+ * write access if the file is opened for writing
+ */
+ public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
+ Set<? extends OpenOption> options,
+ ExecutorService executor,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+}