Move RAP specific to subdirectory
[lgpl/argeo-commons.git] / rap / org.argeo.cms.ui.rap / src / org / argeo / cms / ui / script / CmsScriptRwtApplication.java
diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptRwtApplication.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptRwtApplication.java
new file mode 100644 (file)
index 0000000..d7c1a63
--- /dev/null
@@ -0,0 +1,121 @@
+package org.argeo.cms.ui.script;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+
+import javax.jcr.Repository;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.CmsException;
+import org.eclipse.rap.rwt.application.Application;
+import org.eclipse.rap.rwt.application.ApplicationConfiguration;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class CmsScriptRwtApplication implements ApplicationConfiguration {
+       public final static String APP = "APP";
+       public final static String BC = "BC";
+
+       private final Log log = LogFactory.getLog(CmsScriptRwtApplication.class);
+
+       BundleContext bundleContext;
+       Repository repository;
+
+       ScriptEngine engine;
+
+       public void init(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+               ClassLoader bundleCl = bundleContext.getBundle().adapt(BundleWiring.class).getClassLoader();
+               ClassLoader originalCcl = Thread.currentThread().getContextClassLoader();
+               try {
+//                     Thread.currentThread().setContextClassLoader(bundleCl);// GraalVM needs it to be before creating manager
+//                     ScriptEngineManager scriptEngineManager = new ScriptEngineManager(bundleCl);
+//                     engine = scriptEngineManager.getEngineByName("JavaScript");
+//                     if (engine == null) {// Nashorn
+//                             Thread.currentThread().setContextClassLoader(originalCcl);
+//                             scriptEngineManager = new ScriptEngineManager();
+//                             Thread.currentThread().setContextClassLoader(bundleCl);
+//                             engine = scriptEngineManager.getEngineByName("JavaScript");
+//                     }
+                       engine = loadScriptEngine(originalCcl, bundleCl);
+
+                       // Load script
+                       URL appUrl = bundleContext.getBundle().getEntry("cms/app.js");
+                       // System.out.println("Loading " + appUrl);
+                       // System.out.println("Loading " + appUrl.getHost());
+                       // System.out.println("Loading " + appUrl.getPath());
+
+                       CmsScriptApp app = new CmsScriptApp(engine);
+                       engine.put(APP, app);
+                       engine.put(BC, bundleContext);
+                       try (Reader reader = new InputStreamReader(appUrl.openStream())) {
+                               engine.eval(reader);
+                       } catch (IOException | ScriptException e) {
+                               throw new CmsException("Cannot execute " + appUrl, e);
+                       }
+
+                       if (log.isDebugEnabled())
+                               log.debug("CMS script app initialized from " + appUrl);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               } finally {
+                       Thread.currentThread().setContextClassLoader(originalCcl);
+               }
+       }
+
+       public void destroy(BundleContext bundleContext) {
+               engine = null;
+       }
+
+       @Override
+       public void configure(Application application) {
+               load(application);
+       }
+
+       void load(Application application) {
+               CmsScriptApp app = getApp();
+               app.apply(bundleContext, repository, application);
+               if (log.isDebugEnabled())
+                       log.debug("CMS script app loaded to " + app.getWebPath());
+       }
+
+       CmsScriptApp getApp() {
+               if (engine == null)
+                       throw new IllegalStateException("CMS script app is not initialized");
+               return (CmsScriptApp) engine.get(APP);
+       }
+
+       void update() {
+
+               try {
+                       bundleContext.getBundle().update();
+               } catch (BundleException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       private static ScriptEngine loadScriptEngine(ClassLoader originalCcl, ClassLoader bundleCl) {
+               Thread.currentThread().setContextClassLoader(bundleCl);// GraalVM needs it to be before creating manager
+               ScriptEngineManager scriptEngineManager = new ScriptEngineManager(bundleCl);
+               ScriptEngine engine = scriptEngineManager.getEngineByName("JavaScript");
+               if (engine == null) {// Nashorn
+                       Thread.currentThread().setContextClassLoader(originalCcl);
+                       scriptEngineManager = new ScriptEngineManager();
+                       Thread.currentThread().setContextClassLoader(bundleCl);
+                       engine = scriptEngineManager.getEngineByName("JavaScript");
+               }
+               return engine;
+       }
+}