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=885eaf19f4b0962b850de47122b36601ad0f0603;hpb=d8037dd6a59ff5d38d7c7182a9ef6c26c8001a4f;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 885eaf19f..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,22 +8,149 @@ 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; - public JcrFileSystem(JcrFileSystemProvider provider, 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); +// 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 = 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 @@ -34,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 @@ -48,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 @@ -105,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; } }