1 package org.argeo.jcr;
2
3 import java.math.BigDecimal;
4 import java.time.Instant;
5 import java.util.ArrayList;
6 import java.util.Calendar;
7 import java.util.Collections;
8 import java.util.Date;
9 import java.util.GregorianCalendar;
10 import java.util.Iterator;
11 import java.util.List;
12
13 import javax.jcr.Binary;
14 import javax.jcr.ItemNotFoundException;
15 import javax.jcr.Node;
16 import javax.jcr.NodeIterator;
17 import javax.jcr.Property;
18 import javax.jcr.PropertyType;
19 import javax.jcr.Repository;
20 import javax.jcr.RepositoryException;
21 import javax.jcr.Session;
22 import javax.jcr.Value;
23 import javax.jcr.nodetype.NodeType;
24 import javax.jcr.security.Privilege;
25 import javax.jcr.version.Version;
26 import javax.jcr.version.VersionHistory;
27 import javax.jcr.version.VersionIterator;
28 import javax.jcr.version.VersionManager;
29
30
31
32
33
34
35
36
37 public class Jcr {
38
39
40
41
42
43 public static boolean isNodeType(Node node, String nodeTypeName) {
44 try {
45 return node.isNodeType(nodeTypeName);
46 } catch (RepositoryException e) {
47 throw new IllegalStateException("Cannot get whether " + node + " is of type " + nodeTypeName, e);
48 }
49 }
50
51
52
53
54
55 public static boolean hasNodes(Node node) {
56 try {
57 return node.hasNodes();
58 } catch (RepositoryException e) {
59 throw new IllegalStateException("Cannot get whether " + node + " has children.", e);
60 }
61 }
62
63
64
65
66
67 public static Node getParent(Node node) {
68 try {
69 return isRoot(node) ? null : node.getParent();
70 } catch (RepositoryException e) {
71 throw new IllegalStateException("Cannot get parent of " + node, e);
72 }
73 }
74
75
76
77
78
79
80 public static boolean isRoot(Node node) {
81 try {
82 return node.getDepth() == 0;
83 } catch (RepositoryException e) {
84 throw new IllegalStateException("Cannot get depth of " + node, e);
85 }
86 }
87
88
89
90
91
92 public static String getPath(Node node) {
93 try {
94 return node.getPath();
95 } catch (RepositoryException e) {
96 throw new IllegalStateException("Cannot get path of " + node, e);
97 }
98 }
99
100
101
102
103
104 public static String getIdentifier(Node node) {
105 try {
106 return node.getIdentifier();
107 } catch (RepositoryException e) {
108 throw new IllegalStateException("Cannot get identifier of " + node, e);
109 }
110 }
111
112
113
114
115
116 public static String getName(Node node) {
117 try {
118 return node.getName();
119 } catch (RepositoryException e) {
120 throw new IllegalStateException("Cannot get name of " + node, e);
121 }
122 }
123
124
125 @SuppressWarnings("unchecked")
126 public static Iterable<Node> iterate(NodeIterator nodeIterator) {
127 return new Iterable<Node>() {
128
129 @Override
130 public Iterator<Node> iterator() {
131 return nodeIterator;
132 }
133 };
134 }
135
136
137
138
139
140
141 public static Iterable<Node> nodes(Node node) {
142 try {
143 return iterate(node.getNodes());
144 } catch (RepositoryException e) {
145 throw new IllegalStateException("Cannot get children of " + node, e);
146 }
147 }
148
149
150
151
152
153
154 public static List<Node> getNodes(Node node) {
155 List<Node> nodes = new ArrayList<>();
156 try {
157 if (node.hasNodes()) {
158 NodeIterator nit = node.getNodes();
159 while (nit.hasNext())
160 nodes.add(nit.nextNode());
161 return nodes;
162 } else
163 return nodes;
164 } catch (RepositoryException e) {
165 throw new IllegalStateException("Cannot get children of " + node, e);
166 }
167 }
168
169
170
171
172
173
174 public static Node getNode(Node node, String child) {
175 try {
176 if (node.hasNode(child))
177 return node.getNode(child);
178 else
179 return null;
180 } catch (RepositoryException e) {
181 throw new IllegalStateException("Cannot get child of " + node, e);
182 }
183 }
184
185
186
187
188
189
190 public static Node getNode(Session session, String path) {
191 try {
192 if (session.nodeExists(path))
193 return session.getNode(path);
194 else
195 return null;
196 } catch (RepositoryException e) {
197 throw new IllegalStateException("Cannot get node " + path, e);
198 }
199 }
200
201
202
203
204
205
206 public static Node getNodeById(Session session, String id) {
207 try {
208 return session.getNodeByIdentifier(id);
209 } catch (ItemNotFoundException e) {
210 return null;
211 } catch (RepositoryException e) {
212 throw new IllegalStateException("Cannot get node with id " + id, e);
213 }
214 }
215
216
217
218
219
220
221
222 public static void set(Node node, String property, Object value) {
223 try {
224 if (!node.hasProperty(property))
225 throw new IllegalArgumentException("No property " + property + " in " + node);
226 Property prop = node.getProperty(property);
227 if (value == null) {
228 prop.remove();
229 return;
230 }
231
232 if (value instanceof String)
233 prop.setValue((String) value);
234 else if (value instanceof Long)
235 prop.setValue((Long) value);
236 else if (value instanceof Double)
237 prop.setValue((Double) value);
238 else if (value instanceof Calendar)
239 prop.setValue((Calendar) value);
240 else if (value instanceof BigDecimal)
241 prop.setValue((BigDecimal) value);
242 else if (value instanceof Boolean)
243 prop.setValue((Boolean) value);
244 else if (value instanceof byte[])
245 JcrUtils.setBinaryAsBytes(prop, (byte[]) value);
246 else if (value instanceof Instant) {
247 Instant instant = (Instant) value;
248 GregorianCalendar calendar = new GregorianCalendar();
249 calendar.setTime(Date.from(instant));
250 prop.setValue(calendar);
251 } else
252 prop.setValue(value.toString());
253 } catch (RepositoryException e) {
254 throw new IllegalStateException("Cannot set property " + property + " of " + node + " to " + value, e);
255 }
256 }
257
258
259
260
261
262
263
264
265
266 public static String get(Node node, String property) {
267 return get(node, property, null);
268 }
269
270
271
272
273
274
275
276
277
278 public static String get(Node node, String property, String defaultValue) {
279 try {
280 if (node.hasProperty(property))
281 return node.getProperty(property).getString();
282 else
283 return defaultValue;
284 } catch (RepositoryException e) {
285 throw new IllegalStateException("Cannot retrieve property " + property + " from " + node);
286 }
287 }
288
289
290
291
292
293
294
295
296 public static Value getValue(Node node, String property) {
297 try {
298 if (node.hasProperty(property))
299 return node.getProperty(property).getValue();
300 else
301 return null;
302 } catch (RepositoryException e) {
303 throw new IllegalStateException("Cannot retrieve property " + property + " from " + node);
304 }
305 }
306
307
308
309
310
311
312
313
314
315
316 @SuppressWarnings("unchecked")
317 public static <T> T getAs(Node node, String property, T defaultValue) {
318 try {
319 if (node.hasProperty(property)) {
320 Property p = node.getProperty(property);
321 try {
322 switch (p.getType()) {
323 case PropertyType.STRING:
324 return (T) node.getProperty(property).getString();
325 case PropertyType.DOUBLE:
326 return (T) (Double) node.getProperty(property).getDouble();
327 case PropertyType.LONG:
328 return (T) (Long) node.getProperty(property).getLong();
329 case PropertyType.BOOLEAN:
330 return (T) (Boolean) node.getProperty(property).getBoolean();
331 case PropertyType.DATE:
332 return (T) node.getProperty(property).getDate();
333 default:
334 return (T) node.getProperty(property).getString();
335 }
336 } catch (ClassCastException e) {
337 throw new IllegalArgumentException(
338 "Cannot cast property of type " + PropertyType.nameFromValue(p.getType()), e);
339 }
340 } else {
341 return defaultValue;
342 }
343 } catch (RepositoryException e) {
344 throw new IllegalStateException("Cannot retrieve property " + property + " from " + node);
345 }
346 }
347
348
349 public static Session session(Node node) {
350 try {
351 return node.getSession();
352 } catch (RepositoryException e) {
353 throw new IllegalStateException("Cannot retrieve session related to " + node, e);
354 }
355 }
356
357
358
359
360
361 public static void save(Node node) {
362 try {
363 Session session = node.getSession();
364
365
366
367
368 if (session.hasPendingChanges())
369 session.save();
370 } catch (RepositoryException e) {
371 throw new IllegalStateException("Cannot save session related to " + node + " in workspace "
372 + session(node).getWorkspace().getName(), e);
373 }
374 }
375
376
377 public static Session login(Repository repository, String workspace) {
378 try {
379 return repository.login(workspace);
380 } catch (RepositoryException e) {
381 throw new IllegalArgumentException("Cannot login to repository", e);
382 }
383 }
384
385
386 public static void logout(Session session) {
387 try {
388 if (session != null)
389 if (session.isLive())
390 session.logout();
391 } catch (Exception e) {
392
393 }
394 }
395
396
397
398
399
400
401
402
403
404 public static void addPrivilege(Node node, String principal, String privilege) {
405 try {
406 Session session = node.getSession();
407 JcrUtils.addPrivilege(session, node.getPath(), principal, privilege);
408 } catch (RepositoryException e) {
409 throw new IllegalStateException("Cannot add privilege " + privilege + " to " + node, e);
410 }
411 }
412
413
414
415
416
417 public static boolean isCheckedOut(Node node) {
418 try {
419 return node.isCheckedOut();
420 } catch (RepositoryException e) {
421 throw new IllegalStateException("Cannot retrieve checked out status of " + node, e);
422 }
423 }
424
425
426 public static void checkpoint(Node node) {
427 try {
428 versionManager(node).checkpoint(node.getPath());
429 } catch (RepositoryException e) {
430 throw new IllegalStateException("Cannot check in " + node, e);
431 }
432 }
433
434
435 public static void checkin(Node node) {
436 try {
437 versionManager(node).checkin(node.getPath());
438 } catch (RepositoryException e) {
439 throw new IllegalStateException("Cannot check in " + node, e);
440 }
441 }
442
443
444 public static void checkout(Node node) {
445 try {
446 versionManager(node).checkout(node.getPath());
447 } catch (RepositoryException e) {
448 throw new IllegalStateException("Cannot check out " + node, e);
449 }
450 }
451
452
453 public static VersionManager versionManager(Node node) {
454 try {
455 return node.getSession().getWorkspace().getVersionManager();
456 } catch (RepositoryException e) {
457 throw new IllegalStateException("Cannot get version manager from " + node, e);
458 }
459 }
460
461
462 public static VersionHistory getVersionHistory(Node node) {
463 try {
464 return versionManager(node).getVersionHistory(node.getPath());
465 } catch (RepositoryException e) {
466 throw new IllegalStateException("Cannot get version history from " + node, e);
467 }
468 }
469
470
471
472
473
474 public static List<Version> getLinearVersions(VersionHistory versionHistory) {
475 try {
476 List<Version> lst = new ArrayList<>();
477 VersionIterator vit = versionHistory.getAllLinearVersions();
478 while (vit.hasNext())
479 lst.add(vit.nextVersion());
480 lst.remove(0);
481 Collections.reverse(lst);
482 return lst;
483 } catch (RepositoryException e) {
484 throw new IllegalStateException("Cannot get linear versions from " + versionHistory, e);
485 }
486 }
487
488
489 public static Node getFrozenNode(Version version) {
490 try {
491 return version.getFrozenNode();
492 } catch (RepositoryException e) {
493 throw new IllegalStateException("Cannot get frozen node from " + version, e);
494 }
495 }
496
497
498 public static Version getBaseVersion(Node node) {
499 try {
500 return versionManager(node).getBaseVersion(node.getPath());
501 } catch (RepositoryException e) {
502 throw new IllegalStateException("Cannot get base version from " + node, e);
503 }
504 }
505
506
507
508
509
510
511
512
513
514 public static long getFileSize(Node fileNode) {
515 try {
516 if (!fileNode.isNodeType(NodeType.NT_FILE))
517 throw new IllegalArgumentException(fileNode + " must be a file.");
518 return getBinarySize(fileNode.getNode(Node.JCR_CONTENT).getProperty(Property.JCR_DATA).getBinary());
519 } catch (RepositoryException e) {
520 throw new IllegalStateException("Cannot get file size of " + fileNode, e);
521 }
522 }
523
524
525 public static long getBinarySize(Binary binaryArg) {
526 try {
527 try (Bin binary = new Bin(binaryArg)) {
528 return binary.getSize();
529 }
530 } catch (RepositoryException e) {
531 throw new IllegalStateException("Cannot get file size of binary " + binaryArg, e);
532 }
533 }
534
535
536 private Jcr() {
537
538 }
539 }