Improve JCR utilities.
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 28 Oct 2019 09:08:37 +0000 (10:08 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 28 Oct 2019 09:08:37 +0000 (10:08 +0100)
org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java
org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/jcr/utils/JcrItemsComparator.java
org.argeo.jcr/src/org/argeo/jcr/ArgeoJcrException.java
org.argeo.jcr/src/org/argeo/jcr/Jcr.java
org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java

index f45e876f0d4aba7faa6358b867a05e54fdb5b276..b688e625938386bb7a7e0ad92e2042f733fd60e8 100644 (file)
@@ -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<Node> result = new ArrayList<Node>();
-                       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<Node> children = new ArrayList<Node>();
                        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;
index 5f17f416355e482a36b6cc1c5baf1355e372fa13..015670ba58e419ab052edfa356c7cec894d98426 100644 (file)
@@ -27,7 +27,7 @@ public class JcrItemsComparator implements Comparator<Item> {
        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);
                }
index 09a645b5040f472a8db548e7429408309b59f204..40f57ab6550f6207596915235b36bafe6b20bcde 100644 (file)
@@ -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) {
index 43e47dacad11512df281923caca5ae37e5bea9dc..230921d551f191ae65f879b998308936d7aff248 100644 (file)
@@ -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
+        * <code>null</code>.
+        * 
+        * @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<Version> getLinearVersions(VersionHistory versionHistory) {
                try {
                        List<Version> 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() {
 
index 331164cf2b442dec485bb7a71ebb0d7a0c50dd65..3e7c8737403ed969378e9c93972508abea85293b 100644 (file)
@@ -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);
                }
        }