Introduce JCR XML utilities.
[lgpl/argeo-commons.git] / org.argeo.jcr / src / org / argeo / jcr / Jcr.java
index 230921d551f191ae65f879b998308936d7aff248..5ce8017ca4120c14accae02dc6669f1d87176771 100644 (file)
@@ -20,6 +20,7 @@ import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.Value;
+import javax.jcr.Workspace;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.security.Privilege;
 import javax.jcr.version.Version;
@@ -36,6 +37,54 @@ import javax.jcr.version.VersionManager;
  */
 public class Jcr {
 
+       /**
+        * <code>jcr:name</code>, when used in another context than
+        * {@link Property#JCR_NAME}, typically to name a node rather than a property.
+        */
+       public final static String JCR_NAME = "jcr:name";
+
+       /**
+        * <code>jcr:path</code>, when used in another context than
+        * {@link Property#JCR_PATH}, typically to name a node rather than a property.
+        */
+       public final static String JCR_PATH = "jcr:path";
+
+       /**
+        * <code>jcr:primaryType</code> with prefix instead of namespace (as in
+        * {@link Property#JCR_PRIMARY_TYPE}.
+        */
+       public final static String JCR_PRIMARY_TYPE = "jcr:primaryType";
+       /**
+        * <code>jcr:mixinTypes</code> with prefix instead of namespace (as in
+        * {@link Property#JCR_MIXIN_TYPES}.
+        */
+       public final static String JCR_MIXIN_TYPES = "jcr:mixinTypes";
+       /**
+        * <code>jcr:uuid</code> with prefix instead of namespace (as in
+        * {@link Property#JCR_UUID}.
+        */
+       public final static String JCR_UUID = "jcr:uuid";
+       /**
+        * <code>jcr:created</code> with prefix instead of namespace (as in
+        * {@link Property#JCR_CREATED}.
+        */
+       public final static String JCR_CREATED = "jcr:created";
+       /**
+        * <code>jcr:createdBy</code> with prefix instead of namespace (as in
+        * {@link Property#JCR_CREATED_BY}.
+        */
+       public final static String JCR_CREATED_BY = "jcr:createdBy";
+       /**
+        * <code>jcr:lastModified</code> with prefix instead of namespace (as in
+        * {@link Property#JCR_LAST_MODIFIED}.
+        */
+       public final static String JCR_LAST_MODIFIED = "jcr:lastModified";
+       /**
+        * <code>jcr:lastModifiedBy</code> with prefix instead of namespace (as in
+        * {@link Property#JCR_LAST_MODIFIED_BY}.
+        */
+       public final static String JCR_LAST_MODIFIED_BY = "jcr:lastModifiedBy";
+
        /**
         * @see Node#isNodeType(String)
         * @throws IllegalStateException caused by {@link RepositoryException}
@@ -97,6 +146,15 @@ public class Jcr {
                }
        }
 
+       /**
+        * @see Node#getSession()
+        * @see Session#getWorkspace()
+        * @see Workspace#getName()
+        */
+       public static String getWorkspaceName(Node node) {
+               return session(node).getWorkspace().getName();
+       }
+
        /**
         * @see Node#getIdentifier()
         * @throws IllegalStateException caused by {@link RepositoryException}
@@ -121,6 +179,17 @@ public class Jcr {
                }
        }
 
+       /**
+        * If node has mixin {@link NodeType#MIX_TITLE}, return
+        * {@link Property#JCR_TITLE}, otherwise return {@link #getName(Node)}.
+        */
+       public static String getTitle(Node node) {
+               if (Jcr.isNodeType(node, NodeType.MIX_TITLE))
+                       return get(node, Property.JCR_TITLE);
+               else
+                       return Jcr.getName(node);
+       }
+
        /** Accesses a {@link NodeIterator} as an {@link Iterable}. */
        @SuppressWarnings("unchecked")
        public static Iterable<Node> iterate(NodeIterator nodeIterator) {
@@ -345,8 +414,18 @@ public class Jcr {
                }
        }
 
-       /** Retrieves the {@link Session} related to this node. */
+       /**
+        * Retrieves the {@link Session} related to this node.
+        * 
+        * @deprecated Use {@link #getSession(Node)} instead.
+        */
+       @Deprecated
        public static Session session(Node node) {
+               return getSession(node);
+       }
+
+       /** Retrieves the {@link Session} related to this node. */
+       public static Session getSession(Node node) {
                try {
                        return node.getSession();
                } catch (RepositoryException e) {
@@ -354,6 +433,15 @@ public class Jcr {
                }
        }
 
+       /** Retrieves the root node related to this session. */
+       public static Node getRootNode(Session session) {
+               try {
+                       return session.getRootNode();
+               } catch (RepositoryException e) {
+                       throw new IllegalStateException("Cannot get root node for " + session, e);
+               }
+       }
+
        /**
         * Saves the {@link Session} related to this node. Note that all other unrelated
         * modifications in this session will also be saved.
@@ -361,11 +449,12 @@ public class Jcr {
        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();
+//                     if (node.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
+//                             set(node, Property.JCR_LAST_MODIFIED, Instant.now());
+//                             set(node, Property.JCR_LAST_MODIFIED_BY, session.getUserID());
+//                     }
+                       if (session.hasPendingChanges())
+                               session.save();
                } catch (RepositoryException e) {
                        throw new IllegalStateException("Cannot save session related to " + node + " in workspace "
                                        + session(node).getWorkspace().getName(), e);
@@ -392,6 +481,11 @@ public class Jcr {
                }
        }
 
+       /** Safely and silently logs out the underlying session. */
+       public static void logout(Node node) {
+               Jcr.logout(session(node));
+       }
+
        /*
         * SECURITY
         */
@@ -421,7 +515,16 @@ public class Jcr {
                }
        }
 
-       /** Check in this node. */
+       /** @see VersionManager#checkpoint(String) */
+       public static void checkpoint(Node node) {
+               try {
+                       versionManager(node).checkpoint(node.getPath());
+               } catch (RepositoryException e) {
+                       throw new IllegalStateException("Cannot check in " + node, e);
+               }
+       }
+
+       /** @see VersionManager#checkin(String) */
        public static void checkin(Node node) {
                try {
                        versionManager(node).checkin(node.getPath());
@@ -430,7 +533,7 @@ public class Jcr {
                }
        }
 
-       /** Check out this node. */
+       /** @see VersionManager#checkout(String) */
        public static void checkout(Node node) {
                try {
                        versionManager(node).checkout(node.getPath());