1 package org
.argeo
.jcr
.fs
;
3 import java
.io
.IOException
;
4 import java
.nio
.file
.FileStore
;
5 import java
.nio
.file
.FileSystem
;
6 import java
.nio
.file
.Path
;
7 import java
.nio
.file
.PathMatcher
;
8 import java
.nio
.file
.WatchService
;
9 import java
.nio
.file
.attribute
.UserPrincipalLookupService
;
10 import java
.nio
.file
.spi
.FileSystemProvider
;
11 import java
.util
.ArrayList
;
12 import java
.util
.HashSet
;
13 import java
.util
.Iterator
;
14 import java
.util
.List
;
17 import java
.util
.TreeMap
;
19 import javax
.jcr
.Credentials
;
20 import javax
.jcr
.Node
;
21 import javax
.jcr
.Repository
;
22 import javax
.jcr
.RepositoryException
;
23 import javax
.jcr
.Session
;
24 import javax
.jcr
.nodetype
.NodeType
;
26 import org
.argeo
.api
.acr
.fs
.AbstractFsStore
;
27 import org
.argeo
.api
.acr
.fs
.AbstractFsSystem
;
28 import org
.argeo
.jcr
.Jcr
;
29 import org
.argeo
.jcr
.JcrUtils
;
31 public class JcrFileSystem
extends AbstractFsSystem
<WorkspaceFileStore
> {
32 private final JcrFileSystemProvider provider
;
34 private final Repository repository
;
35 private Session session
;
36 private WorkspaceFileStore baseFileStore
;
38 private Map
<String
, WorkspaceFileStore
> mounts
= new TreeMap
<>();
40 private String userHomePath
= null;
43 public JcrFileSystem(JcrFileSystemProvider provider
, Session session
) throws IOException
{
45 this.provider
= provider
;
46 baseFileStore
= new WorkspaceFileStore(null, session
.getWorkspace());
47 this.session
= session
;
48 // Node userHome = provider.getUserHome(session);
49 // if (userHome != null)
51 // userHomePath = userHome.getPath();
52 // } catch (RepositoryException e) {
53 // throw new IOException("Cannot retrieve user home path", e);
55 this.repository
= null;
58 public JcrFileSystem(JcrFileSystemProvider provider
, Repository repository
) throws IOException
{
59 this(provider
, repository
, null);
62 public JcrFileSystem(JcrFileSystemProvider provider
, Repository repository
, Credentials credentials
)
65 this.provider
= provider
;
66 this.repository
= repository
;
68 this.session
= credentials
== null ? repository
.login() : repository
.login(credentials
);
69 baseFileStore
= new WorkspaceFileStore(null, session
.getWorkspace());
70 workspaces
: for (String workspaceName
: baseFileStore
.getWorkspace().getAccessibleWorkspaceNames()) {
71 if (workspaceName
.equals(baseFileStore
.getWorkspace().getName()))
72 continue workspaces
;// do not mount base
73 if (workspaceName
.equals("security")) {
74 continue workspaces
;// do not mount security workspace
75 // TODO make it configurable
77 Session mountSession
= credentials
== null ? repository
.login(workspaceName
)
78 : repository
.login(credentials
, workspaceName
);
79 String mountPath
= JcrPath
.separator
+ workspaceName
;
80 mounts
.put(mountPath
, new WorkspaceFileStore(mountPath
, mountSession
.getWorkspace()));
82 } catch (RepositoryException e
) {
83 throw new IOException("Cannot initialise file system", e
);
86 Node userHome
= provider
.getUserHome(repository
);
89 userHomePath
= toFsPath(userHome
);
90 } catch (RepositoryException e
) {
91 throw new IOException("Cannot retrieve user home path", e
);
93 JcrUtils
.logoutQuietly(Jcr
.session(userHome
));
97 public String
toFsPath(Node node
) throws RepositoryException
{
98 return getFileStore(node
).toFsPath(node
);
101 /** Whether this node should be skipped in directory listings */
102 public boolean skipNode(Node node
) throws RepositoryException
{
103 if (node
.isNodeType(NodeType
.NT_HIERARCHY_NODE
))
108 public String
getUserHomePath() {
112 public WorkspaceFileStore
getFileStore(String path
) {
113 WorkspaceFileStore res
= baseFileStore
;
114 for (String mountPath
: mounts
.keySet()) {
115 if (path
.equals(mountPath
))
116 return mounts
.get(mountPath
);
117 if (path
.startsWith(mountPath
+ JcrPath
.separator
)) {
118 res
= mounts
.get(mountPath
);
119 // we keep the last one
126 public WorkspaceFileStore
getFileStore(Node node
) throws RepositoryException
{
127 String workspaceName
= node
.getSession().getWorkspace().getName();
128 if (workspaceName
.equals(baseFileStore
.getWorkspace().getName()))
129 return baseFileStore
;
130 for (String mountPath
: mounts
.keySet()) {
131 WorkspaceFileStore fileStore
= mounts
.get(mountPath
);
132 if (workspaceName
.equals(fileStore
.getWorkspace().getName()))
135 throw new IllegalStateException("No workspace mount found for " + node
+ " in workspace " + workspaceName
);
138 public Iterator
<JcrPath
> listDirectMounts(Path base
) {
139 String baseStr
= base
.toString();
140 Set
<JcrPath
> res
= new HashSet
<>();
141 mounts
: for (String mountPath
: mounts
.keySet()) {
142 if (mountPath
.equals(baseStr
))
144 if (mountPath
.startsWith(baseStr
)) {
145 JcrPath path
= new JcrPath(this, mountPath
);
146 Path relPath
= base
.relativize(path
);
147 if (relPath
.getNameCount() == 1)
151 return res
.iterator();
154 public WorkspaceFileStore
getBaseFileStore() {
155 return baseFileStore
;
159 public FileSystemProvider
provider() {
164 public void close() throws IOException
{
165 JcrUtils
.logoutQuietly(session
);
166 for (String mountPath
: mounts
.keySet()) {
167 WorkspaceFileStore fileStore
= mounts
.get(mountPath
);
170 } catch (Exception e
) {
177 public boolean isOpen() {
178 return session
.isLive();
182 public boolean isReadOnly() {
187 public String
getSeparator() {
188 return JcrPath
.separator
;
192 public Iterable
<Path
> getRootDirectories() {
193 Set
<Path
> single
= new HashSet
<>();
194 single
.add(new JcrPath(this, JcrPath
.separator
));
199 public Iterable
<FileStore
> getFileStores() {
200 List
<FileStore
> stores
= new ArrayList
<>();
201 stores
.add(baseFileStore
);
202 stores
.addAll(mounts
.values());
207 public Set
<String
> supportedFileAttributeViews() {
209 String
[] prefixes
= session
.getNamespacePrefixes();
210 Set
<String
> res
= new HashSet
<>();
211 for (String prefix
: prefixes
)
215 } catch (RepositoryException e
) {
216 throw new JcrFsException("Cannot get supported file attributes views", e
);
221 public Path
getPath(String first
, String
... more
) {
222 StringBuilder sb
= new StringBuilder(first
);
223 // TODO Make it more robust
224 for (String part
: more
)
225 sb
.append('/').append(part
);
226 return new JcrPath(this, sb
.toString());
230 public PathMatcher
getPathMatcher(String syntaxAndPattern
) {
231 throw new UnsupportedOperationException();
235 public UserPrincipalLookupService
getUserPrincipalLookupService() {
236 throw new UnsupportedOperationException();
240 public WatchService
newWatchService() throws IOException
{
241 throw new UnsupportedOperationException();
244 // public Session getSession() {
248 public Repository
getRepository() {