X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=swt%2Forg.argeo.cms.swt%2Fsrc%2Forg%2Fargeo%2Fcms%2Fswt%2FAbstractSwtCmsView.java;h=127be0856195fecf7b0d484a16e654030f6849c4;hb=bd79aaa6f342553778a6051313580ab9841f4d3b;hp=2059803036f2ab476205564534f0203ed1bdde62;hpb=8c6e16aa43d9523e1ec57a41a06b3ceba7d23fdb;p=lgpl%2Fargeo-commons.git diff --git a/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/AbstractSwtCmsView.java b/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/AbstractSwtCmsView.java index 205980303..127be0856 100644 --- a/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/AbstractSwtCmsView.java +++ b/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/AbstractSwtCmsView.java @@ -1,28 +1,50 @@ package org.argeo.cms.swt; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +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.cms.CurrentUser; +import org.argeo.cms.util.CurrentSubject; import org.eclipse.swt.widgets.Display; public abstract class AbstractSwtCmsView implements CmsView { + private final static CmsLog log = CmsLog.getLog(AbstractSwtCmsView.class); + + /** A timer to be used to perform background UX tasks. */ + private final static Timer uxTimer = new Timer(true); + + static { + // purge every day + uxTimer.schedule(new TimerTask() { + + @Override + public void run() { + uxTimer.purge(); + } + }, 0, 24 * 60 * 60 * 1000); + } + protected final String uiName; protected LoginContext loginContext; protected String state; - protected Throwable exception; +// protected Throwable exception; protected UxContext uxContext; protected CmsImageManager imageManager; @@ -37,6 +59,8 @@ public abstract class AbstractSwtCmsView implements CmsView { public abstract CmsEventBus getCmsEventBus(); + public abstract CmsApp getCmsApp(); + @Override public void sendEvent(String topic, Map properties) { if (properties == null) @@ -45,20 +69,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.trace(() -> uid + ": send event to " + topic); + getCmsEventBus().sendEvent(topic, properties); + // getCmsApp().onEvent(topic, properties); } - public T doAs(PrivilegedAction action) { +// public void runAs(Runnable runnable) { +// display.asyncExec(() -> doAs(Executors.callable(runnable))); +// } + + public T doAs(Callable action) { try { CompletableFuture result = new CompletableFuture<>(); Runnable toDo = () -> { - T res = Subject.doAs(getSubject(), action); + log.trace(() -> 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); @@ -107,4 +154,37 @@ public abstract class AbstractSwtCmsView implements CmsView { } } + @Override + public TimerTask schedule(Runnable task, long delay) { + TimerTask timerTask = newSwtUxTimerTask(task); + uxTimer.schedule(timerTask, delay); + return timerTask; + } + + @Override + public TimerTask schedule(Runnable task, long delay, long period) { + TimerTask timerTask = newSwtUxTimerTask(task); + uxTimer.schedule(timerTask, delay, period); + return timerTask; + } + + protected TimerTask newSwtUxTimerTask(Runnable todo) { + return new TimerTask() { + + @Override + public void run() { + synchronized (display) { + try { + if (!display.isDisposed()) { + display.syncExec(() -> { + todo.run(); + }); + } + } catch (Exception e) { + log.error("Cannot run UX timer task", e); + } + } + } + }; + } }