X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.jcr%2Fsrc%2Forg%2Fargeo%2Fjcr%2FJcr.java;h=230921d551f191ae65f879b998308936d7aff248;hb=5ec9d72c96b13bf18d702bf01dc2c03b0aee43a4;hp=f8ad9c79cca88dd58526b0320612940e61993c8d;hpb=25e4528153640a2e211e217468f8f5aa01607cf0;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.jcr/src/org/argeo/jcr/Jcr.java b/org.argeo.jcr/src/org/argeo/jcr/Jcr.java index f8ad9c79c..230921d55 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/Jcr.java +++ b/org.argeo.jcr/src/org/argeo/jcr/Jcr.java @@ -1,9 +1,16 @@ package org.argeo.jcr; +import java.math.BigDecimal; +import java.time.Instant; import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; +import javax.jcr.Binary; import javax.jcr.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.NodeIterator; @@ -13,6 +20,12 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; +import javax.jcr.nodetype.NodeType; +import javax.jcr.security.Privilege; +import javax.jcr.version.Version; +import javax.jcr.version.VersionHistory; +import javax.jcr.version.VersionIterator; +import javax.jcr.version.VersionManager; /** * Utility class whose purpose is to make using JCR less verbose by @@ -200,6 +213,48 @@ public class Jcr { } } + /** + * Set a property to the given value, or remove it if the value is + * null. + * + * @throws IllegalStateException caused by {@link RepositoryException} + */ + public static void set(Node node, String property, Object value) { + try { + if (!node.hasProperty(property)) + throw new IllegalArgumentException("No property " + property + " in " + node); + Property prop = node.getProperty(property); + if (value == null) { + prop.remove(); + return; + } + + if (value instanceof String) + prop.setValue((String) value); + else if (value instanceof Long) + prop.setValue((Long) value); + else if (value instanceof Double) + prop.setValue((Double) value); + else if (value instanceof Calendar) + prop.setValue((Calendar) value); + else if (value instanceof BigDecimal) + prop.setValue((BigDecimal) value); + else if (value instanceof Boolean) + prop.setValue((Boolean) value); + else if (value instanceof byte[]) + JcrUtils.setBinaryAsBytes(prop, (byte[]) value); + else if (value instanceof Instant) { + Instant instant = (Instant) value; + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(Date.from(instant)); + prop.setValue(calendar); + } else // try with toString() + prop.setValue(value.toString()); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot set property " + property + " of " + node + " to " + value, e); + } + } + /** * Get property as {@link String}. * @@ -290,6 +345,33 @@ public class Jcr { } } + /** Retrieves the {@link Session} related to this node. */ + public static Session session(Node node) { + try { + return node.getSession(); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot retrieve session related to " + node, e); + } + } + + /** + * Saves the {@link Session} related to this node. Note that all other unrelated + * modifications in this session will also be saved. + */ + public static void save(Node node) { + try { + Session session = node.getSession(); + if (node.isNodeType(NodeType.MIX_LAST_MODIFIED)) { + set(node, Property.JCR_LAST_MODIFIED, Instant.now()); + set(node, Property.JCR_LAST_MODIFIED_BY, session.getUserID()); + } + session.save(); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot save session related to " + node + " in workspace " + + session(node).getWorkspace().getName(), e); + } + } + /** Login to a JCR repository. */ public static Session login(Repository repository, String workspace) { try { @@ -310,6 +392,136 @@ public class Jcr { } } + /* + * SECURITY + */ + /** + * Add a single privilege to a node. + * + * @see Privilege + */ + public static void addPrivilege(Node node, String principal, String privilege) { + try { + Session session = node.getSession(); + JcrUtils.addPrivilege(session, node.getPath(), principal, privilege); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot add privilege " + privilege + " to " + node, e); + } + } + + /* + * VERSIONING + */ + /** Get checked out status. */ + public static boolean isCheckedOut(Node node) { + try { + return node.isCheckedOut(); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot retrieve checked out status of " + node, e); + } + } + + /** Check in this node. */ + public static void checkin(Node node) { + try { + versionManager(node).checkin(node.getPath()); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot check in " + node, e); + } + } + + /** Check out this node. */ + public static void checkout(Node node) { + try { + versionManager(node).checkout(node.getPath()); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot check out " + node, e); + } + } + + /** Get the {@link VersionManager} related to this node. */ + public static VersionManager versionManager(Node node) { + try { + return node.getSession().getWorkspace().getVersionManager(); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot get version manager from " + node, e); + } + } + + /** Get the {@link VersionHistory} related to this node. */ + public static VersionHistory getVersionHistory(Node node) { + try { + return versionManager(node).getVersionHistory(node.getPath()); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot get version history from " + node, e); + } + } + + /** + * The linear versions of this version history in reverse order and without the + * root version. + */ + public static List getLinearVersions(VersionHistory versionHistory) { + try { + List lst = new ArrayList<>(); + VersionIterator vit = versionHistory.getAllLinearVersions(); + while (vit.hasNext()) + lst.add(vit.nextVersion()); + lst.remove(0); + Collections.reverse(lst); + return lst; + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot get linear versions from " + versionHistory, e); + } + } + + /** The frozen node related to this {@link Version}. */ + public static Node getFrozenNode(Version version) { + try { + return version.getFrozenNode(); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot get frozen node from " + version, e); + } + } + + /** Get the base {@link Version} related to this node. */ + public static Version getBaseVersion(Node node) { + try { + return versionManager(node).getBaseVersion(node.getPath()); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot get base version from " + node, e); + } + } + + /* + * FILES + */ + /** + * Returns the size of this file. + * + * @see NodeType#NT_FILE + */ + public static long getFileSize(Node fileNode) { + try { + if (!fileNode.isNodeType(NodeType.NT_FILE)) + throw new IllegalArgumentException(fileNode + " must be a file."); + return getBinarySize(fileNode.getNode(Node.JCR_CONTENT).getProperty(Property.JCR_DATA).getBinary()); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot get file size of " + fileNode, e); + } + } + + /** Returns the size of this {@link Binary}. */ + public static long getBinarySize(Binary binaryArg) { + try { + try (Bin binary = new Bin(binaryArg)) { + return binary.getSize(); + } + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot get file size of binary " + binaryArg, e); + } + } + /** Singleton. */ private Jcr() {