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