> operationProviders = new HashMap<>();
private final FileTypeMap typeMap = new FileTypeMap();
private LocalFileProvider localFileProvider;
private FileProvider defaultProvider;
private FileReplicator fileReplicator;
private FileObject baseFile;
private FilesCache filesCache;
private CacheStrategy fileCacheStrategy;
private Class fileObjectDecorator;
private Constructor fileObjectDecoratorConst;
private FileContentInfoFactory fileContentInfoFactory;
private Log log = LogFactory.getLog(getClass());
private TemporaryFileStore tempFileStore;
private VirtualFileProvider vfsProvider;
private boolean init;
protected Log getLogger() {
return log;
}
public void addProvider(final String urlScheme, final FileProvider provider) throws FileSystemException {
addProvider(new String[] { urlScheme }, provider);
}
public void addProvider(final String[] urlSchemes, final FileProvider provider) throws FileSystemException {
for (final String scheme : urlSchemes) {
if (providers.containsKey(scheme)) {
throw new FileSystemException("vfs.impl/multiple-providers-for-scheme.error", scheme);
}
}
setupComponent(provider);
for (final String scheme : urlSchemes) {
providers.put(scheme, provider);
}
if (provider instanceof LocalFileProvider && localFileProvider == null) {
localFileProvider = (LocalFileProvider) provider;
}
}
@Override
public boolean hasProvider(final String scheme) {
return providers.containsKey(scheme);
}
public void addExtensionMap(final String extension, final String scheme) {
typeMap.addExtension(extension, scheme);
}
public void addMimeTypeMap(final String mimeType, final String scheme) {
typeMap.addMimeType(mimeType, scheme);
}
public void setDefaultProvider(final FileProvider provider) throws FileSystemException {
setupComponent(provider);
defaultProvider = provider;
}
@Override
public FilesCache getFilesCache() {
return filesCache;
}
public void setFilesCache(final FilesCache filesCache) throws FileSystemException {
if (init) {
throw new FileSystemException("vfs.impl/already-inited.error");
}
this.filesCache = filesCache;
}
public void setCacheStrategy(final CacheStrategy fileCacheStrategy) throws FileSystemException {
if (init) {
throw new FileSystemException("vfs.impl/already-inited.error");
}
this.fileCacheStrategy = fileCacheStrategy;
}
@Override
public CacheStrategy getCacheStrategy() {
return fileCacheStrategy;
}
@Override
public Class getFileObjectDecorator() {
return fileObjectDecorator;
}
@Override
public Constructor getFileObjectDecoratorConst() {
return fileObjectDecoratorConst;
}
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;
}
@Override
public FileContentInfoFactory getFileContentInfoFactory() {
return fileContentInfoFactory;
}
public void setFileContentInfoFactory(final FileContentInfoFactory fileContentInfoFactory)
throws FileSystemException {
if (init) {
throw new FileSystemException("vfs.impl/already-inited.error");
}
this.fileContentInfoFactory = fileContentInfoFactory;
}
public void setReplicator(final FileReplicator replicator) throws FileSystemException {
setupComponent(replicator);
fileReplicator = replicator;
}
public void setTemporaryFileStore(final TemporaryFileStore tempFileStore) throws FileSystemException {
setupComponent(tempFileStore);
this.tempFileStore = tempFileStore;
}
@Override
public void setLogger(final Log log) {
this.log = log;
}
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);
}
}
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);
}
}
public FileReplicator getReplicator() throws FileSystemException {
return FileSystemException.requireNonNull(fileReplicator, "vfs.impl/no-replicator.error");
}
public TemporaryFileStore getTemporaryFileStore() throws FileSystemException {
return FileSystemException.requireNonNull(tempFileStore, "vfs.impl/no-temp-file-store.error");
}
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 void close() {
if (!init) {
return;
}
for (final FileProvider provider : providers.values()) {
closeComponent(provider);
}
closeComponent(vfsProvider);
closeComponent(fileReplicator);
closeComponent(tempFileStore);
closeComponent(filesCache);
closeComponent(defaultProvider);
providers.clear();
for (final List opproviders : operationProviders.values()) {
for (final FileOperationProvider p : opproviders) {
closeComponent(p);
}
}
operationProviders.clear();
typeMap.clear();
if (!components.isEmpty()) {
log.warn("DefaultFilesystemManager.close: not all components are closed: " + components.toString());
}
components.clear();
vfsProvider = null;
virtualFileSystemSchemes.clear();
defaultProvider = null;
baseFile = null;
fileObjectDecorator = null;
fileObjectDecoratorConst = null;
localFileProvider = null;
fileReplicator = null;
tempFileStore = null;
filesCache = null;
fileCacheStrategy = null;
fileContentInfoFactory = null;
init = false;
}
public void freeUnusedResources() {
if (!init) {
return;
}
for (final FileProvider fileProvider : providers.values()) {
final AbstractFileProvider provider = (AbstractFileProvider) fileProvider;
provider.freeUnusedResources();
}
}
public void setBaseFile(final FileObject baseFile) throws FileSystemException {
this.baseFile = baseFile;
}
public void setBaseFile(final File baseFile) throws FileSystemException {
this.baseFile = getLocalFileProvider().findLocalFile(baseFile);
}
@Override
public FileObject getBaseFile() throws FileSystemException {
return baseFile;
}
@Override
public FileObject resolveFile(final String uri) throws FileSystemException {
return resolveFile(getBaseFile(), uri);
}
@Override
public FileObject resolveFile(final String uri, final FileSystemOptions fileSystemOptions)
throws FileSystemException {
return resolveFile(getBaseFile(), uri, fileSystemOptions);
}
@Override
public FileObject resolveFile(final File baseFile, final String uri) throws FileSystemException {
final FileObject baseFileObj = getLocalFileProvider().findLocalFile(baseFile);
return resolveFile(baseFileObj, uri);
}
@Override
public FileObject resolveFile(final FileObject baseFile, final String uri) throws FileSystemException {
return resolveFile(baseFile, uri, baseFile == null ? null : baseFile.getFileSystem().getFileSystemOptions());
}
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;
}
UriParser.checkUriEncoding(uri);
if (uri == null) {
throw new IllegalArgumentException();
}
final String scheme = UriParser.extractScheme(getSchemes(), uri);
if (scheme != null) {
final FileProvider provider = providers.get(scheme);
if (provider != null) {
return provider.findFile(realBaseFile, uri, fileSystemOptions);
}
}
if (localFileProvider != null && localFileProvider.isAbsoluteLocalName(uri)) {
return localFileProvider.findLocalFile(uri);
}
if (scheme != null) {
FileSystemException.requireNonNull(defaultProvider, "vfs.impl/unknown-scheme.error", scheme, uri);
return defaultProvider.findFile(realBaseFile, uri, fileSystemOptions);
}
FileSystemException.requireNonNull(realBaseFile, "vfs.impl/find-rel-file.error", uri);
return realBaseFile.resolveFile(uri);
}
@Override
public FileName resolveName(final FileName root, final String path) throws FileSystemException {
return resolveName(root, path, NameScope.FILE_SYSTEM);
}
@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);
UriParser.fixSeparators(buffer);
String scheme = UriParser.extractScheme(getSchemes(), buffer.toString());
if (name.length() == 0 || (scheme == null && buffer.charAt(0) != FileName.SEPARATOR_CHAR)) {
if (!VFS.isUriStyle()) {
buffer.insert(0, FileName.SEPARATOR_CHAR);
}
buffer.insert(0, realBase.getPath());
}
final FileType fileType = UriParser.normalisePath(buffer);
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) {
return provider.parseUri(realBase, fullPath);
}
if (scheme != null && defaultProvider != null) {
return defaultProvider.parseUri(realBase, fullPath);
}
return ((AbstractFileName) realBase).createName(resolvedPath, fileType);
}
@Override
public FileName resolveURI(final String uri) throws FileSystemException {
UriParser.checkUriEncoding(uri);
if (uri == null) {
throw new IllegalArgumentException();
}
final String scheme = UriParser.extractScheme(getSchemes(), uri);
if (scheme != null) {
final FileProvider provider = providers.get(scheme);
if (provider != null) {
return provider.parseUri(null, uri);
}
}
if (localFileProvider != null && localFileProvider.isAbsoluteLocalName(uri)) {
return localFileProvider.parseUri(null, uri);
}
if (scheme != null) {
FileSystemException.requireNonNull(defaultProvider, "vfs.impl/unknown-scheme.error", scheme, uri);
return defaultProvider.parseUri(null, uri);
}
FileSystemException.requireNonNull(baseFile, "vfs.impl/find-rel-file.error", uri);
return resolveName(baseFile.getName(), uri, NameScope.FILE_SYSTEM);
}
@Override
public FileObject toFileObject(final File file) throws FileSystemException {
return getLocalFileProvider().findLocalFile(file);
}
@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());
}
@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);
}
@Override
public boolean canCreateFileSystem(final FileObject file) throws FileSystemException {
return typeMap.getScheme(file) != null;
}
@Override
public FileObject createVirtualFileSystem(final FileObject rootFile) throws FileSystemException {
final FileObject fileObject = vfsProvider.createFileSystem(rootFile);
addVirtualFileSystemScheme(rootFile.getName().getScheme());
return fileObject;
}
@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);
}
private LocalFileProvider getLocalFileProvider() throws FileSystemException {
return FileSystemException.requireNonNull(localFileProvider, "vfs.impl/no-local-file-provider.error");
}
@Override
public URLStreamHandlerFactory getURLStreamHandlerFactory() {
return new VfsStreamHandlerFactory();
}
@Override
public void closeFileSystem(final FileSystem fileSystem) {
getFilesCache().clear(fileSystem);
_closeFileSystem(fileSystem);
}
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.closeFileSystem(fileSystem);
}
}
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);
}
return new URLStreamHandlerProxy();
}
}
@Override
public String[] getSchemes() {
final List schemes = new ArrayList<>(providers.size() + virtualFileSystemSchemes.size());
schemes.addAll(providers.keySet());
schemes.addAll(virtualFileSystemSchemes);
return schemes.toArray(new String[]{});
}
@Override
public Collection getProviderCapabilities(final String scheme) throws FileSystemException {
final FileProvider provider = providers.get(scheme);
FileSystemException.requireNonNull(provider, "vfs.impl/unknown-scheme.error", scheme);
return provider.getCapabilities();
}
@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();
}
@Override
public void addOperationProvider(final String scheme, final FileOperationProvider operationProvider)
throws FileSystemException {
addOperationProvider(new String[] { scheme }, operationProvider);
}
@Override
public void addOperationProvider(final String[] schemes, final FileOperationProvider operationProvider)
throws FileSystemException {
for (final String scheme : schemes) {
if (!operationProviders.containsKey(scheme)) {
final List providers = new ArrayList<>();
operationProviders.put(scheme, providers);
}
final List providers = operationProviders.get(scheme);
if (providers.contains(operationProvider)) {
throw new FileSystemException("vfs.operation/operation-provider-already-added.error", scheme);
}
setupComponent(operationProvider);
providers.add(operationProvider);
}
}
@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[] {});
}
@Override
public FileObject resolveFile(final URI uri) throws FileSystemException {
return resolveFile(baseFile, uri.toString(), null);
}
@Override
public FileObject resolveFile(final URL url) throws FileSystemException {
try {
return this.resolveFile(url.toURI());
} catch (final URISyntaxException e) {
throw new FileSystemException(e);
}
}
}