]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java
Merge remote-tracking branch 'origin/master' into v2.x
[lgpl/argeo-commons.git] / org.argeo.jcr / src / org / argeo / jcr / fs / JcrFileSystem.java
1 package org.argeo.jcr.fs;
2
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;
15 import java.util.Map;
16 import java.util.Set;
17 import java.util.TreeMap;
18
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;
25
26 import org.argeo.jcr.Jcr;
27 import org.argeo.jcr.JcrUtils;
28
29 public class JcrFileSystem extends FileSystem {
30 private final JcrFileSystemProvider provider;
31
32 private final Repository repository;
33 private Session session;
34 private WorkspaceFileStore baseFileStore;
35
36 private Map<String, WorkspaceFileStore> mounts = new TreeMap<>();
37
38 private String userHomePath = null;
39
40 @Deprecated
41 public JcrFileSystem(JcrFileSystemProvider provider, Session session) throws IOException {
42 super();
43 this.provider = provider;
44 baseFileStore = new WorkspaceFileStore(null, session.getWorkspace());
45 this.session = session;
46 // Node userHome = provider.getUserHome(session);
47 // if (userHome != null)
48 // try {
49 // userHomePath = userHome.getPath();
50 // } catch (RepositoryException e) {
51 // throw new IOException("Cannot retrieve user home path", e);
52 // }
53 this.repository = null;
54 }
55
56 public JcrFileSystem(JcrFileSystemProvider provider, Repository repository) throws IOException {
57 this(provider, repository, null);
58 }
59
60 public JcrFileSystem(JcrFileSystemProvider provider, Repository repository, Credentials credentials)
61 throws IOException {
62 super();
63 this.provider = provider;
64 this.repository = repository;
65 try {
66 this.session = credentials == null ? repository.login() : repository.login(credentials);
67 baseFileStore = new WorkspaceFileStore(null, session.getWorkspace());
68 workspaces: for (String workspaceName : baseFileStore.getWorkspace().getAccessibleWorkspaceNames()) {
69 if (workspaceName.equals(baseFileStore.getWorkspace().getName()))
70 continue workspaces;// do not mount base
71 if (workspaceName.equals("security")) {
72 continue workspaces;// do not mount security workspace
73 // TODO make it configurable
74 }
75 Session mountSession = credentials == null ? repository.login(workspaceName)
76 : repository.login(credentials, workspaceName);
77 String mountPath = JcrPath.separator + workspaceName;
78 mounts.put(mountPath, new WorkspaceFileStore(mountPath, mountSession.getWorkspace()));
79 }
80 } catch (RepositoryException e) {
81 throw new IOException("Cannot initialise file system", e);
82 }
83
84 Node userHome = provider.getUserHome(repository);
85 if (userHome != null)
86 try {
87 userHomePath = toFsPath(userHome);
88 } catch (RepositoryException e) {
89 throw new IOException("Cannot retrieve user home path", e);
90 } finally {
91 JcrUtils.logoutQuietly(Jcr.session(userHome));
92 }
93 }
94
95 public String toFsPath(Node node) throws RepositoryException {
96 return getFileStore(node).toFsPath(node);
97 }
98
99 /** Whether this node should be skipped in directory listings */
100 public boolean skipNode(Node node) throws RepositoryException {
101 if (node.isNodeType(NodeType.NT_HIERARCHY_NODE))
102 return false;
103 return true;
104 }
105
106 public String getUserHomePath() {
107 return userHomePath;
108 }
109
110 public WorkspaceFileStore getFileStore(String path) {
111 WorkspaceFileStore res = baseFileStore;
112 for (String mountPath : mounts.keySet()) {
113 if (path.equals(mountPath))
114 return mounts.get(mountPath);
115 if (path.startsWith(mountPath + JcrPath.separator)) {
116 res = mounts.get(mountPath);
117 // we keep the last one
118 }
119 }
120 assert res != null;
121 return res;
122 }
123
124 public WorkspaceFileStore getFileStore(Node node) throws RepositoryException {
125 String workspaceName = node.getSession().getWorkspace().getName();
126 if (workspaceName.equals(baseFileStore.getWorkspace().getName()))
127 return baseFileStore;
128 for (String mountPath : mounts.keySet()) {
129 WorkspaceFileStore fileStore = mounts.get(mountPath);
130 if (workspaceName.equals(fileStore.getWorkspace().getName()))
131 return fileStore;
132 }
133 throw new IllegalStateException("No workspace mount found for " + node + " in workspace " + workspaceName);
134 }
135
136 public Iterator<JcrPath> listDirectMounts(Path base) {
137 String baseStr = base.toString();
138 Set<JcrPath> res = new HashSet<>();
139 mounts: for (String mountPath : mounts.keySet()) {
140 if (mountPath.equals(baseStr))
141 continue mounts;
142 if (mountPath.startsWith(baseStr)) {
143 JcrPath path = new JcrPath(this, mountPath);
144 Path relPath = base.relativize(path);
145 if (relPath.getNameCount() == 1)
146 res.add(path);
147 }
148 }
149 return res.iterator();
150 }
151
152 public WorkspaceFileStore getBaseFileStore() {
153 return baseFileStore;
154 }
155
156 @Override
157 public FileSystemProvider provider() {
158 return provider;
159 }
160
161 @Override
162 public void close() throws IOException {
163 JcrUtils.logoutQuietly(session);
164 for (String mountPath : mounts.keySet()) {
165 WorkspaceFileStore fileStore = mounts.get(mountPath);
166 try {
167 fileStore.close();
168 } catch (Exception e) {
169 e.printStackTrace();
170 }
171 }
172 }
173
174 @Override
175 public boolean isOpen() {
176 return session.isLive();
177 }
178
179 @Override
180 public boolean isReadOnly() {
181 return false;
182 }
183
184 @Override
185 public String getSeparator() {
186 return JcrPath.separator;
187 }
188
189 @Override
190 public Iterable<Path> getRootDirectories() {
191 Set<Path> single = new HashSet<>();
192 single.add(new JcrPath(this, JcrPath.separator));
193 return single;
194 }
195
196 @Override
197 public Iterable<FileStore> getFileStores() {
198 List<FileStore> stores = new ArrayList<>();
199 stores.add(baseFileStore);
200 stores.addAll(mounts.values());
201 return stores;
202 }
203
204 @Override
205 public Set<String> supportedFileAttributeViews() {
206 try {
207 String[] prefixes = session.getNamespacePrefixes();
208 Set<String> res = new HashSet<>();
209 for (String prefix : prefixes)
210 res.add(prefix);
211 res.add("basic");
212 return res;
213 } catch (RepositoryException e) {
214 throw new JcrFsException("Cannot get supported file attributes views", e);
215 }
216 }
217
218 @Override
219 public Path getPath(String first, String... more) {
220 StringBuilder sb = new StringBuilder(first);
221 // TODO Make it more robust
222 for (String part : more)
223 sb.append('/').append(part);
224 return new JcrPath(this, sb.toString());
225 }
226
227 @Override
228 public PathMatcher getPathMatcher(String syntaxAndPattern) {
229 throw new UnsupportedOperationException();
230 }
231
232 @Override
233 public UserPrincipalLookupService getUserPrincipalLookupService() {
234 throw new UnsupportedOperationException();
235 }
236
237 @Override
238 public WatchService newWatchService() throws IOException {
239 throw new UnsupportedOperationException();
240 }
241
242 // public Session getSession() {
243 // return session;
244 // }
245
246 public Repository getRepository() {
247 return repository;
248 }
249
250 }