X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms.jcr%2Fsrc%2Forg%2Fargeo%2Fcms%2Fjcr%2Facr%2FJcrContent.java;h=9e662ecc96ab8dcbf128c452ba1c1f42acfc661f;hb=940ce9759c33a2f409fb4491a05b0edb892584c7;hp=864fbfb7eb8efead51c7475d7b0ce8453ba15fc3;hpb=311d6e47ad278fd00d1ad15fe9d59be47e23e385;p=gpl%2Fargeo-jcr.git diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java index 864fbfb..9e662ec 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java @@ -54,6 +54,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 +88,13 @@ public class JcrContent extends AbstractContent { return NamespaceUtils.parsePrefixedName(provider, name); } -// @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") @Override public Optional get(QName key, Class 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 +168,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); } @@ -189,6 +202,14 @@ public class JcrContent extends AbstractContent { return Jcr.getIndex(getJcrNode()); } + /* + * MAP OPTIMISATIONS + */ + @Override + public boolean containsKey(Object key) { + return Jcr.hasProperty(getJcrNode(), key.toString()); + } + /* * WRITE */ @@ -503,8 +524,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 +552,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); }