]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.ui/src/org/argeo/cms/script/CmsScriptApp.java
Improve UI scripting
[lgpl/argeo-commons.git] / org.argeo.cms.ui / src / org / argeo / cms / script / CmsScriptApp.java
1 package org.argeo.cms.script;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.Hashtable;
8 import java.util.List;
9 import java.util.Map;
10
11 import javax.jcr.Node;
12 import javax.jcr.Property;
13 import javax.jcr.PropertyIterator;
14 import javax.jcr.PropertyType;
15 import javax.jcr.Repository;
16 import javax.jcr.RepositoryException;
17 import javax.script.ScriptEngine;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.argeo.cms.CmsException;
22 import org.argeo.cms.ui.CmsConstants;
23 import org.argeo.cms.ui.CmsUiProvider;
24 import org.argeo.cms.util.BundleResourceLoader;
25 import org.argeo.cms.util.CmsUtils;
26 import org.argeo.cms.util.SimpleErgonomics;
27 import org.eclipse.rap.rwt.application.Application;
28 import org.eclipse.rap.rwt.application.Application.OperationMode;
29 import org.eclipse.rap.rwt.application.ApplicationConfiguration;
30 import org.eclipse.rap.rwt.application.ExceptionHandler;
31 import org.eclipse.rap.rwt.client.WebClient;
32 import org.eclipse.rap.rwt.service.ResourceLoader;
33 import org.osgi.framework.BundleContext;
34 import org.osgi.framework.ServiceRegistration;
35
36 public class CmsScriptApp implements Branding {
37 public final static String CONTEXT_NAME = "contextName";
38
39 ServiceRegistration<ApplicationConfiguration> appConfigReg;
40
41 private ScriptEngine scriptEngine;
42
43 private final static Log log = LogFactory.getLog(CmsScriptApp.class);
44
45 private String webPath;
46 private String repo = "(cn=node)";
47
48 // private Branding branding = new Branding();
49 private Theme theme;
50
51 private List<String> resources = new ArrayList<>();
52
53 private Map<String, AppUi> ui = new HashMap<>();
54
55 private CmsUiProvider header;
56 private Integer headerHeight = null;
57 private CmsUiProvider lead;
58 private CmsUiProvider end;
59 private CmsUiProvider footer;
60
61 // Branding
62 private String themeId;
63 private String additionalHeaders;
64 private String bodyHtml;
65 private String pageTitle;
66 private String pageOverflow;
67 private String favicon;
68
69 public CmsScriptApp(ScriptEngine scriptEngine) {
70 super();
71 this.scriptEngine = scriptEngine;
72 }
73
74 public void apply(BundleContext bundleContext, Repository repository, Application application) {
75 BundleResourceLoader bundleRL = new BundleResourceLoader(bundleContext.getBundle());
76
77 application.setOperationMode(OperationMode.SWT_COMPATIBILITY);
78 // application.setOperationMode(OperationMode.JEE_COMPATIBILITY);
79
80 application.setExceptionHandler(new CmsExceptionHandler());
81
82 // loading animated gif
83 application.addResource(CmsConstants.LOADING_IMAGE, createResourceLoader(CmsConstants.LOADING_IMAGE));
84 // empty image
85 application.addResource(CmsConstants.NO_IMAGE, createResourceLoader(CmsConstants.NO_IMAGE));
86
87 for (String resource : resources) {
88 application.addResource(resource, bundleRL);
89 if (log.isTraceEnabled())
90 log.trace("Resource " + resource);
91 }
92
93 if (theme != null) {
94 theme.apply(application);
95 String themeHeaders = theme.getAdditionalHeaders();
96 if (themeHeaders != null) {
97 if (additionalHeaders == null)
98 additionalHeaders = themeHeaders;
99 else
100 additionalHeaders = themeHeaders + "\n" + additionalHeaders;
101 }
102 themeId = theme.getThemeId();
103 }
104
105 for (String appUiName : ui.keySet()) {
106 AppUi appUi = ui.get(appUiName);
107 appUi.apply(repository, application, this, appUiName);
108 }
109
110 }
111
112 public void applySides(SimpleErgonomics simpleErgonomics) {
113 simpleErgonomics.setHeader(header);
114 simpleErgonomics.setLead(lead);
115 simpleErgonomics.setEnd(end);
116 simpleErgonomics.setFooter(footer);
117 }
118
119 public void register(BundleContext bundleContext, ApplicationConfiguration appConfig) {
120 Hashtable<String, String> props = new Hashtable<>();
121 props.put(CONTEXT_NAME, webPath);
122 appConfigReg = bundleContext.registerService(ApplicationConfiguration.class, appConfig, props);
123 }
124
125 public void reload() {
126 BundleContext bundleContext = appConfigReg.getReference().getBundle().getBundleContext();
127 ApplicationConfiguration appConfig = bundleContext.getService(appConfigReg.getReference());
128 appConfigReg.unregister();
129 register(bundleContext, appConfig);
130
131 // BundleContext bundleContext = (BundleContext)
132 // getScriptEngine().get("bundleContext");
133 // try {
134 // Bundle bundle = bundleContext.getBundle();
135 // bundle.stop();
136 // bundle.start();
137 // } catch (BundleException e) {
138 // // TODO Auto-generated catch block
139 // e.printStackTrace();
140 // }
141 }
142
143 private static ResourceLoader createResourceLoader(final String resourceName) {
144 return new ResourceLoader() {
145 public InputStream getResourceAsStream(String resourceName) throws IOException {
146 return getClass().getClassLoader().getResourceAsStream(resourceName);
147 }
148 };
149 }
150
151 public List<String> getResources() {
152 return resources;
153 }
154
155 public AppUi newUi(String name) {
156 if (ui.containsKey(name))
157 throw new IllegalArgumentException("There is already an UI named " + name);
158 AppUi appUi = new AppUi(this);
159 // appUi.setApp(this);
160 ui.put(name, appUi);
161 return appUi;
162 }
163
164 public void addUi(String name, AppUi appUi) {
165 if (ui.containsKey(name))
166 throw new IllegalArgumentException("There is already an UI named " + name);
167 // appUi.setApp(this);
168 ui.put(name, appUi);
169 }
170
171 public void applyBranding(Map<String, String> properties) {
172 if (themeId != null)
173 properties.put(WebClient.THEME_ID, themeId);
174 if (additionalHeaders != null)
175 properties.put(WebClient.HEAD_HTML, additionalHeaders);
176 if (bodyHtml != null)
177 properties.put(WebClient.BODY_HTML, bodyHtml);
178 if (pageTitle != null)
179 properties.put(WebClient.PAGE_TITLE, pageTitle);
180 if (pageOverflow != null)
181 properties.put(WebClient.PAGE_OVERFLOW, pageOverflow);
182 if (favicon != null)
183 properties.put(WebClient.FAVICON, favicon);
184 }
185
186 class CmsExceptionHandler implements ExceptionHandler {
187
188 @Override
189 public void handleException(Throwable throwable) {
190 // TODO be smarter
191 CmsUtils.getCmsView().exception(throwable);
192 }
193
194 }
195
196 // public Branding getBranding() {
197 // return branding;
198 // }
199
200 ScriptEngine getScriptEngine() {
201 return scriptEngine;
202 }
203
204 public static String toJson(Node node) {
205 try {
206 StringBuilder sb = new StringBuilder();
207 sb.append('{');
208 PropertyIterator pit = node.getProperties();
209 int count = 0;
210 while (pit.hasNext()) {
211 Property p = pit.nextProperty();
212 int type = p.getType();
213 if (type == PropertyType.REFERENCE || type == PropertyType.WEAKREFERENCE || type == PropertyType.PATH) {
214 Node ref = p.getNode();
215 if (count != 0)
216 sb.append(',');
217 // TODO limit depth?
218 sb.append(toJson(ref));
219 count++;
220 } else if (!p.isMultiple()) {
221 if (count != 0)
222 sb.append(',');
223 sb.append('\"').append(p.getName()).append("\":\"").append(p.getString()).append('\"');
224 count++;
225 }
226 }
227 sb.append('}');
228 return sb.toString();
229 } catch (RepositoryException e) {
230 throw new CmsException("Cannot convert " + node + " to JSON", e);
231 }
232 }
233
234 public void fromJson(Node node, String json) {
235 // TODO
236 }
237
238 public Theme getTheme() {
239 return theme;
240 }
241
242 public void setTheme(Theme theme) {
243 this.theme = theme;
244 }
245
246 public String getWebPath() {
247 return webPath;
248 }
249
250 public void setWebPath(String context) {
251 this.webPath = context;
252 }
253
254 public String getRepo() {
255 return repo;
256 }
257
258 public void setRepo(String repo) {
259 this.repo = repo;
260 }
261
262 public Map<String, AppUi> getUi() {
263 return ui;
264 }
265
266 public void setUi(Map<String, AppUi> ui) {
267 this.ui = ui;
268 }
269
270 // Branding
271 public String getThemeId() {
272 return themeId;
273 }
274
275 public void setThemeId(String themeId) {
276 this.themeId = themeId;
277 }
278
279 public String getAdditionalHeaders() {
280 return additionalHeaders;
281 }
282
283 public void setAdditionalHeaders(String additionalHeaders) {
284 this.additionalHeaders = additionalHeaders;
285 }
286
287 public String getBodyHtml() {
288 return bodyHtml;
289 }
290
291 public void setBodyHtml(String bodyHtml) {
292 this.bodyHtml = bodyHtml;
293 }
294
295 public String getPageTitle() {
296 return pageTitle;
297 }
298
299 public void setPageTitle(String pageTitle) {
300 this.pageTitle = pageTitle;
301 }
302
303 public String getPageOverflow() {
304 return pageOverflow;
305 }
306
307 public void setPageOverflow(String pageOverflow) {
308 this.pageOverflow = pageOverflow;
309 }
310
311 public String getFavicon() {
312 return favicon;
313 }
314
315 public void setFavicon(String favicon) {
316 this.favicon = favicon;
317 }
318
319 public CmsUiProvider getHeader() {
320 return header;
321 }
322
323 public void setHeader(CmsUiProvider header) {
324 this.header = header;
325 }
326
327 public Integer getHeaderHeight() {
328 return headerHeight;
329 }
330
331 public void setHeaderHeight(Integer headerHeight) {
332 this.headerHeight = headerHeight;
333 }
334
335 public CmsUiProvider getLead() {
336 return lead;
337 }
338
339 public void setLead(CmsUiProvider lead) {
340 this.lead = lead;
341 }
342
343 public CmsUiProvider getEnd() {
344 return end;
345 }
346
347 public void setEnd(CmsUiProvider end) {
348 this.end = end;
349 }
350
351 public CmsUiProvider getFooter() {
352 return footer;
353 }
354
355 public void setFooter(CmsUiProvider footer) {
356 this.footer = footer;
357 }
358
359 }