]> git.argeo.org Git - lgpl/argeo-commons.git/blob - CmsRcpApp.java
e25a9f71149b66d0aaf2168e4f0fe31e936e8e92
[lgpl/argeo-commons.git] / CmsRcpApp.java
1 package org.argeo.cms.ui.rcp;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.security.PrivilegedAction;
6 import java.util.HashMap;
7 import java.util.Map;
8 import java.util.UUID;
9
10 import javax.security.auth.Subject;
11 import javax.security.auth.login.LoginContext;
12 import javax.security.auth.login.LoginException;
13
14 import org.argeo.api.cms.CmsApp;
15 import org.argeo.api.cms.CmsAuth;
16 import org.argeo.api.cms.CmsLog;
17 import org.argeo.api.cms.CmsSession;
18 import org.argeo.api.cms.ux.CmsImageManager;
19 import org.argeo.api.cms.ux.CmsTheme;
20 import org.argeo.api.cms.ux.CmsUi;
21 import org.argeo.api.cms.ux.CmsView;
22 import org.argeo.api.cms.ux.UxContext;
23 import org.argeo.cms.swt.CmsSwtUtils;
24 import org.eclipse.e4.ui.css.core.engine.CSSEngine;
25 import org.eclipse.e4.ui.css.core.engine.CSSErrorHandler;
26 import org.eclipse.e4.ui.css.swt.engine.CSSSWTEngineImpl;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Display;
29 import org.eclipse.swt.widgets.Shell;
30 import org.osgi.service.event.Event;
31 import org.osgi.service.event.EventAdmin;
32
33 /** Runs a {@link CmsApp} as an SWT desktop application. */
34 @SuppressWarnings("restriction")
35 public class CmsRcpApp implements CmsView {
36 private final static CmsLog log = CmsLog.getLog(CmsRcpApp.class);
37
38 // private BundleContext bundleContext =
39 // FrameworkUtil.getBundle(CmsRcpApp.class).getBundleContext();
40
41 private Shell shell;
42 private CmsApp cmsApp;
43
44 // CMS View
45 private String uid;
46 private LoginContext loginContext;
47
48 private EventAdmin eventAdmin;
49
50 private CSSEngine cssEngine;
51
52 private CmsUi ui;
53 // TODO make it configurable
54 private String uiName = "desktop";
55
56 public CmsRcpApp(String uiName) {
57 uid = UUID.randomUUID().toString();
58 this.uiName = uiName;
59 }
60
61 public void initRcpApp() {
62 Display display = Display.getCurrent();
63 shell = new Shell(display);
64 shell.setText("Argeo CMS");
65 Composite parent = shell;
66 parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
67 CmsSwtUtils.registerCmsView(shell, CmsRcpApp.this);
68
69 try {
70 loginContext = new LoginContext(CmsAuth.SINGLE_USER.getLoginContextName());
71 loginContext.login();
72 } catch (LoginException e) {
73 throw new IllegalStateException("Could not log in.", e);
74 }
75 if (log.isDebugEnabled())
76 log.debug("Logged in to desktop: " + loginContext.getSubject());
77
78 Subject.doAs(loginContext.getSubject(), (PrivilegedAction<Void>) () -> {
79
80 // TODO factorise with web app
81 parent.setData(CmsApp.UI_NAME_PROPERTY, uiName);
82 ui = cmsApp.initUi(parent);
83 if (ui instanceof Composite)
84 ((Composite) ui).setLayoutData(CmsSwtUtils.fillAll());
85 // we need ui to be set before refresh so that CmsView can store UI context data
86 // in it.
87 cmsApp.refreshUi(ui, null);
88
89 // Styling
90 CmsTheme theme = CmsSwtUtils.getCmsTheme(parent);
91 if (theme != null) {
92 cssEngine = new CSSSWTEngineImpl(display);
93 for (String path : theme.getSwtCssPaths()) {
94 try (InputStream in = theme.loadPath(path)) {
95 cssEngine.parseStyleSheet(in);
96 } catch (IOException e) {
97 throw new IllegalStateException("Cannot load stylesheet " + path, e);
98 }
99 }
100 cssEngine.setErrorHandler(new CSSErrorHandler() {
101 public void error(Exception e) {
102 log.error("SWT styling error: ", e);
103 }
104 });
105 applyStyles(shell);
106 }
107 shell.layout(true, true);
108
109 shell.open();
110 return null;
111 });
112 }
113
114 /*
115 * CMS VIEW
116 */
117
118 @Override
119 public String getUid() {
120 return uid;
121 }
122
123 @Override
124 public UxContext getUxContext() {
125 throw new UnsupportedOperationException();
126 }
127
128 @Override
129 public void navigateTo(String state) {
130 throw new UnsupportedOperationException();
131 }
132
133 @Override
134 public void authChange(LoginContext loginContext) {
135 }
136
137 @Override
138 public void logout() {
139 if (loginContext != null)
140 try {
141 loginContext.logout();
142 } catch (LoginException e) {
143 log.error("Cannot log out", e);
144 }
145 }
146
147 @Override
148 public void exception(Throwable e) {
149 log.error("Unexpected exception in CMS RCP", e);
150 }
151
152 @Override
153 public CmsImageManager getImageManager() {
154 throw new UnsupportedOperationException();
155 }
156
157 @Override
158 public CmsSession getCmsSession() {
159 CmsSession cmsSession = cmsApp.getCmsContext().getCmsSession(getSubject());
160 return cmsSession;
161 }
162
163 @Override
164 public Object getData(String key) {
165 if (ui != null) {
166 return ui.getData(key);
167 } else {
168 throw new IllegalStateException("UI is not initialized");
169 }
170 }
171
172 @Override
173 public void setData(String key, Object value) {
174 if (ui != null) {
175 ui.setData(key, value);
176 } else {
177 throw new IllegalStateException("UI is not initialized");
178 }
179 }
180
181 @Override
182 public boolean isAnonymous() {
183 return false;
184 }
185
186 @Override
187 public void applyStyles(Object node) {
188 if (cssEngine != null)
189 cssEngine.applyStyles(node, true);
190 }
191
192 @Override
193 public void sendEvent(String topic, Map<String, Object> properties) {
194 if (properties == null)
195 properties = new HashMap<>();
196 if (properties.containsKey(CMS_VIEW_UID_PROPERTY) && !properties.get(CMS_VIEW_UID_PROPERTY).equals(uid))
197 throw new IllegalArgumentException("Property " + CMS_VIEW_UID_PROPERTY + " is set to another CMS view uid ("
198 + properties.get(CMS_VIEW_UID_PROPERTY) + ") then " + uid);
199 properties.put(CMS_VIEW_UID_PROPERTY, uid);
200 eventAdmin.sendEvent(new Event(topic, properties));
201 }
202
203 public <T> T doAs(PrivilegedAction<T> action) {
204 return Subject.doAs(getSubject(), action);
205 }
206
207 protected Subject getSubject() {
208 return loginContext.getSubject();
209 }
210
211 public Shell getShell() {
212 return shell;
213 }
214
215 /*
216 * DEPENDENCY INJECTION
217 */
218 public void setCmsApp(CmsApp cmsApp, Map<String, String> properties) {
219 this.cmsApp = cmsApp;
220 }
221
222 public void unsetCmsApp(CmsApp cmsApp, Map<String, String> properties) {
223 this.cmsApp = null;
224 }
225
226 public void setEventAdmin(EventAdmin eventAdmin) {
227 this.eventAdmin = eventAdmin;
228 }
229
230 }