Simplify JCR queries.
[lgpl/argeo-commons.git] / org.argeo.jcr / src / org / argeo / jcr / Jcr.java
index 3cbdd57f5df6731578875e5328601b79b28606d3..229d2e87a95d19b6adcdefa9f7c2e6dcee5c9ce8 100644 (file)
@@ -1,8 +1,10 @@
 package org.argeo.jcr;
 
 import java.math.BigDecimal;
+import java.text.MessageFormat;
 import java.time.Instant;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.Date;
@@ -22,6 +24,8 @@ import javax.jcr.Session;
 import javax.jcr.Value;
 import javax.jcr.Workspace;
 import javax.jcr.nodetype.NodeType;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
 import javax.jcr.security.Privilege;
 import javax.jcr.version.Version;
 import javax.jcr.version.VersionHistory;
@@ -297,8 +301,13 @@ public class Jcr {
         */
        public static void set(Node node, String property, Object value) {
                try {
-                       if (!node.hasProperty(property))
-                               throw new IllegalArgumentException("No property " + property + " in " + node);
+                       if (!node.hasProperty(property)) {
+                               if (value != null)
+                                       node.setProperty(property, value.toString());
+                               return;
+                               // throw new IllegalArgumentException("No property " + property + " in " +
+                               // node);
+                       }
                        Property prop = node.getProperty(property);
                        if (value == null) {
                                prop.remove();
@@ -656,6 +665,73 @@ public class Jcr {
                }
        }
 
+       // 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);
+       }
+
        /** Singleton. */
        private Jcr() {