]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebApp.java
Start making the component system more dynamic
[lgpl/argeo-commons.git] / org.argeo.cms.ui.rap / src / org / argeo / cms / web / CmsWebApp.java
1 package org.argeo.cms.web;
2
3 import java.util.Dictionary;
4 import java.util.HashMap;
5 import java.util.Map;
6 import java.util.Set;
7
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.argeo.api.cms.CmsApp;
11 import org.argeo.api.cms.CmsAppListener;
12 import org.argeo.api.cms.CmsTheme;
13 import org.argeo.api.cms.CmsView;
14 import org.argeo.cms.swt.CmsSwtUtils;
15 import org.argeo.util.LangUtils;
16 import org.eclipse.rap.rwt.RWT;
17 import org.eclipse.rap.rwt.application.Application;
18 import org.eclipse.rap.rwt.application.Application.OperationMode;
19 import org.eclipse.rap.rwt.application.ApplicationConfiguration;
20 import org.eclipse.rap.rwt.application.ExceptionHandler;
21 import org.eclipse.rap.rwt.client.WebClient;
22 import org.eclipse.swt.widgets.Display;
23 import org.osgi.framework.BundleContext;
24 import org.osgi.framework.Constants;
25 import org.osgi.framework.ServiceRegistration;
26 import org.osgi.service.event.EventAdmin;
27
28 /** An RWT web app integrating with a {@link CmsApp}. */
29 public class CmsWebApp implements ApplicationConfiguration, ExceptionHandler, CmsAppListener {
30 private final static Log log = LogFactory.getLog(CmsWebApp.class);
31
32 private BundleContext bundleContext;
33 private CmsApp cmsApp;
34 private String cmsAppId;
35 private EventAdmin eventAdmin;
36
37 private ServiceRegistration<ApplicationConfiguration> rwtAppReg;
38
39 private final static String CONTEXT_NAME = "contextName";
40 private String contextName;
41
42 private final static String FAVICON_PNG = "favicon.png";
43
44 public void init(BundleContext bundleContext, Map<String, String> properties) {
45 this.bundleContext = bundleContext;
46 contextName = properties.get(CONTEXT_NAME);
47 if (cmsApp != null) {
48 if (cmsApp.allThemesAvailable())
49 publishWebApp();
50 }
51 }
52
53 public void destroy(BundleContext bundleContext, Map<String, String> properties) {
54 if (cmsApp != null) {
55 cmsApp.removeCmsAppListener(this);
56 cmsApp = null;
57 }
58 }
59
60 @Override
61 public void configure(Application application) {
62 // TODO make it configurable?
63 // SWT compatibility is required for:
64 // - Browser.execute()
65 // - blocking dialogs
66 application.setOperationMode(OperationMode.SWT_COMPATIBILITY);
67 for (String uiName : cmsApp.getUiNames()) {
68 CmsTheme theme = cmsApp.getTheme(uiName);
69 if (theme != null)
70 WebThemeUtils.apply(application, theme);
71 }
72
73 Map<String, String> properties = new HashMap<>();
74 addEntryPoints(application, properties);
75 application.setExceptionHandler(this);
76 }
77
78 @Override
79 public void handleException(Throwable throwable) {
80 Display display = Display.getCurrent();
81 if (display != null && !display.isDisposed()) {
82 CmsView cmsView = CmsSwtUtils.getCmsView(display.getActiveShell());
83 cmsView.exception(throwable);
84 } else {
85 log.error("Unexpected exception outside an UI thread", throwable);
86 }
87
88 }
89
90 protected void addEntryPoints(Application application, Map<String, String> commonProperties) {
91 for (String uiName : cmsApp.getUiNames()) {
92 Map<String, String> properties = new HashMap<>(commonProperties);
93 CmsTheme theme = cmsApp.getTheme(uiName);
94 if (theme != null) {
95 properties.put(WebClient.THEME_ID, theme.getThemeId());
96 properties.put(WebClient.HEAD_HTML, theme.getHtmlHeaders());
97 properties.put(WebClient.BODY_HTML, theme.getBodyHtml());
98 Set<String> imagePaths = theme.getImagesPaths();
99 if (imagePaths.contains(FAVICON_PNG)) {
100 properties.put(WebClient.FAVICON, FAVICON_PNG);
101 }
102 } else {
103 properties.put(WebClient.THEME_ID, RWT.DEFAULT_THEME_ID);
104 }
105 String entryPointName = !uiName.equals("") ? "/" + uiName : "/";
106 application.addEntryPoint(entryPointName, () -> {
107 CmsWebEntryPoint entryPoint = new CmsWebEntryPoint(this, uiName);
108 entryPoint.setEventAdmin(eventAdmin);
109 return entryPoint;
110 }, properties);
111 if (log.isDebugEnabled())
112 log.info("Added web entry point " + (contextName != null ? "/" + contextName : "") + entryPointName);
113 }
114 // if (log.isDebugEnabled())
115 // log.debug("Published CMS web app /" + (contextName != null ? contextName : ""));
116 }
117
118 CmsApp getCmsApp() {
119 return cmsApp;
120 }
121
122 BundleContext getBundleContext() {
123 return bundleContext;
124 }
125
126 public void setCmsApp(CmsApp cmsApp, Map<String, String> properties) {
127 this.cmsApp = cmsApp;
128 this.cmsAppId = properties.get(Constants.SERVICE_PID);
129 this.cmsApp.addCmsAppListener(this);
130 }
131
132 public void unsetCmsApp(CmsApp cmsApp, Map<String, String> properties) {
133 String cmsAppId = properties.get(Constants.SERVICE_PID);
134 if (!cmsAppId.equals(this.cmsAppId))
135 return;
136 if (this.cmsApp != null) {
137 this.cmsApp.removeCmsAppListener(this);
138 }
139 if (rwtAppReg != null)
140 rwtAppReg.unregister();
141 this.cmsApp = null;
142 }
143
144 @Override
145 public void themingUpdated() {
146 if (cmsApp != null && cmsApp.allThemesAvailable())
147 publishWebApp();
148 }
149
150 protected void publishWebApp() {
151 Dictionary<String, Object> regProps = LangUtils.dict(CONTEXT_NAME, contextName);
152 if (rwtAppReg != null)
153 rwtAppReg.unregister();
154 if (bundleContext != null) {
155 rwtAppReg = bundleContext.registerService(ApplicationConfiguration.class, this, regProps);
156 if (log.isDebugEnabled())
157 log.debug("Publishing CMS web app /" + (contextName != null ? contextName : "") + " ...");
158 }
159 }
160
161 public void setEventAdmin(EventAdmin eventAdmin) {
162 this.eventAdmin = eventAdmin;
163 }
164
165 }