diff --git a/src/main/scala/plugin/Plugin.scala b/src/main/scala/plugin/Plugin.scala new file mode 100644 index 0000000..0c8164e --- /dev/null +++ b/src/main/scala/plugin/Plugin.scala @@ -0,0 +1,14 @@ +package plugin + +trait Plugin { + + val pluginId: String + val pluginName: String + val description: String + val version: String + + def initialize(registry: PluginRegistry): Unit + + def shutdown(registry: PluginRegistry): Unit + +} diff --git a/src/main/scala/plugin/PluginRegistory.scala b/src/main/scala/plugin/PluginRegistory.scala new file mode 100644 index 0000000..9abb6bd --- /dev/null +++ b/src/main/scala/plugin/PluginRegistory.scala @@ -0,0 +1,87 @@ +package plugin + +import java.io.{FilenameFilter, File} +import java.net.URLClassLoader + +import org.slf4j.LoggerFactory +import util.Directory._ + +import scala.collection.mutable.ListBuffer + +class PluginRegistry { + + private val plugins = new ListBuffer[PluginInfo] + private val javaScripts = new ListBuffer[(String, String)] + + def addPlugin(pluginInfo: PluginInfo): Unit = { + plugins += pluginInfo + } + + def getPlugins(): List[PluginInfo] = plugins.toList + + def addJavaScript(path: String, script: String): Unit = { + javaScripts += Tuple2(path, script) + } + + def getJavaScripts(): List[(String, String)] = javaScripts.toList + + def getJavaScript(currentPath: String): Option[String] = { + println(currentPath) + getJavaScripts().find(x => currentPath.matches(x._1)).map(_._2) + } + +} + +object PluginRegistry { + + private val logger = LoggerFactory.getLogger(classOf[PluginRegistry]) + + private val instance = new PluginRegistry() + + def apply(): PluginRegistry = instance + + def initialize(): Unit = { + new File(PluginHome).listFiles(new FilenameFilter { + override def accept(dir: File, name: String): Boolean = name.endsWith(".jar") + }).foreach { pluginJar => + val classLoader = new URLClassLoader(Array(pluginJar.toURI.toURL), Thread.currentThread.getContextClassLoader) + try { + val plugin = classLoader.loadClass("Plugin").newInstance().asInstanceOf[Plugin] + plugin.initialize(instance) + instance.addPlugin(PluginInfo( + pluginId = plugin.pluginId, + pluginName = plugin.pluginName, + version = plugin.version, + description = plugin.description, + pluginClass = plugin + )) + } catch { + case e: Exception => { + logger.error(s"Error during plugin initialization", e) + } + } + } + } + + def shutdown(): Unit = { + instance.getPlugins().foreach { pluginInfo => + try { + pluginInfo.pluginClass.shutdown(instance) + } catch { + case e: Exception => { + logger.error(s"Error during plugin shutdown", e) + } + } + } + } + + +} + +case class PluginInfo( + pluginId: String, + pluginName: String, + version: String, + description: String, + pluginClass: Plugin +) \ No newline at end of file diff --git a/src/main/scala/servlet/AutoUpdateListener.scala b/src/main/scala/servlet/AutoUpdateListener.scala index 6020a0f..c8ed683 100644 --- a/src/main/scala/servlet/AutoUpdateListener.scala +++ b/src/main/scala/servlet/AutoUpdateListener.scala @@ -11,6 +11,7 @@ import util.JDBCUtil._ import org.eclipse.jgit.api.Git import util.Directory +import plugin._ object AutoUpdate { @@ -211,6 +212,7 @@ val context = event.getServletContext context.setInitParameter("db.url", s"jdbc:h2:${DatabaseHome};MVCC=true") + // Migration defining(getConnection(event.getServletContext)){ conn => logger.debug("Start schema update") try { @@ -234,9 +236,14 @@ } logger.debug("End schema update") } + + // Load plugins + PluginRegistry.initialize() } def contextDestroyed(sce: ServletContextEvent): Unit = { + // Shutdown plugins + PluginRegistry.shutdown() } private def getConnection(servletContext: ServletContext): Connection = diff --git a/src/main/twirl/main.scala.html b/src/main/twirl/main.scala.html index 9b8ae02..6d35ff1 100644 --- a/src/main/twirl/main.scala.html +++ b/src/main/twirl/main.scala.html @@ -82,5 +82,10 @@ }); }); + @plugin.PluginRegistry().getJavaScript(request.getRequestURI).map { script => + + }