893N/A/*
3909N/A * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
893N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
893N/A *
893N/A * This code is free software; you can redistribute it and/or modify it
893N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
893N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
893N/A *
893N/A * This code is distributed in the hope that it will be useful, but WITHOUT
893N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
893N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
893N/A * version 2 for more details (a copy is included in the LICENSE file that
893N/A * accompanied this code).
893N/A *
893N/A * You should have received a copy of the GNU General Public License version
893N/A * 2 along with this work; if not, write to the Free Software Foundation,
893N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
893N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
893N/A */
893N/A
893N/Apackage java.nio.file;
893N/A
893N/Aimport java.nio.file.spi.FileSystemProvider;
893N/Aimport java.net.URI;
893N/Aimport java.io.IOException;
893N/Aimport java.security.AccessController;
893N/Aimport java.security.PrivilegedAction;
893N/Aimport java.util.*;
893N/Aimport java.lang.reflect.Constructor;
893N/A
893N/A/**
893N/A * Factory methods for file systems. This class defines the {@link #getDefault
893N/A * getDefault} method to get the default file system and factory methods to
893N/A * construct other types of file systems.
893N/A *
893N/A * <p> The first invocation of any of the methods defined by this class causes
893N/A * the default {@link FileSystemProvider provider} to be loaded. The default
893N/A * provider, identified by the URI scheme "file", creates the {@link FileSystem}
893N/A * that provides access to the file systems accessible to the Java virtual
893N/A * machine. If the process of loading or initializing the default provider fails
893N/A * then an unspecified error is thrown.
893N/A *
893N/A * <p> The first invocation of the {@link FileSystemProvider#installedProviders
893N/A * installedProviders} method, by way of invoking any of the {@code
893N/A * newFileSystem} methods defined by this class, locates and loads all
893N/A * installed file system providers. Installed providers are loaded using the
893N/A * service-provider loading facility defined by the {@link ServiceLoader} class.
893N/A * Installed providers are loaded using the system class loader. If the
893N/A * system class loader cannot be found then the extension class loader is used;
893N/A * if there is no extension class loader then the bootstrap class loader is used.
893N/A * Providers are typically installed by placing them in a JAR file on the
893N/A * application class path or in the extension directory, the JAR file contains a
893N/A * provider-configuration file named {@code java.nio.file.spi.FileSystemProvider}
893N/A * in the resource directory {@code META-INF/services}, and the file lists one or
893N/A * more fully-qualified names of concrete subclass of {@link FileSystemProvider}
893N/A * that have a zero argument constructor.
893N/A * The ordering that installed providers are located is implementation specific.
893N/A * If a provider is instantiated and its {@link FileSystemProvider#getScheme()
893N/A * getScheme} returns the same URI scheme of a provider that was previously
893N/A * instantiated then the most recently instantiated duplicate is discarded. URI
893N/A * schemes are compared without regard to case. During construction a provider
893N/A * may safely access files associated with the default provider but care needs
893N/A * to be taken to avoid circular loading of other installed providers. If
893N/A * circular loading of installed providers is detected then an unspecified error
893N/A * is thrown.
893N/A *
893N/A * <p> This class also defines factory methods that allow a {@link ClassLoader}
893N/A * to be specified when locating a provider. As with installed providers, the
893N/A * provider classes are identified by placing the provider configuration file
893N/A * in the resource directory {@code META-INF/services}.
893N/A *
893N/A * <p> If a thread initiates the loading of the installed file system providers
893N/A * and another thread invokes a method that also attempts to load the providers
893N/A * then the method will block until the loading completes.
893N/A *
893N/A * @since 1.7
893N/A */
893N/A
893N/Apublic final class FileSystems {
893N/A private FileSystems() {
893N/A }
893N/A
893N/A // lazy initialization of default file system
893N/A private static class DefaultFileSystemHolder {
893N/A static final FileSystem defaultFileSystem = defaultFileSystem();
893N/A
893N/A // returns default file system
893N/A private static FileSystem defaultFileSystem() {
893N/A // load default provider
893N/A FileSystemProvider provider = AccessController
893N/A .doPrivileged(new PrivilegedAction<FileSystemProvider>() {
893N/A public FileSystemProvider run() {
893N/A return getDefaultProvider();
893N/A }
893N/A });
893N/A
893N/A // return file system
893N/A return provider.getFileSystem(URI.create("file:///"));
893N/A }
893N/A
893N/A // returns default provider
893N/A private static FileSystemProvider getDefaultProvider() {
893N/A FileSystemProvider provider = sun.nio.fs.DefaultFileSystemProvider.create();
893N/A
893N/A // if the property java.nio.file.spi.DefaultFileSystemProvider is
893N/A // set then its value is the name of the default provider (or a list)
893N/A String propValue = System
893N/A .getProperty("java.nio.file.spi.DefaultFileSystemProvider");
893N/A if (propValue != null) {
893N/A for (String cn: propValue.split(",")) {
893N/A try {
893N/A Class<?> c = Class
893N/A .forName(cn, true, ClassLoader.getSystemClassLoader());
893N/A Constructor<?> ctor = c
893N/A .getDeclaredConstructor(FileSystemProvider.class);
893N/A provider = (FileSystemProvider)ctor.newInstance(provider);
893N/A
893N/A // must be "file"
893N/A if (!provider.getScheme().equals("file"))
893N/A throw new Error("Default provider must use scheme 'file'");
893N/A
893N/A } catch (Exception x) {
893N/A throw new Error(x);
893N/A }
893N/A }
893N/A }
893N/A return provider;
893N/A }
893N/A }
893N/A
893N/A /**
893N/A * Returns the default {@code FileSystem}. The default file system creates
893N/A * objects that provide access to the file systems accessible to the Java
893N/A * virtual machine. The <em>working directory</em> of the file system is
893N/A * the current user directory, named by the system property {@code user.dir}.
893N/A * This allows for interoperability with the {@link java.io.File java.io.File}
893N/A * class.
893N/A *
893N/A * <p> The first invocation of any of the methods defined by this class
893N/A * locates the default {@link FileSystemProvider provider} object. Where the
893N/A * system property {@code java.nio.file.spi.DefaultFileSystemProvider} is
893N/A * not defined then the default provider is a system-default provider that
893N/A * is invoked to create the default file system.
893N/A *
893N/A * <p> If the system property {@code java.nio.file.spi.DefaultFileSystemProvider}
893N/A * is defined then it is taken to be a list of one or more fully-qualified
893N/A * names of concrete provider classes identified by the URI scheme
893N/A * {@code "file"}. Where the property is a list of more than one name then
893N/A * the names are separated by a comma. Each class is loaded, using the system
893N/A * class loader, and instantiated by invoking a one argument constructor
893N/A * whose formal parameter type is {@code FileSystemProvider}. The providers
893N/A * are loaded and instantiated in the order they are listed in the property.
893N/A * If this process fails or a provider's scheme is not equal to {@code "file"}
893N/A * then an unspecified error is thrown. URI schemes are normally compared
893N/A * without regard to case but for the default provider, the scheme is
893N/A * required to be {@code "file"}. The first provider class is instantiated
893N/A * by invoking it with a reference to the system-default provider.
893N/A * The second provider class is instantiated by invoking it with a reference
893N/A * to the first provider instance. The third provider class is instantiated
893N/A * by invoking it with a reference to the second instance, and so on. The
893N/A * last provider to be instantiated becomes the default provider; its {@code
3471N/A * getFileSystem} method is invoked with the URI {@code "file:///"} to
3471N/A * get a reference to the default file system.
893N/A *
893N/A * <p> Subsequent invocations of this method return the file system that was
893N/A * returned by the first invocation.
893N/A *
893N/A * @return the default file system
893N/A */
893N/A public static FileSystem getDefault() {
893N/A return DefaultFileSystemHolder.defaultFileSystem;
893N/A }
893N/A
893N/A /**
893N/A * Returns a reference to an existing {@code FileSystem}.
893N/A *
893N/A * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
893N/A * installed} providers to locate the provider that is identified by the URI
893N/A * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
893N/A * without regard to case. The exact form of the URI is highly provider
893N/A * dependent. If found, the provider's {@link FileSystemProvider#getFileSystem
893N/A * getFileSystem} method is invoked to obtain a reference to the {@code
893N/A * FileSystem}.
893N/A *
893N/A * <p> Once a file system created by this provider is {@link FileSystem#close
893N/A * closed} it is provider-dependent if this method returns a reference to
893N/A * the closed file system or throws {@link FileSystemNotFoundException}.
893N/A * If the provider allows a new file system to be created with the same URI
893N/A * as a file system it previously created then this method throws the
893N/A * exception if invoked after the file system is closed (and before a new
893N/A * instance is created by the {@link #newFileSystem newFileSystem} method).
893N/A *
893N/A * <p> If a security manager is installed then a provider implementation
893N/A * may require to check a permission before returning a reference to an
893N/A * existing file system. In the case of the {@link FileSystems#getDefault
893N/A * default} file system, no permission check is required.
893N/A *
893N/A * @throws IllegalArgumentException
908N/A * if the pre-conditions for the {@code uri} parameter are not met
893N/A * @throws FileSystemNotFoundException
908N/A * if the file system, identified by the URI, does not exist
893N/A * @throws ProviderNotFoundException
908N/A * if a provider supporting the URI scheme is not installed
893N/A * @throws SecurityException
908N/A * if a security manager is installed and it denies an unspecified
908N/A * permission
893N/A */
893N/A public static FileSystem getFileSystem(URI uri) {
893N/A String scheme = uri.getScheme();
893N/A for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
893N/A if (scheme.equalsIgnoreCase(provider.getScheme())) {
893N/A return provider.getFileSystem(uri);
893N/A }
893N/A }
893N/A throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
893N/A }
893N/A
893N/A /**
893N/A * Constructs a new file system that is identified by a {@link URI}
893N/A *
893N/A * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
893N/A * installed} providers to locate the provider that is identified by the URI
893N/A * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
893N/A * without regard to case. The exact form of the URI is highly provider
893N/A * dependent. If found, the provider's {@link FileSystemProvider#newFileSystem(URI,Map)
893N/A * newFileSystem(URI,Map)} method is invoked to construct the new file system.
893N/A *
893N/A * <p> Once a file system is {@link FileSystem#close closed} it is
893N/A * provider-dependent if the provider allows a new file system to be created
893N/A * with the same URI as a file system it previously created.
893N/A *
893N/A * <p> <b>Usage Example:</b>
893N/A * Suppose there is a provider identified by the scheme {@code "memory"}
893N/A * installed:
893N/A * <pre>
3471N/A * Map&lt;String,String&gt; env = new HashMap&lt;&gt;();
893N/A * env.put("capacity", "16G");
893N/A * env.put("blockSize", "4k");
893N/A * FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
893N/A * </pre>
893N/A *
893N/A * @param uri
908N/A * the URI identifying the file system
893N/A * @param env
908N/A * a map of provider specific properties to configure the file system;
893N/A * may be empty
893N/A *
908N/A * @return a new file system
893N/A *
893N/A * @throws IllegalArgumentException
908N/A * if the pre-conditions for the {@code uri} parameter are not met,
893N/A * or the {@code env} parameter does not contain properties required
893N/A * by the provider, or a property value is invalid
893N/A * @throws FileSystemAlreadyExistsException
908N/A * if the file system has already been created
893N/A * @throws ProviderNotFoundException
908N/A * if a provider supporting the URI scheme is not installed
893N/A * @throws IOException
908N/A * if an I/O error occurs creating the file system
893N/A * @throws SecurityException
908N/A * if a security manager is installed and it denies an unspecified
893N/A * permission required by the file system provider implementation
893N/A */
893N/A public static FileSystem newFileSystem(URI uri, Map<String,?> env)
893N/A throws IOException
893N/A {
893N/A return newFileSystem(uri, env, null);
893N/A }
893N/A
893N/A /**
893N/A * Constructs a new file system that is identified by a {@link URI}
893N/A *
893N/A * <p> This method first attempts to locate an installed provider in exactly
893N/A * the same manner as the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
893N/A * method. If none of the installed providers support the URI scheme then an
893N/A * attempt is made to locate the provider using the given class loader. If a
893N/A * provider supporting the URI scheme is located then its {@link
893N/A * FileSystemProvider#newFileSystem(URI,Map) newFileSystem(URI,Map)} is
893N/A * invoked to construct the new file system.
893N/A *
893N/A * @param uri
908N/A * the URI identifying the file system
893N/A * @param env
908N/A * a map of provider specific properties to configure the file system;
893N/A * may be empty
893N/A * @param loader
908N/A * the class loader to locate the provider or {@code null} to only
893N/A * attempt to locate an installed provider
893N/A *
908N/A * @return a new file system
893N/A *
893N/A * @throws IllegalArgumentException
908N/A * if the pre-conditions for the {@code uri} parameter are not met,
893N/A * or the {@code env} parameter does not contain properties required
893N/A * by the provider, or a property value is invalid
893N/A * @throws FileSystemAlreadyExistsException
908N/A * if the URI scheme identifies an installed provider and the file
893N/A * system has already been created
893N/A * @throws ProviderNotFoundException
908N/A * if a provider supporting the URI scheme is not found
893N/A * @throws ServiceConfigurationError
908N/A * when an error occurs while loading a service provider
893N/A * @throws IOException
908N/A * an I/O error occurs creating the file system
893N/A * @throws SecurityException
908N/A * if a security manager is installed and it denies an unspecified
893N/A * permission required by the file system provider implementation
893N/A */
893N/A public static FileSystem newFileSystem(URI uri, Map<String,?> env, ClassLoader loader)
893N/A throws IOException
893N/A {
893N/A String scheme = uri.getScheme();
893N/A
893N/A // check installed providers
893N/A for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
893N/A if (scheme.equalsIgnoreCase(provider.getScheme())) {
893N/A return provider.newFileSystem(uri, env);
893N/A }
893N/A }
893N/A
893N/A // if not found, use service-provider loading facility
893N/A if (loader != null) {
893N/A ServiceLoader<FileSystemProvider> sl = ServiceLoader
893N/A .load(FileSystemProvider.class, loader);
893N/A for (FileSystemProvider provider: sl) {
893N/A if (scheme.equalsIgnoreCase(provider.getScheme())) {
893N/A return provider.newFileSystem(uri, env);
893N/A }
893N/A }
893N/A }
893N/A
893N/A throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
893N/A }
893N/A
893N/A /**
893N/A * Constructs a new {@code FileSystem} to access the contents of a file as a
893N/A * file system.
893N/A *
893N/A * <p> This method makes use of specialized providers that create pseudo file
893N/A * systems where the contents of one or more files is treated as a file
3471N/A * system.
893N/A *
893N/A * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
893N/A * installed} providers. It invokes, in turn, each provider's {@link
3471N/A * FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)} method
3471N/A * with an empty map. If a provider returns a file system then the iteration
3471N/A * terminates and the file system is returned. If none of the installed
3471N/A * providers return a {@code FileSystem} then an attempt is made to locate
3471N/A * the provider using the given class loader. If a provider returns a file
3471N/A * system then the lookup terminates and the file system is returned.
893N/A *
3471N/A * @param path
3471N/A * the path to the file
893N/A * @param loader
908N/A * the class loader to locate the provider or {@code null} to only
893N/A * attempt to locate an installed provider
893N/A *
908N/A * @return a new file system
893N/A *
893N/A * @throws ProviderNotFoundException
908N/A * if a provider supporting this file type cannot be located
893N/A * @throws ServiceConfigurationError
908N/A * when an error occurs while loading a service provider
893N/A * @throws IOException
908N/A * if an I/O error occurs
893N/A * @throws SecurityException
908N/A * if a security manager is installed and it denies an unspecified
908N/A * permission
893N/A */
3471N/A public static FileSystem newFileSystem(Path path,
893N/A ClassLoader loader)
893N/A throws IOException
893N/A {
3471N/A if (path == null)
893N/A throw new NullPointerException();
3471N/A Map<String,?> env = Collections.emptyMap();
893N/A
893N/A // check installed providers
893N/A for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
893N/A try {
3471N/A return provider.newFileSystem(path, env);
893N/A } catch (UnsupportedOperationException uoe) {
893N/A }
893N/A }
893N/A
893N/A // if not found, use service-provider loading facility
893N/A if (loader != null) {
893N/A ServiceLoader<FileSystemProvider> sl = ServiceLoader
893N/A .load(FileSystemProvider.class, loader);
893N/A for (FileSystemProvider provider: sl) {
893N/A try {
3471N/A return provider.newFileSystem(path, env);
893N/A } catch (UnsupportedOperationException uoe) {
893N/A }
893N/A }
893N/A }
893N/A
893N/A throw new ProviderNotFoundException("Provider not found");
893N/A }
893N/A}