diff --git a/build.sbt b/build.sbt
index e0c7236..35aebe6 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,6 +1,6 @@
val Organization = "gitbucket"
val Name = "gitbucket"
-val GitBucketVersion = "4.2.1"
+val GitBucketVersion = "4.3.0-SNAPSHOT"
val ScalatraVersion = "2.4.1"
val JettyVersion = "9.3.9.v20160517"
diff --git a/src/main/scala/gitbucket/core/plugin/Plugin.scala b/src/main/scala/gitbucket/core/plugin/Plugin.scala
index caaf726..6f04ec9 100644
--- a/src/main/scala/gitbucket/core/plugin/Plugin.scala
+++ b/src/main/scala/gitbucket/core/plugin/Plugin.scala
@@ -150,6 +150,16 @@
def dashboardTabs(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(Context) => Option[Link]] = Nil
/**
+ * Override to add assets mappings.
+ */
+ val assetsMappings: Seq[(String, String)] = Nil
+
+ /**
+ * Override to add assets mappings.
+ */
+ def assetsMappings(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(String, String)] = Nil
+
+ /**
* This method is invoked in initialization of plugin system.
* Register plugin functionality to PluginRegistry.
*/
@@ -193,6 +203,9 @@
(dashboardTabs ++ dashboardTabs(registry, context, settings)).foreach { dashboardTab =>
registry.addDashboardTab(dashboardTab)
}
+ (assetsMappings ++ assetsMappings(registry, context, settings)).foreach { assetMapping =>
+ registry.addAssetsMapping((assetMapping._1, assetMapping._2, getClass.getClassLoader))
+ }
}
/**
diff --git a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala
index 849fbc3..81f228f 100644
--- a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala
+++ b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala
@@ -41,6 +41,7 @@
private val systemSettingMenus = new ListBuffer[(Context) => Option[Link]]
private val accountSettingMenus = new ListBuffer[(Context) => Option[Link]]
private val dashboardTabs = new ListBuffer[(Context) => Option[Link]]
+ private val assetsMappings = new ListBuffer[(String, String, ClassLoader)]
def addPlugin(pluginInfo: PluginInfo): Unit = {
plugins += pluginInfo
@@ -158,6 +159,12 @@
def getDashboardTabs: Seq[(Context) => Option[Link]] = dashboardTabs.toSeq
+ def addAssetsMapping(assetsMapping: (String, String, ClassLoader)): Unit = {
+ assetsMappings += assetsMapping
+ }
+
+ def getAssetsMappings: Seq[(String, String, ClassLoader)] = assetsMappings.toSeq
+
}
/**
diff --git a/src/main/scala/gitbucket/core/servlet/PluginAssetsServlet.scala b/src/main/scala/gitbucket/core/servlet/PluginAssetsServlet.scala
new file mode 100644
index 0000000..0b59881
--- /dev/null
+++ b/src/main/scala/gitbucket/core/servlet/PluginAssetsServlet.scala
@@ -0,0 +1,39 @@
+package gitbucket.core.servlet
+
+import javax.servlet.http.{HttpServlet, HttpServletRequest, HttpServletResponse}
+
+import gitbucket.core.plugin.PluginRegistry
+import gitbucket.core.util.FileUtil
+import org.apache.commons.io.IOUtils
+
+/**
+ * Supply assets which are provided by plugins.
+ */
+class PluginAssetsServlet extends HttpServlet {
+
+ override def doGet(req: HttpServletRequest, resp: HttpServletResponse): Unit = {
+ val assetsMappings = PluginRegistry().getAssetsMappings
+ val path = req.getRequestURI.substring(req.getContextPath.length)
+
+ assetsMappings
+ .find { case (prefix, _, _) => path.startsWith("/plugin-assets" + prefix) }
+ .flatMap { case (prefix, resourcePath, classLoader) =>
+ val resourceName = path.substring(("/plugin-assets" + prefix).length)
+ Option(classLoader.getResourceAsStream(resourcePath + resourceName))
+ }
+ .map { in =>
+ try {
+ val bytes = IOUtils.toByteArray(in)
+ resp.setContentLength(bytes.length)
+ resp.setContentType(FileUtil.getContentType(path, bytes))
+ resp.getOutputStream.write(bytes)
+ } finally {
+ in.close()
+ }
+ }
+ .getOrElse {
+ resp.setStatus(404)
+ }
+ }
+
+}
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index 37bca8f..e8ee9e9 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -45,7 +45,20 @@
GitRepositoryServlet
/git/*
-
+
+
+
+
+
+ PluginAssetsServlet
+ gitbucket.core.servlet.PluginAssetsServlet
+
+
+
+ PluginAssetsServlet
+ /plugin-assets/*
+
+