JCR as an ACR backend
[lgpl/argeo-commons.git] / jcr / org.argeo.cms.jcr / src / org / argeo / cms / jcr / acr / JcrContent.java
index 04c5d2d8c3b2f0d32960c52d05e64bc572e70b77..94fe7cf58ef9f8b2ffd6c3a53f70af265f4a7107 100644 (file)
@@ -1,8 +1,12 @@
 package org.argeo.cms.jcr.acr;
 
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
@@ -15,11 +19,13 @@ import javax.jcr.nodetype.NodeType;
 import javax.xml.namespace.QName;
 
 import org.argeo.api.acr.Content;
+import org.argeo.api.acr.NamespaceUtils;
 import org.argeo.api.acr.spi.AbstractContent;
 import org.argeo.api.acr.spi.ProvidedSession;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrException;
 
+/** A JCR {@link Node} accessed as {@link Content}. */
 public class JcrContent extends AbstractContent {
        private Node jcrNode;
 
@@ -34,7 +40,11 @@ public class JcrContent extends AbstractContent {
 
        @Override
        public QName getName() {
-               return session.parsePrefixedName(Jcr.getName(jcrNode));
+               String name = Jcr.getName(jcrNode);
+               if (name.equals("")) {// root
+                       name = Jcr.getWorkspaceName(jcrNode);
+               }
+               return NamespaceUtils.parsePrefixedName(provider, name);
        }
 
        @Override
@@ -56,18 +66,32 @@ public class JcrContent extends AbstractContent {
 
        @Override
        protected Iterable<QName> keys() {
-               return new Iterable<QName>() {
-
-                       @Override
-                       public Iterator<QName> iterator() {
-                               try {
-                                       PropertyIterator propertyIterator = jcrNode.getProperties();
-                                       return new JcrKeyIterator(provider, propertyIterator);
-                               } catch (RepositoryException e) {
-                                       throw new JcrException("Cannot retrive properties from " + jcrNode, e);
-                               }
+               try {
+                       Set<QName> keys = new HashSet<>();
+                       properties: for (PropertyIterator propertyIterator = jcrNode.getProperties(); propertyIterator.hasNext();) {
+                               Property property = propertyIterator.nextProperty();
+                               // TODO convert standard names
+                               // TODO skip technical properties
+                               QName name = NamespaceUtils.parsePrefixedName(provider, property.getName());
+                               keys.add(name);
                        }
-               };
+                       return keys;
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot list properties of " + jcrNode, e);
+               }
+
+//             return new Iterable<QName>() {
+//
+//                     @Override
+//                     public Iterator<QName> iterator() {
+//                             try {
+//                                     PropertyIterator propertyIterator = jcrNode.getProperties();
+//                                     return new JcrKeyIterator(provider, propertyIterator);
+//                             } catch (RepositoryException e) {
+//                                     throw new JcrException("Cannot retrive properties from " + jcrNode, e);
+//                             }
+//                     }
+//             };
        }
 
        public Node getJcrNode() {
@@ -77,29 +101,43 @@ public class JcrContent extends AbstractContent {
        /** Cast to a standard Java object. */
        static Object get(Node node, String property) {
                try {
-                       Value value = node.getProperty(property).getValue();
-                       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:
-                               Calendar calendar = value.getDate();
-                               return calendar.toInstant();
-                       case PropertyType.BINARY:
-                               throw new IllegalArgumentException("Binary is not supported as an attribute");
-                       default:
-                               return value.getString();
+                       Property p = node.getProperty(property);
+                       if (p.isMultiple()) {
+                               Value[] values = p.getValues();
+                               List<Object> lst = new ArrayList<>();
+                               for (Value value : values) {
+                                       lst.add(convertSingleValue(value));
+                               }
+                               return lst;
+                       } else {
+                               Value value = node.getProperty(property).getValue();
+                               return convertSingleValue(value);
                        }
                } catch (RepositoryException e) {
                        throw new JcrException("Cannot cast value from " + property + " of node " + node, e);
                }
        }
 
+       static Object convertSingleValue(Value value) throws RepositoryException {
+               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:
+                       Calendar calendar = value.getDate();
+                       return calendar.toInstant();
+               case PropertyType.BINARY:
+                       throw new IllegalArgumentException("Binary is not supported as an attribute");
+               default:
+                       return value.getString();
+               }
+       }
+
        class JcrContentIterator implements Iterator<Content> {
                private final NodeIterator nodeIterator;
                // we keep track in order to be able to delete it
@@ -191,7 +229,7 @@ public class JcrContent extends AbstractContent {
                        try {
                                property = propertyIterator.nextProperty();
                                // TODO map standard property names
-                               return session.parsePrefixedName(property.getName());
+                               return NamespaceUtils.parsePrefixedName(provider, property.getName());
                        } catch (RepositoryException e) {
                                throw new JcrException("Cannot retrieve property " + property, null);
                        }