X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms.jcr%2Fsrc%2Forg%2Fargeo%2Fcms%2Fjcr%2Facr%2FJcrContentProvider.java;h=5fc7d7c241d2496b040a13d2f2a0b68fa1fc7ed8;hb=5e444f98184584e55114e86c5baf3a4bcb458cdf;hp=eaa27b7fc631d806fde1f1590c0eca142f786cd7;hpb=bce03099b0d2f1758e7a3d74fba339d0200924d5;p=gpl%2Fargeo-jcr.git diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java index eaa27b7..5fc7d7c 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java @@ -6,13 +6,21 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Objects; +import java.util.Spliterator; +import java.util.function.Consumer; +import java.util.function.Function; +import javax.jcr.Node; +import javax.jcr.NodeIterator; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.query.Query; +import javax.jcr.query.QueryResult; import javax.xml.namespace.NamespaceContext; import org.argeo.api.acr.Content; +import org.argeo.api.acr.search.BasicSearch; import org.argeo.api.acr.spi.ContentProvider; import org.argeo.api.acr.spi.ProvidedContent; import org.argeo.api.acr.spi.ProvidedSession; @@ -53,20 +61,27 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { this.jcrRepository = jcrRepository; } + @Override + public String getMountPath() { + return mountPath; + } + + /* + * READ + */ + @Override public ProvidedContent get(ProvidedSession contentSession, String relativePath) { - String jcrPath = "/" + relativePath; - return new JcrContent(contentSession, this, jcrWorkspace, jcrPath); + return new JcrContent(contentSession, this, jcrWorkspace, toJcrPath(relativePath)); } @Override public boolean exists(ProvidedSession contentSession, String relativePath) { - String jcrWorkspace = ContentUtils.getParentPath(mountPath)[1]; - String jcrPath = "/" + relativePath; + String jcrPath = ContentUtils.SLASH + relativePath; return new JcrContent(contentSession, this, jcrWorkspace, jcrPath).exists(); } - public Session getJcrSession(ProvidedSession contentSession, String jcrWorkspace) { + protected JcrSessionAdapter getJcrSessionAdapter(ProvidedSession contentSession) { JcrSessionAdapter sessionAdapter = sessionAdapters.get(contentSession); if (sessionAdapter == null) { final JcrSessionAdapter newSessionAdapter = new JcrSessionAdapter(jcrRepository, contentSession, @@ -75,7 +90,11 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { contentSession.onClose().thenAccept((s) -> newSessionAdapter.close()); sessionAdapter = newSessionAdapter; } + return sessionAdapter; + } + public Session getJcrSession(ProvidedSession contentSession, String jcrWorkspace) { + JcrSessionAdapter sessionAdapter = getJcrSessionAdapter(contentSession); Session jcrSession = sessionAdapter.getSession(jcrWorkspace); return jcrSession; } @@ -84,16 +103,71 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { return getJcrSession(((ProvidedContent) content).getSession(), jcrWorkspace); } + /* + * WRITE + */ + Node openForEdit(ProvidedSession contentSession, String jcrWorkspace, String jcrPath) { + try { + if (contentSession.isEditing()) { + JcrSessionAdapter sessionAdapter = getJcrSessionAdapter(contentSession); + return sessionAdapter.openForEdit(jcrWorkspace, jcrPath); + } else { + return getJcrSession(contentSession, jcrWorkspace).getNode(jcrPath); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot open for edit " + jcrPath + " in workspace " + jcrWorkspace, e); + } + } + @Override - public String getMountPath() { - return mountPath; + public void persist(ProvidedSession contentSession) { + try { + JcrSessionAdapter sessionAdapter = getJcrSessionAdapter(contentSession); + sessionAdapter.persist(); + } catch (RepositoryException e) { + throw new JcrException("Cannot persist " + contentSession, e); + } + } + + /* + * EDITING + */ + + @Override + public void openForEdit(ProvidedSession session, String relativePath) { + openForEdit(session, relativePath, toJcrPath(relativePath)); + } + + @Override + public void freeze(ProvidedSession session, String relativePath) { + try { + String jcrPath = toJcrPath(relativePath); + if (session.isEditing()) { + JcrSessionAdapter sessionAdapter = getJcrSessionAdapter(session); + sessionAdapter.freeze(jcrWorkspace, jcrPath); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot freeze " + relativePath + " in workspace " + jcrWorkspace, e); + } + } + + @Override + public boolean isOpenForEdit(ProvidedSession session, String relativePath) { + try { + String jcrPath = toJcrPath(relativePath); + JcrSessionAdapter sessionAdapter = getJcrSessionAdapter(session); + return sessionAdapter.isOpenForEdit(jcrWorkspace, jcrPath); + } catch (RepositoryException e) { + throw new JcrException( + "Cannot check whether " + relativePath + " is open for edit in workspace " + jcrWorkspace, e); + } } /* * NAMESPACE CONTEXT */ @Override - public String getNamespaceURI(String prefix) { + public synchronized String getNamespaceURI(String prefix) { try { return adminSession.getNamespaceURI(prefix); } catch (RepositoryException e) { @@ -102,7 +176,7 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { } @Override - public String getPrefix(String namespaceURI) { + public synchronized String getPrefix(String namespaceURI) { try { return adminSession.getNamespacePrefix(namespaceURI); } catch (RepositoryException e) { @@ -111,7 +185,7 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { } @Override - public Iterator getPrefixes(String namespaceURI) { + public synchronized Iterator getPrefixes(String namespaceURI) { try { return Arrays.asList(adminSession.getNamespacePrefix(namespaceURI)).iterator(); } catch (RepositoryException e) { @@ -119,4 +193,92 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { } } + /* + * SEARCH + */ + + @Override + public Spliterator search(ProvidedSession session, BasicSearch search, String relPath) { + try { + Session jcrSession = getJcrSession(session, jcrWorkspace); + BasicSearchToQom jcrBasicSearch = new BasicSearchToQom(jcrSession, search, relPath); + Query query = jcrBasicSearch.createQuery(); + QueryResult queryResult = query.execute(); + return new QueryResultSpliterator(session, queryResult.getNodes()); + } catch (RepositoryException e) { + throw new JcrException(e); + } + } + + class QueryResultSpliterator implements Spliterator { + private ProvidedSession providedSession; + private NodeIterator nodeIterator; + + public QueryResultSpliterator(ProvidedSession providedSession, NodeIterator nodeIterator) { + super(); + this.providedSession = providedSession; + this.nodeIterator = nodeIterator; + } + + @Override + public boolean tryAdvance(Consumer action) { + if (!nodeIterator.hasNext()) + return false; + try { + Node node = nodeIterator.nextNode(); + // TODO optimise by reusing the Node + JcrContent jcrContent = new JcrContent(providedSession, JcrContentProvider.this, jcrWorkspace, + node.getPath()); + action.accept(jcrContent); + return true; + } catch (RepositoryException e) { + throw new JcrException(e); + } + } + + @Override + public Spliterator trySplit() { + return null; + } + + @Override + public long estimateSize() { + return nodeIterator.getSize(); + } + + @Override + public int characteristics() { + return NONNULL | SIZED; + } + + } + + /* + * UTILITIES + */ + /** + * Just adds a '/' so that it becomes an absolute JCR path within the JCR + * workspace of this provider. + */ + private String toJcrPath(String relativePath) { + return ContentUtils.SLASH + relativePath; + } + + /* + * TRANSITIONAL, WHILE MIGRATING FROM JCR TO ACR + */ + @Deprecated + public synchronized T doInAdminSession(Function toDo) { + try { + return toDo.apply(adminSession); + } finally { + try { + if (adminSession.hasPendingChanges()) + adminSession.save(); + } catch (RepositoryException e) { + throw new JcrException("Cannot save admin session", e); + } + } + } + }