diff --git a/src/main/scala/app/RepositoryViewerController.scala b/src/main/scala/app/RepositoryViewerController.scala index 886a772..e753bc0 100644 --- a/src/main/scala/app/RepositoryViewerController.scala +++ b/src/main/scala/app/RepositoryViewerController.scala @@ -124,12 +124,14 @@ val branchName = params("branch") val page = params.getOrElse("page", "1").toInt - val (logs, hasNext) = JGitUtil.getCommitLog(Git.open(getRepositoryDir(owner, repository)), branchName, page, 30) + JGitUtil.withGit(getRepositoryDir(owner, repository)){ git => + val (logs, hasNext) = JGitUtil.getCommitLog(git, branchName, page, 30) - repo.html.commits(Nil, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext), - logs.splitWith{ (commit1, commit2) => - view.helpers.date(commit1.time) == view.helpers.date(commit2.time) - }, page, hasNext) + repo.html.commits(Nil, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext), + logs.splitWith{ (commit1, commit2) => + view.helpers.date(commit1.time) == view.helpers.date(commit2.time) + }, page, hasNext) + } } /** @@ -142,12 +144,14 @@ val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "") val page = params.getOrElse("page", "1").toInt - val (logs, hasNext) = JGitUtil.getCommitLog(Git.open(getRepositoryDir(owner, repository)), branchName, page, 30, path) + JGitUtil.withGit(getRepositoryDir(owner, repository)){ git => + val (logs, hasNext) = JGitUtil.getCommitLog(git, branchName, page, 30, path) - repo.html.commits(path.split("/").toList, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext), - logs.splitWith{ (commit1, commit2) => - view.helpers.date(commit1.time) == view.helpers.date(commit2.time) - }, page, hasNext) + repo.html.commits(path.split("/").toList, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext), + logs.splitWith{ (commit1, commit2) => + view.helpers.date(commit1.time) == view.helpers.date(commit2.time) + }, page, hasNext) + } } @@ -162,33 +166,34 @@ val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "") val repositoryInfo = JGitUtil.getRepositoryInfo(owner, repository, servletContext) - val git = Git.open(getRepositoryDir(owner, repository)) - val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id)) + JGitUtil.withGit(getRepositoryDir(owner, repository)){ git => + val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id)) - @scala.annotation.tailrec - def getPathObjectId(path: String, walk: TreeWalk): ObjectId = walk.next match { - case true if(walk.getPathString == path) => walk.getObjectId(0) - case true => getPathObjectId(path, walk) - } + @scala.annotation.tailrec + def getPathObjectId(path: String, walk: TreeWalk): ObjectId = walk.next match { + case true if(walk.getPathString == path) => walk.getObjectId(0) + case true => getPathObjectId(path, walk) + } - val treeWalk = new TreeWalk(git.getRepository) - treeWalk.addTree(revCommit.getTree) - treeWalk.setRecursive(true) - val objectId = getPathObjectId(path, treeWalk) - treeWalk.release + val treeWalk = new TreeWalk(git.getRepository) + treeWalk.addTree(revCommit.getTree) + treeWalk.setRecursive(true) + val objectId = getPathObjectId(path, treeWalk) + treeWalk.release - if(raw){ - // Download - contentType = "application/octet-stream" - JGitUtil.getContent(git, objectId, false).get + if(raw){ + // Download + contentType = "application/octet-stream" + JGitUtil.getContent(git, objectId, false).get + } else { + // Viewer + val large = FileTypeUtil.isLarge(git.getRepository.getObjectDatabase.open(objectId).getSize) + val viewer = if(FileTypeUtil.isImage(path)) "image" else if(large) "large" else "text" + val content = ContentInfo(viewer, + if(viewer == "text") JGitUtil.getContent(git, objectId, false).map(new String(_, "UTF-8")) else None) - } else { - // Viewer - val large = FileTypeUtil.isLarge(git.getRepository.getObjectDatabase.open(objectId).getSize) - val viewer = if(FileTypeUtil.isImage(path)) "image" else if(large) "large" else "text" - val content = ContentInfo(viewer, if(viewer == "text") JGitUtil.getContent(git, objectId, false).map(new String(_, "UTF-8")) else None) - - repo.html.blob(id, repositoryInfo, path.split("/").toList, content, new CommitInfo(revCommit)) + repo.html.blob(id, repositoryInfo, path.split("/").toList, content, new CommitInfo(revCommit)) + } } } @@ -200,10 +205,11 @@ val repository = params("repository") val id = params("id") - val git = Git.open(getRepositoryDir(owner, repository)) - val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id)) - - repo.html.commit(id, new CommitInfo(revCommit), JGitUtil.getRepositoryInfo(owner, repository, servletContext), JGitUtil.getDiffs(git, id)) + JGitUtil.withGit(getRepositoryDir(owner, repository)){ git => + val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id)) + repo.html.commit(id, new CommitInfo(revCommit), + JGitUtil.getRepositoryInfo(owner, repository, servletContext), JGitUtil.getDiffs(git, id)) + } } /** @@ -234,14 +240,14 @@ // clone the repository val cloneDir = new File(workDir, revision) - val git = Git.cloneRepository - .setURI(getRepositoryDir(owner, repository).toURI.toString) - .setDirectory(cloneDir) - .call + JGitUtil.withGit(Git.cloneRepository + .setURI(getRepositoryDir(owner, repository).toURI.toString) + .setDirectory(cloneDir) + .call){ git => - // checkout the specified revision - git.checkout.setName(revision).call - git.getRepository.close + // checkout the specified revision + git.checkout.setName(revision).call + } // remove .git FileUtils.deleteDirectory(new File(cloneDir, ".git")) @@ -273,32 +279,32 @@ revstr } - val git = Git.open(getRepositoryDir(owner, repository)) - - // get latest commit - val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision)) + JGitUtil.withGit(getRepositoryDir(owner, repository)){ git => + // get latest commit + val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision)) - val files = JGitUtil.getFileList(git, revision, path) + val files = JGitUtil.getFileList(git, revision, path) - // process README.md - val readme = files.find(_.name == "README.md").map { file => - new String(JGitUtil.getContent(Git.open(getRepositoryDir(owner, repository)), file.id, true).get, "UTF-8") + // process README.md + val readme = files.find(_.name == "README.md").map { file => + new String(JGitUtil.getContent(Git.open(getRepositoryDir(owner, repository)), file.id, true).get, "UTF-8") + } + + repo.html.files( + // current branch + revision, + // repository + JGitUtil.getRepositoryInfo(owner, repository, servletContext), + // current path + if(path == ".") Nil else path.split("/").toList, + // latest commit + new CommitInfo(revCommit), + // file list + files, + // readme + readme + ) } - - repo.html.files( - // current branch - revision, - // repository - JGitUtil.getRepositoryInfo(owner, repository, servletContext), - // current path - if(path == ".") Nil else path.split("/").toList, - // latest commit - new CommitInfo(revCommit), - // file list - files, - // readme - readme - ) } } \ No newline at end of file diff --git a/src/main/scala/app/WikiController.scala b/src/main/scala/app/WikiController.scala index 07b821b..c929ea1 100644 --- a/src/main/scala/app/WikiController.scala +++ b/src/main/scala/app/WikiController.scala @@ -45,11 +45,12 @@ val owner = params("owner") val repository = params("repository") val page = params("page") - val git = Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)) - wiki.html.wikihistory(Some(page), - JGitUtil.getCommitLog(git, "master", path = page + ".md")._1, - JGitUtil.getRepositoryInfo(owner, repository, servletContext)) + JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git => + wiki.html.wikihistory(Some(page), + JGitUtil.getCommitLog(git, "master", path = page + ".md")._1, + JGitUtil.getRepositoryInfo(owner, repository, servletContext)) + } } get("/:owner/:repository/wiki/:page/_compare/:commitId"){ @@ -58,12 +59,11 @@ val page = params("page") val commitId = params("commitId").split("\\.\\.\\.") - println(commitId(0)) - println(commitId(1)) - - wiki.html.wikicompare(Some(page), - WikiUtil.getDiffs(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), commitId(0), commitId(1)), - JGitUtil.getRepositoryInfo(owner, repository, servletContext)) + JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git => + wiki.html.wikicompare(Some(page), + WikiUtil.getDiffs(git, commitId(0), commitId(1)), + JGitUtil.getRepositoryInfo(owner, repository, servletContext)) + } } get("/:owner/:repository/wiki/_compare/:commitId"){ @@ -71,12 +71,11 @@ val repository = params("repository") val commitId = params("commitId").split("\\.\\.\\.") - println(commitId(0)) - println(commitId(1)) - - wiki.html.wikicompare(None, - WikiUtil.getDiffs(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), commitId(0), commitId(1)), - JGitUtil.getRepositoryInfo(owner, repository, servletContext)) + JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git => + wiki.html.wikicompare(None, + WikiUtil.getDiffs(git, commitId(0), commitId(1)), + JGitUtil.getRepositoryInfo(owner, repository, servletContext)) + } } get("/:owner/:repository/wiki/:page/_edit"){ @@ -139,9 +138,11 @@ val owner = params("owner") val repository = params("repository") - wiki.html.wikihistory(None, - JGitUtil.getCommitLog(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), "master")._1, + JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git => + wiki.html.wikihistory(None, + JGitUtil.getCommitLog(git, "master")._1, JGitUtil.getRepositoryInfo(owner, repository, servletContext)) + } } post("/:owner/:repository/wiki/_preview"){ diff --git a/src/main/scala/util/JGitUtil.scala b/src/main/scala/util/JGitUtil.scala index 4e53eec..8dd2b63 100644 --- a/src/main/scala/util/JGitUtil.scala +++ b/src/main/scala/util/JGitUtil.scala @@ -5,22 +5,15 @@ import util.Directory._ import scala.collection.JavaConverters._ import javax.servlet.ServletContext -import org.eclipse.jgit.lib.Ref -import org.eclipse.jgit.lib.ObjectId -import org.eclipse.jgit.errors.MissingObjectException -import org.eclipse.jgit.revwalk.RevCommit -import org.eclipse.jgit.diff.DiffFormatter -import org.eclipse.jgit.treewalk.TreeWalk -import org.eclipse.jgit.revwalk.RevWalk -import org.eclipse.jgit.diff.RawTextComparator -import org.eclipse.jgit.util.io.DisabledOutputStream -import org.eclipse.jgit.lib.Repository -import org.eclipse.jgit.revwalk.RevSort -import org.eclipse.jgit.diff.DiffEntry.ChangeType -import org.eclipse.jgit.lib.FileMode -import org.eclipse.jgit.treewalk.filter.PathFilter -import org.eclipse.jgit.treewalk.CanonicalTreeParser +import org.eclipse.jgit.lib._ +import org.eclipse.jgit.revwalk._ import org.eclipse.jgit.revwalk.filter.RevFilter +import org.eclipse.jgit.treewalk._ +import org.eclipse.jgit.treewalk.filter.PathFilter +import org.eclipse.jgit.diff._ +import org.eclipse.jgit.diff.DiffEntry.ChangeType +import org.eclipse.jgit.util.io.DisabledOutputStream +import org.eclipse.jgit.errors.MissingObjectException /** * Provides complex JGit operations. @@ -28,6 +21,24 @@ object JGitUtil { /** + * Use this method to use the Git object. + * Repository resources are released certainly after processing. + */ + def withGit[T](dir: java.io.File)(f: Git => T): T = withGit(Git.open(dir))(f) + + /** + * Use this method to use the Git object. + * Repository resources are released certainly after processing. + */ + def withGit[T](git: Git)(f: Git => T): T = { + try { + f(git) + } finally { + git.getRepository.close + } + } + + /** * Returns RevCommit from the commit id. * * @param git the Git object @@ -45,19 +56,20 @@ * Returns the repository information. It contains branch names and tag names. */ def getRepositoryInfo(owner: String, repository: String, servletContext: ServletContext): RepositoryInfo = { - val git = Git.open(getRepositoryDir(owner, repository)) - RepositoryInfo( - owner, repository, "http://localhost:8080%s/git/%s/%s.git".format(servletContext.getContextPath, owner, repository), - // branches - git.branchList.call.asScala.map { ref => - ref.getName.replaceFirst("^refs/heads/", "") - }.toList, - // tags - git.tagList.call.asScala.map { ref => - val revCommit = getRevCommitFromId(git, ref.getObjectId) - TagInfo(ref.getName.replaceFirst("^refs/tags/", ""), revCommit.getCommitterIdent.getWhen, revCommit.getName) - }.toList - ) + withGit(getRepositoryDir(owner, repository)){ git => + RepositoryInfo( + owner, repository, "http://localhost:8080%s/git/%s/%s.git".format(servletContext.getContextPath, owner, repository), + // branches + git.branchList.call.asScala.map { ref => + ref.getName.replaceFirst("^refs/heads/", "") + }.toList, + // tags + git.tagList.call.asScala.map { ref => + val revCommit = getRevCommitFromId(git, ref.getObjectId) + TagInfo(ref.getName.replaceFirst("^refs/tags/", ""), revCommit.getCommitterIdent.getWhen, revCommit.getName) + }.toList + ) + } } /** diff --git a/src/main/scala/util/WikiUtil.scala b/src/main/scala/util/WikiUtil.scala index 924bc87..c91fff0 100644 --- a/src/main/scala/util/WikiUtil.scala +++ b/src/main/scala/util/WikiUtil.scala @@ -51,8 +51,12 @@ val dir = getWikiRepositoryDir(owner, repository) if(!dir.exists){ val repo = new RepositoryBuilder().setGitDir(dir).setBare.build - repo.create - savePage(owner, repository, "Home", "Home", "Welcome to the %s wiki!!".format(repository), owner, "Initial Commit") + try { + repo.create + savePage(owner, repository, "Home", "Home", "Welcome to the %s wiki!!".format(repository), owner, "Initial Commit") + } finally { + repo.close + } } } @@ -63,14 +67,15 @@ // TODO create wiki repository in the repository setting changing. createWikiRepository(owner, repository) - val git = Git.open(getWikiRepositoryDir(owner, repository)) - try { - JGitUtil.getFileList(git, "master", ".").find(_.name == pageName + ".md").map { file => - WikiPageInfo(file.name, new String(git.getRepository.open(file.id).getBytes, "UTF-8"), file.committer, file.time) + JGitUtil.withGit(getWikiRepositoryDir(owner, repository)){ git => + try { + JGitUtil.getFileList(git, "master", ".").find(_.name == pageName + ".md").map { file => + WikiPageInfo(file.name, new String(git.getRepository.open(file.id).getBytes, "UTF-8"), file.committer, file.time) + } + } catch { + // TODO no commit, but it should not judge by exception. + case e: NullPointerException => None } - } catch { - // TODO no commit, but it should not judge by exception. - case e: NullPointerException => None } } @@ -99,29 +104,30 @@ } // write as file - val cloned = Git.open(workDir) - val file = new File(workDir, newPageName + ".md") - val added = if(!file.exists || FileUtils.readFileToString(file, "UTF-8") != content){ - FileUtils.writeStringToFile(file, content, "UTF-8") - cloned.add.addFilepattern(file.getName).call - true - } else { - false - } + JGitUtil.withGit(workDir){ git => + val file = new File(workDir, newPageName + ".md") + val added = if(!file.exists || FileUtils.readFileToString(file, "UTF-8") != content){ + FileUtils.writeStringToFile(file, content, "UTF-8") + git.add.addFilepattern(file.getName).call + true + } else { + false + } - // delete file - val deleted = if(currentPageName != "" && currentPageName != newPageName){ - cloned.rm.addFilepattern(currentPageName + ".md").call - true - } else { - false - } + // delete file + val deleted = if(currentPageName != "" && currentPageName != newPageName){ + git.rm.addFilepattern(currentPageName + ".md").call + true + } else { + false + } - // commit and push - if(added || deleted){ - // TODO committer's mail address - cloned.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call - cloned.push.call + // commit and push + if(added || deleted){ + // TODO committer's mail address + git.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call + git.push.call + } } } @@ -142,13 +148,14 @@ // delete file new File(workDir, pageName + ".md").delete - val cloned = Git.open(workDir) - cloned.rm.addFilepattern(pageName + ".md").call + JGitUtil.withGit(workDir){ git => + git.rm.addFilepattern(pageName + ".md").call - // commit and push - // TODO committer's mail address - cloned.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call - cloned.push.call + // commit and push + // TODO committer's mail address + git.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call + git.push.call + } } def getDiffs(git: Git, commitId1: String, commitId2: String): List[DiffInfo] = {