{"thread":{"id":"20546","subject":"[JGIT PATCH] Add PathSuffixFilter class which is TreeFilter.","startedAt":"2009-08-12T01:16:09Z","lastAt":"2009-08-12T01:16:09Z","messageCount":1,"participants":["Grzegorz Kossakowski"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"120346","messageId":"1250039769-1331-1-git-send-email-grek@tuffmail.com","threadId":"20546","inReplyTo":null,"subject":"[JGIT PATCH] Add PathSuffixFilter class which is TreeFilter.","fromName":"Grzegorz Kossakowski","fromEmail":"grek@tuffmail.com","sentAt":"2009-08-12T01:16:09Z","receivedAt":"2009-08-12T01:16:09Z","isPatch":true,"sender":{"key":"grek@tuffmail.com","avatar":"https://gravatar.com/avatar/98a80b7992e9f598c7b24addc73338dbacf94a14e4a14f3fa50c3f00dbee7dd3?d=mp&s=160"},"body":"From: Grzegorz Kossakowski <grek@google.com>\n\nAdded a simple TreeFilter that filters all entries that have path with\ngiven suffix. This filter is always recursive.\n\nSigned-off-by: Grzegorz Kossakowski <grek@google.com>\n---\n .../treewalk/filter/PathSuffixFilterTestCase.java  |  133 ++++++++++++++++++++\n .../src/org/spearce/jgit/treewalk/TreeWalk.java    |   32 +++++\n .../jgit/treewalk/filter/PathSuffixFilter.java     |   97 ++++++++++++++\n 3 files changed, 262 insertions(+), 0 deletions(-)\n create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/treewalk/filter/PathSuffixFilterTestCase.java\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/treewalk/filter/PathSuffixFilter.java\n\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/treewalk/filter/PathSuffixFilterTestCase.java b/org.spearce.jgit.test/tst/org/spearce/jgit/treewalk/filter/PathSuffixFilterTestCase.java\nnew file mode 100644\nindex 0000000..5240ed9\n--- /dev/null\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/treewalk/filter/PathSuffixFilterTestCase.java\n@@ -0,0 +1,133 @@\n+/*\n+ * 2009 Copyright Google, Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.treewalk.filter;\n+\n+import java.io.IOException;\n+import java.util.LinkedList;\n+import java.util.List;\n+\n+import org.spearce.jgit.dircache.DirCache;\n+import org.spearce.jgit.dircache.DirCacheBuilder;\n+import org.spearce.jgit.dircache.DirCacheEntry;\n+import org.spearce.jgit.lib.FileMode;\n+import org.spearce.jgit.lib.ObjectId;\n+import org.spearce.jgit.lib.ObjectWriter;\n+import org.spearce.jgit.lib.RepositoryTestCase;\n+import org.spearce.jgit.treewalk.TreeWalk;\n+\n+public class PathSuffixFilterTestCase extends RepositoryTestCase {\n+\n+\tpublic void testNonRecursiveFiltering() throws IOException {\n+\t\tfinal ObjectWriter ow = new ObjectWriter(db);\n+\t\tfinal ObjectId aSth = ow.writeBlob(\"a.sth\".getBytes());\n+\t\tfinal ObjectId aTxt = ow.writeBlob(\"a.txt\".getBytes());\n+\t\tfinal DirCache dc = DirCache.read(db);\n+\t\tfinal DirCacheBuilder builder = dc.builder();\n+\t\tfinal DirCacheEntry aSthEntry = new DirCacheEntry(\"a.sth\");\n+\t\taSthEntry.setFileMode(FileMode.REGULAR_FILE);\n+\t\taSthEntry.setObjectId(aSth);\n+\t\tfinal DirCacheEntry aTxtEntry = new DirCacheEntry(\"a.txt\");\n+\t\taTxtEntry.setFileMode(FileMode.REGULAR_FILE);\n+\t\taTxtEntry.setObjectId(aTxt);\n+\t\tbuilder.add(aSthEntry);\n+\t\tbuilder.add(aTxtEntry);\n+\t\tbuilder.finish();\n+\t\tfinal ObjectId treeId = dc.writeTree(ow);\n+\n+\n+\t\tfinal TreeWalk tw = new TreeWalk(db);\n+\t\ttw.setFilter(PathSuffixFilter.create(\".txt\"));\n+\t\ttw.addTree(treeId);\n+\n+\t\tList<String> paths = new LinkedList<String>();\n+\t\twhile (tw.next()) {\n+\t\t\tpaths.add(tw.getPathString());\n+\t\t}\n+\n+\t\tList<String> expected =  new LinkedList<String>();\n+\t\texpected.add(\"a.txt\");\n+\n+\t\tassertEquals(expected, paths);\n+\t}\n+\n+\tpublic void testRecursiveFiltering() throws IOException {\n+\t\tfinal ObjectWriter ow = new ObjectWriter(db);\n+\t\tfinal ObjectId aSth = ow.writeBlob(\"a.sth\".getBytes());\n+\t\tfinal ObjectId aTxt = ow.writeBlob(\"a.txt\".getBytes());\n+\t\tfinal ObjectId bSth = ow.writeBlob(\"b.sth\".getBytes());\n+\t\tfinal ObjectId bTxt = ow.writeBlob(\"b.txt\".getBytes());\n+\t\tfinal DirCache dc = DirCache.read(db);\n+\t\tfinal DirCacheBuilder builder = dc.builder();\n+\t\tfinal DirCacheEntry aSthEntry = new DirCacheEntry(\"a.sth\");\n+\t\taSthEntry.setFileMode(FileMode.REGULAR_FILE);\n+\t\taSthEntry.setObjectId(aSth);\n+\t\tfinal DirCacheEntry aTxtEntry = new DirCacheEntry(\"a.txt\");\n+\t\taTxtEntry.setFileMode(FileMode.REGULAR_FILE);\n+\t\taTxtEntry.setObjectId(aTxt);\n+\t\tbuilder.add(aSthEntry);\n+\t\tbuilder.add(aTxtEntry);\n+\t\tfinal DirCacheEntry bSthEntry = new DirCacheEntry(\"sub/b.sth\");\n+\t\tbSthEntry.setFileMode(FileMode.REGULAR_FILE);\n+\t\tbSthEntry.setObjectId(bSth);\n+\t\tfinal DirCacheEntry bTxtEntry = new DirCacheEntry(\"sub/b.txt\");\n+\t\tbTxtEntry.setFileMode(FileMode.REGULAR_FILE);\n+\t\tbTxtEntry.setObjectId(bTxt);\n+\t\tbuilder.add(bSthEntry);\n+\t\tbuilder.add(bTxtEntry);\n+\t\tbuilder.finish();\n+\t\tfinal ObjectId treeId = dc.writeTree(ow);\n+\n+\n+\t\tfinal TreeWalk tw = new TreeWalk(db);\n+\t\ttw.setRecursive(true);\n+\t\ttw.setFilter(PathSuffixFilter.create(\".txt\"));\n+\t\ttw.addTree(treeId);\n+\n+\t\tList<String> paths = new LinkedList<String>();\n+\t\twhile (tw.next()) {\n+\t\t\tpaths.add(tw.getPathString());\n+\t\t}\n+\n+\t\tList<String> expected =  new LinkedList<String>();\n+\t\texpected.add(\"a.txt\");\n+\t\texpected.add(\"sub/b.txt\");\n+\n+\t\tassertEquals(expected, paths);\n+\t}\n+\n+}\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/treewalk/TreeWalk.java b/org.spearce.jgit/src/org/spearce/jgit/treewalk/TreeWalk.java\nindex 5705936..16088b4 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/treewalk/TreeWalk.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/treewalk/TreeWalk.java\n@@ -739,6 +739,38 @@ public int isPathPrefix(final byte[] p, final int pLen) {\n \t}\n \n \t/**\n+\t * Test if the supplied path matches (being suffix of) the current entry's\n+\t * path.\n+\t * <p>\n+\t * This method tests that the supplied path is exactly equal to the current\n+\t * entry, or is relative to one of entry's parent directories. It is faster\n+\t * to use this method then to use {@link #getPathString()} to first create\n+\t * a String object, then test <code>endsWith</code> or some other type of\n+\t * string match function.\n+\t *\n+\t * @param p\n+\t *            path buffer to test.\n+\t * @param pLen\n+\t *            number of bytes from <code>buf</code> to test.\n+\t * @return true if p is suffix of the current path;\n+\t *         false if otherwise\n+\t *\n+\t */\n+\tpublic boolean isPathSuffix(final byte[] p, final int pLen) {\n+\t\tfinal AbstractTreeIterator t = currentHead;\n+\t\tfinal byte[] c = t.path;\n+\t\tfinal int cLen = t.pathLen;\n+\t\tint ci;\n+\n+\t\tfor (ci = 1; ci < cLen && ci < pLen; ci++) {\n+\t\t\tif (c[cLen-ci] != p[pLen-ci])\n+\t\t\t\treturn false;\n+\t\t}\n+\n+\t\treturn true;\n+\t}\n+\n+\t/**\n \t * Get the current subtree depth of this walker.\n \t *\n \t * @return the current subtree depth of this walker.\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/treewalk/filter/PathSuffixFilter.java b/org.spearce.jgit/src/org/spearce/jgit/treewalk/filter/PathSuffixFilter.java\nnew file mode 100644\nindex 0000000..8777e7d\n--- /dev/null\n+++ b/org.spearce.jgit/src/org/spearce/jgit/treewalk/filter/PathSuffixFilter.java\n@@ -0,0 +1,97 @@\n+/*\n+ * 2009 Copyright Google, Inc.\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.jgit.treewalk.filter;\n+\n+import java.io.IOException;\n+\n+import org.spearce.jgit.errors.IncorrectObjectTypeException;\n+import org.spearce.jgit.errors.MissingObjectException;\n+import org.spearce.jgit.lib.Constants;\n+import org.spearce.jgit.treewalk.TreeWalk;\n+\n+/**\n+ * Includes tree entries only if they match the configured path.\n+ */\n+public class PathSuffixFilter extends TreeFilter {\n+\n+\t/**\n+\t * Create a new tree filter for a user supplied path.\n+\t * <p>\n+\t * Path strings use '/' to delimit directories on all platforms.\n+\t *\n+\t * @param path\n+\t *            the path (suffix) to filter on. Must not be the empty string.\n+\t * @return a new filter for the requested path.\n+\t * @throws IllegalArgumentException\n+\t *             the path supplied was the empty string.\n+\t */\n+\tpublic static PathSuffixFilter create(String path) {\n+\t\tif (path.length() == 0)\n+\t\t\tthrow new IllegalArgumentException(\"Empty path not permitted.\");\n+\t\treturn new PathSuffixFilter(path);\n+\t}\n+\n+\tfinal String pathStr;\n+\tfinal byte[] pathRaw;\n+\n+\tprivate PathSuffixFilter(final String s) {\n+\t\tpathStr = s;\n+\t\tpathRaw = Constants.encode(pathStr);\n+\t}\n+\n+\t@Override\n+\tpublic TreeFilter clone() {\n+\t\treturn this;\n+\t}\n+\n+\t@Override\n+\tpublic boolean include(TreeWalk walker) throws MissingObjectException,\n+\t\t\tIncorrectObjectTypeException, IOException {\n+\t\tif (walker.isSubtree())\n+\t\t\treturn true;\n+\t\telse\n+\t\t\treturn walker.isPathSuffix(pathRaw, pathRaw.length);\n+\n+\t}\n+\n+\t@Override\n+\tpublic boolean shouldBeRecursive() {\n+\t\treturn true;\n+\t}\n+\n+}\n-- \n1.6.3.3\n"}]}