Extend CMS view.
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 8 Oct 2020 08:25:26 +0000 (10:25 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 8 Oct 2020 08:25:26 +0000 (10:25 +0200)
org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java
org.argeo.cms.ui/src/org/argeo/cms/ui/CmsView.java
org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java
org.argeo.cms.ui/src/org/argeo/cms/ui/util/LoginEntryPoint.java
org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebApp.java
org.argeo.cms.ui/src/org/argeo/cms/web/CmsWebEntryPoint.java
org.argeo.cms.ui/src/org/argeo/cms/web/SimpleErgonomics.java
org.argeo.util/src/org/argeo/util/LangUtils.java

index acdbd07a34122d7ba3b86ab7282d59ec1f6b88c3..300c7566b4efcd9f348e2950f9f4160aad23d8bc 100644 (file)
@@ -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() {
        }
index ce0acb89fd2b68c0c2c249b6f9df362310d0483c..0e7e7268042a64650a9979acb5e03dba53dd5553 100644 (file)
@@ -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<String, Object> 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);
        }
index 167d7341f441748bf1e4bd99d4126572de794f84..303fb7deadb81d78905acca58645d3b6ca0e9a6c 100644 (file)
@@ -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<String, Object> 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<String, Object> 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 extends Widget> T style(T widget, String style) {
                widget.setData(CmsConstants.STYLE, style);
index 74c00b59fc319a452b1b02dcd514852486ea53c1..0bbed1d77dfa06a7fda5573805b09f0ee7f8210c 100644 (file)
@@ -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 <b>not</b>
+        * 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 <b>not</b>
         * 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
index 70d3917d48813edbb82b7a2365f98a0215890e25..03ac353df248ab5952daa0ad559747d477131532 100644 (file)
@@ -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<ApplicationConfiguration> 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;
+       }
+
 }
index 351f771c141285e896bc45ec5f5cd385949d9f1f..186c988b1d1cacff17718800b32bad617ee20200 100644 (file)
@@ -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<String, Object> 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;
+       }
+
 }
index 0ca37e2fd8b0976c58ba195675229d2dc14070fe..7e17770e64ef15e2000d67d45091dba8b6ecbb51 100644 (file)
@@ -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<String, String> 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() {
index 779adb01eb4a204dd2dc07d27bee06be386d6083..2f99bb3e0d735bb75a99704ce9ffbee2847b560c 100644 (file)
@@ -71,6 +71,29 @@ public class LangUtils {
                return res;
        }
 
+       /**
+        * Get a string property from this map, expecting to find it, or
+        * <code>null</code> if not found.
+        */
+       public static String get(Map<String, ?> 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<String, ?> 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}.
         */