From: Mathieu Baudier Date: Thu, 8 Oct 2020 08:25:26 +0000 (+0200) Subject: Extend CMS view. X-Git-Tag: argeo-commons-2.1.89~80 X-Git-Url: https://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=d289fa62f9dadd0a5bd49ab5e3d499e87152525d Extend CMS view. --- diff --git a/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java b/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java index acdbd07a3..300c7566b 100644 --- a/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java +++ b/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java @@ -1,6 +1,7 @@ package org.argeo.cms.e4.rap; import java.security.AccessController; +import java.util.UUID; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; @@ -41,9 +42,11 @@ public class CmsLoginLifecycle implements CmsView { private BrowserNavigation browserNavigation; private String state = null; + private String uid; @PostContextCreate boolean login(final IEventBroker eventBroker) { + uid = UUID.randomUUID().toString(); browserNavigation = RWT.getClient().getService(BrowserNavigation.class); if (browserNavigation != null) browserNavigation.addBrowserNavigationListener(new BrowserNavigationListener() { @@ -155,6 +158,11 @@ public class CmsLoginLifecycle implements CmsView { return CurrentUser.isAnonymous(getSubject()); } + @Override + public String getUid() { + return uid; + } + // CALLBACKS protected void startupComplete() { } diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsView.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsView.java index ce0acb89f..0e7e72680 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsView.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsView.java @@ -1,5 +1,7 @@ package org.argeo.cms.ui; +import java.util.Map; + import javax.security.auth.login.LoginContext; import org.eclipse.swt.widgets.Composite; @@ -7,7 +9,10 @@ import org.eclipse.swt.widgets.Shell; /** Provides interaction with the CMS system. */ public interface CmsView { - //String KEY = "org.argeo.cms.ui.view"; + final static String CMS_VIEW_UID_PROPERTY = "argeo.cms.view.uid"; + // String KEY = "org.argeo.cms.ui.view"; + + String getUid(); UxContext getUxContext(); @@ -28,6 +33,14 @@ public interface CmsView { boolean isAnonymous(); + /** + * Send an event to this topic. Does noothing by default., but if implemented it + * MUST set the {@link #CMS_VIEW_UID_PROPERTY} in the properties. + */ + default void sendEvent(String topic, Map properties) { + + } + static CmsView getCmsView(Composite parent) { // find parent shell Shell topShell = parent.getShell(); @@ -44,8 +57,7 @@ public interface CmsView { // check if already set if (topShell.getData(CmsView.class.getName()) != null) { CmsView registeredView = (CmsView) topShell.getData(CmsView.class.getName()); - throw new IllegalArgumentException( - "Cms view " + registeredView + " already registered in this shell"); + throw new IllegalArgumentException("Cms view " + registeredView + " already registered in this shell"); } shell.setData(CmsView.class.getName(), view); } diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java index 167d7341f..303fb7dea 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import javax.jcr.Node; import javax.jcr.RepositoryException; @@ -14,13 +16,17 @@ import org.argeo.api.NodeUtils; import org.argeo.cms.CmsException; import org.argeo.cms.ui.CmsConstants; import org.argeo.cms.ui.CmsView; +import org.argeo.eclipse.ui.Selected; import org.argeo.jcr.JcrUtils; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.service.ResourceManager; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowData; @@ -37,6 +43,31 @@ import org.eclipse.swt.widgets.Widget; public class CmsUiUtils implements CmsConstants { // private final static Log log = LogFactory.getLog(CmsUiUtils.class); + /* + * CMS VIEW + */ + + /** Sends an event via {@link CmsView#sendEvent(String, Map)}. */ + public static void sendEventOnSelect(Control control, String topic, Map properties) { + SelectionListener listener = (Selected) (e) -> { + CmsView.getCmsView(control.getParent()).sendEvent(topic, properties); + }; + if (control instanceof Button) { + ((Button) control).addSelectionListener(listener); + } else + throw new UnsupportedOperationException("Control type " + control.getClass() + " is not supported."); + } + + /** + * Convenience method to sends an event via + * {@link CmsView#sendEvent(String, Map)}. + */ + public static void sendEventOnSelect(Control control, String topic, String key, Object value) { + Map properties = new HashMap<>(); + properties.put(key, value); + sendEventOnSelect(control, topic, properties); + } + /** * The CMS view related to this display, or null if none is available from this * call. @@ -86,6 +117,9 @@ public class CmsUiUtils implements CmsConstants { @Deprecated public static RowData ROW_DATA_16px = new RowData(16, 16); + /* + * GRID LAYOUT + */ public static GridLayout noSpaceGridLayout() { return noSpaceGridLayout(new GridLayout()); } @@ -102,9 +136,6 @@ public class CmsUiUtils implements CmsConstants { return layout; } - // - // GRID DATA - // public static GridData fillAll() { return new GridData(SWT.FILL, SWT.FILL, true, true); } @@ -129,6 +160,23 @@ public class CmsUiUtils implements CmsConstants { return new RowData(16, 16); } + /* + * FORM LAYOUT + */ + + public static FormData coversAll() { + FormData fdLabel = new FormData(); + fdLabel.top = new FormAttachment(0, 0); + fdLabel.left = new FormAttachment(0, 0); + fdLabel.right = new FormAttachment(100, 0); + fdLabel.bottom = new FormAttachment(100, 0); + return fdLabel; + } + + /* + * STYLING + */ + /** Style widget */ public static T style(T widget, String style) { widget.setData(CmsConstants.STYLE, style); diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/LoginEntryPoint.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/LoginEntryPoint.java index 74c00b59f..0bbed1d77 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/LoginEntryPoint.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/LoginEntryPoint.java @@ -1,6 +1,7 @@ package org.argeo.cms.ui.util; import java.util.Locale; +import java.util.UUID; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; @@ -30,9 +31,11 @@ public class LoginEntryPoint implements EntryPoint, CmsView { private final static Log log = LogFactory.getLog(LoginEntryPoint.class); private LoginContext loginContext; private UxContext uxContext = null; + private String uid; @Override public int createUI() { + uid = UUID.randomUUID().toString(); final Display display = createDisplay(); // UiContext.setData(CmsView.KEY, this); @@ -104,9 +107,9 @@ public class LoginEntryPoint implements EntryPoint, CmsView { } /** - * To be overridden. CmsLogin#createCredentialsBlock() should be called at - * some point in order to create the credentials composite. In order to use - * the default layout, call CmsLogin#defaultCreateContents() but not + * To be overridden. CmsLogin#createCredentialsBlock() should be called at some + * point in order to create the credentials composite. In order to use the + * default layout, call CmsLogin#defaultCreateContents() but not * CmsLogin#createContent(), since it would lead to a stack overflow. */ protected void createLoginPage(Composite parent, CmsLogin login) { @@ -118,6 +121,11 @@ public class LoginEntryPoint implements EntryPoint, CmsView { } + @Override + public String getUid() { + return uid; + } + @Override public void navigateTo(String state) { // TODO Auto-generated method stub diff --git a/org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebApp.java b/org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebApp.java index 70d3917d4..03ac353df 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebApp.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebApp.java @@ -16,6 +16,7 @@ import org.eclipse.rap.rwt.application.ApplicationConfiguration; import org.eclipse.rap.rwt.client.WebClient; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; +import org.osgi.service.event.EventAdmin; /** An RWT web app integrating with a {@link CmsApp}. */ public class CmsWebApp implements ApplicationConfiguration, CmsAppListener { @@ -23,6 +24,7 @@ public class CmsWebApp implements ApplicationConfiguration, CmsAppListener { private BundleContext bundleContext; private CmsApp cmsApp; + private EventAdmin eventAdmin; private ServiceRegistration rwtAppReg; @@ -70,7 +72,9 @@ public class CmsWebApp implements ApplicationConfiguration, CmsAppListener { // log.warn("Theme id " + themeId + " was specified but it was not found, using default RWT theme."); } application.addEntryPoint("/" + uiName, () -> { - return new CmsWebEntryPoint(this, uiName); + CmsWebEntryPoint entryPoint = new CmsWebEntryPoint(this, uiName); + entryPoint.setEventAdmin(eventAdmin); + return entryPoint; }, properties); if (log.isDebugEnabled()) log.info("Added web entry point /" + (contextName != null ? contextName : "") + "/" + uiName); @@ -126,4 +130,8 @@ public class CmsWebApp implements ApplicationConfiguration, CmsAppListener { } } + public void setEventAdmin(EventAdmin eventAdmin) { + this.eventAdmin = eventAdmin; + } + } diff --git a/org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebEntryPoint.java b/org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebEntryPoint.java index 351f771c1..186c988b1 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebEntryPoint.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebEntryPoint.java @@ -3,6 +3,8 @@ package org.argeo.cms.web; import static org.eclipse.rap.rwt.internal.service.ContextProvider.getApplicationContext; import java.security.PrivilegedAction; +import java.util.Map; +import java.util.UUID; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; @@ -19,6 +21,8 @@ import org.argeo.cms.ui.CmsView; import org.argeo.cms.ui.UxContext; import org.argeo.cms.ui.dialogs.CmsFeedback; import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.util.DefaultImageManager; +import org.argeo.cms.ui.util.SimpleUxContext; import org.argeo.eclipse.ui.specific.UiContext; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.application.EntryPoint; @@ -30,21 +34,29 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventAdmin; /** The {@link CmsView} for a {@link CmsWebApp}. */ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationListener { private static final long serialVersionUID = 7733510691684570402L; private final static Log log = LogFactory.getLog(CmsWebEntryPoint.class); + private EventAdmin eventAdmin; + private final CmsWebApp cmsWebApp; private final String uiName; private LoginContext loginContext; private String state; private Throwable exception; + private UxContext uxContext; + private CmsImageManager imageManager; private Composite ui; + private String uid; + // Client services // private final JavaScriptExecutor jsExecutor; private final BrowserNavigation browserNavigation; @@ -57,6 +69,7 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL assert uiName != null; this.cmsWebApp = cmsWebApp; this.uiName = uiName; + uid = UUID.randomUUID().toString(); // Initial login LoginContext lc; @@ -85,6 +98,8 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL @Override public Void run() { try { + uxContext = new SimpleUxContext(); + imageManager = new DefaultImageManager(); ui = cmsWebApp.getCmsApp().initUi(parent); ui.setData(CmsApp.UI_NAME_PROPERTY, uiName); ui.setLayoutData(CmsUiUtils.fillAll()); @@ -168,8 +183,12 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL @Override public UxContext getUxContext() { - // TODO Auto-generated method stub - return null; + return uxContext; + } + + @Override + public String getUid() { + return uid; } @Override @@ -183,8 +202,7 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL @Override public CmsImageManager getImageManager() { - // TODO Auto-generated method stub - return null; + return imageManager; } @Override @@ -193,6 +211,15 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL doRefresh(); } + @Override + public void sendEvent(String topic, Map properties) { + if (properties.containsKey(CMS_VIEW_UID_PROPERTY) && !properties.get(CMS_VIEW_UID_PROPERTY).equals(uid)) + throw new IllegalArgumentException("Property " + CMS_VIEW_UID_PROPERTY + " is set to another CMS view uid (" + + properties.get(CMS_VIEW_UID_PROPERTY) + ") then " + uid); + properties.put(CMS_VIEW_UID_PROPERTY, uid); + eventAdmin.sendEvent(new Event(topic, properties)); + } + /* * EntryPoint IMPLEMENTATION */ @@ -234,4 +261,8 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL return shell; } + public void setEventAdmin(EventAdmin eventAdmin) { + this.eventAdmin = eventAdmin; + } + } diff --git a/org.argeo.cms.ui/src/org/argeo/cms/web/SimpleErgonomics.java b/org.argeo.cms.ui/src/org/argeo/cms/web/SimpleErgonomics.java index 0ca37e2fd..7e17770e6 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/web/SimpleErgonomics.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/web/SimpleErgonomics.java @@ -1,6 +1,7 @@ package org.argeo.cms.web; import java.util.Map; +import java.util.UUID; import javax.jcr.Node; import javax.jcr.Repository; @@ -48,6 +49,7 @@ public class SimpleErgonomics extends AbstractCmsEntryPoint { private CmsImageManager imageManager = new DefaultImageManager(); private UxContext uxContext = null; + private String uid; public SimpleErgonomics(Repository repository, String workspace, String defaultPath, CmsUiProvider uiProvider, Map factoryProperties) { @@ -57,6 +59,7 @@ public class SimpleErgonomics extends AbstractCmsEntryPoint { @Override protected void initUi(Composite parent) { + uid = UUID.randomUUID().toString(); parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); parent.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(3, false))); @@ -179,6 +182,10 @@ public class SimpleErgonomics extends AbstractCmsEntryPoint { public UxContext getUxContext() { return uxContext; } + @Override + public String getUid() { + return uid; + } @Override public CmsImageManager getImageManager() { diff --git a/org.argeo.util/src/org/argeo/util/LangUtils.java b/org.argeo.util/src/org/argeo/util/LangUtils.java index 779adb01e..2f99bb3e0 100644 --- a/org.argeo.util/src/org/argeo/util/LangUtils.java +++ b/org.argeo.util/src/org/argeo/util/LangUtils.java @@ -71,6 +71,29 @@ public class LangUtils { return res; } + /** + * Get a string property from this map, expecting to find it, or + * null if not found. + */ + public static String get(Map map, String key) { + Object res = map.get(key); + if (res == null) + return null; + return res.toString(); + } + + /** + * Get a string property from this map, expecting to find it. + * + * @throws IllegalArgumentException if the key was not found + */ + public static String getNotNull(Map map, String key) { + Object res = map.get(key); + if (res == null) + throw new IllegalArgumentException("Map " + map + " should contain key " + key); + return res.toString(); + } + /** * Wraps the keys of the provided {@link Dictionary} as an {@link Iterable}. */