package com.revolsys.io.file; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeSupport; import java.io.File; import java.io.IOException; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; import java.nio.file.FileStore; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.PathMatcher; import java.nio.file.WatchService; import java.nio.file.attribute.UserPrincipalLookupService; import java.nio.file.spi.FileSystemProvider; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import com.revolsys.io.connection.ConnectionRegistryManager; import com.revolsys.spring.resource.Resource; public class FileConnectionManager extends FileSystem implements ConnectionRegistryManager<FolderConnectionRegistry>, URLStreamHandlerFactory { static FileConnectionManager instance; private static final FileSystem DEFAULT_FILE_SYSTEM = FileSystems.getDefault(); public static FileConnectionManager get() { if (instance == null) { new FileConnectionFileSystemProvider(); } return instance; } public static File getConnection(final String name) { final FileConnectionManager connectionManager = get(); final List<FolderConnectionRegistry> registries = new ArrayList<>(); registries.addAll(connectionManager.getConnectionRegistries()); final FolderConnectionRegistry threadRegistry = FolderConnectionRegistry.getForThread(); if (threadRegistry != null) { registries.add(threadRegistry); } Collections.reverse(registries); for (final FolderConnectionRegistry registry : registries) { final FolderConnection connection = registry.getConnection(name); if (connection != null) { return connection.getFile(); } } return null; } private final FileConnectionFileSystemProvider provider; private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); private final List<FolderConnectionRegistry> registries = new ArrayList<>(); public FileConnectionManager(final FileConnectionFileSystemProvider provider) { this.provider = provider; } @Override public void addConnectionRegistry(final FolderConnectionRegistry registry) { if (registry != null) { int index = -1; synchronized (this.registries) { if (!this.registries.contains(registry)) { index = this.registries.size(); this.registries.add(registry); registry.setConnectionManager(this); } } if (index != -1) { index = getVisibleConnectionRegistries().indexOf(registry); if (index != -1) { this.propertyChangeSupport.fireIndexedPropertyChange("registries", index, null, registry); this.propertyChangeSupport.fireIndexedPropertyChange("children", index, null, registry); } } } } public synchronized FolderConnectionRegistry addConnectionRegistry(final String name) { final FolderConnectionRegistry registry = new FolderConnectionRegistry(this, name); addConnectionRegistry(registry); return registry; } public synchronized FolderConnectionRegistry addConnectionRegistry(final String name, final Resource resource) { final FolderConnectionRegistry registry = new FolderConnectionRegistry(this, name, resource, false); addConnectionRegistry(registry); return registry; } @Override public void close() throws IOException { } @Override public URLStreamHandler createURLStreamHandler(final String protocol) { return null; } protected FolderConnectionRegistry findConnectionRegistry(final String name) { for (final FolderConnectionRegistry registry : this.registries) { if (registry.getName().equals(name)) { return registry; } } return null; } @Override public List<FolderConnectionRegistry> getConnectionRegistries() { return new ArrayList<>(this.registries); } @Override public FolderConnectionRegistry getConnectionRegistry(final String name) { final FolderConnectionRegistry connectionRegistry = findConnectionRegistry(name); if (connectionRegistry == null) { return this.registries.get(0); } return connectionRegistry; } @Override public Iterable<FileStore> getFileStores() { return Collections.emptyList(); } @Override public String getIconName() { return "folder:link"; } @Override public String getName() { return "Folder Connections"; } @Override public Path getPath(final String first, final String... more) { String path; if (more.length == 0) { path = first; } else { final StringBuilder sb = new StringBuilder(); sb.append(first); for (final String segment : more) { if (segment.length() > 0) { if (sb.length() > 0) { sb.append('/'); } sb.append(segment); } } path = sb.toString(); } // return new FileConnectionPath(this, path); return null; } @Override public PathMatcher getPathMatcher(final String syntaxAndPattern) { // TODO Auto-generated method stub return null; } @Override public PropertyChangeSupport getPropertyChangeSupport() { return this.propertyChangeSupport; } @Override public Iterable<Path> getRootDirectories() { // TODO Auto-generated method stub return null; } @Override public String getSeparator() { return "/"; } @Override public UserPrincipalLookupService getUserPrincipalLookupService() { return DEFAULT_FILE_SYSTEM.getUserPrincipalLookupService(); } @Override public List<FolderConnectionRegistry> getVisibleConnectionRegistries() { final List<FolderConnectionRegistry> registries = new ArrayList<>(); for (final FolderConnectionRegistry registry : this.registries) { if (registry != null && registry.isVisible()) { registries.add(registry); } } return registries; } @Override public boolean isOpen() { return true; } @Override public boolean isReadOnly() { return false; } @Override public WatchService newWatchService() throws IOException { return DEFAULT_FILE_SYSTEM.newWatchService(); } @Override public void propertyChange(final PropertyChangeEvent event) { this.propertyChangeSupport.firePropertyChange(event); } @Override public FileSystemProvider provider() { return this.provider; } @Override public void removeConnectionRegistry(final FolderConnectionRegistry registry) { if (registry != null) { final int index; synchronized (this.registries) { index = this.registries.indexOf(registry); if (index != -1) { this.registries.remove(registry); registry.setConnectionManager(null); registry.getPropertyChangeSupport().removePropertyChangeListener(this); } } if (index != -1) { this.propertyChangeSupport.fireIndexedPropertyChange("registries", index, registry, null); } } } public void removeConnectionRegistry(final String name) { final FolderConnectionRegistry connectionRegistry = findConnectionRegistry(name); removeConnectionRegistry(connectionRegistry); } @Override public Set<String> supportedFileAttributeViews() { return DEFAULT_FILE_SYSTEM.supportedFileAttributeViews(); } @Override public String toString() { return getName(); } }