Add plugin interfaces

This commit is contained in:
Naoki Takezoe
2015-02-07 00:53:41 +09:00
parent eed7e5177f
commit 73c76a5a88
4 changed files with 113 additions and 0 deletions

View File

@@ -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
}

View File

@@ -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
)

View File

@@ -11,6 +11,7 @@ import util.ControlUtil._
import util.JDBCUtil._ import util.JDBCUtil._
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
import util.Directory import util.Directory
import plugin._
object AutoUpdate { object AutoUpdate {
@@ -211,6 +212,7 @@ class AutoUpdateListener extends ServletContextListener {
val context = event.getServletContext val context = event.getServletContext
context.setInitParameter("db.url", s"jdbc:h2:${DatabaseHome};MVCC=true") context.setInitParameter("db.url", s"jdbc:h2:${DatabaseHome};MVCC=true")
// Migration
defining(getConnection(event.getServletContext)){ conn => defining(getConnection(event.getServletContext)){ conn =>
logger.debug("Start schema update") logger.debug("Start schema update")
try { try {
@@ -234,9 +236,14 @@ class AutoUpdateListener extends ServletContextListener {
} }
logger.debug("End schema update") logger.debug("End schema update")
} }
// Load plugins
PluginRegistry.initialize()
} }
def contextDestroyed(sce: ServletContextEvent): Unit = { def contextDestroyed(sce: ServletContextEvent): Unit = {
// Shutdown plugins
PluginRegistry.shutdown()
} }
private def getConnection(servletContext: ServletContext): Connection = private def getConnection(servletContext: ServletContext): Connection =

View File

@@ -82,5 +82,10 @@
}); });
}); });
</script> </script>
@plugin.PluginRegistry().getJavaScript(request.getRequestURI).map { script =>
<script>
@Html(script)
</script>
}
</body> </body>
</html> </html>