X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.jcr%2Fsrc%2Forg%2Fargeo%2Fjcr%2FJcr.java;h=31077737e8e7e789335e263409b2279d190b1b27;hb=f65811e6912330a8d1e2ab330114f22d2bae43ed;hp=4b8bfc3eae5761bcfd3d04f8cd188706ba99c242;hpb=4f6cfbd6862813e917883ea93e13ee95edc1c024;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 4b8bfc3ea..31077737e 100644
--- a/org.argeo.jcr/src/org/argeo/jcr/Jcr.java
+++ b/org.argeo.jcr/src/org/argeo/jcr/Jcr.java
@@ -1,5 +1,8 @@
package org.argeo.jcr;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.time.Instant;
@@ -32,6 +35,8 @@ import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;
import javax.jcr.version.VersionManager;
+import org.apache.commons.io.IOUtils;
+
/**
* Utility class whose purpose is to make using JCR less verbose by
* systematically using unchecked exceptions and returning null
@@ -132,6 +137,14 @@ public class Jcr {
}
}
+ /**
+ * @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.
*
@@ -190,6 +203,48 @@ public class Jcr {
}
}
+ /**
+ * Returns the node name with its current index (useful for re-ordering).
+ *
+ * @see Node#getName()
+ * @see Node#getIndex()
+ * @throws JcrException caused by {@link RepositoryException}
+ */
+ public static String getIndexedName(Node node) {
+ try {
+ return node.getName() + "[" + node.getIndex() + "]";
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot get name of " + node, e);
+ }
+ }
+
+ /**
+ * @see Node#getProperty(String)
+ * @throws JcrException caused by {@link RepositoryException}
+ */
+ public static Property getProperty(Node node, String property) {
+ try {
+ if (node.hasProperty(property))
+ return node.getProperty(property);
+ else
+ return null;
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot get property " + property + " of " + node, e);
+ }
+ }
+
+ /**
+ * @see Node#getIndex()
+ * @throws JcrException caused by {@link RepositoryException}
+ */
+ public static int getIndex(Node node) {
+ try {
+ return node.getIndex();
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot get index of " + node, e);
+ }
+ }
+
/**
* If node has mixin {@link NodeType#MIX_TITLE}, return
* {@link Property#JCR_TITLE}, otherwise return {@link #getName(Node)}.
@@ -381,11 +436,19 @@ public class Jcr {
public static void set(Node node, String property, Object value) {
try {
if (!node.hasProperty(property)) {
- if (value != null)
- node.setProperty(property, value.toString());
+ if (value != null) {
+ if (value instanceof List) {// multiple
+ List> lst = (List>) value;
+ String[] values = new String[lst.size()];
+ for (int i = 0; i < lst.size(); i++) {
+ values[i] = lst.get(i).toString();
+ }
+ node.setProperty(property, values);
+ } else {
+ node.setProperty(property, value.toString());
+ }
+ }
return;
- // throw new IllegalArgumentException("No property " + property + " in " +
- // node);
}
Property prop = node.getProperty(property);
if (value == null) {
@@ -393,6 +456,27 @@ public class Jcr {
return;
}
+ // multiple
+ if (value instanceof List) {
+ List> lst = (List>) value;
+ String[] values = new String[lst.size()];
+ // TODO better cast?
+ for (int i = 0; i < lst.size(); i++) {
+ values[i] = lst.get(i).toString();
+ }
+ if (!prop.isMultiple())
+ prop.remove();
+ node.setProperty(property, values);
+ return;
+ }
+
+ // single
+ if (prop.isMultiple()) {
+ prop.remove();
+ node.setProperty(property, value.toString());
+ return;
+ }
+
if (value instanceof String)
prop.setValue((String) value);
else if (value instanceof Long)
@@ -498,20 +582,11 @@ public class Jcr {
if (node.hasProperty(property)) {
Property p = node.getProperty(property);
try {
- switch (p.getType()) {
- case PropertyType.STRING:
- return (T) node.getProperty(property).getString();
- case PropertyType.DOUBLE:
- return (T) (Double) node.getProperty(property).getDouble();
- case PropertyType.LONG:
- return (T) (Long) node.getProperty(property).getLong();
- case PropertyType.BOOLEAN:
- return (T) (Boolean) node.getProperty(property).getBoolean();
- case PropertyType.DATE:
- return (T) node.getProperty(property).getDate();
- default:
- return (T) node.getProperty(property).getString();
+ if (p.isMultiple()) {
+ throw new UnsupportedOperationException("Multiple values properties are not supported");
}
+ Value value = p.getValue();
+ return (T) get(value);
} catch (ClassCastException e) {
throw new IllegalArgumentException(
"Cannot cast property of type " + PropertyType.nameFromValue(p.getType()), e);
@@ -524,6 +599,86 @@ public class Jcr {
}
}
+ /**
+ * Get a multiple property as a list, doing a best effort to cast it as the
+ * target list.
+ *
+ * @return the value of {@link Node#getProperty(String)}.
+ * @throws IllegalArgumentException if the value could not be cast
+ * @throws JcrException in case of unexpected
+ * {@link RepositoryException}
+ */
+ public static List getMultiple(Node node, String property) {
+ try {
+ if (node.hasProperty(property)) {
+ Property p = node.getProperty(property);
+ return getMultiple(p);
+ } else {
+ return null;
+ }
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot retrieve multiple values property " + property + " from " + node, e);
+ }
+ }
+
+ /**
+ * Get a multiple property as a list, doing a best effort to cast it as the
+ * target list.
+ */
+ @SuppressWarnings("unchecked")
+ public static List getMultiple(Property p) {
+ try {
+ List res = new ArrayList<>();
+ if (!p.isMultiple()) {
+ res.add((T) get(p.getValue()));
+ return res;
+ }
+ Value[] values = p.getValues();
+ for (Value value : values) {
+ res.add((T) get(value));
+ }
+ return res;
+ } catch (ClassCastException | RepositoryException e) {
+ throw new IllegalArgumentException("Cannot get property " + p, e);
+ }
+ }
+
+ /** Cast a {@link Value} to a standard Java object. */
+ public static Object get(Value value) {
+ Binary binary = null;
+ try {
+ switch (value.getType()) {
+ case PropertyType.STRING:
+ return value.getString();
+ case PropertyType.DOUBLE:
+ return (Double) value.getDouble();
+ case PropertyType.LONG:
+ return (Long) value.getLong();
+ case PropertyType.BOOLEAN:
+ return (Boolean) value.getBoolean();
+ case PropertyType.DATE:
+ return value.getDate();
+ case PropertyType.BINARY:
+ binary = value.getBinary();
+ byte[] arr = null;
+ try (InputStream in = binary.getStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();) {
+ IOUtils.copy(in, out);
+ arr = out.toByteArray();
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot read binary from " + value, e);
+ }
+ return arr;
+ default:
+ return value.getString();
+ }
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot cast value from " + value, e);
+ } finally {
+ if (binary != null)
+ binary.dispose();
+ }
+ }
+
/**
* Retrieves the {@link Session} related to this node.
*