diff --git a/src/main/scala/ScalatraBootstrap.scala b/src/main/scala/ScalatraBootstrap.scala index 90fe415..25dbf5b 100644 --- a/src/main/scala/ScalatraBootstrap.scala +++ b/src/main/scala/ScalatraBootstrap.scala @@ -1,4 +1,4 @@ -import _root_.servlet.{BasicAuthenticationFilter, TransactionFilter} +import _root_.servlet.{PluginActionInvokeFilter, BasicAuthenticationFilter, TransactionFilter} import app._ //import jp.sf.amateras.scalatra.forms.ValidationJavaScriptProvider import org.scalatra._ @@ -10,6 +10,8 @@ // Register TransactionFilter and BasicAuthenticationFilter at first context.addFilter("transactionFilter", new TransactionFilter) context.getFilterRegistration("transactionFilter").addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/*") + context.addFilter("pluginActionInvokeFilter", new PluginActionInvokeFilter) + context.getFilterRegistration("pluginActionInvokeFilter").addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/*") context.addFilter("basicAuthenticationFilter", new BasicAuthenticationFilter) context.getFilterRegistration("basicAuthenticationFilter").addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/git/*") diff --git a/src/main/scala/plugin/PluginSystem.scala b/src/main/scala/plugin/PluginSystem.scala index 2733333..db46a3d 100644 --- a/src/main/scala/plugin/PluginSystem.scala +++ b/src/main/scala/plugin/PluginSystem.scala @@ -1,6 +1,7 @@ package plugin import app.Context +import javax.servlet.http.{HttpServletResponse, HttpServletRequest} /** * Provides extension points to plug-ins. @@ -9,8 +10,10 @@ private val repositoryMenuList = scala.collection.mutable.ListBuffer[Menu]() private val globalMenuList = scala.collection.mutable.ListBuffer[Menu]() + private val actionList = scala.collection.mutable.ListBuffer[Action]() case class Menu(label: String, url: String, icon: String, condition: Context => Boolean) + case class Action(path: String, function: (HttpServletRequest, HttpServletResponse) => Any) def addRepositoryMenu(label: String, url: String, icon: String = "")(condition: Context => Boolean): Unit = { repositoryMenuList += Menu(label, url, icon, condition) @@ -20,16 +23,21 @@ globalMenuList += Menu(label, url, icon, condition) } - def addAction(path: String): Unit = { - // TODO + def addAction(path: String)(function: (HttpServletRequest, HttpServletResponse) => Any): Unit = { + actionList += Action(path, function) } - def repositoryMenus: List[Menu] = repositoryMenuList.toList - def globalMenus: List[Menu] = globalMenuList.toList + lazy val repositoryMenus: List[Menu] = repositoryMenuList.toList + lazy val globalMenus: List[Menu] = globalMenuList.toList + lazy val actions: List[Action] = actionList.toList // TODO This is a test addGlobalMenu("Google", "http://www.google.co.jp/"){ context => context.loginAccount.isDefined } + addAction("/hello"){ (request, response) => + "Hello World!" + } + } diff --git a/src/main/scala/servlet/PluginActionInvokeFilter.scala b/src/main/scala/servlet/PluginActionInvokeFilter.scala new file mode 100644 index 0000000..6840153 --- /dev/null +++ b/src/main/scala/servlet/PluginActionInvokeFilter.scala @@ -0,0 +1,40 @@ +package servlet + +import javax.servlet._ +import javax.servlet.http.{HttpServletResponse, HttpServletRequest} +import org.apache.commons.io.IOUtils + +class PluginActionInvokeFilter extends Filter { + + def init(config: FilterConfig) = {} + + def destroy(): Unit = {} + + def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = { + (req, res) match { + case (request: HttpServletRequest, response: HttpServletResponse) => { + val path = req.asInstanceOf[HttpServletRequest].getRequestURI + //println(req.asInstanceOf[HttpServletRequest].getContextPath) + //println(req.asInstanceOf[HttpServletRequest].getRequestURL) + + val action = plugin.PluginSystem.actions.find(_.path == path) + if(action.isDefined){ + val result = action.get.function(request, response) + result match { + case x: String => { + response.setContentType("text/plain; charset=UTF-8") + IOUtils.write(x.getBytes("UTF-8"), response.getOutputStream) + } + case x => { + // TODO returns as JSON? + } + } + } else { + chain.doFilter(req, res) + } + } + } + } + + +}