Support Content getText()
[gpl/argeo-jcr.git] / org.argeo.cms.jcr / src / org / argeo / cms / jcr / acr / JcrContent.java
index 864fbfb7eb8efead51c7475d7b0ce8453ba15fc3..a46dd859fd0e5df2f605da056eba5d9d96be80c8 100644 (file)
@@ -44,6 +44,7 @@ import org.argeo.cms.acr.ContentUtils;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.JcrxApi;
 
 /** A JCR {@link Node} accessed as {@link Content}. */
 public class JcrContent extends AbstractContent {
@@ -54,6 +55,16 @@ public class JcrContent extends AbstractContent {
 
        private final boolean isMountBase;
 
+       /* OPTIMISATIONS */
+       /**
+        * While we want to support thread-safe access, it is very likely that only
+        * thread and only one sesssion will be used (typically from a single-threaded
+        * UI). We therefore cache was long as the same thread is calling.
+        */
+       private Thread lastRetrievingThread = null;
+       private Node cachedNode = null;
+       private boolean caching = true;
+
        protected JcrContent(ProvidedSession session, JcrContentProvider provider, String jcrWorkspace, String jcrPath) {
                super(session);
                this.provider = provider;
@@ -78,10 +89,13 @@ public class JcrContent extends AbstractContent {
                return NamespaceUtils.parsePrefixedName(provider, name);
        }
 
-//     @SuppressWarnings("unchecked")
+       @SuppressWarnings("unchecked")
        @Override
        public <A> Optional<A> get(QName key, Class<A> clss) {
                Object value = get(getJcrNode(), key.toString());
+               if (value instanceof List<?> lst)
+                       return Optional.of((A) lst);
+               // TODO check other collections?
                return CrAttributeType.cast(clss, value);
        }
 
@@ -155,7 +169,7 @@ public class JcrContent extends AbstractContent {
                try {
                        // Note: it is important to to use the default way (recursing through parents),
                        // since the session may not have access to parent nodes
-                       return ContentUtils.ROOT_SLASH + jcrWorkspace + getJcrNode().getPath();
+                       return Content.ROOT_PATH + jcrWorkspace + getJcrNode().getPath();
                } catch (RepositoryException e) {
                        throw new JcrException("Cannot get depth of " + getJcrNode(), e);
                }
@@ -188,6 +202,21 @@ public class JcrContent extends AbstractContent {
        public int getSiblingIndex() {
                return Jcr.getIndex(getJcrNode());
        }
+       
+       
+
+       @Override
+       public String getText() {
+               return  JcrxApi.getXmlValue(getJcrNode());
+       }
+
+       /*
+        * MAP OPTIMISATIONS
+        */
+       @Override
+       public boolean containsKey(Object key) {
+               return Jcr.hasProperty(getJcrNode(), key.toString());
+       }
 
        /*
         * WRITE
@@ -503,8 +532,17 @@ public class JcrContent extends AbstractContent {
 
        protected Node getJcrNode() {
                try {
-                       // TODO caching?
-                       return getJcrSession().getNode(jcrPath);
+                       if (caching) {
+                               synchronized (this) {
+                                       if (lastRetrievingThread != Thread.currentThread()) {
+                                               cachedNode = getJcrSession().getNode(jcrPath);
+                                               lastRetrievingThread = Thread.currentThread();
+                                       }
+                                       return cachedNode;
+                               }
+                       } else {
+                               return getJcrSession().getNode(jcrPath);
+                       }
                } catch (RepositoryException e) {
                        throw new JcrException("Cannot retrieve " + jcrPath + " from workspace " + jcrWorkspace, e);
                }
@@ -522,7 +560,7 @@ public class JcrContent extends AbstractContent {
                        if (contentSession == null)
                                throw new IllegalArgumentException(
                                                "Cannot adapt " + node + " to content, because it was not loaded from a content session");
-                       return contentSession.get(ContentUtils.SLASH + CmsConstants.SYS_WORKSPACE + node.getPath());
+                       return contentSession.get(Content.ROOT_PATH + CmsConstants.SYS_WORKSPACE + node.getPath());
                } catch (RepositoryException e) {
                        throw new JcrException("Cannot adapt " + node + " to a content", e);
                }