(refs #1238) Add new extension point to supply assets by plugin

This commit is contained in:
Naoki Takezoe
2016-07-11 18:14:43 +09:00
parent b0f819b9bd
commit 26a18287c7
5 changed files with 74 additions and 2 deletions

View File

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

View File

@@ -149,6 +149,16 @@ abstract class Plugin {
*/
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 @@ abstract class Plugin {
(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))
}
}
/**

View File

@@ -41,6 +41,7 @@ class PluginRegistry {
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 @@ class PluginRegistry {
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
}
/**

View File

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

View File

@@ -45,7 +45,20 @@
<servlet-name>GitRepositoryServlet</servlet-name>
<url-pattern>/git/*</url-pattern>
</servlet-mapping>
<!-- ===================================================================== -->
<!-- Supply assets which are provided by plugins -->
<!-- ===================================================================== -->
<servlet>
<servlet-name>PluginAssetsServlet</servlet-name>
<servlet-class>gitbucket.core.servlet.PluginAssetsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PluginAssetsServlet</servlet-name>
<url-pattern>/plugin-assets/*</url-pattern>
</servlet-mapping>
<!-- ===================================================================== -->
<!-- H2 console configuration -->
<!-- ===================================================================== -->