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