package org.argeo.cms.script; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; import javax.jcr.Node; import javax.jcr.Property; import javax.jcr.PropertyIterator; import javax.jcr.PropertyType; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.script.ScriptEngine; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsException; import org.argeo.cms.ui.CmsConstants; import org.argeo.cms.util.BundleResourceLoader; import org.argeo.cms.util.CmsUtils; import org.eclipse.rap.rwt.application.Application; import org.eclipse.rap.rwt.application.Application.OperationMode; import org.eclipse.rap.rwt.application.ApplicationConfiguration; import org.eclipse.rap.rwt.application.ExceptionHandler; import org.eclipse.rap.rwt.client.WebClient; import org.eclipse.rap.rwt.service.ResourceLoader; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; public class CmsScriptApp implements Branding { public final static String CONTEXT_NAME = "contextName"; ServiceRegistration appConfigReg; private ScriptEngine scriptEngine; private final static Log log = LogFactory.getLog(CmsScriptApp.class); private String webPath; private String repo = "(cn=node)"; // private Branding branding = new Branding(); private Theme theme; private List resources = new ArrayList<>(); private Map ui = new HashMap<>(); // Branding private String themeId; private String additionalHeaders; private String bodyHtml; private String pageTitle; private String pageOverflow; private String favicon; public CmsScriptApp(ScriptEngine scriptEngine) { super(); this.scriptEngine = scriptEngine; } public void apply(BundleContext bundleContext, Repository repository, Application application) { BundleResourceLoader bundleRL = new BundleResourceLoader(bundleContext.getBundle()); application.setOperationMode(OperationMode.SWT_COMPATIBILITY); // application.setOperationMode(OperationMode.JEE_COMPATIBILITY); application.setExceptionHandler(new CmsExceptionHandler()); // loading animated gif application.addResource(CmsConstants.LOADING_IMAGE, createResourceLoader(CmsConstants.LOADING_IMAGE)); // empty image application.addResource(CmsConstants.NO_IMAGE, createResourceLoader(CmsConstants.NO_IMAGE)); for (String resource : resources) { application.addResource(resource, bundleRL); if (log.isTraceEnabled()) log.trace("Resource " + resource); } if (theme != null) { theme.apply(application); String themeHeaders = theme.getAdditionalHeaders(); if (themeHeaders != null) { if (additionalHeaders == null) additionalHeaders = themeHeaders; else additionalHeaders = themeHeaders + "\n" + additionalHeaders; } themeId = theme.getThemeId(); } for (String appUiName : ui.keySet()) { AppUi appUi = ui.get(appUiName); appUi.apply(repository, application, this, appUiName); } } public void register(BundleContext bundleContext, ApplicationConfiguration appConfig) { Hashtable props = new Hashtable<>(); props.put(CONTEXT_NAME, webPath); appConfigReg = bundleContext.registerService(ApplicationConfiguration.class, appConfig, props); } public void reload() { BundleContext bundleContext = appConfigReg.getReference().getBundle().getBundleContext(); ApplicationConfiguration appConfig = bundleContext.getService(appConfigReg.getReference()); appConfigReg.unregister(); register(bundleContext, appConfig); // BundleContext bundleContext = (BundleContext) // getScriptEngine().get("bundleContext"); // try { // Bundle bundle = bundleContext.getBundle(); // bundle.stop(); // bundle.start(); // } catch (BundleException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } } private static ResourceLoader createResourceLoader(final String resourceName) { return new ResourceLoader() { public InputStream getResourceAsStream(String resourceName) throws IOException { return getClass().getClassLoader().getResourceAsStream(resourceName); } }; } public List getResources() { return resources; } public AppUi newUi(String name) { if (ui.containsKey(name)) throw new IllegalArgumentException("There is already an UI named " + name); AppUi appUi = new AppUi(this); // appUi.setApp(this); ui.put(name, appUi); return appUi; } public void addUi(String name, AppUi appUi) { if (ui.containsKey(name)) throw new IllegalArgumentException("There is already an UI named " + name); // appUi.setApp(this); ui.put(name, appUi); } public void applyBranding(Map properties) { if (themeId != null) properties.put(WebClient.THEME_ID, themeId); if (additionalHeaders != null) properties.put(WebClient.HEAD_HTML, additionalHeaders); if (bodyHtml != null) properties.put(WebClient.BODY_HTML, bodyHtml); if (pageTitle != null) properties.put(WebClient.PAGE_TITLE, pageTitle); if (pageOverflow != null) properties.put(WebClient.PAGE_OVERFLOW, pageOverflow); if (favicon != null) properties.put(WebClient.FAVICON, favicon); } class CmsExceptionHandler implements ExceptionHandler { @Override public void handleException(Throwable throwable) { // TODO be smarter CmsUtils.getCmsView().exception(throwable); } } // public Branding getBranding() { // return branding; // } ScriptEngine getScriptEngine() { return scriptEngine; } public static String toJson(Node node) { try { StringBuilder sb = new StringBuilder(); sb.append('{'); PropertyIterator pit = node.getProperties(); int count = 0; while (pit.hasNext()) { Property p = pit.nextProperty(); int type = p.getType(); if (type == PropertyType.REFERENCE || type == PropertyType.WEAKREFERENCE || type == PropertyType.PATH) { Node ref = p.getNode(); if (count != 0) sb.append(','); // TODO limit depth? sb.append(toJson(ref)); count++; } else if (!p.isMultiple()) { if (count != 0) sb.append(','); sb.append('\"').append(p.getName()).append("\":\"").append(p.getString()).append('\"'); count++; } } sb.append('}'); return sb.toString(); } catch (RepositoryException e) { throw new CmsException("Cannot convert " + node + " to JSON", e); } } public void fromJson(Node node, String json) { // TODO } public Theme getTheme() { return theme; } public void setTheme(Theme theme) { this.theme = theme; } public String getWebPath() { return webPath; } public void setWebPath(String context) { this.webPath = context; } public String getRepo() { return repo; } public void setRepo(String repo) { this.repo = repo; } public Map getUi() { return ui; } public void setUi(Map ui) { this.ui = ui; } // Branding public String getThemeId() { return themeId; } public void setThemeId(String themeId) { this.themeId = themeId; } public String getAdditionalHeaders() { return additionalHeaders; } public void setAdditionalHeaders(String additionalHeaders) { this.additionalHeaders = additionalHeaders; } public String getBodyHtml() { return bodyHtml; } public void setBodyHtml(String bodyHtml) { this.bodyHtml = bodyHtml; } public String getPageTitle() { return pageTitle; } public void setPageTitle(String pageTitle) { this.pageTitle = pageTitle; } public String getPageOverflow() { return pageOverflow; } public void setPageOverflow(String pageOverflow) { this.pageOverflow = pageOverflow; } public String getFavicon() { return favicon; } public void setFavicon(String favicon) { this.favicon = favicon; } }