/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.vfs2.impl;
import java.io.File;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs2.CacheStrategy;
import org.apache.commons.vfs2.Capability;
import org.apache.commons.vfs2.FileContentInfoFactory;
import org.apache.commons.vfs2.FileName;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystem;
import org.apache.commons.vfs2.FileSystemConfigBuilder;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.FilesCache;
import org.apache.commons.vfs2.NameScope;
import org.apache.commons.vfs2.VFS;
import org.apache.commons.vfs2.cache.SoftRefFilesCache;
import org.apache.commons.vfs2.operations.FileOperationProvider;
import org.apache.commons.vfs2.provider.AbstractFileName;
import org.apache.commons.vfs2.provider.AbstractFileProvider;
import org.apache.commons.vfs2.provider.DefaultURLStreamHandler;
import org.apache.commons.vfs2.provider.FileProvider;
import org.apache.commons.vfs2.provider.FileReplicator;
import org.apache.commons.vfs2.provider.LocalFileProvider;
import org.apache.commons.vfs2.provider.TemporaryFileStore;
import org.apache.commons.vfs2.provider.UriParser;
import org.apache.commons.vfs2.provider.VfsComponent;
The default file system manager implementation.
/**
* The default file system manager implementation.
*/
public class DefaultFileSystemManager implements FileSystemManager, AutoCloseable {
Mapping from URI scheme to FileProvider.
/**
* Mapping from URI scheme to FileProvider.
*/
private final Map<String, FileProvider> providers = new HashMap<>();
List of the schemes of virtual file systems added.
/**
* List of the schemes of virtual file systems added.
*/
private final List<String> virtualFileSystemSchemes = new ArrayList<>();
All components used by this manager.
/**
* All components used by this manager.
*/
private final ArrayList<Object> components = new ArrayList<>();
The context to pass to providers.
/**
* The context to pass to providers.
*/
private final DefaultVfsComponentContext context = new DefaultVfsComponentContext(this);
Operations providers added to this manager.
/**
* Operations providers added to this manager.
*/
private final Map<String, List<FileOperationProvider>> operationProviders = new HashMap<>();
Mappings of file types.
/**
* Mappings of file types.
*/
private final FileTypeMap typeMap = new FileTypeMap();
The provider for local files.
/**
* The provider for local files.
*/
private LocalFileProvider localFileProvider;
The default provider.
/**
* The default provider.
*/
private FileProvider defaultProvider;
The file replicator to use.
/**
* The file replicator to use.
*/
private FileReplicator fileReplicator;
The base file to use for relative URI.
/**
* The base file to use for relative URI.
*/
private FileObject baseFile;
The files cache
/**
* The files cache
*/
private FilesCache filesCache;
The cache strategy
/**
* The cache strategy
*/
private CacheStrategy fileCacheStrategy;
Class which decorates all returned fileObjects
/**
* Class which decorates all returned fileObjects
*/
private Class<?> fileObjectDecorator;
Reflection constructor extracted from fileObjectDecorator
/**
* Reflection constructor extracted from {@link #fileObjectDecorator}
*/
private Constructor<?> fileObjectDecoratorConst;
The class to use to determine the content-type (mime-type)
/**
* The class to use to determine the content-type (mime-type)
*/
private FileContentInfoFactory fileContentInfoFactory;
The logger to use. Default implementation.
/**
* The logger to use. Default implementation.
*/
private Log log = LogFactory.getLog(getClass());
The temporary file store to use.
/**
* The temporary file store to use.
*/
private TemporaryFileStore tempFileStore;
The virtual file provider.
/**
* The virtual file provider.
*/
private VirtualFileProvider vfsProvider;
Flag, if manager is initialized (after init() and before close()).
/**
* Flag, if manager is initialized (after init() and before close()).
*/
private boolean init;
Returns the logger used by this manager.
Returns: the Logger.
/**
* Returns the logger used by this manager.
*
* @return the Logger.
*/
protected Log getLogger() {
return log;
}
Registers a file system provider.
The manager takes care of all lifecycle management. A provider may be registered multiple times. The first LocalFileProvider
added will be remembered for getLocalFileProvider()
.
Params: - urlScheme – The scheme the provider will handle.
- provider – The provider.
Throws: - FileSystemException – if an error occurs adding the provider.
/**
* Registers a file system provider.
* <p>
* The manager takes care of all lifecycle management. A provider may be registered multiple times. The first
* {@link LocalFileProvider} added will be remembered for {@link #getLocalFileProvider()}.
*
* @param urlScheme The scheme the provider will handle.
* @param provider The provider.
* @throws FileSystemException if an error occurs adding the provider.
*/
public void addProvider(final String urlScheme, final FileProvider provider) throws FileSystemException {
addProvider(new String[] { urlScheme }, provider);
}
Registers a file system provider.
The manager takes care of all lifecycle management. A provider may be registered multiple times. The first LocalFileProvider
added will be remembered for getLocalFileProvider()
.
Params: - urlSchemes – The schemes the provider will handle.
- provider – The provider.
Throws: - FileSystemException – if an error occurs adding the provider.
/**
* Registers a file system provider.
* <p>
* The manager takes care of all lifecycle management. A provider may be registered multiple times. The first
* {@link LocalFileProvider} added will be remembered for {@link #getLocalFileProvider()}.
*
* @param urlSchemes The schemes the provider will handle.
* @param provider The provider.
* @throws FileSystemException if an error occurs adding the provider.
*/
public void addProvider(final String[] urlSchemes, final FileProvider provider) throws FileSystemException {
// fail duplicate schemes
for (final String scheme : urlSchemes) {
if (providers.containsKey(scheme)) {
throw new FileSystemException("vfs.impl/multiple-providers-for-scheme.error", scheme);
}
}
// Contextualise the component (if not already)
setupComponent(provider);
// Add to map
for (final String scheme : urlSchemes) {
providers.put(scheme, provider);
}
if (provider instanceof LocalFileProvider && localFileProvider == null) {
localFileProvider = (LocalFileProvider) provider;
}
}
Returns true if this manager has a provider for a particular scheme.
Params: - scheme – The scheme to check.
Returns: true if a provider is configured for this scheme, false otherwise.
/**
* Returns true if this manager has a provider for a particular scheme.
*
* @param scheme The scheme to check.
* @return true if a provider is configured for this scheme, false otherwise.
*/
@Override
public boolean hasProvider(final String scheme) {
return providers.containsKey(scheme);
}
Adds an file name extension mapping.
Params: - extension – The file name extension.
- scheme – The scheme to use for files with this extension.
/**
* Adds an file name extension mapping.
*
* @param extension The file name extension.
* @param scheme The scheme to use for files with this extension.
*/
public void addExtensionMap(final String extension, final String scheme) {
typeMap.addExtension(extension, scheme);
}
Adds a mime type mapping.
Params: - mimeType – The mime type.
- scheme – The scheme to use for files with this mime type.
/**
* Adds a mime type mapping.
*
* @param mimeType The mime type.
* @param scheme The scheme to use for files with this mime type.
*/
public void addMimeTypeMap(final String mimeType, final String scheme) {
typeMap.addMimeType(mimeType, scheme);
}
Sets the default provider. This is the provider that will handle URI with unknown schemes. The manager takes care
of all lifecycle management.
Params: - provider – The FileProvider.
Throws: - FileSystemException – if an error occurs setting the provider.
/**
* Sets the default provider. This is the provider that will handle URI with unknown schemes. The manager takes care
* of all lifecycle management.
*
* @param provider The FileProvider.
* @throws FileSystemException if an error occurs setting the provider.
*/
public void setDefaultProvider(final FileProvider provider) throws FileSystemException {
setupComponent(provider);
defaultProvider = provider;
}
Returns the filesCache implementation used to cache files.
Returns: The FilesCache.
/**
* Returns the filesCache implementation used to cache files.
*
* @return The FilesCache.
*/
@Override
public FilesCache getFilesCache() {
return filesCache;
}
Sets the filesCache implementation used to cache files.
Can only be set before the FileSystemManager is initialized.
The manager takes care of the lifecycle. If none is set, a default is picked in init()
.
Params: - filesCache – The FilesCache.
Throws: - FileSystemException – if an error occurs setting the cache..
/**
* Sets the filesCache implementation used to cache files.
* <p>
* Can only be set before the FileSystemManager is initialized.
* <p>
* The manager takes care of the lifecycle. If none is set, a default is picked in {@link #init()}.
*
* @param filesCache The FilesCache.
* @throws FileSystemException if an error occurs setting the cache..
*/
public void setFilesCache(final FilesCache filesCache) throws FileSystemException {
if (init) {
throw new FileSystemException("vfs.impl/already-inited.error");
}
this.filesCache = filesCache;
}
Set the cache strategy to use when dealing with file object data.
Can only be set before the FileSystemManager is initialized.
The default is CacheStrategy.ON_RESOLVE
Params: - fileCacheStrategy – The CacheStrategy to use.
Throws: - FileSystemException – if this is not possible. e.g. it is already set.
/**
* Set the cache strategy to use when dealing with file object data.
* <p>
* Can only be set before the FileSystemManager is initialized.
* <p>
* The default is {@link CacheStrategy#ON_RESOLVE}
*
* @param fileCacheStrategy The CacheStrategy to use.
* @throws FileSystemException if this is not possible. e.g. it is already set.
*/
public void setCacheStrategy(final CacheStrategy fileCacheStrategy) throws FileSystemException {
if (init) {
throw new FileSystemException("vfs.impl/already-inited.error");
}
this.fileCacheStrategy = fileCacheStrategy;
}
Get the cache strategy used.
Returns: The CacheStrategy.
/**
* Get the cache strategy used.
*
* @return The CacheStrategy.
*/
@Override
public CacheStrategy getCacheStrategy() {
return fileCacheStrategy;
}
Get the file object decorator used.
Returns: The decorator.
/**
* Get the file object decorator used.
*
* @return The decorator.
*/
@Override
public Class<?> getFileObjectDecorator() {
return fileObjectDecorator;
}
The constructor associated to the fileObjectDecorator. We cache it here for performance reasons.
Returns: The decorator's Constructor.
/**
* The constructor associated to the fileObjectDecorator. We cache it here for performance reasons.
*
* @return The decorator's Constructor.
*/
@Override
public Constructor<?> getFileObjectDecoratorConst() {
return fileObjectDecoratorConst;
}
Set a fileObject decorator to be used for ALL returned file objects.
Can only be set before the FileSystemManager is initialized.
Params: - fileObjectDecorator – must be inherted from
DecoratedFileObject
a has to provide a constructor with a single FileObject
as argument
Throws: - FileSystemException – if an error occurs setting the decorator.
/**
* Set a fileObject decorator to be used for ALL returned file objects.
* <p>
* Can only be set before the FileSystemManager is initialized.
*
* @param fileObjectDecorator must be inherted from {@link DecoratedFileObject} a has to provide a constructor with
* a single {@link FileObject} as argument
* @throws FileSystemException if an error occurs setting the decorator.
*/
public void setFileObjectDecorator(final Class<?> fileObjectDecorator) throws FileSystemException {
if (init) {
throw new FileSystemException("vfs.impl/already-inited.error");
}
if (!DecoratedFileObject.class.isAssignableFrom(fileObjectDecorator)) {
throw new FileSystemException("vfs.impl/invalid-decorator.error", fileObjectDecorator.getName());
}
try {
fileObjectDecoratorConst = fileObjectDecorator.getConstructor(new Class[] { FileObject.class });
} catch (final NoSuchMethodException e) {
throw new FileSystemException("vfs.impl/invalid-decorator.error", fileObjectDecorator.getName(), e);
}
this.fileObjectDecorator = fileObjectDecorator;
}
get the fileContentInfoFactory used to determine the infos of a file content.
Returns: The FileContentInfoFactory.
/**
* get the fileContentInfoFactory used to determine the infos of a file content.
*
* @return The FileContentInfoFactory.
*/
@Override
public FileContentInfoFactory getFileContentInfoFactory() {
return fileContentInfoFactory;
}
set the fileContentInfoFactory used to determine the infos of a file content.
Can only be set before the FileSystemManager is initialized.
Params: - fileContentInfoFactory – The FileContentInfoFactory.
Throws: - FileSystemException – if an error occurs setting the FileContentInfoFactory.
/**
* set the fileContentInfoFactory used to determine the infos of a file content.
* <p>
* Can only be set before the FileSystemManager is initialized.
*
* @param fileContentInfoFactory The FileContentInfoFactory.
* @throws FileSystemException if an error occurs setting the FileContentInfoFactory.
*/
public void setFileContentInfoFactory(final FileContentInfoFactory fileContentInfoFactory)
throws FileSystemException {
if (init) {
throw new FileSystemException("vfs.impl/already-inited.error");
}
this.fileContentInfoFactory = fileContentInfoFactory;
}
Sets the file replicator to use.
The manager takes care of all lifecycle management.
Params: - replicator – The FileReplicator.
Throws: - FileSystemException – if an error occurs setting the replicator.
/**
* Sets the file replicator to use.
* <p>
* The manager takes care of all lifecycle management.
*
* @param replicator The FileReplicator.
* @throws FileSystemException if an error occurs setting the replicator.
*/
public void setReplicator(final FileReplicator replicator) throws FileSystemException {
setupComponent(replicator);
fileReplicator = replicator;
}
Sets the temporary file store to use.
The manager takes care of all lifecycle management.
Params: - tempFileStore – The temporary FileStore.
Throws: - FileSystemException – if an error occurs adding the file store.
/**
* Sets the temporary file store to use.
* <p>
* The manager takes care of all lifecycle management.
*
* @param tempFileStore The temporary FileStore.
* @throws FileSystemException if an error occurs adding the file store.
*/
public void setTemporaryFileStore(final TemporaryFileStore tempFileStore) throws FileSystemException {
setupComponent(tempFileStore);
this.tempFileStore = tempFileStore;
}
Sets the logger to use.
This overwrites the default logger for this manager and is not reset in close()
.
Params: - log – The Logger to use.
/**
* Sets the logger to use.
* <p>
* This overwrites the default logger for this manager and is not reset in {@link #close()}.
*
* @param log The Logger to use.
*/
@Override
public void setLogger(final Log log) {
this.log = log;
}
Initializes a component, if it has not already been initialised.
Params: - component – The component to setup.
Throws: - FileSystemException – if an error occurs.
/**
* Initializes a component, if it has not already been initialised.
*
* @param component The component to setup.
* @throws FileSystemException if an error occurs.
*/
private void setupComponent(final Object component) throws FileSystemException {
if (!components.contains(component)) {
if (component instanceof VfsComponent) {
final VfsComponent vfsComponent = (VfsComponent) component;
vfsComponent.setLogger(getLogger());
vfsComponent.setContext(context);
vfsComponent.init();
}
components.add(component);
}
}
Closes a component, if it has not already been closed.
Params: - component – The component to close.
/**
* Closes a component, if it has not already been closed.
*
* @param component The component to close.
*/
private void closeComponent(final Object component) {
if (component != null && components.contains(component)) {
if (component instanceof VfsComponent) {
final VfsComponent vfsComponent = (VfsComponent) component;
vfsComponent.close();
}
components.remove(component);
}
}
Returns the file replicator.
Throws: - FileSystemException – if there is no FileReplicator.
Returns: The file replicator. Never returns null.
/**
* Returns the file replicator.
*
* @return The file replicator. Never returns null.
* @throws FileSystemException if there is no FileReplicator.
*/
public FileReplicator getReplicator() throws FileSystemException {
return FileSystemException.requireNonNull(fileReplicator, "vfs.impl/no-replicator.error");
}
Returns the temporary file store.
Throws: - FileSystemException – if there is no TemporaryFileStore.
Returns: The file store. Never returns null.
/**
* Returns the temporary file store.
*
* @return The file store. Never returns null.
* @throws FileSystemException if there is no TemporaryFileStore.
*/
public TemporaryFileStore getTemporaryFileStore() throws FileSystemException {
return FileSystemException.requireNonNull(tempFileStore, "vfs.impl/no-temp-file-store.error");
}
Initializes this manager.
If no value for the following properties was specified, it will use the following defaults:
- fileContentInfoFactory = new FileContentInfoFilenameFactory()
- filesCache = new SoftRefFilesCache()
- fileCacheStrategy = CacheStrategy.ON_RESOLVE
Throws: - FileSystemException – if an error occurs during initialization.
/**
* Initializes this manager.
* <p>
* If no value for the following properties was specified, it will use the following defaults:
* <ul>
* <li>fileContentInfoFactory = new FileContentInfoFilenameFactory()</li>
* <li>filesCache = new SoftRefFilesCache()</li>
* <li>fileCacheStrategy = CacheStrategy.ON_RESOLVE</li>
* </ul>
*
* @throws FileSystemException if an error occurs during initialization.
*/
public void init() throws FileSystemException {
if (fileContentInfoFactory == null) {
fileContentInfoFactory = new FileContentInfoFilenameFactory();
}
if (filesCache == null) {
// filesCache = new DefaultFilesCache();
filesCache = new SoftRefFilesCache();
}
if (fileCacheStrategy == null) {
fileCacheStrategy = CacheStrategy.ON_RESOLVE;
}
setupComponent(filesCache);
vfsProvider = new VirtualFileProvider();
setupComponent(vfsProvider);
init = true;
}
Closes the manager.
This will close all providers (all files), it will also close all managed components including temporary files,
replicator, file cache and file operations.
The manager is in uninitialized state after this method.
/**
* Closes the manager.
* <p>
* This will close all providers (all files), it will also close all managed components including temporary files,
* replicator, file cache and file operations.
* <p>
* The manager is in uninitialized state after this method.
*/
public void close() {
if (!init) {
return;
}
// make sure all discovered components in
// org.apache.commons.vfs2.impl.StandardFileSystemManager.configure(Element)
// are closed here
// Close the file system providers.
for (final FileProvider provider : providers.values()) {
closeComponent(provider);
}
// Close the other components
closeComponent(vfsProvider);
closeComponent(fileReplicator);
closeComponent(tempFileStore);
closeComponent(filesCache);
closeComponent(defaultProvider);
// unregister all providers here, so if any components have local file references
// they can still resolve against the supported schemes
providers.clear();
// FileOperations are components, too
for (final List<FileOperationProvider> opproviders : operationProviders.values()) {
for (final FileOperationProvider p : opproviders) {
closeComponent(p);
}
}
// unregister all
operationProviders.clear();
// collections with add()
typeMap.clear();
// should not happen, but make debugging easier:
if (!components.isEmpty()) {
log.warn("DefaultFilesystemManager.close: not all components are closed: " + components.toString());
}
components.clear();
// managed components
vfsProvider = null;
// virtual schemas
virtualFileSystemSchemes.clear();
// setters and derived state
defaultProvider = null;
baseFile = null;
fileObjectDecorator = null;
fileObjectDecoratorConst = null;
localFileProvider = null;
fileReplicator = null;
tempFileStore = null;
// setters with init() defaults
filesCache = null;
fileCacheStrategy = null;
fileContentInfoFactory = null;
init = false;
}
Free all resources used by unused file systems created by this manager.
/**
* Free all resources used by unused file systems created by this manager.
*/
public void freeUnusedResources() {
if (!init) {
return;
}
// Close the providers.
for (final FileProvider fileProvider : providers.values()) {
final AbstractFileProvider provider = (AbstractFileProvider) fileProvider;
provider.freeUnusedResources();
}
// vfsProvider does not need to free resources
}
Sets the base file to use when resolving relative URI.
Params: - baseFile – The new base FileObject.
Throws: - FileSystemException – if an error occurs.
/**
* Sets the base file to use when resolving relative URI.
*
* @param baseFile The new base FileObject.
* @throws FileSystemException if an error occurs.
*/
public void setBaseFile(final FileObject baseFile) throws FileSystemException {
this.baseFile = baseFile;
}
Sets the base file to use when resolving relative URI.
Params: - baseFile – The new base FileObject.
Throws: - FileSystemException – if an error occurs.
/**
* Sets the base file to use when resolving relative URI.
*
* @param baseFile The new base FileObject.
* @throws FileSystemException if an error occurs.
*/
public void setBaseFile(final File baseFile) throws FileSystemException {
this.baseFile = getLocalFileProvider().findLocalFile(baseFile);
}
Returns the base file used to resolve relative URI.
Throws: - FileSystemException – if an error occurs.
Returns: The FileObject that represents the base file.
/**
* Returns the base file used to resolve relative URI.
*
* @return The FileObject that represents the base file.
* @throws FileSystemException if an error occurs.
*/
@Override
public FileObject getBaseFile() throws FileSystemException {
return baseFile;
}
Locates a file by URI.
Params: - uri – The URI of the file to locate.
Throws: - FileSystemException – if the file cannot be located or an error occurs.
Returns: The FileObject for the located file.
/**
* Locates a file by URI.
*
* @param uri The URI of the file to locate.
* @return The FileObject for the located file.
* @throws FileSystemException if the file cannot be located or an error occurs.
*/
@Override
public FileObject resolveFile(final String uri) throws FileSystemException {
return resolveFile(getBaseFile(), uri);
}
Locate a file by URI, use the FileSystemOptions for file-system creation.
Params: - uri – The URI of the file to locate.
- fileSystemOptions – The options for the FileSystem.
Throws: - FileSystemException – if the file cannot be located or an error occurs.
Returns: The FileObject for the located file.
/**
* Locate a file by URI, use the FileSystemOptions for file-system creation.
*
* @param uri The URI of the file to locate.
* @param fileSystemOptions The options for the FileSystem.
* @return The FileObject for the located file.
* @throws FileSystemException if the file cannot be located or an error occurs.
*/
@Override
public FileObject resolveFile(final String uri, final FileSystemOptions fileSystemOptions)
throws FileSystemException {
// return resolveFile(baseFile, uri, fileSystemOptions);
return resolveFile(getBaseFile(), uri, fileSystemOptions);
}
Resolves a URI, relative to base file.
Uses the local file provider to locate the system file.
Params: - baseFile – The base File to use to locate the file.
- uri – The URI of the file to locate.
Throws: - FileSystemException – if the file cannot be located or an error occurs.
Returns: The FileObject for the located file.
/**
* Resolves a URI, relative to base file.
* <p>
* Uses the {@linkplain #getLocalFileProvider() local file provider} to locate the system file.
*
* @param baseFile The base File to use to locate the file.
* @param uri The URI of the file to locate.
* @return The FileObject for the located file.
* @throws FileSystemException if the file cannot be located or an error occurs.
*/
@Override
public FileObject resolveFile(final File baseFile, final String uri) throws FileSystemException {
final FileObject baseFileObj = getLocalFileProvider().findLocalFile(baseFile);
return resolveFile(baseFileObj, uri);
}
Resolves a URI, relative to a base file.
Params: - baseFile – The base FileOjbect to use to locate the file.
- uri – The URI of the file to locate.
Throws: - FileSystemException – if the file cannot be located or an error occurs.
Returns: The FileObject for the located file.
/**
* Resolves a URI, relative to a base file.
*
* @param baseFile The base FileOjbect to use to locate the file.
* @param uri The URI of the file to locate.
* @return The FileObject for the located file.
* @throws FileSystemException if the file cannot be located or an error occurs.
*/
@Override
public FileObject resolveFile(final FileObject baseFile, final String uri) throws FileSystemException {
return resolveFile(baseFile, uri, baseFile == null ? null : baseFile.getFileSystem().getFileSystemOptions());
}
Resolves a URI, relative to a base file with specified FileSystem configuration.
Params: - baseFile – The base file.
- uri – The file name. May be a fully qualified or relative path or a url.
- fileSystemOptions – Options to pass to the file system.
Throws: - FileSystemException – if an error occurs accessing the file.
Returns: A FileObject representing the target file.
/**
* Resolves a URI, relative to a base file with specified FileSystem configuration.
*
* @param baseFile The base file.
* @param uri The file name. May be a fully qualified or relative path or a url.
* @param fileSystemOptions Options to pass to the file system.
* @return A FileObject representing the target file.
* @throws FileSystemException if an error occurs accessing the file.
*/
public FileObject resolveFile(final FileObject baseFile, final String uri,
final FileSystemOptions fileSystemOptions) throws FileSystemException {
final FileObject realBaseFile;
if (baseFile != null && VFS.isUriStyle() && baseFile.getName().isFile()) {
realBaseFile = baseFile.getParent();
} else {
realBaseFile = baseFile;
}
// TODO: use resolveName and use this name to resolve the fileObject
UriParser.checkUriEncoding(uri);
if (uri == null) {
throw new IllegalArgumentException();
}
// Extract the scheme
final String scheme = UriParser.extractScheme(getSchemes(),uri);
if (scheme != null) {
// An absolute URI - locate the provider
final FileProvider provider = providers.get(scheme);
if (provider != null) {
return provider.findFile(realBaseFile, uri, fileSystemOptions);
}
// Otherwise, assume a local file
}
// Handle absolute file names
if (localFileProvider != null && localFileProvider.isAbsoluteLocalName(uri)) {
return localFileProvider.findLocalFile(uri);
}
if (scheme != null) {
// An unknown scheme - hand it to the default provider
FileSystemException.requireNonNull(defaultProvider, "vfs.impl/unknown-scheme.error", scheme, uri);
return defaultProvider.findFile(realBaseFile, uri, fileSystemOptions);
}
// Assume a relative name - use the supplied base file
FileSystemException.requireNonNull(realBaseFile, "vfs.impl/find-rel-file.error", uri);
return realBaseFile.resolveFile(uri);
}
Resolves a name, relative to the file. If the supplied name is an absolute path, then it is resolved relative to
the root of the file system that the file belongs to. If a relative name is supplied, then it is resolved
relative to this file name.
Params: - root – The base FileName.
- path – The path to the file relative to the base FileName or an absolute path.
Throws: - FileSystemException – if an error occurs constructing the FileName.
Returns: The constructed FileName.
/**
* Resolves a name, relative to the file. If the supplied name is an absolute path, then it is resolved relative to
* the root of the file system that the file belongs to. If a relative name is supplied, then it is resolved
* relative to this file name.
*
* @param root The base FileName.
* @param path The path to the file relative to the base FileName or an absolute path.
* @return The constructed FileName.
* @throws FileSystemException if an error occurs constructing the FileName.
*/
@Override
public FileName resolveName(final FileName root, final String path) throws FileSystemException {
return resolveName(root, path, NameScope.FILE_SYSTEM);
}
Resolves a name, relative to the root.
Params: - base – the base file name
- name – the name
- scope – the
NameScope
Throws: - FileSystemException – if an error occurs.
Returns: The FileName of the file.
/**
* Resolves a name, relative to the root.
*
* @param base the base file name
* @param name the name
* @param scope the {@link NameScope}
* @return The FileName of the file.
* @throws FileSystemException if an error occurs.
*/
@Override
public FileName resolveName(final FileName base, final String name, final NameScope scope)
throws FileSystemException {
FileSystemException.requireNonNull(base, "Invalid base FileName.");
FileSystemException.requireNonNull(name, "Invalid name FileName.");
final FileName realBase;
if (VFS.isUriStyle() && base.isFile()) {
realBase = base.getParent();
} else {
realBase = base;
}
final StringBuilder buffer = new StringBuilder(name);
// Adjust separators
UriParser.fixSeparators(buffer);
String scheme = UriParser.extractScheme(getSchemes(), buffer.toString());
// Determine whether to prepend the base path
if (name.length() == 0 || (scheme == null && buffer.charAt(0) != FileName.SEPARATOR_CHAR)) {
// Supplied path is not absolute
if (!VFS.isUriStyle()) {
// when using uris the parent already do have the trailing "/"
buffer.insert(0, FileName.SEPARATOR_CHAR);
}
buffer.insert(0, realBase.getPath());
}
// Normalise the path
final FileType fileType = UriParser.normalisePath(buffer);
// Check the name is ok
final String resolvedPath = buffer.toString();
if (!AbstractFileName.checkName(realBase.getPath(), resolvedPath, scope)) {
throw new FileSystemException("vfs.provider/invalid-descendent-name.error", name);
}
String fullPath;
if (scheme != null) {
fullPath = resolvedPath;
} else {
scheme = realBase.getScheme();
fullPath = realBase.getRootURI() + resolvedPath;
}
final FileProvider provider = providers.get(scheme);
if (provider != null) {
// TODO: extend the file name parser to be able to parse
// only a pathname and take the missing informations from
// the base. Then we can get rid of the string operation.
// // String fullPath = base.getRootURI() +
// resolvedPath.substring(1);
return provider.parseUri(realBase, fullPath);
}
// An unknown scheme - hand it to the default provider - if possible
if (scheme != null && defaultProvider != null) {
return defaultProvider.parseUri(realBase, fullPath);
}
// TODO: avoid fallback to this point
// this happens if we have a virtual filesystem (no provider for scheme)
return ((AbstractFileName) realBase).createName(resolvedPath, fileType);
}
Resolve the uri to a file name.
Params: - uri – The URI to resolve.
Throws: - FileSystemException – if an error occurs.
Returns: The FileName of the file.
/**
* Resolve the uri to a file name.
*
* @param uri The URI to resolve.
* @return The FileName of the file.
* @throws FileSystemException if an error occurs.
*/
@Override
public FileName resolveURI(final String uri) throws FileSystemException {
UriParser.checkUriEncoding(uri);
if (uri == null) {
throw new IllegalArgumentException();
}
// Extract the scheme
final String scheme = UriParser.extractScheme(getSchemes(), uri);
if (scheme != null) {
// An absolute URI - locate the provider
final FileProvider provider = providers.get(scheme);
if (provider != null) {
return provider.parseUri(null, uri);
}
// Otherwise, assume a local file
}
// Handle absolute file names
if (localFileProvider != null && localFileProvider.isAbsoluteLocalName(uri)) {
return localFileProvider.parseUri(null, uri);
}
if (scheme != null) {
// An unknown scheme - hand it to the default provider
FileSystemException.requireNonNull(defaultProvider, "vfs.impl/unknown-scheme.error", scheme, uri);
return defaultProvider.parseUri(null, uri);
}
// Assume a relative name - use the supplied base file
FileSystemException.requireNonNull(baseFile, "vfs.impl/find-rel-file.error", uri);
return resolveName(baseFile.getName(), uri, NameScope.FILE_SYSTEM);
}
Converts a local file into a FileObject
. Params: - file – The input File.
Throws: - FileSystemException – if an error occurs creating the file.
Returns: the create FileObject
/**
* Converts a local file into a {@link FileObject}.
*
* @param file The input File.
* @return the create FileObject
* @throws FileSystemException if an error occurs creating the file.
*/
@Override
public FileObject toFileObject(final File file) throws FileSystemException {
return getLocalFileProvider().findLocalFile(file);
}
Creates a layered file system.
Params: - scheme – The scheme to use.
- file – The FileObject.
Throws: - FileSystemException – if an error occurs.
Returns: The layered FileObject.
/**
* Creates a layered file system.
*
* @param scheme The scheme to use.
* @param file The FileObject.
* @return The layered FileObject.
* @throws FileSystemException if an error occurs.
*/
@Override
public FileObject createFileSystem(final String scheme, final FileObject file) throws FileSystemException {
final FileProvider provider = providers.get(scheme);
FileSystemException.requireNonNull(provider, "vfs.impl/unknown-provider.error", scheme, file);
return provider.createFileSystem(scheme, file, file.getFileSystem().getFileSystemOptions());
}
Creates a layered file system.
Params: - file – The FileObject to use.
Throws: - FileSystemException – if an error occurs.
Returns: The layered FileObject.
/**
* Creates a layered file system.
*
* @param file The FileObject to use.
* @return The layered FileObject.
* @throws FileSystemException if an error occurs.
*/
@Override
public FileObject createFileSystem(final FileObject file) throws FileSystemException {
final String scheme = typeMap.getScheme(file);
FileSystemException.requireNonNull(scheme, "vfs.impl/no-provider-for-file.error", file);
return createFileSystem(scheme, file);
}
Determines if a layered file system can be created for a given file.
Params: - file – The file to check for.
Throws: - FileSystemException – if an error occurs.
Returns: true if the FileSystem can be created.
/**
* Determines if a layered file system can be created for a given file.
*
* @param file The file to check for.
* @return true if the FileSystem can be created.
* @throws FileSystemException if an error occurs.
*/
@Override
public boolean canCreateFileSystem(final FileObject file) throws FileSystemException {
return typeMap.getScheme(file) != null;
}
Creates a virtual file system.
Params: - rootFile – The FileObject to use.
Throws: - FileSystemException – if an error occurs creating the file.
Returns: The FileObject in the VirtualFileSystem.
/**
* Creates a virtual file system.
*
* @param rootFile The FileObject to use.
* @return The FileObject in the VirtualFileSystem.
* @throws FileSystemException if an error occurs creating the file.
*/
@Override
public FileObject createVirtualFileSystem(final FileObject rootFile) throws FileSystemException {
final FileObject fileObject = vfsProvider.createFileSystem(rootFile);
addVirtualFileSystemScheme(rootFile.getName().getScheme());
return fileObject;
}
Creates an empty virtual file system.
Params: - rootUri – The URI to use as the root of the FileSystem.
Throws: - FileSystemException – if an error occurs.
Returns: A FileObject in the virtual FileSystem.
/**
* Creates an empty virtual file system.
*
* @param rootUri The URI to use as the root of the FileSystem.
* @return A FileObject in the virtual FileSystem.
* @throws FileSystemException if an error occurs.
*/
@Override
public FileObject createVirtualFileSystem(final String rootUri) throws FileSystemException {
final FileObject fileObject = vfsProvider.createFileSystem(rootUri);
addVirtualFileSystemScheme(rootUri);
return fileObject;
}
protected void addVirtualFileSystemScheme(String rootUri) {
if (rootUri.indexOf(':') != -1) {
rootUri = rootUri.substring(0, rootUri.indexOf(':'));
}
virtualFileSystemSchemes.add(rootUri);
}
Locates the local file provider.
The local file provider is the first provider added implementing LocalFileProvider
.
Throws: - FileSystemException – if no local file provider was set.
Returns: The LocalFileProvider.
/**
* Locates the local file provider.
* <p>
* The local file provider is the first {@linkplain #addProvider(String[], FileProvider) provider added}
* implementing {@link LocalFileProvider}.
*
* @return The LocalFileProvider.
* @throws FileSystemException if no local file provider was set.
*/
private LocalFileProvider getLocalFileProvider() throws FileSystemException {
return FileSystemException.requireNonNull(localFileProvider, "vfs.impl/no-local-file-provider.error");
}
Get the URLStreamHandlerFactory.
Returns: The URLStreamHandlerFactory.
/**
* Get the URLStreamHandlerFactory.
*
* @return The URLStreamHandlerFactory.
*/
@Override
public URLStreamHandlerFactory getURLStreamHandlerFactory() {
return new VfsStreamHandlerFactory();
}
Closes the given file system.
If you use VFS as singleton it is VERY dangerous to call this method.
Params: - fileSystem – The FileSystem to close.
/**
* Closes the given file system.
* <p>
* If you use VFS as singleton it is VERY dangerous to call this method.
*
* @param fileSystem The FileSystem to close.
*/
@Override
public void closeFileSystem(final FileSystem fileSystem) {
// inform the cache ...
getFilesCache().clear(fileSystem);
// just in case the cache didnt call _closeFileSystem
_closeFileSystem(fileSystem);
}
Closes the given file system.
If you use VFS as singleton it is VERY dangerous to call this method
Params: - fileSystem – The FileSystem to close.
/**
* Closes the given file system.
* <p>
* If you use VFS as singleton it is VERY dangerous to call this method
* </p>
*
* @param fileSystem The FileSystem to close.
*/
public void _closeFileSystem(final FileSystem fileSystem) {
final FileProvider provider = providers.get(fileSystem.getRootName().getScheme());
if (provider != null) {
((AbstractFileProvider) provider).closeFileSystem(fileSystem);
} else if (fileSystem instanceof VirtualFileSystem) {
// vfsProvider does not implement AbstractFileProvider
vfsProvider.closeFileSystem(fileSystem);
}
}
This is an internal class because it needs access to the private member providers.
/**
* This is an internal class because it needs access to the private member providers.
*/
final class VfsStreamHandlerFactory implements URLStreamHandlerFactory {
@Override
public URLStreamHandler createURLStreamHandler(final String protocol) {
final FileProvider provider = providers.get(protocol);
if (provider != null) {
return new DefaultURLStreamHandler(context);
}
// Route all other calls to the default URLStreamHandlerFactory
return new URLStreamHandlerProxy();
}
}
Get the schemes currently available.
Returns: The array of scheme names.
/**
* Get the schemes currently available.
*
* @return The array of scheme names.
*/
@Override
public String[] getSchemes() {
final List<String> schemes = new ArrayList<>(providers.size() + virtualFileSystemSchemes.size());
schemes.addAll(providers.keySet());
schemes.addAll(virtualFileSystemSchemes);
return schemes.toArray(new String[]{});
}
Get the capabilities for a given scheme.
Params: - scheme – The scheme to located.
Throws: - FileSystemException – if the given scheme is not konwn
Returns: A Collection of capabilities.
/**
* Get the capabilities for a given scheme.
*
* @param scheme The scheme to located.
* @return A Collection of capabilities.
* @throws FileSystemException if the given scheme is not konwn
*/
@Override
public Collection<Capability> getProviderCapabilities(final String scheme) throws FileSystemException {
final FileProvider provider = providers.get(scheme);
FileSystemException.requireNonNull(provider, "vfs.impl/unknown-scheme.error", scheme);
return provider.getCapabilities();
}
Get the configuration builder for the given scheme.
Params: - scheme – The scheme to locate.
Throws: - FileSystemException – if the given scheme is not konwn
Returns: The FileSystemConfigBuilder for the scheme.
/**
* Get the configuration builder for the given scheme.
*
* @param scheme The scheme to locate.
* @return The FileSystemConfigBuilder for the scheme.
* @throws FileSystemException if the given scheme is not konwn
*/
@Override
public FileSystemConfigBuilder getFileSystemConfigBuilder(final String scheme) throws FileSystemException {
final FileProvider provider = providers.get(scheme);
FileSystemException.requireNonNull(provider, "vfs.impl/unknown-scheme.error", scheme);
return provider.getConfigBuilder();
}
// -- OPERATIONS --
Adds the specified FileOperationProvider for the specified scheme. Several FileOperationProvider's might be
registered for the same scheme. For example, for "file" scheme we can register SvnWsOperationProvider and
CvsOperationProvider.
Params: - scheme – The scheme the provider should be registered for.
- operationProvider – The FileOperationProvider.
Throws: - FileSystemException – if an error occurs adding the provider.
/**
* Adds the specified FileOperationProvider for the specified scheme. Several FileOperationProvider's might be
* registered for the same scheme. For example, for "file" scheme we can register SvnWsOperationProvider and
* CvsOperationProvider.
*
* @param scheme The scheme the provider should be registered for.
* @param operationProvider The FileOperationProvider.
* @throws FileSystemException if an error occurs adding the provider.
*/
@Override
public void addOperationProvider(final String scheme, final FileOperationProvider operationProvider)
throws FileSystemException {
addOperationProvider(new String[] { scheme }, operationProvider);
}
Params: - schemes – The array of schemes the provider should apply to.
- operationProvider – The FileOperationProvider.
Throws: - FileSystemException – if an error occurs.
See Also: - addOperationProvider.addOperationProvider(String, FileOperationProvider)
/**
* @see FileSystemManager#addOperationProvider(String, org.apache.commons.vfs2.operations.FileOperationProvider)
*
* @param schemes The array of schemes the provider should apply to.
* @param operationProvider The FileOperationProvider.
* @throws FileSystemException if an error occurs.
*/
@Override
public void addOperationProvider(final String[] schemes, final FileOperationProvider operationProvider)
throws FileSystemException {
for (final String scheme : schemes) {
if (!operationProviders.containsKey(scheme)) {
final List<FileOperationProvider> providers = new ArrayList<>();
operationProviders.put(scheme, providers);
}
final List<FileOperationProvider> providers = operationProviders.get(scheme);
if (providers.contains(operationProvider)) {
throw new FileSystemException("vfs.operation/operation-provider-already-added.error", scheme);
}
setupComponent(operationProvider);
providers.add(operationProvider);
}
}
Params: - scheme – the scheme for wich we want to get the list af registered providers.
Throws: - FileSystemException – if an error occurs.
Returns: the registered FileOperationProviders for the specified scheme. If there were no providers registered for
the scheme, it returns null.
/**
* @param scheme the scheme for wich we want to get the list af registered providers.
*
* @return the registered FileOperationProviders for the specified scheme. If there were no providers registered for
* the scheme, it returns null.
*
* @throws FileSystemException if an error occurs.
*/
@Override
public FileOperationProvider[] getOperationProviders(final String scheme) throws FileSystemException {
final List<?> providers = operationProviders.get(scheme);
if (providers == null || providers.size() == 0) {
return null;
}
return providers.toArray(new FileOperationProvider[] {});
}
Converts a URI into a FileObject
. Params: - uri – The URI to convert.
Throws: - FileSystemException – On error converting the URI.
Returns: The FileObject
that represents the URI. Never returns null. Since: 2.1
/**
* Converts a URI into a {@link FileObject}.
*
* @param uri The URI to convert.
* @return The {@link FileObject} that represents the URI. Never returns null.
* @throws FileSystemException On error converting the URI.
* @since 2.1
*/
@Override
public FileObject resolveFile(final URI uri) throws FileSystemException {
// TODO Push the URI deeper into VFS
return resolveFile(baseFile, uri.toString(), null);
}
Converts a URL into a FileObject
. Params: - url – The URL to convert.
Throws: - FileSystemException – On error converting the URL.
Returns: The FileObject
that represents the URL. Never returns null. Since: 2.1
/**
* Converts a URL into a {@link FileObject}.
*
* @param url The URL to convert.
* @return The {@link FileObject} that represents the URL. Never returns null.
* @throws FileSystemException On error converting the URL.
* @since 2.1
*/
@Override
public FileObject resolveFile(final URL url) throws FileSystemException {
try {
return this.resolveFile(url.toURI());
} catch (final URISyntaxException e) {
throw new FileSystemException(e);
}
}
}