From: Mathieu Baudier Date: Mon, 28 Oct 2019 09:08:37 +0000 (+0100) Subject: Improve JCR utilities. X-Git-Tag: argeo-commons-2.1.82~3 X-Git-Url: http://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=5ec9d72c96b13bf18d702bf01dc2c03b0aee43a4 Improve JCR utilities. --- diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java index f45e876f0..b688e6259 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java @@ -38,20 +38,12 @@ public class JcrTreeContentProvider implements ITreeContentProvider { private JcrItemsComparator itemComparator = new JcrItemsComparator(); /** - * Sends back the first level of the Tree. input element must be a single - * node object + * Sends back the first level of the Tree. input element must be a single node + * object */ public Object[] getElements(Object inputElement) { - try { - Node rootNode = (Node) inputElement; - List result = new ArrayList(); - NodeIterator ni = rootNode.getNodes(); - while (ni.hasNext()) - result.add(ni.nextNode()); - return result.toArray(); - } catch (RepositoryException re) { - throw new EclipseUiException("Unable to retrieve elements for " + inputElement, re); - } + Node rootNode = (Node) inputElement; + return childrenNodes(rootNode); } public Object[] getChildren(Object parentElement) { @@ -82,8 +74,13 @@ public class JcrTreeContentProvider implements ITreeContentProvider { try { List children = new ArrayList(); NodeIterator nit = parentNode.getNodes(); - while (nit.hasNext()) - children.add(nit.nextNode()); + while (nit.hasNext()) { + Node node = nit.nextNode(); +// if (node.getName().startsWith("rep:") || node.getName().startsWith("jcr:") +// || node.getName().startsWith("nt:")) +// continue nodes; + children.add(node); + } Node[] arr = children.toArray(new Node[0]); Arrays.sort(arr, itemComparator); return arr; diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/utils/JcrItemsComparator.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/utils/JcrItemsComparator.java index 5f17f4163..015670ba5 100644 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/utils/JcrItemsComparator.java +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/utils/JcrItemsComparator.java @@ -27,7 +27,7 @@ public class JcrItemsComparator implements Comparator { public int compare(Item o1, Item o2) { try { // TODO: put folder before files - return o1.getName().compareTo(o2.getName()); + return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase()); } catch (RepositoryException e) { throw new EclipseUiException("Cannot compare " + o1 + " and " + o2, e); } diff --git a/org.argeo.jcr/src/org/argeo/jcr/ArgeoJcrException.java b/org.argeo.jcr/src/org/argeo/jcr/ArgeoJcrException.java index 09a645b50..40f57ab65 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/ArgeoJcrException.java +++ b/org.argeo.jcr/src/org/argeo/jcr/ArgeoJcrException.java @@ -1,7 +1,7 @@ package org.argeo.jcr; /** Argeo JCR specific exceptions. */ -public class ArgeoJcrException extends RuntimeException { +public class ArgeoJcrException extends IllegalStateException { private static final long serialVersionUID = -1941940005390084331L; public ArgeoJcrException(String message, Throwable e) { diff --git a/org.argeo.jcr/src/org/argeo/jcr/Jcr.java b/org.argeo.jcr/src/org/argeo/jcr/Jcr.java index 43e47daca..230921d55 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/Jcr.java +++ b/org.argeo.jcr/src/org/argeo/jcr/Jcr.java @@ -1,10 +1,16 @@ package org.argeo.jcr; +import java.math.BigDecimal; +import java.time.Instant; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; +import javax.jcr.Binary; import javax.jcr.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.NodeIterator; @@ -14,6 +20,7 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; +import javax.jcr.nodetype.NodeType; import javax.jcr.security.Privilege; import javax.jcr.version.Version; import javax.jcr.version.VersionHistory; @@ -206,6 +213,48 @@ public class Jcr { } } + /** + * Set a property to the given value, or remove it if the value is + * null. + * + * @throws IllegalStateException caused by {@link RepositoryException} + */ + public static void set(Node node, String property, Object value) { + try { + if (!node.hasProperty(property)) + throw new IllegalArgumentException("No property " + property + " in " + node); + Property prop = node.getProperty(property); + if (value == null) { + prop.remove(); + return; + } + + if (value instanceof String) + prop.setValue((String) value); + else if (value instanceof Long) + prop.setValue((Long) value); + else if (value instanceof Double) + prop.setValue((Double) value); + else if (value instanceof Calendar) + prop.setValue((Calendar) value); + else if (value instanceof BigDecimal) + prop.setValue((BigDecimal) value); + else if (value instanceof Boolean) + prop.setValue((Boolean) value); + else if (value instanceof byte[]) + JcrUtils.setBinaryAsBytes(prop, (byte[]) value); + else if (value instanceof Instant) { + Instant instant = (Instant) value; + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(Date.from(instant)); + prop.setValue(calendar); + } else // try with toString() + prop.setValue(value.toString()); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot set property " + property + " of " + node + " to " + value, e); + } + } + /** * Get property as {@link String}. * @@ -311,7 +360,12 @@ public class Jcr { */ public static void save(Node node) { try { - session(node).save(); + 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(); } catch (RepositoryException e) { throw new IllegalStateException("Cannot save session related to " + node + " in workspace " + session(node).getWorkspace().getName(), e); @@ -403,13 +457,17 @@ public class Jcr { } } - /** The linear versions of this version history in reverse order. */ + /** + * The linear versions of this version history in reverse order and without the + * root version. + */ public static List getLinearVersions(VersionHistory versionHistory) { try { List lst = new ArrayList<>(); VersionIterator vit = versionHistory.getAllLinearVersions(); while (vit.hasNext()) lst.add(vit.nextVersion()); + lst.remove(0); Collections.reverse(lst); return lst; } catch (RepositoryException e) { @@ -435,6 +493,35 @@ public class Jcr { } } + /* + * FILES + */ + /** + * Returns the size of this file. + * + * @see NodeType#NT_FILE + */ + public static long getFileSize(Node fileNode) { + try { + if (!fileNode.isNodeType(NodeType.NT_FILE)) + throw new IllegalArgumentException(fileNode + " must be a file."); + return getBinarySize(fileNode.getNode(Node.JCR_CONTENT).getProperty(Property.JCR_DATA).getBinary()); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot get file size of " + fileNode, e); + } + } + + /** Returns the size of this {@link Binary}. */ + public static long getBinarySize(Binary binaryArg) { + try { + try (Bin binary = new Bin(binaryArg)) { + return binary.getSize(); + } + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot get file size of binary " + binaryArg, e); + } + } + /** Singleton. */ private Jcr() { diff --git a/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java b/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java index 331164cf2..3e7c87374 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java +++ b/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java @@ -991,16 +991,26 @@ public class JcrUtils { /** Writes a {@link Binary} from a byte array */ public static void setBinaryAsBytes(Node node, String property, byte[] bytes) { - // InputStream in = null; Binary binary = null; try (InputStream in = new ByteArrayInputStream(bytes)) { - // in = new ByteArrayInputStream(bytes); binary = node.getSession().getValueFactory().createBinary(in); node.setProperty(property, binary); } catch (Exception e) { - throw new ArgeoJcrException("Cannot read binary " + property + " as bytes", e); + throw new ArgeoJcrException("Cannot set binary " + property + " as bytes", e); + } finally { + closeQuietly(binary); + } + } + + /** Writes a {@link Binary} from a byte array */ + public static void setBinaryAsBytes(Property prop, byte[] bytes) { + Binary binary = null; + try (InputStream in = new ByteArrayInputStream(bytes)) { + binary = prop.getSession().getValueFactory().createBinary(in); + prop.setValue(binary); + } catch (RepositoryException | IOException e) { + throw new ArgeoJcrException("Cannot set binary " + prop + " as bytes", e); } finally { - // IOUtils.closeQuietly(in); closeQuietly(binary); } }