diff --git a/src/main/scala/servlet/AutoUpdateListener.scala b/src/main/scala/servlet/AutoUpdateListener.scala
new file mode 100644
index 0000000..aa48a00
--- /dev/null
+++ b/src/main/scala/servlet/AutoUpdateListener.scala
@@ -0,0 +1,118 @@
+package servlet
+
+import java.io.File
+import java.sql.Connection
+import org.apache.commons.io.FileUtils
+import javax.servlet.ServletContextEvent
+import org.apache.commons.io.IOUtils
+import org.slf4j.LoggerFactory
+import util.Directory
+
+object AutoUpdate {
+
+ /**
+ * Version of GitBucket
+ *
+ * @param majorVersion the major version
+ * @param minorVersion the minor version
+ */
+ case class Version(majorVersion: Int, minorVersion: Int){
+
+ private val logger = LoggerFactory.getLogger(classOf[servlet.AutoUpdate.Version])
+
+ /**
+ * Execute update/MAJOR_MINOR.sql to update schema to this version.
+ * If corresponding SQL file does not exist, this method do nothing.
+ */
+ def update(conn: Connection): Unit = {
+ val sqlPath = "update/%d_%d.sql".format(majorVersion, minorVersion)
+ val in = Thread.currentThread.getContextClassLoader.getResourceAsStream(sqlPath)
+ if(in != null){
+ val sql = IOUtils.toString(in, "UTF-8")
+ val stmt = conn.createStatement()
+ try {
+ logger.debug(sqlPath + "=" + sql)
+ stmt.executeUpdate(sql)
+ } finally {
+ stmt.close()
+ }
+ }
+ }
+
+ /**
+ * MAJOR.MINOR
+ */
+ val versionString = "%d.%d".format(majorVersion, minorVersion)
+ }
+
+ /**
+ * The history of versions. A head of this sequence is the current BitBucket version.
+ */
+ val versions = Seq(
+ Version(1, 0)
+ )
+
+ /**
+ * The head version of BitBucket.
+ */
+ val headVersion = versions.head
+
+ /**
+ * The version file (GITBUCKET_HOME/version).
+ */
+ val versionFile = new File(Directory.GitBucketHome, "version")
+
+ /**
+ * Returns the current version from the version file.
+ */
+ def getCurrentVersion(): Version = {
+ if(versionFile.exists){
+ FileUtils.readFileToString(versionFile, "UTF-8").split("\\.") match {
+ case Array(majorVersion, minorVersion) => {
+ versions.find { v =>
+ v.majorVersion == majorVersion.toInt && v.minorVersion == minorVersion.toInt
+ }.getOrElse(Version(0, 0))
+ }
+ case _ => Version(0, 0)
+ }
+ } else {
+ Version(0, 0)
+ }
+
+ }
+
+}
+
+/**
+ * Start H2 database and update schema automatically.
+ */
+class AutoUpdateListener extends org.h2.server.web.DbStarter {
+ import AutoUpdate._
+ private val logger = LoggerFactory.getLogger(classOf[AutoUpdateListener])
+
+ override def contextInitialized(event: ServletContextEvent): Unit = {
+ super.contextInitialized(event)
+ logger.debug("H2 started")
+
+ logger.debug("Start schema update")
+ val conn = getConnection()
+ try {
+ val currentVersion = getCurrentVersion()
+ if(currentVersion == headVersion){
+ logger.debug("No update")
+ } else {
+ versions.takeWhile(_ != currentVersion).reverse.foreach(_.update(conn))
+ FileUtils.writeStringToFile(versionFile, headVersion.versionString, "UTF-8")
+ conn.commit()
+ logger.debug("Updated from " + currentVersion.versionString + " to " + headVersion.versionString)
+ }
+ } catch {
+ case ex: Throwable => {
+ logger.error("Failed to schema update", ex)
+ conn.rollback()
+ }
+ }
+ logger.debug("End schema update")
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/servlet/BasicAuthenticationFilter.scala b/src/main/scala/servlet/BasicAuthenticationFilter.scala
new file mode 100644
index 0000000..d097c9f
--- /dev/null
+++ b/src/main/scala/servlet/BasicAuthenticationFilter.scala
@@ -0,0 +1,52 @@
+package servlet
+
+import javax.servlet._
+import javax.servlet.http._
+
+/**
+ * Provides BASIC Authentication for [[app.GitRepositoryServlet]].
+ */
+class BasicAuthenticationFilter extends Filter {
+
+ def init(config: FilterConfig) = {}
+
+ def destroy(): Unit = {}
+
+ def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = {
+ val request = req.asInstanceOf[HttpServletRequest]
+ val response = res.asInstanceOf[HttpServletResponse]
+ val session = request.getSession
+
+ try {
+ session.getAttribute("USER_INFO") match {
+ case null => request.getHeader("Authorization") match {
+ case null => requireAuth(response)
+ case auth => decodeAuthHeader(auth).split(":") match {
+ // TODO authenticate using registered user info
+ case Array(username, password) if(username == "gitbucket" && password == "password") => {
+ session.setAttribute("USER_INFO", "gitbucket")
+ chain.doFilter(req, res)
+ }
+ case _ => requireAuth(response)
+ }
+ }
+ case user => chain.doFilter(req, res)
+ }
+ } catch {
+ case _: Exception => requireAuth(response)
+ }
+ }
+
+ private def requireAuth(response: HttpServletResponse): Unit = {
+ response.setHeader("WWW-Authenticate", "BASIC realm=\"GitBucket\"")
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED)
+ }
+
+ private def decodeAuthHeader(header: String): String = {
+ try {
+ new String(new sun.misc.BASE64Decoder().decodeBuffer(header.substring(6)))
+ } catch {
+ case _: Throwable => ""
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/scala/servlet/GitRepositoryServlet.scala b/src/main/scala/servlet/GitRepositoryServlet.scala
new file mode 100644
index 0000000..77dd293
--- /dev/null
+++ b/src/main/scala/servlet/GitRepositoryServlet.scala
@@ -0,0 +1,37 @@
+package servlet
+
+import java.io._
+import javax.servlet._
+import javax.servlet.http._
+import org.eclipse.jgit.http.server.GitServlet
+import org.slf4j.LoggerFactory
+import util.Directory
+
+/**
+ * Provides Git repository via HTTP.
+ *
+ * This servlet provides only Git repository functionality.
+ * Authentication is provided by [[app.BasicAuthenticationFilter]].
+ */
+class GitRepositoryServlet extends GitServlet {
+
+ private val logger = LoggerFactory.getLogger(classOf[GitRepositoryServlet])
+
+ // TODO are there any other ways...?
+ override def init(config: ServletConfig): Unit = {
+ super.init(new ServletConfig(){
+ def getInitParameter(name: String): String = name match {
+ case "base-path" => Directory.RepositoryHome
+ case "export-all" => "true"
+ case name => config.getInitParameter(name)
+ }
+ def getInitParameterNames(): java.util.Enumeration[String] = {
+ config.getInitParameterNames
+ }
+
+ def getServletContext(): ServletContext = config.getServletContext
+ def getServletName(): String = config.getServletName
+ });
+ }
+
+}
diff --git a/src/main/scala/servlet/TransactionFilter.scala b/src/main/scala/servlet/TransactionFilter.scala
new file mode 100644
index 0000000..cfc21ee
--- /dev/null
+++ b/src/main/scala/servlet/TransactionFilter.scala
@@ -0,0 +1,30 @@
+package servlet
+
+import javax.servlet._
+import org.slf4j.LoggerFactory
+import javax.servlet.http.HttpServletRequest
+
+/**
+ * Controls the transaction with the open session in view pattern.
+ */
+class TransactionFilter extends Filter {
+
+ private val logger = LoggerFactory.getLogger(classOf[TransactionFilter])
+
+ def init(config: FilterConfig) = {}
+
+ def destroy(): Unit = {}
+
+ def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = {
+ if(req.asInstanceOf[HttpServletRequest].getRequestURI().startsWith("/assets/")){
+ // assets don't need transaction
+ chain.doFilter(req, res)
+ } else {
+ // TODO begin transaction!
+ logger.debug("TODO begin transaction")
+ chain.doFilter(req, res)
+ logger.debug("TODO end transaction")
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/util/AutoUpdate.scala b/src/main/scala/util/AutoUpdate.scala
deleted file mode 100644
index 6fa1843..0000000
--- a/src/main/scala/util/AutoUpdate.scala
+++ /dev/null
@@ -1,118 +0,0 @@
-package util
-
-import java.io.File
-import java.sql.Connection
-import org.apache.commons.io.FileUtils
-import javax.servlet.ServletContextEvent
-import org.apache.commons.io.IOUtils
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-
-object AutoUpdate {
-
- /**
- * Version of GitBucket
- *
- * @param majorVersion the major version
- * @param minorVersion the minor version
- */
- case class Version(majorVersion: Int, minorVersion: Int){
-
- private val logger = LoggerFactory.getLogger(classOf[Version])
-
- /**
- * Execute update/MAJOR_MINOR.sql to update schema to this version.
- * If corresponding SQL file does not exist, this method do nothing.
- */
- def update(conn: Connection): Unit = {
- val sqlPath = "update/%d_%d.sql".format(majorVersion, minorVersion)
- val in = Thread.currentThread.getContextClassLoader.getResourceAsStream(sqlPath)
- if(in != null){
- val sql = IOUtils.toString(in, "UTF-8")
- val stmt = conn.createStatement()
- try {
- logger.debug(sqlPath + "=" + sql)
- stmt.executeUpdate(sql)
- } finally {
- stmt.close()
- }
- }
- }
-
- /**
- * MAJOR.MINOR
- */
- val versionString = "%d.%d".format(majorVersion, minorVersion)
- }
-
- /**
- * The history of versions. A head of this sequence is the current BitBucket version.
- */
- val versions = Seq(
- Version(1, 0)
- )
-
- /**
- * The head version of BitBucket.
- */
- val headVersion = versions.head
-
- /**
- * The version file (GITBUCKET_HOME/version).
- */
- val versionFile = new File(Directory.GitBucketHome, "version")
-
- /**
- * Returns the current version from the version file.
- */
- def getCurrentVersion(): Version = {
- if(versionFile.exists){
- FileUtils.readFileToString(versionFile, "UTF-8").split("\\.") match {
- case Array(majorVersion, minorVersion) => {
- versions.find { v =>
- v.majorVersion == majorVersion.toInt && v.minorVersion == minorVersion.toInt
- }.getOrElse(Version(0, 0))
- }
- case _ => Version(0, 0)
- }
- } else {
- Version(0, 0)
- }
-
- }
-
-}
-
-/**
- * Start H2 database and update schema automatically.
- */
-class AutoUpdateListener extends org.h2.server.web.DbStarter {
- import AutoUpdate._
- private val logger = LoggerFactory.getLogger(classOf[AutoUpdateListener])
-
- override def contextInitialized(event: ServletContextEvent): Unit = {
- super.contextInitialized(event)
- logger.debug("H2 started")
-
- logger.debug("Start schema update")
- val conn = getConnection()
- try {
- val currentVersion = getCurrentVersion()
- if(currentVersion == headVersion){
- logger.debug("No update")
- } else {
- versions.takeWhile(_ != currentVersion).reverse.foreach(_.update(conn))
- FileUtils.writeStringToFile(versionFile, headVersion.versionString, "UTF-8")
- conn.commit()
- logger.debug("Updated from " + currentVersion.versionString + " to " + headVersion.versionString)
- }
- } catch {
- case ex: Throwable => {
- logger.error("Failed to schema update", ex)
- conn.rollback()
- }
- }
- logger.debug("End schema update")
- }
-
-}
\ No newline at end of file
diff --git a/src/main/scala/util/BasicAuthenticationFilter.scala b/src/main/scala/util/BasicAuthenticationFilter.scala
deleted file mode 100644
index c81c221..0000000
--- a/src/main/scala/util/BasicAuthenticationFilter.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-package util
-
-import javax.servlet._
-import javax.servlet.http._
-
-/**
- * Provides BASIC Authentication for [[app.GitRepositoryServlet]].
- */
-class BasicAuthenticationFilter extends Filter {
-
- def init(config: FilterConfig) = {}
-
- def destroy(): Unit = {}
-
- def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = {
- val request = req.asInstanceOf[HttpServletRequest]
- val response = res.asInstanceOf[HttpServletResponse]
- val session = request.getSession
-
- try {
- session.getAttribute("USER_INFO") match {
- case null => request.getHeader("Authorization") match {
- case null => requireAuth(response)
- case auth => decodeAuthHeader(auth).split(":") match {
- // TODO authenticate using registered user info
- case Array(username, password) if(username == "gitbucket" && password == "password") => {
- session.setAttribute("USER_INFO", "gitbucket")
- chain.doFilter(req, res)
- }
- case _ => requireAuth(response)
- }
- }
- case user => chain.doFilter(req, res)
- }
- } catch {
- case _: Exception => requireAuth(response)
- }
- }
-
- private def requireAuth(response: HttpServletResponse): Unit = {
- response.setHeader("WWW-Authenticate", "BASIC realm=\"GitBucket\"")
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED)
- }
-
- private def decodeAuthHeader(header: String): String = {
- try {
- new String(new sun.misc.BASE64Decoder().decodeBuffer(header.substring(6)))
- } catch {
- case _: Throwable => ""
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/scala/util/GitRepositoryServlet.scala b/src/main/scala/util/GitRepositoryServlet.scala
deleted file mode 100644
index 7f1461a..0000000
--- a/src/main/scala/util/GitRepositoryServlet.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-package util
-
-import java.io._
-import javax.servlet._
-import javax.servlet.http._
-import org.eclipse.jgit.http.server.GitServlet
-import org.slf4j.LoggerFactory
-
-/**
- * Provides Git repository via HTTP.
- *
- * This servlet provides only Git repository functionality.
- * Authentication is provided by [[app.BasicAuthenticationFilter]].
- */
-class GitRepositoryServlet extends GitServlet {
-
- private val logger = LoggerFactory.getLogger(classOf[GitRepositoryServlet])
-
- // TODO are there any other ways...?
- override def init(config: ServletConfig): Unit = {
- super.init(new ServletConfig(){
- def getInitParameter(name: String): String = name match {
- case "base-path" => Directory.RepositoryHome
- case "export-all" => "true"
- case name => config.getInitParameter(name)
- }
- def getInitParameterNames(): java.util.Enumeration[String] = {
- config.getInitParameterNames
- }
-
- def getServletContext(): ServletContext = config.getServletContext
- def getServletName(): String = config.getServletName
- });
- }
-
-}
diff --git a/src/main/scala/util/TransactionFilter.scala b/src/main/scala/util/TransactionFilter.scala
deleted file mode 100644
index 499a62f..0000000
--- a/src/main/scala/util/TransactionFilter.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-package util
-
-import javax.servlet._
-import org.slf4j.LoggerFactory
-import javax.servlet.http.HttpServletRequest
-
-/**
- * Controls the transaction with the open session in view pattern.
- */
-class TransactionFilter extends Filter {
-
- private val logger = LoggerFactory.getLogger(classOf[TransactionFilter])
-
- def init(config: FilterConfig) = {}
-
- def destroy(): Unit = {}
-
- def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = {
- if(req.asInstanceOf[HttpServletRequest].getRequestURI().startsWith("/assets/")){
- // assets don't need transaction
- chain.doFilter(req, res)
- } else {
- // TODO begin transaction!
- logger.debug("TODO begin transaction")
- chain.doFilter(req, res)
- logger.debug("TODO end transaction")
- }
- }
-
-}
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index cb33996..a051a67 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -13,7 +13,7 @@
GitRepositoryServlet
- util.GitRepositoryServlet
+ servlet.GitRepositoryServlet
@@ -23,7 +23,7 @@
TransactionFilter
- util.TransactionFilter
+ servlet.TransactionFilter
@@ -33,7 +33,7 @@
BasicAuthenticationFilter
- util.BasicAuthenticationFilter
+ servlet.BasicAuthenticationFilter
@@ -45,7 +45,7 @@
- util.AutoUpdateListener
+ servlet.AutoUpdateListener