JCR as an ACR backend
[lgpl/argeo-commons.git] / jcr / org.argeo.cms.jcr / src / org / argeo / cms / jcr / acr / JcrContentProvider.java
index ef8e375d012731972b4597114aae57d4f5d2dbab..fc4a61bf9e61a72c316f5b5f5f8bf50a291932fb 100644 (file)
@@ -1,29 +1,37 @@
 package org.argeo.cms.jcr.acr;
 
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 
+import javax.jcr.Node;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.xml.namespace.NamespaceContext;
 
 import org.argeo.api.acr.Content;
+import org.argeo.api.acr.ContentUtils;
 import org.argeo.api.acr.spi.ContentProvider;
 import org.argeo.api.acr.spi.ProvidedSession;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
 
+/** A JCR workspace accessed as an {@link ContentProvider}. */
 public class JcrContentProvider implements ContentProvider, NamespaceContext {
        private Repository jcrRepository;
        private Session adminSession;
 
-       public void init() {
+       private Map<ProvidedSession, JcrSessionAdapter> sessionAdapters = Collections.synchronizedMap(new HashMap<>());
+
+       public void start() {
                adminSession = CmsJcrUtils.openDataAdminSession(jcrRepository, null);
        }
 
-       public void destroy() {
+       public void stop() {
                JcrUtils.logoutQuietly(adminSession);
        }
 
@@ -32,9 +40,26 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext {
        }
 
        @Override
-       public Content get(ProvidedSession session, String mountPath, String relativePath) {
-               // TODO Auto-generated method stub
-               return null;
+       public Content get(ProvidedSession contentSession, String mountPath, String relativePath) {
+               String workspace = ContentUtils.getParentPath(mountPath)[1];
+               JcrSessionAdapter sessionAdapter = sessionAdapters.get(contentSession);
+               if (sessionAdapter == null) {
+                       final JcrSessionAdapter newSessionAdapter = new JcrSessionAdapter(jcrRepository,
+                                       contentSession.getSubject());
+                       sessionAdapters.put(contentSession, newSessionAdapter);
+                       contentSession.onClose().thenAccept((s) -> newSessionAdapter.close());
+                       sessionAdapter = newSessionAdapter;
+               }
+
+               Session jcrSession = sessionAdapter.getSession(workspace);
+               String jcrPath = "/" + relativePath;
+               try {
+                       Node node = jcrSession.getNode(jcrPath);
+                       return new JcrContent(contentSession, this, node);
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot get JCR content '" + jcrPath + ", mounted from '" + mountPath
+                                       + "' with JCR session " + jcrSession, e);
+               }
        }
 
        /*