+ /** Safely and silently logs out the underlying session. */
+ public static void logout(Node node) {
+ Jcr.logout(session(node));
+ }
+
+ /*
+ * 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 JcrException("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 JcrException("Cannot retrieve checked out status of " + node, e);
+ }
+ }
+
+ /** @see VersionManager#checkpoint(String) */
+ public static void checkpoint(Node node) {
+ try {
+ versionManager(node).checkpoint(node.getPath());
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot check in " + node, e);
+ }
+ }
+
+ /** @see VersionManager#checkin(String) */
+ public static void checkin(Node node) {
+ try {
+ versionManager(node).checkin(node.getPath());
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot check in " + node, e);
+ }
+ }
+
+ /** @see VersionManager#checkout(String) */
+ public static void checkout(Node node) {
+ try {
+ versionManager(node).checkout(node.getPath());
+ } catch (RepositoryException e) {
+ throw new JcrException("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 JcrException("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 JcrException("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<Version> getLinearVersions(VersionHistory versionHistory) {
+ try {
+ List<Version> 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 JcrException("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 JcrException("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 JcrException("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 JcrException("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 JcrException("Cannot get file size of binary " + binaryArg, e);
+ }
+ }
+
+ // QUERY
+ /** Creates a JCR-SQL2 query using {@link MessageFormat}. */
+ public static Query createQuery(QueryManager qm, String sql, Object... args) {
+ String query = MessageFormat.format(sql, args);
+ try {
+ return qm.createQuery(query, Query.JCR_SQL2);
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot create JCR-SQL2 query from " + query, e);
+ }
+ }
+
+ /** Executes a JCR-SQL2 query using {@link MessageFormat}. */
+ public static NodeIterator executeQuery(QueryManager qm, String sql, Object... args) {
+ Query query = createQuery(qm, sql, args);
+ try {
+ return query.execute().getNodes();
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot execute query " + sql + " with arguments " + Arrays.asList(args), e);
+ }
+ }
+
+ /** Executes a JCR-SQL2 query using {@link MessageFormat}. */
+ public static NodeIterator executeQuery(Session session, String sql, Object... args) {
+ QueryManager queryManager;
+ try {
+ queryManager = session.getWorkspace().getQueryManager();
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot get query manager from session " + session, e);
+ }
+ return executeQuery(queryManager, sql, args);
+ }
+
+ /**
+ * Executes a JCR-SQL2 query using {@link MessageFormat}, which must return a
+ * single node at most.
+ *
+ * @return the node or <code>null</code> if not found.
+ */
+ public static Node getNode(QueryManager qm, String sql, Object... args) {
+ NodeIterator nit = executeQuery(qm, sql, args);
+ if (nit.hasNext()) {
+ Node node = nit.nextNode();
+ if (nit.hasNext())
+ throw new IllegalStateException(
+ "Query " + sql + " with arguments " + Arrays.asList(args) + " returned more than one node.");
+ return node;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Executes a JCR-SQL2 query using {@link MessageFormat}, which must return a
+ * single node at most.
+ *
+ * @return the node or <code>null</code> if not found.
+ */
+ public static Node getNode(Session session, String sql, Object... args) {
+ QueryManager queryManager;
+ try {
+ queryManager = session.getWorkspace().getQueryManager();
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot get query manager from session " + session, e);
+ }
+ return getNode(queryManager, sql, args);
+ }
+