1 package org.argeo.documents.core;
2
3 import java.io.IOException;
4 import java.net.URI;
5 import java.net.URISyntaxException;
6 import java.nio.file.FileSystem;
7 import java.nio.file.Path;
8 import java.nio.file.spi.FileSystemProvider;
9 import java.util.ArrayList;
10 import java.util.List;
11
12 import javax.jcr.Node;
13 import javax.jcr.NodeIterator;
14 import javax.jcr.Property;
15 import javax.jcr.Repository;
16 import javax.jcr.RepositoryException;
17 import javax.jcr.Session;
18 import javax.jcr.nodetype.NodeType;
19 import javax.jcr.query.Query;
20 import javax.jcr.query.QueryManager;
21 import javax.naming.ldap.LdapName;
22
23 import org.argeo.cms.auth.CurrentUser;
24 import org.argeo.connect.ConnectConstants;
25 import org.argeo.connect.core.AbstractAppService;
26 import org.argeo.connect.util.ConnectJcrUtils;
27 import org.argeo.documents.DocumentsConstants;
28 import org.argeo.documents.DocumentsException;
29 import org.argeo.documents.DocumentsNames;
30 import org.argeo.documents.DocumentsService;
31 import org.argeo.documents.DocumentsTypes;
32 import org.argeo.jcr.JcrUtils;
33 import org.argeo.node.NodeConstants;
34 import org.argeo.node.NodeUtils;
35
36
37 public class DocumentsServiceImpl extends AbstractAppService implements DocumentsService {
38
39
40 @Override
41 public Node publishEntity(Node parent, String nodeType, Node srcNode, boolean removeSrcNode)
42 throws RepositoryException {
43 return null;
44 }
45
46 @Override
47 public String getAppBaseName() {
48 return DocumentsConstants.DOCUMENTS_APP_LBL;
49 }
50
51 @Override
52 public String getDefaultRelPath(Node entity) throws RepositoryException {
53 throw new DocumentsException("No default relpath is defined for the Documents App");
54 }
55
56 @Override
57 public String getDefaultRelPath(Session session, String nodeType, String id) {
58 throw new DocumentsException("No default relpath is defined for the Documents App");
59 }
60
61 @Override
62 public boolean isKnownType(Node entity) {
63 if (ConnectJcrUtils.isNodeType(entity, NodeType.NT_FILE)
64 || ConnectJcrUtils.isNodeType(entity, NodeType.NT_FOLDER))
65 return true;
66 else
67 return false;
68 }
69
70 @Override
71 public boolean isKnownType(String nodeType) {
72 if (NodeType.NT_FILE.equals(nodeType) || NodeType.NT_FOLDER.equals(nodeType))
73 return true;
74 else
75 return false;
76 }
77
78
79
80 public Path[] getMyDocumentsPath(FileSystemProvider nodeFileSystemProvider, Session session) {
81 Node home = NodeUtils.getUserHome(session);
82 Path[] paths = { getPath(nodeFileSystemProvider, ConnectJcrUtils.getPath(home)) };
83
84
85
86
87 return paths;
88 }
89
90 public Path[] getMyGroupsFilesPath(FileSystemProvider nodeFileSystemProvider, Session session) {
91 try {
92 List<Path> paths = new ArrayList<>();
93 for (String dn : CurrentUser.roles()) {
94 LdapName ln = new LdapName(dn);
95 String cn = (String) ln.getRdn(ln.size() - 1).getValue();
96 Node workgroupHome = NodeUtils.getGroupHome(session, cn);
97 if (workgroupHome != null) {
98 paths.add(getPath(nodeFileSystemProvider, ConnectJcrUtils.getPath(workgroupHome)));
99
100
101
102
103
104
105
106
107 }
108 }
109 return paths.toArray(new Path[0]);
110 } catch (Exception e) {
111 throw new DocumentsException("Cannot retrieve work group home paths", e);
112 }
113 }
114
115 public Path[] getMyBookmarks(FileSystemProvider nodeFileSystemProvider, Session session) {
116 try {
117 Node bookmarkParent = getMyBookmarksParent(session);
118 List<Path> bookmarks = new ArrayList<>();
119 NodeIterator nit = bookmarkParent.getNodes();
120 while (nit.hasNext()) {
121 Node currBookmark = nit.nextNode();
122 String uriStr = ConnectJcrUtils.get(currBookmark, DocumentsNames.DOCUMENTS_URI);
123 URI uri = new URI(uriStr);
124 bookmarks.add(getPath(nodeFileSystemProvider, uri));
125 }
126 return bookmarks.toArray(new Path[0]);
127 } catch (URISyntaxException | RepositoryException e) {
128 throw new DocumentsException("Cannot retrieve CurrentUser bookmarks", e);
129 }
130 }
131
132 public Node[] getMyBookmarks(Session session) {
133 try {
134 Node bookmarkParent = getMyBookmarksParent(session);
135 List<Node> bookmarks = new ArrayList<>();
136 NodeIterator nit = bookmarkParent.getNodes();
137 while (nit.hasNext()) {
138 Node currBookmark = nit.nextNode();
139 if (currBookmark.isNodeType(DocumentsTypes.DOCUMENTS_BOOKMARK)) {
140 bookmarks.add(currBookmark);
141 }
142 }
143 return bookmarks.toArray(new Node[0]);
144 } catch (RepositoryException e) {
145 throw new DocumentsException("Cannot retrieve CurrentUser bookmarks", e);
146 }
147 }
148
149 public Node getMyBookmarksParent(Session session) {
150 try {
151
152
153
154
155
156
157
158
159
160
161
162 if (session.hasPendingChanges())
163 throw new DocumentsException("Session must be clean to retrieve bookmarks");
164 Node home = NodeUtils.getUserHome(session);
165 String relPath = ConnectConstants.HOME_APP_SYS_RELPARPATH + "/" + DocumentsConstants.DOCUMENTS_APP_BASE_NAME
166 + "/" + DocumentsConstants.DOCUMENTS_BOOKMARKS;
167 Node bookmarkParent = JcrUtils.mkdirs(home, relPath);
168 if (session.hasPendingChanges())
169 session.save();
170 return bookmarkParent;
171 } catch (RepositoryException e) {
172 throw new DocumentsException("Cannot retrieve bookmark parent for session " + session, e);
173 }
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 public Path getPath(FileSystemProvider nodeFileSystemProvider, String nodePath) {
193
194
195 URI uri = nodePathToURI(nodePath);
196 return getPath(nodeFileSystemProvider, uri);
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 }
213
214 public NodeIterator getLastUpdatedDocuments(Session session) {
215 try {
216 String qStr = "//element(*, " + ConnectJcrUtils.getLocalJcrItemName(NodeType.NT_FILE) + ")";
217 qStr += " order by @" + ConnectJcrUtils.getLocalJcrItemName(Property.JCR_LAST_MODIFIED) + " descending";
218 QueryManager queryManager = session.getWorkspace().getQueryManager();
219 Query xpathQuery = queryManager.createQuery(qStr, ConnectConstants.QUERY_XPATH);
220 xpathQuery.setLimit(8);
221 NodeIterator nit = xpathQuery.execute().getNodes();
222 return nit;
223 } catch (RepositoryException e) {
224 throw new DocumentsException("Unable to retrieve last updated documents", e);
225 }
226 }
227
228 public Path getPath(FileSystemProvider nodeFileSystemProvider, URI uri) {
229 try {
230 FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri);
231 if (fileSystem == null)
232 fileSystem = nodeFileSystemProvider.newFileSystem(uri, null);
233
234
235 String path = uri.getPath();
236 return fileSystem.getPath(path);
237 } catch (IOException e) {
238 throw new DocumentsException("Unable to initialise file system for " + uri, e);
239 }
240 }
241
242 public Node createFolderBookmark(Path path, String name, Repository repository) {
243 Session session = null;
244 try {
245 session = repository.login();
246 Node bookmarkParent = getMyBookmarksParent(session);
247
248
249 String nodeName = path.getFileName().toString();
250 Node bookmark = bookmarkParent.addNode(nodeName);
251 bookmark.addMixin(DocumentsTypes.DOCUMENTS_BOOKMARK);
252 bookmark.setProperty(DocumentsNames.DOCUMENTS_URI, nodePathToURI(path.toString()).toString());
253 bookmark.setProperty(Property.JCR_TITLE, name);
254 session.save();
255 return bookmark;
256 } catch (RepositoryException e) {
257 throw new DocumentsException("Cannot create bookmark for " + path + " with name " + name, e);
258 } finally {
259 JcrUtils.logoutQuietly(session);
260 }
261 }
262
263 private static URI nodePathToURI(String nodePath) {
264 try {
265 return new URI(NodeConstants.SCHEME_NODE, null, nodePath, null);
266 } catch (URISyntaxException e) {
267 throw new DocumentsException("Badly formatted path " + nodePath, e);
268 }
269 }
270 }