diff --git a/src/main/scala/app/SystemSettingsController.scala b/src/main/scala/app/SystemSettingsController.scala index e6d0aca..cf1070d 100644 --- a/src/main/scala/app/SystemSettingsController.scala +++ b/src/main/scala/app/SystemSettingsController.scala @@ -82,7 +82,7 @@ post("/admin/script")(adminOnly { val script = request.getParameter("script") - val result = plugin.PluginSystem.evaluateJavaScript(script) + val result = plugin.JavaScriptPlugin.evaluateJavaScript(script) Ok(result) }) } diff --git a/src/main/scala/plugin/JavaScriptPlugin.scala b/src/main/scala/plugin/JavaScriptPlugin.scala new file mode 100644 index 0000000..8c6b690 --- /dev/null +++ b/src/main/scala/plugin/JavaScriptPlugin.scala @@ -0,0 +1,83 @@ +package plugin + +import org.mozilla.javascript.{Context => JsContext} +import org.mozilla.javascript.{Function => JsFunction} +import scala.collection.mutable.ListBuffer +import plugin.PluginSystem.{Action, GlobalMenu, RepositoryMenu} + +class JavaScriptPlugin(val id: String, val author: String, val url: String, val description: String) extends Plugin { + + private val repositoryMenuList = ListBuffer[RepositoryMenu]() + private val globalMenuList = ListBuffer[GlobalMenu]() + private val repositoryActionList = ListBuffer[Action]() + private val globalActionList = ListBuffer[Action]() + + def repositoryMenus : List[RepositoryMenu] = repositoryMenuList.toList + def globalMenus : List[GlobalMenu] = globalMenuList.toList + def repositoryActions : List[Action] = repositoryActionList.toList + def globalActions : List[Action] = globalActionList.toList + + def addRepositoryMenu(label: String, name: String, url: String, icon: String, condition: JsFunction): Unit = { + repositoryMenuList += RepositoryMenu(label, name, url, icon, (context) => { + val context = JsContext.enter() + try { + condition.call(context, condition, condition, Array(context)).asInstanceOf[Boolean] + } finally { + JsContext.exit() + } + }) + } + + def addGlobalMenu(label: String, url: String, icon: String, condition: JsFunction): Unit = { + globalMenuList += GlobalMenu(label, url, icon, (context) => { + val context = JsContext.enter() + try { + condition.call(context, condition, condition, Array(context)).asInstanceOf[Boolean] + } finally { + JsContext.exit() + } + }) + } + + def addGlobalAction(path: String, function: JsFunction): Unit = { + globalActionList += Action(path, (request, response) => { + val context = JsContext.enter() + try { + function.call(context, function, function, Array(request, response)) + } finally { + JsContext.exit() + } + }) + } + + def addRepositoryAction(path: String, function: JsFunction): Unit = { + repositoryActionList += Action(path, (request, response) => { + val context = JsContext.enter() + try { + function.call(context, function, function, Array(request, response)) + } finally { + JsContext.exit() + } + }) + } + +} + +object JavaScriptPlugin { + + def define(id: String, author: String, url: String, description: String) = new JavaScriptPlugin(id, author, url, description) + + def evaluateJavaScript(script: String): Any = { + val context = JsContext.enter() + try { + val scope = context.initStandardObjects() + scope.put("PluginSystem", scope, this) + scope.put("JavaScriptPlugin", scope, this) + val result = context.evaluateString(scope, script, "", 1, null) + result + } finally { + JsContext.exit + } + } + +} \ No newline at end of file diff --git a/src/main/scala/plugin/Plugin.scala b/src/main/scala/plugin/Plugin.scala new file mode 100644 index 0000000..66f475e --- /dev/null +++ b/src/main/scala/plugin/Plugin.scala @@ -0,0 +1,15 @@ +package plugin + +import plugin.PluginSystem.{Action, GlobalMenu, RepositoryMenu} + +trait Plugin { + val id: String + val author: String + val url: String + val description: String + + def repositoryMenus : List[RepositoryMenu] + def globalMenus : List[GlobalMenu] + def repositoryActions : List[Action] + def globalActions : List[Action] +} diff --git a/src/main/scala/plugin/PluginSystem.scala b/src/main/scala/plugin/PluginSystem.scala index 1d661b7..daae34c 100644 --- a/src/main/scala/plugin/PluginSystem.scala +++ b/src/main/scala/plugin/PluginSystem.scala @@ -2,10 +2,7 @@ import app.Context import javax.servlet.http.{HttpServletResponse, HttpServletRequest} -import scala.collection.mutable.ListBuffer import org.slf4j.LoggerFactory -import org.mozilla.javascript.{Context => JsContext} -import org.mozilla.javascript.{Function => JsFunction} /** * Provides extension points to plug-ins. @@ -26,112 +23,16 @@ pluginsMap.remove(id) } - def repositoryMenus : List[RepositoryMenu] = pluginsMap.values.flatMap(_.repositoryMenuList).toList - def globalMenus : List[GlobalMenu] = pluginsMap.values.flatMap(_.globalMenuList).toList - def repositoryActions : List[Action] = pluginsMap.values.flatMap(_.repositoryActionList).toList - def globalActions : List[Action] = pluginsMap.values.flatMap(_.globalActionList).toList + def repositoryMenus : List[RepositoryMenu] = pluginsMap.values.flatMap(_.repositoryMenus).toList + def globalMenus : List[GlobalMenu] = pluginsMap.values.flatMap(_.globalMenus).toList + def repositoryActions : List[Action] = pluginsMap.values.flatMap(_.repositoryActions).toList + def globalActions : List[Action] = pluginsMap.values.flatMap(_.globalActions).toList // Case classes to hold plug-ins information internally in GitBucket 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) - /** - * This is a plug-in definition class. - */ - class Plugin(val id: String, val author: String, val url: String, val description: String) { - - private[PluginSystem] val repositoryMenuList = ListBuffer[RepositoryMenu]() - private[PluginSystem] val globalMenuList = ListBuffer[GlobalMenu]() - private[PluginSystem] val repositoryActionList = ListBuffer[Action]() - private[PluginSystem] val globalActionList = ListBuffer[Action]() - -// def addRepositoryMenu(label: String, name: String, url: String, icon: String)(condition: Context => Boolean): Unit = { -// repositoryMenuList += RepositoryMenu(label, name, url, icon, condition) -// } - - def addRepositoryMenu(label: String, name: String, url: String, icon: String, condition: JsFunction): Unit = { - repositoryMenuList += RepositoryMenu(label, name, url, icon, (context) => { - val context = JsContext.enter() - try { - condition.call(context, condition, condition, Array(context)).asInstanceOf[Boolean] - } finally { - JsContext.exit() - } - }) - } - -// def addGlobalMenu(label: String, url: String, icon: String)(condition: Context => Boolean): Unit = { -// globalMenuList += GlobalMenu(label, url, icon, condition) -// } - - def addGlobalMenu(label: String, url: String, icon: String, condition: JsFunction): Unit = { - globalMenuList += GlobalMenu(label, url, icon, (context) => { - val context = JsContext.enter() - try { - condition.call(context, condition, condition, Array(context)).asInstanceOf[Boolean] - } finally { - JsContext.exit() - } - }) - } - -// def addGlobalAction(path: String)(function: (HttpServletRequest, HttpServletResponse) => Any): Unit = { -// globalActionList += Action(path, function) -// } - - def addGlobalAction(path: String, function: JsFunction): Unit = { - globalActionList += Action(path, (request, response) => { - val context = JsContext.enter() - try { - function.call(context, function, function, Array(request, response)) - } finally { - JsContext.exit() - } - }) - } - -// def addRepositoryAction(path: String)(function: (HttpServletRequest, HttpServletResponse) => Any): Unit = { -// repositoryActionList += Action(path, function) -// } - - def addRepositoryAction(path: String, function: JsFunction): Unit = { - repositoryActionList += Action(path, (request, response) => { - val context = JsContext.enter() - try { - function.call(context, function, function, Array(request, response)) - } finally { - JsContext.exit() - } - }) - } - - } - - def definePlugin(id: String, author: String, url: String, description: String): Plugin = new Plugin(id, author, url, description) - - def evaluateJavaScript(script: String): Any = { - val context = JsContext.enter() - try { - val scope = context.initStandardObjects() - scope.put("PluginSystem", scope, this) - val result = context.evaluateString(scope, script, "", 1, null) - result - } finally { - JsContext.exit - } - - -// val engine = new ScriptEngineManager().getEngineByName("JavaScript") -// logger.debug("Script: " + script) -// engine.put("PluginSystem", this) -// // TODO Support both of Nashorn and Rhino! -// val result = engine.eval("var Plugin = Java.type(\"plugin.PluginSystem.Plugin\"); " + script) -// logger.debug("Result: " + result) -// result - } - - // 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") // { context => context.loginAccount.isDefined } diff --git a/src/main/twirl/admin/plugins.scala.html b/src/main/twirl/admin/plugins.scala.html index 78ab4f3..356534d 100644 --- a/src/main/twirl/admin/plugins.scala.html +++ b/src/main/twirl/admin/plugins.scala.html @@ -1,4 +1,4 @@ -@(plugins: List[plugin.PluginSystem.Plugin])(implicit context: app.Context) +@(plugins: List[plugin.Plugin])(implicit context: app.Context) @import context._ @import view.helpers._ @html.main("Plugins"){