diff options
author | Grzegorz Kossakowski <grek@google.com> | 2009-08-13 13:38:28 -0700 |
---|---|---|
committer | Grzegorz Kossakowski <grek@google.com> | 2009-08-13 13:38:28 -0700 |
commit | 028b925e77bf015a37d38d8901a20bbea0fe88e9 (patch) | |
tree | 09e77917e99434cea27a040db71d6ff4eeb18fe1 | |
parent | 72c14879e6720cc6960c7182f4020a4f397fa653 (diff) | |
download | gimd-028b925e77bf015a37d38d8901a20bbea0fe88e9.tar.gz |
Add JGitDatabase implementation of Database trait along with test-cases.
JGitDatabase implements all[T](fileType: FileType[T]): Iterator[File[T]] by
returning an iterator which encapsulates treeWalk to implement next method.
Signed-off-by: Grzegorz Kossakowski <grek@google.com>
3 files changed, 179 insertions, 0 deletions
diff --git a/src/main/scala/com/google/gimd/jgit/JGitDatabase.scala b/src/main/scala/com/google/gimd/jgit/JGitDatabase.scala new file mode 100644 index 0000000..48f8009 --- /dev/null +++ b/src/main/scala/com/google/gimd/jgit/JGitDatabase.scala @@ -0,0 +1,69 @@ +// Copyright (C) 2009 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gimd.jgit + +import file.{FileType, File} +import org.spearce.jgit.lib._ +import org.spearce.jgit.revwalk.{RevCommit, RevWalk} +import org.spearce.jgit.treewalk.filter.{AndTreeFilter, PathFilter, PathSuffixFilter} +import org.spearce.jgit.treewalk.filter.TreeFilter +import org.spearce.jgit.treewalk.TreeWalk + +final class JGitDatabase(val jgitRepository: Repository) extends Database { + + def all[T](fileType: FileType[T]): Iterator[File[T]] = { + val id = jgitRepository.resolve(Constants.HEAD) + val rw = new RevWalk(jgitRepository) + all(fileType, rw.parseCommit(id)) + } + + private def all[T](fileType: FileType[T], commit: RevCommit): Iterator[File[T]] = { + val treeWalk = new TreeWalk(jgitRepository) + treeWalk.reset(commit.getTree) + treeWalk.setRecursive(true) + treeWalk.setFilter(treeFilter(fileType)) + + val fileIterator = new Iterator[File[T]] { + private var doesHasNext = treeWalk.next + def hasNext = doesHasNext + def next = { + if (!hasNext) + throw new NoSuchElementException + val result = + new JGitFile(treeWalk.getPathString, treeWalk.getObjectId(0), fileType, jgitRepository) + doesHasNext = treeWalk.next + result + } + } + fileIterator + } + + private def treeFilter[T](fileType: FileType[T]): TreeFilter = + AndTreeFilter.create( + Array( + RegularFileFilter, + fileType.pathPrefix.map(PathFilter.create(_)).getOrElse(TreeFilter.ALL), + fileType.pathSuffix.map(PathSuffixFilter.create(_)).getOrElse(TreeFilter.ALL) + ) + ) + + private object RegularFileFilter extends TreeFilter { + def shouldBeRecursive = false + def include(treeWalk: TreeWalk) = + treeWalk.isSubtree || FileMode.REGULAR_FILE.equals(treeWalk.getFileMode(0)) + override def clone = this + } + +} diff --git a/src/test/scala/com/google/gimd/jgit/AbstractJGitTestCase.scala b/src/test/scala/com/google/gimd/jgit/AbstractJGitTestCase.scala index e587f40..ab1562f 100644 --- a/src/test/scala/com/google/gimd/jgit/AbstractJGitTestCase.scala +++ b/src/test/scala/com/google/gimd/jgit/AbstractJGitTestCase.scala @@ -42,6 +42,9 @@ class AbstractJGitTestCase { ow.writeBlob(text.getBytes("UTF-8")) } + protected def writeMessage[U](userType: UserType[U], userObject: U): ObjectId = + writeTextContent(userType.toMessageBuffer(userObject).readOnly.toString) + protected def addFiles(files: List[(String, ObjectId)]): ObjectId = { val dc = org.spearce.jgit.dircache.DirCache.newInCore val builder = dc.builder diff --git a/src/test/scala/com/google/gimd/jgit/JGitDatabaseTestCase.scala b/src/test/scala/com/google/gimd/jgit/JGitDatabaseTestCase.scala new file mode 100644 index 0000000..21a3cf2 --- /dev/null +++ b/src/test/scala/com/google/gimd/jgit/JGitDatabaseTestCase.scala @@ -0,0 +1,107 @@ +// Copyright (C) 2009 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gimd.jgit + +import file.{File, FileType} +import org.junit.Test +import org.junit.Assert._ +import org.spearce.jgit.lib.ObjectId + +final class JGitDatabaseTestCase extends AbstractJGitTestCase { + + case class SimpleMessage(name: String, value: Int) + + object SimpleMessageType extends UserType[SimpleMessage] { + def toMessageBuffer(sm: SimpleMessage) = (new MessageBuffer()) ++ + List(Field("name", sm.name), Field("value", sm.value)) + def toUserType(m: Message): SimpleMessage = { + val name = m.one("name").stringField.value + val value = m.one("value").intField.value + SimpleMessage(name, value) + } + } + + object SimpleMessageFileType extends FileType[SimpleMessage] { + val pathPrefix = Some("sm") + val pathSuffix = Some(".sm") + val userType = SimpleMessageType + } + + @Test + def allPaths { + val first = SimpleMessage("first", 1) + val second = SimpleMessage("second", 2) + + val files = List( + ("sm/toBeIgnored", writeTextContent("this is to be ignored")), + ("sm/first.sm", writeMessage(SimpleMessageType, first)), + ("sm/second.sm", writeMessage(SimpleMessageType, second)) + ) + commit(files) + + val db = new JGitDatabase(repository) + + val foundFiles = db.all(SimpleMessageFileType).toList + + val expected = List("sm/first.sm", "sm/second.sm") + assertEquals(expected, foundFiles.map(_.path)) + } + + @Test + def allSimpleMessages { + val first = SimpleMessage("first", 1) + val second = SimpleMessage("second", 2) + + val files = List( + ("sm/toBeIgnored", writeTextContent("this is to be ignored")), + ("sm/first.sm", writeMessage(SimpleMessageType, first)), + ("sm/second.sm", writeMessage(SimpleMessageType, second)) + ) + commit(files) + + val db = new JGitDatabase(repository) + + val foundFiles = db.all(SimpleMessageFileType).toList + + val expected = List(first, second) + assertEquals(expected, foundFiles.map(_.userObject)) + } + + @Test + def allFilterRegularFilesOnly { + val dc = org.spearce.jgit.dircache.DirCache.newInCore + val builder = dc.builder + val entry = new org.spearce.jgit.dircache.DirCacheEntry("sm/exec.sm") + entry.setFileMode(org.spearce.jgit.lib.FileMode.EXECUTABLE_FILE) + entry.setObjectId(writeTextContent("text content")) + builder.add(entry) + builder.finish() + val treeId = dc.writeTree(new org.spearce.jgit.lib.ObjectWriter(repository)) + val commitId = createCommit("Test commit", treeId) + moveHEAD(commitId) + + val db = new JGitDatabase(repository) + + val foundFiles = db.all(SimpleMessageFileType).toList + assertEquals(Nil, foundFiles) + } + + private def commit(files: List[(String, ObjectId)]) { + val treeId = addFiles(files) + val commitId = createCommit("Test", treeId) + moveHEAD(commitId) + } + +} |