Improve UI event support
[lgpl/argeo-commons.git] / swt / org.argeo.cms.swt / src / org / argeo / cms / swt / AbstractSwtCmsView.java
index 2059803036f2ab476205564534f0203ed1bdde62..c481a2cc07be061e38b0db28c2212e50d096775a 100644 (file)
@@ -1,23 +1,29 @@
 package org.argeo.cms.swt;
 
-import java.security.PrivilegedAction;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.Callable;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
 import java.util.concurrent.ExecutionException;
 
 import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 
+import org.argeo.api.cms.CmsApp;
 import org.argeo.api.cms.CmsEventBus;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.ux.CmsImageManager;
 import org.argeo.api.cms.ux.CmsUi;
 import org.argeo.api.cms.ux.CmsView;
 import org.argeo.api.cms.ux.UxContext;
 import org.argeo.cms.auth.CurrentUser;
+import org.argeo.util.CurrentSubject;
 import org.eclipse.swt.widgets.Display;
 
 public abstract class AbstractSwtCmsView implements CmsView {
+       private final static CmsLog log = CmsLog.getLog(AbstractSwtCmsView.class);
+
        protected final String uiName;
 
        protected LoginContext loginContext;
@@ -37,6 +43,8 @@ public abstract class AbstractSwtCmsView implements CmsView {
 
        public abstract CmsEventBus getCmsEventBus();
 
+       public abstract CmsApp getCmsApp();
+
        @Override
        public void sendEvent(String topic, Map<String, Object> properties) {
                if (properties == null)
@@ -45,20 +53,43 @@ public abstract class AbstractSwtCmsView implements CmsView {
                        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);
+
+               log.debug(() -> uid + ": send event to " + topic);
+
                getCmsEventBus().sendEvent(topic, properties);
+               //getCmsApp().onEvent(topic, properties);
        }
 
-       public <T> T doAs(PrivilegedAction<T> action) {
+//     public void runAs(Runnable runnable) {
+//             display.asyncExec(() -> doAs(Executors.callable(runnable)));
+//     }
+
+       public <T> T doAs(Callable<T> action) {
                try {
                        CompletableFuture<T> result = new CompletableFuture<>();
                        Runnable toDo = () -> {
-                               T res = Subject.doAs(getSubject(), action);
+                               log.debug(() -> uid + ": process doAs");
+                               Subject subject = CurrentSubject.current();
+                               T res;
+                               if (subject != null) {
+                                       assert subject == getSubject();
+                                       try {
+                                               res = action.call();
+                                       } catch (Exception e) {
+                                               throw new CompletionException("Failed to execute action for " + subject, e);
+                                       }
+                               } else {
+                                       res = CurrentSubject.callAs(getSubject(), action);
+                               }
                                result.complete(res);
                        };
                        if (Thread.currentThread() == display.getThread())
                                toDo.run();
-                       else
-                               display.syncExec(toDo);
+                       else {
+                               display.asyncExec(toDo);
+                               display.wake();
+                       }
+//                             throw new IllegalStateException("Must be called from UI thread");
                        return result.get();
                } catch (InterruptedException | ExecutionException e) {
                        throw new IllegalStateException("Cannot execute action ins CMS view " + uid, e);