]> git.argeo.org Git - lgpl/argeo-commons.git/blob - AbstractSwtCmsView.java
127be0856195fecf7b0d484a16e654030f6849c4
[lgpl/argeo-commons.git] / AbstractSwtCmsView.java
1 package org.argeo.cms.swt;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Timer;
6 import java.util.TimerTask;
7 import java.util.concurrent.Callable;
8 import java.util.concurrent.CompletableFuture;
9 import java.util.concurrent.CompletionException;
10 import java.util.concurrent.ExecutionException;
11
12 import javax.security.auth.Subject;
13 import javax.security.auth.login.LoginContext;
14
15 import org.argeo.api.cms.CmsApp;
16 import org.argeo.api.cms.CmsEventBus;
17 import org.argeo.api.cms.CmsLog;
18 import org.argeo.api.cms.ux.CmsImageManager;
19 import org.argeo.api.cms.ux.CmsUi;
20 import org.argeo.api.cms.ux.CmsView;
21 import org.argeo.api.cms.ux.UxContext;
22 import org.argeo.cms.CurrentUser;
23 import org.argeo.cms.util.CurrentSubject;
24 import org.eclipse.swt.widgets.Display;
25
26 public abstract class AbstractSwtCmsView implements CmsView {
27 private final static CmsLog log = CmsLog.getLog(AbstractSwtCmsView.class);
28
29 /** A timer to be used to perform background UX tasks. */
30 private final static Timer uxTimer = new Timer(true);
31
32 static {
33 // purge every day
34 uxTimer.schedule(new TimerTask() {
35
36 @Override
37 public void run() {
38 uxTimer.purge();
39 }
40 }, 0, 24 * 60 * 60 * 1000);
41 }
42
43 protected final String uiName;
44
45 protected LoginContext loginContext;
46 protected String state;
47 // protected Throwable exception;
48 protected UxContext uxContext;
49 protected CmsImageManager imageManager;
50
51 protected Display display;
52 protected CmsUi ui;
53
54 protected String uid;
55
56 public AbstractSwtCmsView(String uiName) {
57 this.uiName = uiName;
58 }
59
60 public abstract CmsEventBus getCmsEventBus();
61
62 public abstract CmsApp getCmsApp();
63
64 @Override
65 public void sendEvent(String topic, Map<String, Object> properties) {
66 if (properties == null)
67 properties = new HashMap<>();
68 if (properties.containsKey(CMS_VIEW_UID_PROPERTY) && !properties.get(CMS_VIEW_UID_PROPERTY).equals(uid))
69 throw new IllegalArgumentException("Property " + CMS_VIEW_UID_PROPERTY + " is set to another CMS view uid ("
70 + properties.get(CMS_VIEW_UID_PROPERTY) + ") then " + uid);
71 properties.put(CMS_VIEW_UID_PROPERTY, uid);
72
73 log.trace(() -> uid + ": send event to " + topic);
74
75 getCmsEventBus().sendEvent(topic, properties);
76 // getCmsApp().onEvent(topic, properties);
77 }
78
79 // public void runAs(Runnable runnable) {
80 // display.asyncExec(() -> doAs(Executors.callable(runnable)));
81 // }
82
83 public <T> T doAs(Callable<T> action) {
84 try {
85 CompletableFuture<T> result = new CompletableFuture<>();
86 Runnable toDo = () -> {
87 log.trace(() -> uid + ": process doAs");
88 Subject subject = CurrentSubject.current();
89 T res;
90 if (subject != null) {
91 assert subject == getSubject();
92 try {
93 res = action.call();
94 } catch (Exception e) {
95 throw new CompletionException("Failed to execute action for " + subject, e);
96 }
97 } else {
98 res = CurrentSubject.callAs(getSubject(), action);
99 }
100 result.complete(res);
101 };
102 if (Thread.currentThread() == display.getThread())
103 toDo.run();
104 else {
105 display.asyncExec(toDo);
106 display.wake();
107 }
108 // throw new IllegalStateException("Must be called from UI thread");
109 return result.get();
110 } catch (InterruptedException | ExecutionException e) {
111 throw new IllegalStateException("Cannot execute action ins CMS view " + uid, e);
112 }
113 }
114
115 @Override
116 public UxContext getUxContext() {
117 return uxContext;
118 }
119
120 @Override
121 public String getUid() {
122 return uid;
123 }
124
125 @Override
126 public CmsImageManager<?, ?> getImageManager() {
127 return imageManager;
128 }
129
130 @Override
131 public boolean isAnonymous() {
132 return CurrentUser.isAnonymous(getSubject());
133 }
134
135 protected Subject getSubject() {
136 return loginContext.getSubject();
137 }
138
139 @Override
140 public Object getData(String key) {
141 if (ui != null) {
142 return ui.getData(key);
143 } else {
144 throw new IllegalStateException("UI is not initialized");
145 }
146 }
147
148 @Override
149 public void setData(String key, Object value) {
150 if (ui != null) {
151 ui.setData(key, value);
152 } else {
153 throw new IllegalStateException("UI is not initialized");
154 }
155 }
156
157 @Override
158 public TimerTask schedule(Runnable task, long delay) {
159 TimerTask timerTask = newSwtUxTimerTask(task);
160 uxTimer.schedule(timerTask, delay);
161 return timerTask;
162 }
163
164 @Override
165 public TimerTask schedule(Runnable task, long delay, long period) {
166 TimerTask timerTask = newSwtUxTimerTask(task);
167 uxTimer.schedule(timerTask, delay, period);
168 return timerTask;
169 }
170
171 protected TimerTask newSwtUxTimerTask(Runnable todo) {
172 return new TimerTask() {
173
174 @Override
175 public void run() {
176 synchronized (display) {
177 try {
178 if (!display.isDisposed()) {
179 display.syncExec(() -> {
180 todo.run();
181 });
182 }
183 } catch (Exception e) {
184 log.error("Cannot run UX timer task", e);
185 }
186 }
187 }
188 };
189 }
190 }