--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/FileSystems.java Sun Feb 15 12:25:54 2009 +0000
@@ -0,0 +1,413 @@
+/*
+ * 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;
+
+import java.nio.file.spi.FileSystemProvider;
+import java.net.URI;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.lang.reflect.Constructor;
+
+/**
+ * Factory methods for file systems. This class defines the {@link #getDefault
+ * getDefault} method to get the default file system and factory methods to
+ * construct other types of file systems.
+ *
+ * <p> The first invocation of any of the methods defined by this class causes
+ * the default {@link FileSystemProvider provider} to be loaded. The default
+ * provider, identified by the URI scheme "file", creates the {@link FileSystem}
+ * that provides access to the file systems accessible to the Java virtual
+ * machine. If the process of loading or initializing the default provider fails
+ * then an unspecified error is thrown.
+ *
+ * <p> The first invocation of the {@link FileSystemProvider#installedProviders
+ * installedProviders} method, by way of invoking any of the {@code
+ * newFileSystem} methods defined by this class, locates and loads all
+ * installed file system providers. Installed providers are loaded using the
+ * service-provider loading facility defined by the {@link ServiceLoader} class.
+ * Installed providers are loaded using the system class loader. If the
+ * system class loader cannot be found then the extension class loader is used;
+ * if there is no extension class loader then the bootstrap class loader is used.
+ * Providers are typically installed by placing them in a JAR file on the
+ * application class path or in the extension directory, the JAR file contains a
+ * provider-configuration file named {@code java.nio.file.spi.FileSystemProvider}
+ * in the resource directory {@code META-INF/services}, and the file lists one or
+ * more fully-qualified names of concrete subclass of {@link FileSystemProvider}
+ * that have a zero argument constructor.
+ * The ordering that installed providers are located is implementation specific.
+ * If a provider is instantiated and its {@link FileSystemProvider#getScheme()
+ * getScheme} returns the same URI scheme of a provider that was previously
+ * instantiated then the most recently instantiated duplicate is discarded. URI
+ * schemes are compared without regard to case. 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.
+ *
+ * <p> This class also defines factory methods that allow a {@link ClassLoader}
+ * to be specified when locating a provider. As with installed providers, the
+ * provider classes are identified by placing the provider configuration file
+ * in the resource directory {@code META-INF/services}.
+ *
+ * <p> If a thread initiates the loading of the installed file system providers
+ * and another thread invokes a method that also attempts to load the providers
+ * then the method will block until the loading completes.
+ *
+ * @since 1.7
+ */
+
+public final class FileSystems {
+ private FileSystems() {
+ }
+
+ // lazy initialization of default file system
+ private static class DefaultFileSystemHolder {
+ static final FileSystem defaultFileSystem = defaultFileSystem();
+
+ // returns default file system
+ private static FileSystem defaultFileSystem() {
+ // load default provider
+ FileSystemProvider provider = AccessController
+ .doPrivileged(new PrivilegedAction<FileSystemProvider>() {
+ public FileSystemProvider run() {
+ return getDefaultProvider();
+ }
+ });
+
+ // return file system
+ return provider.getFileSystem(URI.create("file:///"));
+ }
+
+ // returns default provider
+ private static FileSystemProvider getDefaultProvider() {
+ FileSystemProvider provider = sun.nio.fs.DefaultFileSystemProvider.create();
+
+ // if the property java.nio.file.spi.DefaultFileSystemProvider is
+ // set then its value is the name of the default provider (or a list)
+ String propValue = System
+ .getProperty("java.nio.file.spi.DefaultFileSystemProvider");
+ if (propValue != null) {
+ for (String cn: propValue.split(",")) {
+ try {
+ Class<?> c = Class
+ .forName(cn, true, ClassLoader.getSystemClassLoader());
+ Constructor<?> ctor = c
+ .getDeclaredConstructor(FileSystemProvider.class);
+ provider = (FileSystemProvider)ctor.newInstance(provider);
+
+ // must be "file"
+ if (!provider.getScheme().equals("file"))
+ throw new Error("Default provider must use scheme 'file'");
+
+ } catch (Exception x) {
+ throw new Error(x);
+ }
+ }
+ }
+ return provider;
+ }
+ }
+
+ /**
+ * Returns the default {@code FileSystem}. The default file system creates
+ * objects that provide access to the file systems accessible to the Java
+ * virtual machine. The <em>working directory</em> of the file system is
+ * the current user directory, named by the system property {@code user.dir}.
+ * This allows for interoperability with the {@link java.io.File java.io.File}
+ * class.
+ *
+ * <p> The first invocation of any of the methods defined by this class
+ * locates the default {@link FileSystemProvider provider} object. Where the
+ * system property {@code java.nio.file.spi.DefaultFileSystemProvider} is
+ * not defined then the default provider is a system-default provider that
+ * is invoked to create the default file system.
+ *
+ * <p> If the system property {@code java.nio.file.spi.DefaultFileSystemProvider}
+ * is defined then it is taken to be a list of one or more fully-qualified
+ * names of concrete provider classes identified by the URI scheme
+ * {@code "file"}. Where the property is a list of more than one name then
+ * the names are separated by a comma. Each class is loaded, using the system
+ * class loader, and instantiated by invoking a one argument constructor
+ * whose formal parameter type is {@code FileSystemProvider}. The providers
+ * are loaded and instantiated in the order they are listed in the property.
+ * If this process fails or a provider's scheme is not equal to {@code "file"}
+ * then an unspecified error is thrown. URI schemes are normally compared
+ * without regard to case but for the default provider, the scheme is
+ * required to be {@code "file"}. The first provider class is instantiated
+ * by invoking it with a reference to the system-default provider.
+ * The second provider class is instantiated by invoking it with a reference
+ * to the first provider instance. The third provider class is instantiated
+ * by invoking it with a reference to the second instance, and so on. The
+ * last provider to be instantiated becomes the default provider; its {@code
+ * getFileSystem} method is invoked with the URI {@code "file:///"} to create
+ * the default file system.
+ *
+ * <p> Subsequent invocations of this method return the file system that was
+ * returned by the first invocation.
+ *
+ * @return the default file system
+ */
+ public static FileSystem getDefault() {
+ return DefaultFileSystemHolder.defaultFileSystem;
+ }
+
+ /**
+ * Returns a reference to an existing {@code FileSystem}.
+ *
+ * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+ * installed} providers to locate the provider that is identified by the URI
+ * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
+ * without regard to case. The exact form of the URI is highly provider
+ * dependent. If found, the provider's {@link FileSystemProvider#getFileSystem
+ * getFileSystem} method is invoked to obtain a reference to the {@code
+ * FileSystem}.
+ *
+ * <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.
+ *
+ * @throws IllegalArgumentException
+ * If the pre-conditions for the {@code uri} parameter aren't met
+ * @throws FileSystemNotFoundException
+ * If the file system, identified by the URI, does not exist
+ * @throws ProviderNotFoundException
+ * If a provider supporting the URI scheme is not installed
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission.
+ */
+ public static FileSystem getFileSystem(URI uri) {
+ String scheme = uri.getScheme();
+ for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+ if (scheme.equalsIgnoreCase(provider.getScheme())) {
+ return provider.getFileSystem(uri);
+ }
+ }
+ throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
+ }
+
+ /**
+ * Constructs a new file system that is identified by a {@link URI}
+ *
+ * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+ * installed} providers to locate the provider that is identified by the URI
+ * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
+ * without regard to case. The exact form of the URI is highly provider
+ * dependent. If found, the provider's {@link FileSystemProvider#newFileSystem(URI,Map)
+ * newFileSystem(URI,Map)} method is invoked to construct the new file system.
+ *
+ * <p> 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.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose there is a provider identified by the scheme {@code "memory"}
+ * installed:
+ * <pre>
+ * Map<String,String> env = new HashMap<String,String>();
+ * env.put("capacity", "16G");
+ * env.put("blockSize", "4k");
+ * FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
+ * </pre>
+ *
+ * @param uri
+ * The URI identifying the file system
+ * @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 FileSystemAlreadyExistsException
+ * If the file system has already been created
+ * @throws ProviderNotFoundException
+ * If a provider supporting the URI scheme is not installed
+ * @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
+ */
+ public static FileSystem newFileSystem(URI uri, Map<String,?> env)
+ throws IOException
+ {
+ return newFileSystem(uri, env, null);
+ }
+
+ /**
+ * Constructs a new file system that is identified by a {@link URI}
+ *
+ * <p> This method first attempts to locate an installed provider in exactly
+ * the same manner as the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
+ * method. If none of the installed providers support the URI scheme then an
+ * attempt is made to locate the provider using the given class loader. If a
+ * provider supporting the URI scheme is located then its {@link
+ * FileSystemProvider#newFileSystem(URI,Map) newFileSystem(URI,Map)} is
+ * invoked to construct the new file system.
+ *
+ * @param uri
+ * The URI identifying the file system
+ * @param env
+ * A map of provider specific properties to configure the file system;
+ * may be empty
+ * @param loader
+ * The class loader to locate the provider or {@code null} to only
+ * attempt to locate an installed provider
+ *
+ * @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 FileSystemAlreadyExistsException
+ * If the URI scheme identifies an installed provider and the file
+ * system has already been created
+ * @throws ProviderNotFoundException
+ * If a provider supporting the URI scheme is not found
+ * @throws ServiceConfigurationError
+ * When an error occurs while loading a service provider
+ * @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
+ */
+ public static FileSystem newFileSystem(URI uri, Map<String,?> env, ClassLoader loader)
+ throws IOException
+ {
+ String scheme = uri.getScheme();
+
+ // check installed providers
+ for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+ if (scheme.equalsIgnoreCase(provider.getScheme())) {
+ return provider.newFileSystem(uri, env);
+ }
+ }
+
+ // if not found, use service-provider loading facility
+ if (loader != null) {
+ ServiceLoader<FileSystemProvider> sl = ServiceLoader
+ .load(FileSystemProvider.class, loader);
+ for (FileSystemProvider provider: sl) {
+ if (scheme.equalsIgnoreCase(provider.getScheme())) {
+ return provider.newFileSystem(uri, env);
+ }
+ }
+ }
+
+ throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
+ }
+
+ /**
+ * Constructs a new {@code FileSystem} to access the contents of a file as a
+ * file system.
+ *
+ * <p> This method makes use of specialized providers that create 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> This method iterates over the {@link FileSystemProvider#installedProviders()
+ * installed} providers. It invokes, in turn, each provider's {@link
+ * FileSystemProvider#newFileSystem(FileRef,Map) newFileSystem(FileRef,Map)} method.
+ * If a provider returns a file system then the iteration terminates
+ * and the file system is returned. If none of the installed providers return
+ * a {@code FileSystem} then an attempt is made to locate the provider using
+ * the given class loader. If a provider returns a file system then the lookup
+ * terminates and the file system is returned.
+ *
+ * @param file
+ * A reference to a file
+ * @param env
+ * A map of provider specific properties to configure the file system;
+ * may be empty
+ * @param loader
+ * The class loader to locate the provider or {@code null} to only
+ * attempt to locate an installed provider
+ *
+ * @return A new file system
+ *
+ * @throws IllegalArgumentException
+ * If the {@code env} parameter does not contain properties required
+ * by the provider, or a property value is invalid
+ * @throws ProviderNotFoundException
+ * If a provider supporting this file type cannot be located
+ * @throws ServiceConfigurationError
+ * When an error occurs while loading a service provider
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission.
+ */
+ public static FileSystem newFileSystem(FileRef file,
+ Map<String,?> env,
+ ClassLoader loader)
+ throws IOException
+ {
+ if (file == null)
+ throw new NullPointerException();
+
+ // check installed providers
+ for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+ try {
+ return provider.newFileSystem(file, env);
+ } catch (UnsupportedOperationException uoe) {
+ }
+ }
+
+ // if not found, use service-provider loading facility
+ if (loader != null) {
+ ServiceLoader<FileSystemProvider> sl = ServiceLoader
+ .load(FileSystemProvider.class, loader);
+ for (FileSystemProvider provider: sl) {
+ try {
+ return provider.newFileSystem(file, env);
+ } catch (UnsupportedOperationException uoe) {
+ }
+ }
+ }
+
+ throw new ProviderNotFoundException("Provider not found");
+ }
+}