X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.jcr%2Fsrc%2Forg%2Fargeo%2Fjcr%2Ffs%2FJcrFileSystem.java;h=3d538e8bde485963f1fc0d23b58900f74a2eac9b;hb=46cc2039ac20703c484aa994b830a2da113f2c97;hp=d11f0c51d6bea7896c6d9fa8fa85052aca9bc2bc;hpb=d4a5631f933282d791fb8edddc59a6f6751311e0;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java index d11f0c51d..3d538e8bd 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java +++ b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java @@ -8,37 +8,151 @@ 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.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.TreeMap; +import javax.jcr.Credentials; import javax.jcr.Node; +import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.nodetype.NodeType; +import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrUtils; public class JcrFileSystem extends FileSystem { private final JcrFileSystemProvider provider; - private final Session session; + + private final Repository repository; + private Session session; + private WorkspaceFileStore baseFileStore; + + private Map mounts = new TreeMap<>(); + private String userHomePath = null; + @Deprecated public JcrFileSystem(JcrFileSystemProvider provider, Session session) throws IOException { super(); this.provider = provider; + baseFileStore = new WorkspaceFileStore(null, session.getWorkspace()); this.session = session; - Node userHome = provider.getUserHome(session); +// Node userHome = provider.getUserHome(session); +// if (userHome != null) +// try { +// userHomePath = userHome.getPath(); +// } catch (RepositoryException e) { +// throw new IOException("Cannot retrieve user home path", e); +// } + this.repository = null; + } + + public JcrFileSystem(JcrFileSystemProvider provider, Repository repository) throws IOException { + this(provider, repository, null); + } + + public JcrFileSystem(JcrFileSystemProvider provider, Repository repository, Credentials credentials) + throws IOException { + super(); + this.provider = provider; + this.repository = repository; + try { + this.session = credentials == null ? repository.login() : repository.login(credentials); + baseFileStore = new WorkspaceFileStore(null, session.getWorkspace()); + workspaces: for (String workspaceName : baseFileStore.getWorkspace().getAccessibleWorkspaceNames()) { + if (workspaceName.equals(baseFileStore.getWorkspace().getName())) + continue workspaces;// do not mount base + if (workspaceName.equals("security")) { + continue workspaces;// do not mount security workspace + // TODO make it configurable + } + Session mountSession = credentials == null ? repository.login(workspaceName) + : repository.login(credentials, workspaceName); + String mountPath = JcrPath.separator + workspaceName; + mounts.put(mountPath, new WorkspaceFileStore(mountPath, mountSession.getWorkspace())); + } + } catch (RepositoryException e) { + throw new IOException("Cannot initialise file system", e); + } + + Node userHome = provider.getUserHome(repository); if (userHome != null) try { - userHomePath = userHome.getPath(); + userHomePath = toFsPath(userHome); } catch (RepositoryException e) { throw new IOException("Cannot retrieve user home path", e); + } finally { + JcrUtils.logoutQuietly(Jcr.session(userHome)); } } + public String toFsPath(Node node) throws RepositoryException { + return getFileStore(node).toFsPath(node); + } + + /** Whether this node should be skipped in directory listings */ + public boolean skipNode(Node node) throws RepositoryException { + if (node.isNodeType(NodeType.NT_HIERARCHY_NODE)) + return false; + return true; + } + public String getUserHomePath() { return userHomePath; } + public WorkspaceFileStore getFileStore(String path) { + WorkspaceFileStore res = baseFileStore; + for (String mountPath : mounts.keySet()) { + if (path.equals(mountPath)) + return mounts.get(mountPath); + if (path.startsWith(mountPath + JcrPath.separator)) { + res = mounts.get(mountPath); + // we keep the last one + } + } + assert res != null; + return res; + } + + public WorkspaceFileStore getFileStore(Node node) throws RepositoryException { + String workspaceName = node.getSession().getWorkspace().getName(); + if (workspaceName.equals(baseFileStore.getWorkspace().getName())) + return baseFileStore; + for (String mountPath : mounts.keySet()) { + WorkspaceFileStore fileStore = mounts.get(mountPath); + if (workspaceName.equals(fileStore.getWorkspace().getName())) + return fileStore; + } + throw new IllegalStateException("No workspace mount found for " + node + " in workspace " + workspaceName); + } + + public Iterator listDirectMounts(Path base) { + String baseStr = base.toString(); + Set res = new HashSet<>(); + mounts: for (String mountPath : mounts.keySet()) { + if (mountPath.equals(baseStr)) + continue mounts; + if (mountPath.startsWith(baseStr)) { + JcrPath path = new JcrPath(this, mountPath); + Path relPath = base.relativize(path); + if (relPath.getNameCount() == 1) + res.add(path); + } + } + return res.iterator(); + } + + public WorkspaceFileStore getBaseFileStore() { + return baseFileStore; + } + @Override public FileSystemProvider provider() { return provider; @@ -47,6 +161,14 @@ public class JcrFileSystem extends FileSystem { @Override public void close() throws IOException { JcrUtils.logoutQuietly(session); + for (String mountPath : mounts.keySet()) { + WorkspaceFileStore fileStore = mounts.get(mountPath); + try { + fileStore.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } } @Override @@ -61,23 +183,22 @@ public class JcrFileSystem extends FileSystem { @Override public String getSeparator() { - return "/"; + return JcrPath.separator; } @Override public Iterable getRootDirectories() { - try { - Set single = new HashSet<>(); - single.add(new JcrPath(this, session.getRootNode())); - return single; - } catch (RepositoryException e) { - throw new JcrFsException("Cannot get root path", e); - } + Set single = new HashSet<>(); + single.add(new JcrPath(this, JcrPath.separator)); + return single; } @Override public Iterable getFileStores() { - throw new UnsupportedOperationException(); + List stores = new ArrayList<>(); + stores.add(baseFileStore); + stores.addAll(mounts.values()); + return stores; } @Override @@ -118,8 +239,12 @@ public class JcrFileSystem extends FileSystem { throw new UnsupportedOperationException(); } - public Session getSession() { - return session; +// public Session getSession() { +// return session; +// } + + public Repository getRepository() { + return repository; } }