From: Mathieu Baudier Date: Thu, 2 Jun 2022 08:34:18 +0000 (+0200) Subject: Improve ACR / JCR integration. X-Git-Tag: v2.3.10~208 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=279880f110272df643cee670aa976ae5ab9ec396;p=lgpl%2Fargeo-commons.git Improve ACR / JCR integration. --- diff --git a/eclipse/org.argeo.cms.e4/bnd.bnd b/eclipse/org.argeo.cms.e4/bnd.bnd index ea9504384..8026f9869 100644 --- a/eclipse/org.argeo.cms.e4/bnd.bnd +++ b/eclipse/org.argeo.cms.e4/bnd.bnd @@ -3,7 +3,9 @@ OSGI-INF/userAdminWrapper.xml,\ OSGI-INF/defaultCallbackHandler.xml Bundle-ActivationPolicy: lazy -Import-Package: org.eclipse.swt,\ +Import-Package: \ +org.argeo.api.acr,\ +org.eclipse.swt,\ org.eclipse.swt.widgets;version="0.0.0",\ org.eclipse.e4.ui.model.application.ui,\ org.eclipse.e4.ui.model.application,\ diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtUiProvider.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtUiProvider.java index 46166b859..4988fc6b8 100644 --- a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtUiProvider.java +++ b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/acr/SwtUiProvider.java @@ -1,11 +1,10 @@ package org.argeo.cms.swt.acr; import org.argeo.api.acr.Content; -import org.argeo.api.cms.MvcProvider; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; @FunctionalInterface -public interface SwtUiProvider extends MvcProvider { - +public interface SwtUiProvider { + Control createUiPart(Composite parent, Content context); } diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/jcrContentProvider.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/jcrContentProvider.xml index eb15b4c81..47d724aea 100644 --- a/jcr/org.argeo.cms.jcr/OSGI-INF/jcrContentProvider.xml +++ b/jcr/org.argeo.cms.jcr/OSGI-INF/jcrContentProvider.xml @@ -5,5 +5,6 @@ + diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java index 134f68162..dab419794 100644 --- a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java +++ b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java @@ -31,6 +31,7 @@ import org.argeo.api.acr.ContentUtils; import org.argeo.api.acr.NamespaceUtils; import org.argeo.api.acr.spi.AbstractContent; import org.argeo.api.acr.spi.ProvidedSession; +import org.argeo.api.cms.CmsConstants; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; @@ -284,4 +285,22 @@ public class JcrContent extends AbstractContent { // } // // } + /* + * STATIC UTLITIES + */ + public static Content nodeToContent(Node node) { + if (node == null) + return null; + try { + ProvidedSession contentSession = (ProvidedSession) node.getSession() + .getAttribute(ProvidedSession.class.getName()); + if (contentSession == null) + throw new IllegalArgumentException( + "Cannot adapt " + node + " to content, because it was not loaded from a content session"); + return contentSession.get(CmsConstants.SYS_WORKSPACE + node.getPath()); + } catch (RepositoryException e) { + throw new JcrException("Cannot adapt " + node + " to a content", e); + } + } + } diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java index f7bfd0949..9e0a0089a 100644 --- a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java +++ b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java @@ -54,7 +54,7 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { public Session getJcrSession(ProvidedSession contentSession, String jcrWorkspace) { JcrSessionAdapter sessionAdapter = sessionAdapters.get(contentSession); if (sessionAdapter == null) { - final JcrSessionAdapter newSessionAdapter = new JcrSessionAdapter(jcrRepository, + final JcrSessionAdapter newSessionAdapter = new JcrSessionAdapter(jcrRepository, contentSession, contentSession.getSubject()); sessionAdapters.put(contentSession, newSessionAdapter); contentSession.onClose().thenAccept((s) -> newSessionAdapter.close()); diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionAdapter.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionAdapter.java index f02b8d213..ae8ae80f2 100644 --- a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionAdapter.java +++ b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrSessionAdapter.java @@ -10,6 +10,8 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.security.auth.Subject; +import org.apache.jackrabbit.core.SessionImpl; +import org.argeo.api.acr.spi.ProvidedSession; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; @@ -18,14 +20,17 @@ class JcrSessionAdapter { private Repository repository; private Subject subject; + private ProvidedSession contentSession; + private Map> threadSessions = Collections.synchronizedMap(new HashMap<>()); private boolean closed = false; private Thread lastRetrievingThread = null; - public JcrSessionAdapter(Repository repository, Subject subject) { + public JcrSessionAdapter(Repository repository, ProvidedSession contentSession, Subject subject) { this.repository = repository; + this.contentSession = contentSession; this.subject = subject; } @@ -58,7 +63,12 @@ class JcrSessionAdapter { if (session == null) { session = Subject.doAs(subject, (PrivilegedAction) () -> { try { +// String username = CurrentUser.getUsername(subject); +// SimpleCredentials credentials = new SimpleCredentials(username, new char[0]); +// credentials.setAttribute(ProvidedSession.class.getName(), contentSession); Session sess = repository.login(workspace); + // Jackrabbit specific: + ((SessionImpl)sess).setAttribute(ProvidedSession.class.getName(), contentSession); return sess; } catch (RepositoryException e) { throw new IllegalStateException("Cannot log in to " + workspace, e); diff --git a/jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiProvider.java b/jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiProvider.java index ec76321fe..08b100efa 100644 --- a/jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiProvider.java +++ b/jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiProvider.java @@ -3,13 +3,16 @@ package org.argeo.cms.ui; import javax.jcr.Node; import javax.jcr.RepositoryException; -import org.argeo.api.cms.MvcProvider; +import org.argeo.api.acr.Content; +import org.argeo.cms.jcr.acr.JcrContent; +import org.argeo.cms.swt.acr.SwtUiProvider; +import org.argeo.jcr.JcrException; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; /** Stateless factory building an SWT user interface given a JCR context. */ @FunctionalInterface -public interface CmsUiProvider extends MvcProvider { +public interface CmsUiProvider extends SwtUiProvider { /** * Initialises a user interface. * @@ -18,12 +21,21 @@ public interface CmsUiProvider extends MvcProvider { */ Control createUi(Composite parent, Node context) throws RepositoryException; - @Override default Control createUiPart(Composite parent, Node context) { try { return createUi(parent, context); } catch (RepositoryException e) { - throw new IllegalStateException("Cannot create UI for context " + context, e); + throw new JcrException("Cannot create UI for context " + context, e); + } + } + + @Override + default Control createUiPart(Composite parent, Content context) { + if (context instanceof JcrContent) { + Node node = ((JcrContent) context).getJcrNode(); + return createUiPart(parent, node); + } else { + throw new IllegalArgumentException("Content " + context + " is not compatible with JCR"); } } diff --git a/org.argeo.api.cms/src/org/argeo/api/cms/MvcProvider.java b/org.argeo.api.cms/src/org/argeo/api/cms/MvcProvider.java index c1aa6006c..92864ea5c 100644 --- a/org.argeo.api.cms/src/org/argeo/api/cms/MvcProvider.java +++ b/org.argeo.api.cms/src/org/argeo/api/cms/MvcProvider.java @@ -9,6 +9,7 @@ import java.util.function.BiFunction; * are relevant for all created UI part. */ @FunctionalInterface +@Deprecated public interface MvcProvider extends BiFunction { W createUiPart(V parent, M context); diff --git a/org.argeo.cms.ux/src/org/argeo/cms/ux/CmsUxUtils.java b/org.argeo.cms.ux/src/org/argeo/cms/ux/CmsUxUtils.java new file mode 100644 index 000000000..9e23ff663 --- /dev/null +++ b/org.argeo.cms.ux/src/org/argeo/cms/ux/CmsUxUtils.java @@ -0,0 +1,17 @@ +package org.argeo.cms.ux; + +import org.argeo.api.acr.ContentRepository; +import org.argeo.api.acr.ContentSession; +import org.argeo.api.cms.CmsView; +import org.argeo.cms.auth.CurrentUser; + +public class CmsUxUtils { + public static ContentSession getContentSession(ContentRepository contentRepository, CmsView cmsView) { + return CurrentUser.callAs(cmsView.getCmsSession().getSubject(), () -> contentRepository.get()); + } + + /** singleton */ + private CmsUxUtils() { + + } +} diff --git a/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/HierarchicalPart.java b/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/HierarchicalPart.java new file mode 100644 index 000000000..244765eaf --- /dev/null +++ b/org.argeo.cms.ux/src/org/argeo/cms/ux/widgets/HierarchicalPart.java @@ -0,0 +1,5 @@ +package org.argeo.cms.ux.widgets; + +public interface HierarchicalPart { + +} diff --git a/org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java b/org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java index cbe428692..b43bf98b5 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java @@ -9,6 +9,8 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionException; import javax.security.auth.Subject; import javax.security.auth.x500.X500Principal; @@ -162,6 +164,29 @@ public final class CurrentUser { return true; } + /* + * PREPARE EVOLUTION OF JAVA APIs INTRODUCED IN JDK 18 + * The following static methods will be added to Subject + */ + public Subject current() { + return currentSubject(); + } + + public static T callAs(Subject subject, Callable action) { + try { + return Subject.doAs(subject, new PrivilegedExceptionAction() { + + @Override + public T run() throws Exception { + return action.call(); + } + + }); + } catch (PrivilegedActionException e) { + throw new CompletionException("Failed to execute action for " + subject, e.getCause()); + } + } + private CurrentUser() { } } diff --git a/rap/org.argeo.cms.ui.rap/bnd.bnd b/rap/org.argeo.cms.ui.rap/bnd.bnd index dc528df8c..1d7c4b08b 100644 --- a/rap/org.argeo.cms.ui.rap/bnd.bnd +++ b/rap/org.argeo.cms.ui.rap/bnd.bnd @@ -1,4 +1,5 @@ Import-Package:\ +org.argeo.api.acr,\ org.eclipse.swt,\ org.argeo.eclipse.ui,\ javax.jcr.nodetype,\