diff --git a/src/main/scala/plugin/PluginSystem.scala b/src/main/scala/plugin/PluginSystem.scala index cabe833..18c81f5 100644 --- a/src/main/scala/plugin/PluginSystem.scala +++ b/src/main/scala/plugin/PluginSystem.scala @@ -3,40 +3,71 @@ import app.Context import javax.servlet.http.{HttpServletResponse, HttpServletRequest} import javax.script.ScriptEngineManager +import scala.collection.mutable.ListBuffer +import org.slf4j.LoggerFactory +import jdk.nashorn.api.scripting.ScriptObjectMirror /** * Provides extension points to plug-ins. */ object PluginSystem { - private val repositoryMenuList = scala.collection.mutable.ListBuffer[RepositoryMenu]() - private val globalMenuList = scala.collection.mutable.ListBuffer[GlobalMenu]() - private val actionList = scala.collection.mutable.ListBuffer[Action]() + private val logger = LoggerFactory.getLogger(PluginSystem.getClass) + + private val repositoryMenuList = ListBuffer[RepositoryMenu]() + private val globalMenuList = ListBuffer[GlobalMenu]() + private val repositoryActionList = ListBuffer[Action]() + private val globalActionList = ListBuffer[Action]() case class GlobalMenu(label: String, url: String, icon: String, condition: Context => Boolean) case class RepositoryMenu(label: String, name: String, url: String, icon: String, condition: Context => Boolean) case class Action(path: String, function: (HttpServletRequest, HttpServletResponse) => Any) - def addRepositoryMenu(label: String, name: String, url: String, icon: String = "")(condition: Context => Boolean): Unit = { + def addRepositoryMenu(label: String, name: String, url: String, icon: String)(condition: Context => Boolean): Unit = { repositoryMenuList += RepositoryMenu(label, name, url, icon, condition) } - def addGlobalMenu(label: String, url: String, icon: String = "")(condition: Context => Boolean): Unit = { + def addRepositoryMenu(label: String, name: String, url: String, icon: String, condition: ScriptObjectMirror): Unit = { + repositoryMenuList += RepositoryMenu(label, name, url, icon, (context) => condition.call(this, context).asInstanceOf[Boolean]) + } + + def addGlobalMenu(label: String, url: String, icon: String)(condition: Context => Boolean): Unit = { globalMenuList += GlobalMenu(label, url, icon, condition) } - def addAction(path: String)(function: (HttpServletRequest, HttpServletResponse) => Any): Unit = { - actionList += Action(path, function) + def addGlobalMenu(label: String, url: String, icon: String, condition: ScriptObjectMirror): Unit = { + globalMenuList += GlobalMenu(label, url, icon, (context) => condition.call(this, context).asInstanceOf[Boolean]) + } + + def addGlobalAction(path: String)(function: (HttpServletRequest, HttpServletResponse) => Any): Unit = { + globalActionList += Action(path, function) + } + + def addGlobalAction(path: String, function: ScriptObjectMirror): Unit = { + globalActionList += Action(path, (request, response) => function.call(this, request, response)) + } + + def addRepositoryAction(path: String)(function: (HttpServletRequest, HttpServletResponse) => Any): Unit = { + repositoryActionList += Action(path, function) + } + + def addRepositoryAction(path: String, function: ScriptObjectMirror): Unit = { + repositoryActionList += Action(path, (request, response) => function.call(this, request, response)) } def evaluateJavaScript(script: String): Any = { val engine = new ScriptEngineManager().getEngineByName("JavaScript") - engine.eval(script) + logger.debug("Script: " + script) + engine.put("PluginSystem", this) + val result = engine.eval(script) + logger.debug("Result: " + result) + result } - lazy val repositoryMenus: List[RepositoryMenu] = repositoryMenuList.toList - lazy val globalMenus: List[GlobalMenu] = globalMenuList.toList - lazy val actions: List[Action] = actionList.toList + def repositoryMenus: List[RepositoryMenu] = repositoryMenuList.toList + def globalMenus: List[GlobalMenu] = globalMenuList.toList + def repositoryActions: List[Action] = repositoryActionList.toList + def globalActions: List[Action] = globalActionList.toList // TODO This is a test addGlobalMenu("Google", "http://www.google.co.jp/", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAEvwAABL8BkeKJvAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIgSURBVEiJtdZNiI1hFAfw36ORhSFFPgYLszOKJAsWRLGzks1gYyFZKFs7C7K2Y2XDRiwmq9kIJWQjJR9Tk48xRtTIRwjH4p473nm99yLNqdNTz/mf//+555x7ektEmEmbNaPs6OkUKKX0YBmWp6/IE8bwIs8xjEfEt0aiiJBl6sEuXMRLfEf8pX/PnIvJ0TPFWxE4+w+Ef/Kzbd5qDx5l8H8tkku7LG17gH7sxWatevdhEUoXsjda5RnDTZzH6jagtMe0lHIa23AJw3iOiSRZlmJ9mfcyfTzFl2AldmI3rkbEkbrAYKrX7S1eVRyWVnxhQ87eiLjQ+o2/mtyve+PuYy3W4+EfsP2/TVGKTHRI+Iz9Fdx8XOmAnZjGWRMYqoF/4ESW4hpOYk1iZ2WsLjDUTeBYBfgeuyux2XiNT5hXud+DD5W8Y90EtifoSfultfjx7MVtrKzcr8No5m7vJtCLx1hQJ8/4IZzClpyoy5ibsYUYQW81Z9o2jYgPeKr15+poEXE9+1XF9WIkOaasaV2P4k4pZUdDbEm+VEQcjIgtEfGxlLIVd/Gs6TX1MhzQquU3HK1t23f4IsuS94fxNXMO/MbXIDBg+tidw5yMbcCmylSdqWEH/kagYLKWeAt9Fcxi3KhhJuXq6SqQBMO15NDalvswmLWux4cbuToIbMS9BpJOfg8bm7imtmmTlVJWaa3hpnU9nufziBjtyDHTny0/AaA7Qnb4AM4aAAAAAElFTkSuQmCC") @@ -45,7 +76,7 @@ addRepositoryMenu("Board", "board", "/board", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAEvwAABL8BkeKJvAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIgSURBVEiJtdZNiI1hFAfw36ORhSFFPgYLszOKJAsWRLGzks1gYyFZKFs7C7K2Y2XDRiwmq9kIJWQjJR9Tk48xRtTIRwjH4p473nm99yLNqdNTz/mf//+555x7ektEmEmbNaPs6OkUKKX0YBmWp6/IE8bwIs8xjEfEt0aiiJBl6sEuXMRLfEf8pX/PnIvJ0TPFWxE4+w+Ef/Kzbd5qDx5l8H8tkku7LG17gH7sxWatevdhEUoXsjda5RnDTZzH6jagtMe0lHIa23AJw3iOiSRZlmJ9mfcyfTzFl2AldmI3rkbEkbrAYKrX7S1eVRyWVnxhQ87eiLjQ+o2/mtyve+PuYy3W4+EfsP2/TVGKTHRI+Iz9Fdx8XOmAnZjGWRMYqoF/4ESW4hpOYk1iZ2WsLjDUTeBYBfgeuyux2XiNT5hXud+DD5W8Y90EtifoSfultfjx7MVtrKzcr8No5m7vJtCLx1hQJ8/4IZzClpyoy5ibsYUYQW81Z9o2jYgPeKr15+poEXE9+1XF9WIkOaasaV2P4k4pZUdDbEm+VEQcjIgtEfGxlLIVd/Gs6TX1MhzQquU3HK1t23f4IsuS94fxNXMO/MbXIDBg+tidw5yMbcCmylSdqWEH/kagYLKWeAt9Fcxi3KhhJuXq6SqQBMO15NDalvswmLWux4cbuToIbMS9BpJOfg8bm7imtmmTlVJWaa3hpnU9nufziBjtyDHTny0/AaA7Qnb4AM4aAAAAAElFTkSuQmCC") { context => true} - addAction("/hello"){ (request, response) => + addGlobalAction("/hello"){ (request, response) => "Hello World!" } diff --git a/src/main/scala/servlet/PluginActionInvokeFilter.scala b/src/main/scala/servlet/PluginActionInvokeFilter.scala index 15be40c..a4cc48e 100644 --- a/src/main/scala/servlet/PluginActionInvokeFilter.scala +++ b/src/main/scala/servlet/PluginActionInvokeFilter.scala @@ -18,7 +18,7 @@ (req, res) match { case (request: HttpServletRequest, response: HttpServletResponse) => { val path = req.asInstanceOf[HttpServletRequest].getRequestURI - val action = plugin.PluginSystem.actions.find(_.path == path) + val action = plugin.PluginSystem.globalActions.find(_.path == path) if(action.isDefined){ val result = action.get.function(request, response) diff --git a/src/main/twirl/admin/script.scala.html b/src/main/twirl/admin/script.scala.html index 604b138..9707c1d 100644 --- a/src/main/twirl/admin/script.scala.html +++ b/src/main/twirl/admin/script.scala.html @@ -3,7 +3,7 @@ @import view.helpers._ @html.main("JavaScript Console"){ @menu("script"){ -
+
JavaScript Console
@@ -11,7 +11,7 @@
- +
} @@ -21,12 +21,15 @@ $(function(){ var editor = ace.edit("editor"); editor.setTheme("ace/theme/monokai"); + editor.getSession().setMode("ace/mode/javascript"); $('#evaluate').click(function(){ $.post('@path/admin/script', { script: editor.getValue() }, function(data){ - console.log(data); + alert('Success: ' + data); + }).fail(function(error){ + alert(error.statusText); }); }); });