X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.jcr%2Fsrc%2Forg%2Fargeo%2Fjcr%2FJcr.java;h=263128448f3f5f133b194c91cf2f647013d5b5d2;hb=495daae85d453bce3e030358372907f9e534bfae;hp=230921d551f191ae65f879b998308936d7aff248;hpb=5ec9d72c96b13bf18d702bf01dc2c03b0aee43a4;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 230921d55..263128448 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/Jcr.java +++ b/org.argeo.jcr/src/org/argeo/jcr/Jcr.java @@ -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; @@ -35,6 +36,61 @@ import javax.jcr.version.VersionManager; * exceptions. Loosely inspired by Java's Files singleton. */ public class Jcr { + /** + * The name of a node which will be serialized as XML text, as per section 7.3.1 + * of the JCR 2.0 specifications. + */ + public final static String JCR_XMLTEXT = "jcr:xmltext"; + /** + * The name of a property which will be serialized as XML text, as per section + * 7.3.1 of the JCR 2.0 specifications. + */ + public final static String JCR_XMLCHARACTERS = "jcr:xmlcharacters"; + /** + * jcr:name, 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"; + /** + * jcr:path, 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"; + /** + * jcr:primaryType with prefix instead of namespace (as in + * {@link Property#JCR_PRIMARY_TYPE}. + */ + public final static String JCR_PRIMARY_TYPE = "jcr:primaryType"; + /** + * jcr:mixinTypes with prefix instead of namespace (as in + * {@link Property#JCR_MIXIN_TYPES}. + */ + public final static String JCR_MIXIN_TYPES = "jcr:mixinTypes"; + /** + * jcr:uuid with prefix instead of namespace (as in + * {@link Property#JCR_UUID}. + */ + public final static String JCR_UUID = "jcr:uuid"; + /** + * jcr:created with prefix instead of namespace (as in + * {@link Property#JCR_CREATED}. + */ + public final static String JCR_CREATED = "jcr:created"; + /** + * jcr:createdBy with prefix instead of namespace (as in + * {@link Property#JCR_CREATED_BY}. + */ + public final static String JCR_CREATED_BY = "jcr:createdBy"; + /** + * jcr:lastModified with prefix instead of namespace (as in + * {@link Property#JCR_LAST_MODIFIED}. + */ + public final static String JCR_LAST_MODIFIED = "jcr:lastModified"; + /** + * jcr:lastModifiedBy 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) @@ -97,6 +153,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 +186,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 iterate(NodeIterator nodeIterator) { @@ -268,7 +344,8 @@ public class Jcr { } /** - * Get property as a {@link String}. + * Get property as a {@link String}. If the property is multiple it returns the + * first value. * * @return the value of * {@link Node#getProperty(String)}.{@link Property#getString()} or @@ -277,9 +354,18 @@ public class Jcr { */ public static String get(Node node, String property, String defaultValue) { try { - if (node.hasProperty(property)) - return node.getProperty(property).getString(); - else + if (node.hasProperty(property)) { + Property p = node.getProperty(property); + if (!p.isMultiple()) + return p.getString(); + else { + Value[] values = p.getValues(); + if (values.length == 0) + return defaultValue; + else + return values[0].getString(); + } + } else return defaultValue; } catch (RepositoryException e) { throw new IllegalStateException("Cannot retrieve property " + property + " from " + node); @@ -316,6 +402,7 @@ public class Jcr { @SuppressWarnings("unchecked") public static T getAs(Node node, String property, T defaultValue) { try { + // TODO deal with multiple if (node.hasProperty(property)) { Property p = node.getProperty(property); try { @@ -345,8 +432,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 +451,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 +467,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 +499,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 +533,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 +551,7 @@ public class Jcr { } } - /** Check out this node. */ + /** @see VersionManager#checkout(String) */ public static void checkout(Node node) { try { versionManager(node).checkout(node.getPath());