Sort methods.
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
index c5fb7b1..dd56a15 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
@@ -64,6 +64,22 @@
public class DefaultFileSystemManager implements FileSystemManager {
/**
+ * 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();
+ }
+ }
+
+ /**
* Mapping from URI scheme to FileProvider.
*/
private final Map<String, FileProvider> providers = new HashMap<>();
@@ -122,11 +138,11 @@
* The cache strategy
*/
private CacheStrategy fileCacheStrategy;
-
/**
* Class which decorates all returned fileObjects
*/
private Class<?> fileObjectDecorator;
+
/**
* Reflection constructor extracted from {@link #fileObjectDecorator}
*/
@@ -158,12 +174,84 @@
private boolean init;
/**
- * Returns the logger used by this manager.
+ * Closes the given file system.
+ * <p>
+ * If you use VFS as singleton it is VERY dangerous to call this method
+ * </p>
*
- * @return the Logger.
+ * @param fileSystem The FileSystem to close.
*/
- protected Log getLogger() {
- return log;
+ 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);
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @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);
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * @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);
+ }
}
/**
@@ -211,320 +299,23 @@
}
}
- /**
- * Unregisters a file system provider.
- *
- * @param urlScheme The scheme of the provider.
- * @since 2.8.0
- */
- public void removeProvider(final String urlScheme) {
- final FileProvider provider = providers.remove(urlScheme);
- // check whether the same instance is not used somewhere else
- if (provider != null && !providers.containsValue(provider)) {
- closeComponent(provider);
+ protected void addVirtualFileSystemScheme(String rootUri) {
+ if (rootUri.indexOf(':') != -1) {
+ rootUri = rootUri.substring(0, rootUri.indexOf(':'));
}
+ virtualFileSystemSchemes.add(rootUri);
}
/**
- * Returns true if this manager has a provider for a particular scheme.
+ * Determines if a layered file system can be created for a given file.
*
- * @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.
- *
- * @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.
- *
- * @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.
- *
- * @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.
- *
- * @return The FilesCache.
- */
- @Override
- public FilesCache getFilesCache() {
- return filesCache;
- }
-
- /**
- * Sets the filesCache implementation used to cache files.
- * <p>
- * Can only be set before the FileSystemManager is initialized.
- * </p>
- * <p>
- * The manager takes care of the lifecycle. If none is set, a default is picked in {@link #init()}.
- * </p>
- *
- * @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.
- * <p>
- * Can only be set before the FileSystemManager is initialized.
- * </p>
- * <p>
- * The default is {@link CacheStrategy#ON_RESOLVE}.
- * </p>
- *
- * @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.
- *
- * @return The CacheStrategy.
- */
- @Override
- public CacheStrategy getCacheStrategy() {
- return fileCacheStrategy;
- }
-
- /**
- * 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.
- *
- * @return The decorator's Constructor.
- */
- @Override
- public Constructor<?> getFileObjectDecoratorConst() {
- return fileObjectDecoratorConst;
- }
-
- /**
- * Set a fileObject decorator to be used for ALL returned file objects.
- * <p>
- * Can only be set before the FileSystemManager is initialized.
- * </p>
- *
- * @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(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.
- *
- * @return The FileContentInfoFactory.
- */
- @Override
- public FileContentInfoFactory getFileContentInfoFactory() {
- return fileContentInfoFactory;
- }
-
- /**
- * set the fileContentInfoFactory used to determine the infos of a file content.
- * <p>
- * Can only be set before the FileSystemManager is initialized.
- * </p>
- *
- * @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.
- * <p>
- * The manager takes care of all lifecycle management.
- * </p>
- *
- * @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.
- * <p>
- * The manager takes care of all lifecycle management.
- * </p>
- *
- * @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.
- * <p>
- * This overwrites the default logger for this manager and is not reset in {@link #close()}.
- * </p>
- *
- * @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 initialized.
- *
- * @param component The component to setup.
+ * @param file The file to check for.
+ * @return true if the FileSystem can be created.
* @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.
- *
- * @param component The component to close.
- */
- private void closeComponent(final Object component) {
- if (component != null && components.contains(component)) {
- if (component instanceof VfsComponent) {
- ((VfsComponent) component).close();
- }
- components.remove(component);
- }
- }
-
- /**
- * 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.
- *
- * @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.
- * <p>
- * If no value for the following properties was specified, it will use the following defaults:
- * </p>
- * <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 SoftRefFilesCache();
- }
- if (fileCacheStrategy == null) {
- fileCacheStrategy = CacheStrategy.ON_RESOLVE;
- }
- setupComponent(filesCache);
-
- vfsProvider = new VirtualFileProvider();
- setupComponent(vfsProvider);
-
- init = true;
+ @Override
+ public boolean canCreateFileSystem(final FileObject file) throws FileSystemException {
+ return typeMap.getScheme(file) != null;
}
/**
@@ -601,6 +392,94 @@
}
/**
+ * 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) {
+ ((VfsComponent) component).close();
+ }
+ components.remove(component);
+ }
+ }
+
+ /**
+ * 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.
+ */
+ @Override
+ public void closeFileSystem(final FileSystem fileSystem) {
+ // inform the cache ...
+ getFilesCache().clear(fileSystem);
+
+ // just in case the cache didnt call _closeFileSystem
+ _closeFileSystem(fileSystem);
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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 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.
+ *
+ * @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;
+ }
+
+ /**
* Free all resources used by unused file systems created by this manager.
*/
public void freeUnusedResources() {
@@ -618,26 +497,6 @@
}
/**
- * 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.
- *
- * @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.
*
* @return The FileObject that represents the base file.
@@ -649,31 +508,222 @@
}
/**
- * Locates a file by URI.
+ * Get the cache strategy used.
*
- * @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.
+ * @return The CacheStrategy.
*/
@Override
- public FileObject resolveFile(final String uri) throws FileSystemException {
- return resolveFile(getBaseFile(), uri);
+ public CacheStrategy getCacheStrategy() {
+ return fileCacheStrategy;
}
/**
- * Locate a file by URI, use the FileSystemOptions for file-system creation.
+ * get the fileContentInfoFactory used to determine the infos of a file content.
*
- * @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.
+ * @return The FileContentInfoFactory.
*/
-
@Override
- public FileObject resolveFile(final String uri, final FileSystemOptions fileSystemOptions)
- throws FileSystemException {
- // return resolveFile(baseFile, uri, fileSystemOptions);
- return resolveFile(getBaseFile(), uri, fileSystemOptions);
+ public FileContentInfoFactory getFileContentInfoFactory() {
+ return fileContentInfoFactory;
+ }
+
+ /**
+ * 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.
+ *
+ * @return The decorator's Constructor.
+ */
+ @Override
+ public Constructor<?> getFileObjectDecoratorConst() {
+ return fileObjectDecoratorConst;
+ }
+
+ /**
+ * Returns the filesCache implementation used to cache files.
+ *
+ * @return The FilesCache.
+ */
+ @Override
+ public FilesCache getFilesCache() {
+ return filesCache;
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * Locates the local file provider.
+ * <p>
+ * The local file provider is the first {@linkplain #addProvider(String[], FileProvider) provider added}
+ * implementing {@link LocalFileProvider}.
+ * </p>
+ *
+ * @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");
+ }
+
+ /**
+ * Returns the logger used by this manager.
+ *
+ * @return the Logger.
+ */
+ protected Log getLogger() {
+ return log;
+ }
+
+ /**
+ * @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.isEmpty()) {
+ return null;
+ }
+ return providers.toArray(new FileOperationProvider[] {});
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * 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");
+ }
+
+ /**
+ * 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[]{});
+ }
+
+ /**
+ * 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");
+ }
+
+ /**
+ * Get the URLStreamHandlerFactory.
+ *
+ * @return The URLStreamHandlerFactory.
+ */
+ @Override
+ public URLStreamHandlerFactory getURLStreamHandlerFactory() {
+ return new VfsStreamHandlerFactory();
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * Initializes this manager.
+ * <p>
+ * If no value for the following properties was specified, it will use the following defaults:
+ * </p>
+ * <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 SoftRefFilesCache();
+ }
+ if (fileCacheStrategy == null) {
+ fileCacheStrategy = CacheStrategy.ON_RESOLVE;
+ }
+ setupComponent(filesCache);
+
+ vfsProvider = new VirtualFileProvider();
+ setupComponent(vfsProvider);
+
+ init = true;
+ }
+
+ /**
+ * Unregisters a file system provider.
+ *
+ * @param urlScheme The scheme of the provider.
+ * @since 2.8.0
+ */
+ public void removeProvider(final String urlScheme) {
+ final FileProvider provider = providers.remove(urlScheme);
+ // check whether the same instance is not used somewhere else
+ if (provider != null && !providers.containsValue(provider)) {
+ closeComponent(provider);
+ }
}
/**
@@ -758,6 +808,65 @@
}
/**
+ * 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.
+ *
+ * @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);
+ }
+
+ /**
+ * 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 {@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);
+ }
+ }
+
+ /**
* 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.
@@ -772,6 +881,7 @@
return resolveName(root, path, NameScope.FILE_SYSTEM);
}
+
/**
* Resolves a name, relative to the root.
*
@@ -891,6 +1001,183 @@
}
/**
+ * 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);
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Set the cache strategy to use when dealing with file object data.
+ * <p>
+ * Can only be set before the FileSystemManager is initialized.
+ * </p>
+ * <p>
+ * The default is {@link CacheStrategy#ON_RESOLVE}.
+ * </p>
+ *
+ * @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;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * set the fileContentInfoFactory used to determine the infos of a file content.
+ * <p>
+ * Can only be set before the FileSystemManager is initialized.
+ * </p>
+ *
+ * @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;
+ }
+
+ /**
+ * Set a fileObject decorator to be used for ALL returned file objects.
+ * <p>
+ * Can only be set before the FileSystemManager is initialized.
+ * </p>
+ *
+ * @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(FileObject.class);
+ } catch (final NoSuchMethodException e) {
+ throw new FileSystemException("vfs.impl/invalid-decorator.error", fileObjectDecorator.getName(), e);
+ }
+
+ this.fileObjectDecorator = fileObjectDecorator;
+ }
+
+ /**
+ * Sets the filesCache implementation used to cache files.
+ * <p>
+ * Can only be set before the FileSystemManager is initialized.
+ * </p>
+ * <p>
+ * The manager takes care of the lifecycle. If none is set, a default is picked in {@link #init()}.
+ * </p>
+ *
+ * @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;
+ }
+
+ // -- OPERATIONS --
+
+ /**
+ * Sets the logger to use.
+ * <p>
+ * This overwrites the default logger for this manager and is not reset in {@link #close()}.
+ * </p>
+ *
+ * @param log The Logger to use.
+ */
+ @Override
+ public void setLogger(final Log log) {
+ this.log = log;
+ }
+
+ /**
+ * Sets the file replicator to use.
+ * <p>
+ * The manager takes care of all lifecycle management.
+ * </p>
+ *
+ * @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.
+ * <p>
+ * The manager takes care of all lifecycle management.
+ * </p>
+ *
+ * @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;
+ }
+
+ /**
+ * Initializes a component, if it has not already been initialized.
+ *
+ * @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);
+ }
+ }
+
+ /**
* Converts a local file into a {@link FileObject}.
*
* @param file The input File.
@@ -902,291 +1189,4 @@
return getLocalFileProvider().findLocalFile(file);
}
- /**
- * 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.
- *
- * @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.
- *
- * @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.
- *
- * @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.
- *
- * @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.
- * <p>
- * The local file provider is the first {@linkplain #addProvider(String[], FileProvider) provider added}
- * implementing {@link LocalFileProvider}.
- * </p>
- *
- * @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.
- *
- * @return The URLStreamHandlerFactory.
- */
- @Override
- public URLStreamHandlerFactory getURLStreamHandlerFactory() {
- return new VfsStreamHandlerFactory();
- }
-
- /**
- * 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.
- */
- @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.
- * <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.
- */
- 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.
- *
- * @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.
- *
- * @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.
- *
- * @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.
- *
- * @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);
- }
-
- /**
- * @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);
- }
- }
-
- /**
- * @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.isEmpty()) {
- return null;
- }
- return providers.toArray(new FileOperationProvider[] {});
- }
-
- /**
- * 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 {@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);
- }
- }
-
}