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;
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;
}
}
+ /**
+ * @see Node#getParent()
+ * @throws JcrException caused by {@link RepositoryException}
+ */
+ public static String getParentPath(Node node) {
+ return getPath(getParent(node));
+ }
+
/**
* Whether this node is the root node.
*
}
}
+ /**
+ * Add a node to this parent, setting its primary type and its mixins.
+ *
+ * @param parent the parent node
+ * @param name the name of the node, if <code>null</code>, the primary
+ * type will be used (typically for XML structures)
+ * @param primaryType the primary type, if <code>null</code>
+ * {@link NodeType#NT_UNSTRUCTURED} will be used.
+ * @param mixins the mixins
+ * @return the created node
+ * @see Node#addNode(String, String)
+ * @see Node#addMixin(String)
+ */
+ public static Node addNode(Node parent, String name, String primaryType, String... mixins) {
+ if (name == null && primaryType == null)
+ throw new IllegalArgumentException("Both node name and primary type cannot be null");
+ try {
+ Node newNode = parent.addNode(name == null ? primaryType : name,
+ primaryType == null ? NodeType.NT_UNSTRUCTURED : primaryType);
+ for (String mixin : mixins) {
+ newNode.addMixin(mixin);
+ }
+ return newNode;
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot add node " + name + " to " + parent, e);
+ }
+ }
+
+ /**
+ * Add an {@link NodeType#NT_BASE} node to this parent.
+ *
+ * @param parent the parent node
+ * @param name the name of the node, cannot be <code>null</code>
+ * @return the created node
+ *
+ * @see Node#addNode(String)
+ */
+ public static Node addNode(Node parent, String name) {
+ if (name == null)
+ throw new IllegalArgumentException("Node name cannot be null");
+ try {
+ Node newNode = parent.addNode(name);
+ return newNode;
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot add node " + name + " to " + parent, e);
+ }
+ }
+
+ /**
+ * Add mixins to a node.
+ *
+ * @param node the node
+ * @param mixins the mixins
+ * @return the created node
+ * @see Node#addMixin(String)
+ */
+ public static void addMixin(Node node, String... mixins) {
+ try {
+ for (String mixin : mixins) {
+ node.addMixin(mixin);
+ }
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot add mixins " + Arrays.asList(mixins) + " to " + node, e);
+ }
+ }
+
+ /**
+ * Removes this node.
+ *
+ * @see Node#remove()
+ */
+ public static void remove(Node node) {
+ try {
+ node.remove();
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot remove node " + node, e);
+ }
+ }
+
/**
* @return the node with htis id or <code>null</node> if not found
* @see Session#getNodeByIdentifier(String)
*/
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();
}
}
+ // 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() {