package org.argeo.jcr.fs; import java.io.IOException; import java.nio.file.FileStore; import java.nio.file.attribute.FileAttributeView; import java.nio.file.attribute.FileStoreAttributeView; import java.util.Arrays; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Workspace; import org.argeo.jcr.JcrUtils; /** A {@link FileStore} implementation based on JCR {@link Workspace}. */ public class WorkspaceFileStore extends FileStore { private final String mountPath; private final Workspace workspace; private final String workspaceName; private final int mountDepth; public WorkspaceFileStore(String mountPath, Workspace workspace) { if ("/".equals(mountPath) || "".equals(mountPath)) throw new IllegalArgumentException( "Mount path '" + mountPath + "' is unsupported, use null for the base file store"); if (mountPath != null && !mountPath.startsWith(JcrPath.separator)) throw new IllegalArgumentException("Mount path '" + mountPath + "' cannot end with /"); if (mountPath != null && mountPath.endsWith(JcrPath.separator)) throw new IllegalArgumentException("Mount path '" + mountPath + "' cannot end with /"); this.mountPath = mountPath; if (mountPath == null) mountDepth = 0; else { mountDepth = mountPath.split(JcrPath.separator).length - 1; } this.workspace = workspace; this.workspaceName = workspace.getName(); } public void close() { JcrUtils.logoutQuietly(workspace.getSession()); } @Override public String name() { return workspace.getName(); } @Override public String type() { return "workspace"; } @Override public boolean isReadOnly() { return false; } @Override public long getTotalSpace() throws IOException { return 0; } @Override public long getUsableSpace() throws IOException { return 0; } @Override public long getUnallocatedSpace() throws IOException { return 0; } @Override public boolean supportsFileAttributeView(Class type) { return false; } @Override public boolean supportsFileAttributeView(String name) { return false; } @Override public V getFileStoreAttributeView(Class type) { return null; } @Override public Object getAttribute(String attribute) throws IOException { return workspace.getSession().getRepository().getDescriptor(attribute); } public Workspace getWorkspace() { return workspace; } public String toFsPath(Node node) throws RepositoryException { String nodeWorkspaceName = node.getSession().getWorkspace().getName(); if (!nodeWorkspaceName.equals(workspace.getName())) throw new IllegalArgumentException("Icompatible " + node + " from workspace '" + nodeWorkspaceName + "' in file store '" + workspace.getName() + "'"); return mountPath == null ? node.getPath() : mountPath + node.getPath(); } public boolean isBase() { return mountPath == null; } Node toNode(String[] fullPath) throws RepositoryException { String jcrPath = toJcrPath(fullPath); Session session = workspace.getSession(); if (!session.itemExists(jcrPath)) return null; Node node = session.getNode(jcrPath); return node; } String toJcrPath(String fsPath) { if (fsPath.length() == 1) return toJcrPath((String[]) null);// root String[] arr = fsPath.substring(1).split("/"); // if (arr.length == 0 || (arr.length == 1 && arr[0].equals(""))) // return toJcrPath((String[]) null);// root // else return toJcrPath(arr); } private String toJcrPath(String[] path) { if (path == null) return "/"; if (path.length < mountDepth) throw new IllegalArgumentException( "Path " + Arrays.asList(path) + " is no compatible with mount " + mountPath); if (!isBase()) { // check mount compatibility StringBuilder mount = new StringBuilder(); mount.append('/'); for (int i = 0; i < mountDepth; i++) { if (i != 0) mount.append('/'); mount.append(Text.escapeIllegalJcrChars(path[i])); } if (!mountPath.equals(mount.toString())) throw new IllegalArgumentException( "Path " + Arrays.asList(path) + " is no compatible with mount " + mountPath); } StringBuilder sb = new StringBuilder(); sb.append('/'); for (int i = mountDepth; i < path.length; i++) { if (i != mountDepth) sb.append('/'); sb.append(Text.escapeIllegalJcrChars(path[i])); } return sb.toString(); } public String getMountPath() { return mountPath; } public String getWorkspaceName() { return workspaceName; } public int getMountDepth() { return mountDepth; } @Override public int hashCode() { return workspaceName.hashCode(); } @Override public boolean equals(Object obj) { if (!(obj instanceof WorkspaceFileStore)) return false; WorkspaceFileStore other = (WorkspaceFileStore) obj; return workspaceName.equals(other.workspaceName); } @Override public String toString() { return "WorkspaceFileStore " + workspaceName; } }