Commit f773e893 authored by Mathieu Leclaire's avatar Mathieu Leclaire
Browse files

[GUI] Load plugins.js dynamically

parent d4808c7b
......@@ -8,6 +8,9 @@ import autowire._
import scala.scalajs.concurrent.JSExecutionContext.Implicits.runNow
import rx._
import scalatags.JsDom.all._
import org.openmole.gui.client.tool.JsRxTags._
/*
* Copyright (C) 30/11/16 // mathieu.leclaire@openmole.org
*
......@@ -30,6 +33,18 @@ object Plugins {
private def buildJSObject(obj: String) = scalajs.js.eval(s"new $obj()")
def load =
OMPost()[Api].loadPlugins.call().foreach { _
val pluginScript = script(src := "js/plugins.js").render
// pluginScript.onload = (e: Event) => {
// val apple = scalajs.js.eval("thing.ThingOps().build()")
// println("APPLE " + apple)
// }
org.scalajs.dom.document.head.appendChild(pluginScript)
}
// def updateGUIPlugin = OMPost()[Api].getGUIPlugins().call().foreach { ps ⇒
// ps.authentications.map { p ⇒
// buildJSObject(p.jsObject).asInstanceOf[Authentication]
......
......@@ -19,11 +19,12 @@ import org.scalajs.dom.KeyboardEvent
import scala.scalajs.concurrent.JSExecutionContext.Implicits.runNow
import autowire._
import org.openmole.gui.client.core.files.FileManager
import org.openmole.gui.client.tool.{ OMPost, OMTags }
import org.openmole.gui.ext.api.Api
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import org.openmole.gui.ext.data.ProcessState
import org.scalajs
import org.scalajs.dom.raw.Event
/*
* Copyright (C) 15/04/15 // mathieu.leclaire@openmole.org
......@@ -180,6 +181,7 @@ object ScriptClient {
}
body.appendChild(maindiv)
Plugins.load
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ import org.scalajs.dom.raw._
import autowire._
import org.openmole.gui.client.tool.{ OMPost, Utils }
import org.openmole.gui.ext.api.Api
import org.scalajs.dom
import scala.scalajs.concurrent.JSExecutionContext.Implicits.runNow
......@@ -92,10 +93,20 @@ object FileManager {
}
}
println("sp " + safePath)
println("path " + safePath.path)
println("URI " + Utils.toURI((safePath.path)))
xhr.open("GET", s"downloadFile?path=${Utils.toURI(safePath.path)}", true)
xhr.send()
}
}
def downloadPlugins = {
val xhr = new XMLHttpRequest
xhr.open("GET", s"downloadPlugins", true)
xhr.send()
// xhr.responseText
}
}
......@@ -22,7 +22,7 @@ import org.openmole.gui.ext.data._
trait Api {
//GENERAL
// //GENERAL
def settings(): OMSettings
def shutdown(): Unit
def restart(): Unit
......@@ -88,10 +88,10 @@ trait Api {
def allPluggableIn(path: SafePath): Seq[SafePath]
def listPlugins(): Iterable[Plugin]
def removePlugin(plugin: Plugin): Unit
//GUI PLUGINS
//
// // //GUI PLUGINS
def getGUIPlugins(): AllPluginExtensionData
def addGUIPlugin(): Unit
def loadPlugins(): Unit
//MODEL WIZARDS
def launchingCommands(path: SafePath): Seq[LaunchingCommand]
......
......@@ -21,5 +21,5 @@ import org.openmole.gui.ext.tool._
case class PluginInfo(
clientInstances: Seq[Class[_]],
router: OMRouter[_]
router: OMRouter
)
......@@ -24,9 +24,9 @@ object AutowireServer extends autowire.Server[String, upickle.default.Reader, up
def write[Result: upickle.default.Writer](r: Result) = upickle.default.write(r)
}
case class OMRouter[T: ClassTag](router: AutowireServer.Router) {
def route: String = {
reflect.classTag[T].runtimeClass.getCanonicalName.replace('.', '/')
}
object OMRouter {
def route[T: ClassTag] = reflect.classTag[T].runtimeClass.getCanonicalName.replace('.', '/')
def apply[T: ClassTag](router: AutowireServer.Router): OMRouter = new OMRouter(router, route[T])
}
}
\ No newline at end of file
case class OMRouter(router: AutowireServer.Router, route: String)
\ No newline at end of file
......@@ -32,6 +32,7 @@ import org.openmole.core.module
import org.openmole.core.market
import org.openmole.core.project._
import org.openmole.gui.ext.api.Api
import org.openmole.gui.ext.tool.OMRouter
import rx._
/*
......@@ -51,7 +52,7 @@ import rx._
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class ApiImpl(val arguments: GUIServer.ServletArguments) extends Api {
class ApiImpl(val arguments: GUIServer.ServletArguments, addRoute: OMRouter Unit) extends Api {
val outputSize = ConfigurationLocation[Int]("gui", "outputsize", Some(10 * 1024 * 1024))
......@@ -433,13 +434,11 @@ class ApiImpl(val arguments: GUIServer.ServletArguments) extends Api {
file.recursiveDelete
}
//GUI PLUGINS
//GUI OM PLUGINS
def getGUIPlugins(): AllPluginExtensionData = AllPluginExtensionData(Seq())
def addGUIPlugin(): Unit = {
//Utils.loadPlugins(servlet)
}
def loadPlugins() = Utils.loadPlugins(addRoute)
//MODEL WIZARDS
def launchingCommands(path: SafePath): Seq[LaunchingCommand] = Utils.launchinCommands(path)
......
......@@ -33,6 +33,7 @@ import java.io.File
import org.openmole.core.workspace.Workspace
import org.openmole.gui.ext.api.Api
import org.openmole.gui.ext.data.PasswordState
import org.openmole.gui.ext.tool.{ AutowireServer, OMRouter }
import org.openmole.gui.server.core.GUIServer.ServletArguments
import org.openmole.tool.file._
......@@ -41,15 +42,22 @@ import org.openmole.tool.tar._
import scala.util.{ Failure, Success, Try }
object GUIServlet {
def apply(arguments: GUIServer.ServletArguments) = {
new GUIServlet(arguments)
}
}
@MultipartConfig(fileSizeThreshold = 1024 * 1024)
class GUIServlet(val arguments: GUIServer.ServletArguments) extends ScalatraServlet with FileUploadSupport with AuthenticationSupport {
val apiImpl = new ApiImpl(arguments)
val apiImpl = new ApiImpl(arguments, addRouter)
val connectionRoute = "/connection"
val shutdownRoute = "/shutdown"
val appRoute = "/app"
val downloadFileRoute = "/downloadFile"
val downloadPluginsRoute = "/downloadPlugins"
val uploadFilesRoute = "/uploadFiles"
val resetPasswordRoute = "/resetPassword"
......@@ -184,7 +192,7 @@ class GUIServlet(val arguments: GUIServer.ServletArguments) extends ScalatraServ
get(connectionRoute) {
if (Workspace.passwordHasBeenSet) redirect("/app")
else if (apiImpl.passwordState.chosen) {
else if (Utils.passwordState.chosen) {
response.setHeader("Access-Control-Allow-Origin", "*")
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, OPTIONS")
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With")
......@@ -214,8 +222,6 @@ class GUIServlet(val arguments: GUIServer.ServletArguments) extends ScalatraServ
else redirect(connectionRoute)
}
addRoute(OMRouter[Api](AutowireServer.route[Api](apiImpl)))
def parseParams(toTest: Seq[String], evaluated: Map[String, String] = Map(), errors: Seq[Throwable] = Seq()): (Map[String, String], Seq[Throwable]) = {
if (toTest.isEmpty) (evaluated, errors)
else {
......@@ -227,7 +233,9 @@ class GUIServlet(val arguments: GUIServer.ServletArguments) extends ScalatraServ
}
}
def addRoute[T](router: OMRouter[T]) = {
addRouter(OMRouter[Api](AutowireServer.route[Api](apiImpl)))
def addRouter(router: OMRouter): Unit = {
val bp = classOf[org.openmole.gui.ext.api.Api].getPackage.getName.replace('.', '/')
post(s"/${router.route}/*") {
val coreRequest = autowire.Core.Request(
......
......@@ -37,8 +37,13 @@ import org.openmole.tool.tar._
import java.nio.file.attribute._
import org.openmole.core.exception.UserBadDataError
import org.openmole.gui.ext.plugin.PluginInfo
import org.openmole.gui.ext.plugin.{ PluginActivator, PluginInfo }
import org.openmole.gui.ext.tool.OMRouter
import org.openmole.gui.server.jscompile.JSPack
import org.scalatra.{ Route, ScalatraBase }
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader
object Utils {
......@@ -47,7 +52,12 @@ object Utils {
val webUIProjectFile = Workspace.file("webui")
val pluginUpdoadDirectory = Workspace.tmpDir.newDir("pluginUpload")
val jsPluginDirectory = Workspace.tmpDir.newDir("jsplugin")
val pluginFileName = "plugins.js"
val pluginFile = jsPluginDirectory / pluginFileName
println("jsplugindirectory " + jsPluginDirectory.getAbsolutePath)
pluginUpdoadDirectory.mkdir
jsPluginDirectory.mkdir
def workspaceProjectFile = {
val ws = new File(Workspace.file("webui"), "projects")
......@@ -411,9 +421,18 @@ object Utils {
def getUUID: String = java.util.UUID.randomUUID.toString
def loadPlugins(servlet: GUIServlet, plugins: Seq[PluginInfo]) = {
plugins.foreach { p
servlet.addRoute(p.router)
def loadPlugins(route: OMRouter Unit) = {
import org.openmole.gui.ext.data.ServerFileSytemContext.project
//If no plugin.js in cache: compile it
if (jsPluginDirectory.isDirectoryEmpty) {
val sjsirDir = Workspace.tmpDir
Plugins.gatherJSIRFiles(sjsirDir)
JSPack.link(sjsirDir, Workspace.openMOLELocation / "webapp/js/plugins.js")
PluginActivator.plugins.foreach { p
route(p._2.router)
}
}
}
......
......@@ -31,27 +31,31 @@ import org.openmole.core.workspace.Workspace
object JSPack {
def link(inputDirectory: File, outputJSFile: File): Unit = Workspace.withTmpFile("lib", "jar") { jar
getClass.getClassLoader.getResourceAsStream("scalajs-library.jar") copy jar
// Obtain VirtualScalaJSIRFile's from the input classpath
val irCache = new IRFileCache().newCache
//val irContainers = IRFileCache.IRContainer.fromJar(Seq(jar, inputDirector))
val sjsirFiles =
irCache.cached(
Seq(IRFileCache.IRContainer.fromJar(jar)) ++ IRFileCache.IRContainer.fromDirectory(inputDirectory)
)
// A bunch of options. Here we use all the defaults
val semantics = Semantics.Defaults
val outputMode = OutputMode.Default
val moduleKind = ModuleKind.NoModule
val linkerConfig = Linker.Config()
// Actual linking
val linker = Linker(semantics, outputMode, moduleKind, linkerConfig)
val logger = new ScalaConsoleLogger
linker.link(sjsirFiles, WritableFileVirtualJSFile(outputJSFile), logger)
}
def link(inputDirectory: File, outputJSFile: File): Unit =
Workspace.withTmpFile("lib", "jar") { jar
println("start link")
getClass.getClassLoader.getResourceAsStream("scalajs-library.jar") copy jar
// Obtain VirtualScalaJSIRFile's from the input classpath
val irCache = new IRFileCache().newCache
//val irContainers = IRFileCache.IRContainer.fromJar(Seq(jar, inputDirector))
val sjsirFiles =
irCache.cached(
Seq(IRFileCache.IRContainer.fromJar(jar)) ++ IRFileCache.IRContainer.fromDirectory(inputDirectory)
)
// A bunch of options. Here we use all the defaults
val semantics = Semantics.Defaults
val outputMode = OutputMode.Default
val moduleKind = ModuleKind.NoModule
val linkerConfig = Linker.Config()
// Actual linking
val linker = Linker(semantics, outputMode, moduleKind, linkerConfig)
val logger = new ScalaConsoleLogger
linker.link(sjsirFiles, WritableFileVirtualJSFile(outputJSFile), logger)
println("finish link")
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment