projects
/
lgpl
/
argeo-commons.git
/ commitdiff
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
8c6e16a
)
Improve UI event support
author
Mathieu Baudier <mbaudier@argeo.org>
Sun, 24 Jul 2022 11:21:49 +0000
(13:21 +0200)
committer
Mathieu Baudier <mbaudier@argeo.org>
Sun, 24 Jul 2022 11:21:49 +0000
(13:21 +0200)
org.argeo.api.cms/src/org/argeo/api/cms/CmsApp.java
patch
|
blob
|
history
org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java
patch
|
blob
|
history
org.argeo.cms/src/org/argeo/cms/LocaleUtils.java
patch
|
blob
|
history
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsEventBusImpl.java
patch
|
blob
|
history
swt/org.argeo.cms.swt/src/org/argeo/cms/swt/AbstractSwtCmsView.java
patch
|
blob
|
history
swt/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java
patch
|
blob
|
history
swt/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java
patch
|
blob
|
history
swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java
patch
|
blob
|
history
diff --git
a/org.argeo.api.cms/src/org/argeo/api/cms/CmsApp.java
b/org.argeo.api.cms/src/org/argeo/api/cms/CmsApp.java
index 745e5a4000b0d5d95e4c8673dc19601171c310d3..b180fff75b67593772f8482c1489c2fad69fc9f7 100644
(file)
--- a/
org.argeo.api.cms/src/org/argeo/api/cms/CmsApp.java
+++ b/
org.argeo.api.cms/src/org/argeo/api/cms/CmsApp.java
@@
-1,12
+1,13
@@
package org.argeo.api.cms;
package org.argeo.api.cms;
+import java.util.Map;
import java.util.Set;
import org.argeo.api.cms.ux.CmsTheme;
import org.argeo.api.cms.ux.CmsUi;
/** An extensible user interface base on the CMS backend. */
import java.util.Set;
import org.argeo.api.cms.ux.CmsTheme;
import org.argeo.api.cms.ux.CmsUi;
/** An extensible user interface base on the CMS backend. */
-public interface CmsApp {
+public interface CmsApp
extends CmsEventSubscriber
{
/**
* If {@link CmsUi#setData(String, Object)} is set with this property, it
* indicates a different UI (typically with another theming. The {@link CmsApp}
/**
* If {@link CmsUi#setData(String, Object)} is set with this property, it
* indicates a different UI (typically with another theming. The {@link CmsApp}
@@
-35,4
+36,10
@@
public interface CmsApp {
void removeCmsAppListener(CmsAppListener listener);
CmsContext getCmsContext();
void removeCmsAppListener(CmsAppListener listener);
CmsContext getCmsContext();
+
+ @Override
+ default void onEvent(String topic, Map<String, Object> properties) {
+ }
+
+
}
}
diff --git
a/org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java
b/org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java
index 45629fba5bdd387947f0236b211a366783a3953c..15b6a5dc7aac338a7180f748fa404c31f4f28bb0 100644
(file)
--- a/
org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java
+++ b/
org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java
@@
-1,8
+1,9
@@
package org.argeo.api.cms.ux;
package org.argeo.api.cms.ux;
-import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginContext;
@@
-56,20
+57,14
@@
public interface CmsView {
}
}
- default <T> T doAs(PrivilegedAction<T> action) {
- throw new UnsupportedOperationException();
- }
-
- default Void runAs(Runnable runnable) {
- return doAs(new PrivilegedAction<Void>() {
+ /**
+ * Make sure that this action is executed with the proper subject and in a
+ * proper thread.
+ */
+ <T> T doAs(Callable<T> action);
- @Override
- public Void run() {
- if (runnable != null)
- runnable.run();
- return null;
- }
- });
+ default void runAs(Runnable runnable) {
+ doAs(Executors.callable(runnable));
}
default void stateChanged(String state, String title) {
}
default void stateChanged(String state, String title) {
diff --git
a/org.argeo.cms/src/org/argeo/cms/LocaleUtils.java
b/org.argeo.cms/src/org/argeo/cms/LocaleUtils.java
index 415a0954dff41d4526e39ccf5b8413c3b7573b79..4bfda139d686345f261dd9675de1c500b9cb2eda 100644
(file)
--- a/
org.argeo.cms/src/org/argeo/cms/LocaleUtils.java
+++ b/
org.argeo.cms/src/org/argeo/cms/LocaleUtils.java
@@
-59,9
+59,10
@@
public class LocaleUtils {
/** Where the search for a message is actually performed. */
public static String local(String key, Locale locale, String resource, ClassLoader classLoader) {
ResourceBundle rb = ResourceBundle.getBundle(resource, locale, classLoader);
/** Where the search for a message is actually performed. */
public static String local(String key, Locale locale, String resource, ClassLoader classLoader) {
ResourceBundle rb = ResourceBundle.getBundle(resource, locale, classLoader);
- assert key.length() > 2;
- if (isLocaleKey(key))
+ if (isLocaleKey(key)) {
+ assert key.length() > 1;
key = key.substring(1);
key = key.substring(1);
+ }
if (rb.containsKey(key))
return rb.getString(key);
else // for simple cases, the key will actually be the English word
if (rb.containsKey(key))
return rb.getString(key);
else // for simple cases, the key will actually be the English word
diff --git
a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsEventBusImpl.java
b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsEventBusImpl.java
index 7fca23c991ee75fb3cce34bd7b85f3d216ed5be7..eaa63756dc05e61800ffdb8668bf4ba200907ff3 100644
(file)
--- a/
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsEventBusImpl.java
+++ b/
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsEventBusImpl.java
@@
-72,13
+72,12
@@
public class CmsEventBusImpl implements CmsEventBus {
@Override
public void onSubscribe(Subscription subscription) {
this.subscription = subscription;
@Override
public void onSubscribe(Subscription subscription) {
this.subscription = subscription;
-
subscription.request(1
);
+
this.subscription.request(Long.MAX_VALUE
);
}
@Override
public void onNext(Map<String, Object> item) {
eventSubscriber.onEvent(topic, item);
}
@Override
public void onNext(Map<String, Object> item) {
eventSubscriber.onEvent(topic, item);
- subscription.request(1);
}
@Override
}
@Override
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 2059803036f2ab476205564534f0203ed1bdde62..c481a2cc07be061e38b0db28c2212e50d096775a 100644
(file)
--- 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,23
+1,29
@@
package org.argeo.cms.swt;
package org.argeo.cms.swt;
-import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
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 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.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.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 {
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;
protected final String uiName;
protected LoginContext loginContext;
@@
-37,6
+43,8
@@
public abstract class AbstractSwtCmsView implements CmsView {
public abstract CmsEventBus getCmsEventBus();
public abstract CmsEventBus getCmsEventBus();
+ public abstract CmsApp getCmsApp();
+
@Override
public void sendEvent(String topic, Map<String, Object> properties) {
if (properties == null)
@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);
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);
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 = () -> {
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();
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);
return result.get();
} catch (InterruptedException | ExecutionException e) {
throw new IllegalStateException("Cannot execute action ins CMS view " + uid, e);
diff --git
a/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java
b/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java
index 06e4d0f9f996374b651ad3695e2ce23e88e62ba7..dedf61dea0f31acd0a4ac01e90a00218d5b2abc9 100644
(file)
--- a/
swt/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java
+++ b/
swt/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java
@@
-1,7
+1,7
@@
package org.argeo.cms.swt.dialogs;
package org.argeo.cms.swt.dialogs;
-import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Arrays;
+import java.util.concurrent.Callable;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.ux.CmsView;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.ux.CmsView;
@@
-22,7
+22,7
@@
public class ChangePasswordDialog extends CmsMessageDialog {
private CmsUserManager cmsUserManager;
private CmsView cmsView;
private CmsUserManager cmsUserManager;
private CmsView cmsView;
- private
PrivilegedAction
<Integer> doIt;
+ private
Callable
<Integer> doIt;
public ChangePasswordDialog(Shell parentShell, String message, int kind, CmsUserManager cmsUserManager) {
super(parentShell, message, kind);
public ChangePasswordDialog(Shell parentShell, String message, int kind, CmsUserManager cmsUserManager) {
super(parentShell, message, kind);
diff --git
a/swt/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java
b/swt/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java
index cdd4899289e59d3ce83751eaff39402a8ed115c1..cda9a117f681f0f091590b87ece870517cb96de4 100644
(file)
--- a/
swt/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java
+++ b/
swt/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java
@@
-2,6
+2,7
@@
package org.argeo.cms.e4.rap;
import java.security.AccessController;
import java.util.UUID;
import java.security.AccessController;
import java.util.UUID;
+import java.util.concurrent.Callable;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
@@
-180,4
+181,9
@@
public class CmsLoginLifecycle implements CmsView {
return state;
}
return state;
}
+ @Override
+ public <T> T doAs(Callable<T> action) {
+ throw new UnsupportedOperationException();
+ }
+
}
}
diff --git
a/swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java
b/swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java
index 3c894d158b84101a31e1d2a92aa805d251efd3e8..b3ca245ad76a819c98dc44e19ddcfd24af84850b 100644
(file)
--- a/
swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java
+++ b/
swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java
@@
-34,12
+34,12
@@
import org.eclipse.rap.rwt.client.service.BrowserNavigation;
import org.eclipse.rap.rwt.client.service.BrowserNavigationEvent;
import org.eclipse.rap.rwt.client.service.BrowserNavigationListener;
import org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle;
import org.eclipse.rap.rwt.client.service.BrowserNavigationEvent;
import org.eclipse.rap.rwt.client.service.BrowserNavigationListener;
import org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle;
+import org.eclipse.rap.rwt.service.ServerPushSession;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Widget;
/** The {@link CmsView} for a {@link CmsWebApp}. */
@SuppressWarnings("restriction")
/** The {@link CmsView} for a {@link CmsWebApp}. */
@SuppressWarnings("restriction")
@@
-56,6
+56,8
@@
public class CmsWebEntryPoint extends AbstractSwtCmsView implements EntryPoint,
/** Experimental OS-like multi windows. */
private boolean multipleShells = false;
/** Experimental OS-like multi windows. */
private boolean multipleShells = false;
+ private ServerPushSession serverPushSession;
+
public CmsWebEntryPoint(CmsWebApp cmsWebApp, String uiName) {
super(uiName);
assert cmsWebApp != null;
public CmsWebEntryPoint(CmsWebApp cmsWebApp, String uiName) {
super(uiName);
assert cmsWebApp != null;
@@
-86,6
+88,7
@@
public class CmsWebEntryPoint extends AbstractSwtCmsView implements EntryPoint,
browserNavigation = RWT.getClient().getService(BrowserNavigation.class);
if (browserNavigation != null)
browserNavigation.addBrowserNavigationListener(this);
browserNavigation = RWT.getClient().getService(BrowserNavigation.class);
if (browserNavigation != null)
browserNavigation.addBrowserNavigationListener(this);
+
}
protected void createContents(Composite parent) {
}
protected void createContents(Composite parent) {
@@
-108,6
+111,11
@@
public class CmsWebEntryPoint extends AbstractSwtCmsView implements EntryPoint,
ui = cmsWebApp.getCmsApp().initUi(parent);
if (ui instanceof Composite)
((Composite) ui).setLayoutData(CmsSwtUtils.fillAll());
ui = cmsWebApp.getCmsApp().initUi(parent);
if (ui instanceof Composite)
((Composite) ui).setLayoutData(CmsSwtUtils.fillAll());
+ serverPushSession = new ServerPushSession();
+
+ // required in order to doAs to work
+ // TODO check whether it would be worth optimising
+ serverPushSession.start();
// we need ui to be set before refresh so that CmsView can store UI context data
// in it.
cmsWebApp.getCmsApp().refreshUi(ui, null);
// we need ui to be set before refresh so that CmsView can store UI context data
// in it.
cmsWebApp.getCmsApp().refreshUi(ui, null);
@@
-215,6
+223,11
@@
public class CmsWebEntryPoint extends AbstractSwtCmsView implements EntryPoint,
return cmsWebApp.getCmsEventBus();
}
return cmsWebApp.getCmsEventBus();
}
+ @Override
+ public CmsApp getCmsApp() {
+ return cmsWebApp.getCmsApp();
+ }
+
@Override
public void stateChanged(String state, String title) {
browserNavigation.pushState(state, title);
@Override
public void stateChanged(String state, String title) {
browserNavigation.pushState(state, title);