Was replaced by FastIgnoreRule in 3.6 Change-Id: Ia9c3d1231a5d97f3f5bddc81113954c9f9d8ee1e Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v4.0.0.201505191015-rc1
/** | /** | ||||
* Tests git attributes pattern matches | * Tests git attributes pattern matches | ||||
* <p> | |||||
* Inspired by {@link org.eclipse.jgit.ignore.IgnoreMatcherTest} | |||||
* </p> | |||||
*/ | */ | ||||
public class AttributesMatcherTest { | public class AttributesMatcherTest { | ||||
import static org.junit.Assert.assertFalse; | import static org.junit.Assert.assertFalse; | ||||
import static org.junit.Assert.assertTrue; | import static org.junit.Assert.assertTrue; | ||||
import static org.junit.Assert.fail; | import static org.junit.Assert.fail; | ||||
import static org.junit.Assume.assumeFalse; | |||||
import static org.junit.Assume.assumeTrue; | |||||
import java.util.Arrays; | |||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.junit.runner.RunWith; | |||||
import org.junit.runners.Parameterized; | |||||
import org.junit.runners.Parameterized.Parameter; | |||||
import org.junit.runners.Parameterized.Parameters; | |||||
@SuppressWarnings("deprecation") | |||||
@RunWith(Parameterized.class) | |||||
public class FastIgnoreRuleTest { | public class FastIgnoreRuleTest { | ||||
@Parameters(name = "OldRule? {0}") | |||||
public static Iterable<Boolean[]> data() { | |||||
return Arrays.asList(new Boolean[][] { { Boolean.FALSE }, | |||||
{ Boolean.TRUE } }); | |||||
} | |||||
@Parameter | |||||
public Boolean useOldRule; | |||||
@Test | @Test | ||||
public void testSimpleCharClass() { | public void testSimpleCharClass() { | ||||
assertMatched("[a]", "a"); | assertMatched("[a]", "a"); | ||||
assertNotMatched("a/b/", "c/a/b/c"); | assertNotMatched("a/b/", "c/a/b/c"); | ||||
} | } | ||||
@SuppressWarnings("boxing") | |||||
@Test | @Test | ||||
public void testWildmatch() { | public void testWildmatch() { | ||||
if (useOldRule) | |||||
System.err | |||||
.println("IgnoreRule can't understand wildmatch rules, skipping testWildmatch!"); | |||||
Boolean assume = useOldRule; | |||||
assertMatched("**/a/b", "a/b", assume); | |||||
assertMatched("**/a/b", "c/a/b", assume); | |||||
assertMatched("**/a/b", "c/d/a/b", assume); | |||||
assertMatched("**/**/a/b", "c/d/a/b", assume); | |||||
assertMatched("/**/a/b", "a/b", assume); | |||||
assertMatched("/**/a/b", "c/a/b", assume); | |||||
assertMatched("/**/a/b", "c/d/a/b", assume); | |||||
assertMatched("/**/**/a/b", "c/d/a/b", assume); | |||||
assertMatched("a/b/**", "a/b", assume); | |||||
assertMatched("a/b/**", "a/b/c", assume); | |||||
assertMatched("a/b/**", "a/b/c/d/", assume); | |||||
assertMatched("a/b/**/**", "a/b/c/d", assume); | |||||
assertMatched("**/a/**/b", "c/d/a/b", assume); | |||||
assertMatched("**/a/**/b", "c/d/a/e/b", assume); | |||||
assertMatched("**/**/a/**/**/b", "c/d/a/e/b", assume); | |||||
assertMatched("/**/a/**/b", "c/d/a/b", assume); | |||||
assertMatched("/**/a/**/b", "c/d/a/e/b", assume); | |||||
assertMatched("/**/**/a/**/**/b", "c/d/a/e/b", assume); | |||||
assertMatched("a/**/b", "a/b", assume); | |||||
assertMatched("a/**/b", "a/c/b", assume); | |||||
assertMatched("a/**/b", "a/c/d/b", assume); | |||||
assertMatched("a/**/**/b", "a/c/d/b", assume); | |||||
assertMatched("a/**/b/**/c", "a/c/b/d/c", assume); | |||||
assertMatched("a/**/**/b/**/**/c", "a/c/b/d/c", assume); | |||||
assertMatched("**/a/b", "a/b"); | |||||
assertMatched("**/a/b", "c/a/b"); | |||||
assertMatched("**/a/b", "c/d/a/b"); | |||||
assertMatched("**/**/a/b", "c/d/a/b"); | |||||
assertMatched("/**/a/b", "a/b"); | |||||
assertMatched("/**/a/b", "c/a/b"); | |||||
assertMatched("/**/a/b", "c/d/a/b"); | |||||
assertMatched("/**/**/a/b", "c/d/a/b"); | |||||
assertMatched("a/b/**", "a/b"); | |||||
assertMatched("a/b/**", "a/b/c"); | |||||
assertMatched("a/b/**", "a/b/c/d/"); | |||||
assertMatched("a/b/**/**", "a/b/c/d"); | |||||
assertMatched("**/a/**/b", "c/d/a/b"); | |||||
assertMatched("**/a/**/b", "c/d/a/e/b"); | |||||
assertMatched("**/**/a/**/**/b", "c/d/a/e/b"); | |||||
assertMatched("/**/a/**/b", "c/d/a/b"); | |||||
assertMatched("/**/a/**/b", "c/d/a/e/b"); | |||||
assertMatched("/**/**/a/**/**/b", "c/d/a/e/b"); | |||||
assertMatched("a/**/b", "a/b"); | |||||
assertMatched("a/**/b", "a/c/b"); | |||||
assertMatched("a/**/b", "a/c/d/b"); | |||||
assertMatched("a/**/**/b", "a/c/d/b"); | |||||
assertMatched("a/**/b/**/c", "a/c/b/d/c"); | |||||
assertMatched("a/**/**/b/**/**/c", "a/c/b/d/c"); | |||||
} | } | ||||
@SuppressWarnings("boxing") | |||||
@Test | @Test | ||||
public void testWildmatchDoNotMatch() { | public void testWildmatchDoNotMatch() { | ||||
if (useOldRule) | |||||
System.err | |||||
.println("IgnoreRule can't understand wildmatch rules, skipping testWildmatchDoNotMatch!"); | |||||
Boolean assume = useOldRule; | |||||
assertNotMatched("**/a/b", "a/c/b", assume); | |||||
assertNotMatched("!/**/*.zip", "c/a/b.zip", assume); | |||||
assertNotMatched("!**/*.zip", "c/a/b.zip", assume); | |||||
assertNotMatched("a/**/b", "a/c/bb", assume); | |||||
assertNotMatched("**/a/b", "a/c/b"); | |||||
assertNotMatched("!/**/*.zip", "c/a/b.zip"); | |||||
assertNotMatched("!**/*.zip", "c/a/b.zip"); | |||||
assertNotMatched("a/**/b", "a/c/bb"); | |||||
} | } | ||||
@SuppressWarnings("unused") | @SuppressWarnings("unused") | ||||
split("/a/b/c/", '/').toArray()); | split("/a/b/c/", '/').toArray()); | ||||
} | } | ||||
public void assertMatched(String pattern, String path, Boolean... assume) { | |||||
public void assertMatched(String pattern, String path) { | |||||
boolean match = match(pattern, path); | boolean match = match(pattern, path); | ||||
String result = path + " is " + (match ? "ignored" : "not ignored") | String result = path + " is " + (match ? "ignored" : "not ignored") | ||||
+ " via '" + pattern + "' rule"; | + " via '" + pattern + "' rule"; | ||||
if (!match) | |||||
if (!match) { | |||||
System.err.println(result); | System.err.println(result); | ||||
if (assume.length == 0 || !assume[0].booleanValue()) | |||||
assertTrue("Expected a match for: " + pattern + " with: " + path, | |||||
match); | |||||
else | |||||
assumeTrue("Expected a match for: " + pattern + " with: " + path, | |||||
} | |||||
assertTrue("Expected a match for: " + pattern + " with: " + path, | |||||
match); | match); | ||||
if (pattern.startsWith("!")) | |||||
if (pattern.startsWith("!")) { | |||||
pattern = pattern.substring(1); | pattern = pattern.substring(1); | ||||
else | |||||
} else { | |||||
pattern = "!" + pattern; | pattern = "!" + pattern; | ||||
} | |||||
match = match(pattern, path); | match = match(pattern, path); | ||||
if (assume.length == 0 || !assume[0].booleanValue()) | |||||
assertFalse("Expected no match for: " + pattern + " with: " + path, | |||||
match); | |||||
else | |||||
assumeFalse("Expected no match for: " + pattern + " with: " + path, | |||||
match); | |||||
assertFalse("Expected no match for: " + pattern + " with: " + path, | |||||
match); | |||||
} | } | ||||
public void assertNotMatched(String pattern, String path, Boolean... assume) { | |||||
public void assertNotMatched(String pattern, String path) { | |||||
boolean match = match(pattern, path); | boolean match = match(pattern, path); | ||||
String result = path + " is " + (match ? "ignored" : "not ignored") | String result = path + " is " + (match ? "ignored" : "not ignored") | ||||
+ " via '" + pattern + "' rule"; | + " via '" + pattern + "' rule"; | ||||
if (match) | |||||
if (match) { | |||||
System.err.println(result); | System.err.println(result); | ||||
if (assume.length == 0 || !assume[0].booleanValue()) | |||||
assertFalse("Expected no match for: " + pattern + " with: " + path, | |||||
match); | |||||
else | |||||
assumeFalse("Expected no match for: " + pattern + " with: " + path, | |||||
} | |||||
assertFalse("Expected no match for: " + pattern + " with: " + path, | |||||
match); | match); | ||||
if (pattern.startsWith("!")) | |||||
if (pattern.startsWith("!")) { | |||||
pattern = pattern.substring(1); | pattern = pattern.substring(1); | ||||
else | |||||
} else { | |||||
pattern = "!" + pattern; | pattern = "!" + pattern; | ||||
} | |||||
match = match(pattern, path); | match = match(pattern, path); | ||||
if (assume.length == 0 || !assume[0].booleanValue()) | |||||
assertTrue("Expected a match for: " + pattern + " with: " + path, | |||||
match); | |||||
else | |||||
assumeTrue("Expected a match for: " + pattern + " with: " + path, | |||||
assertTrue("Expected a match for: " + pattern + " with: " + path, | |||||
match); | match); | ||||
} | } | ||||
*/ | */ | ||||
private boolean match(String pattern, String target) { | private boolean match(String pattern, String target) { | ||||
boolean isDirectory = target.endsWith("/"); | boolean isDirectory = target.endsWith("/"); | ||||
if (useOldRule.booleanValue()) { | |||||
IgnoreRule r = new IgnoreRule(pattern); | |||||
// If speed of this test is ever an issue, we can use a presetRule | |||||
// field | |||||
// to avoid recompiling a pattern each time. | |||||
boolean match = r.isMatch(target, isDirectory); | |||||
if (r.getNegation()) | |||||
match = !match; | |||||
return match; | |||||
} | |||||
FastIgnoreRule r = new FastIgnoreRule(pattern); | FastIgnoreRule r = new FastIgnoreRule(pattern); | ||||
// If speed of this test is ever an issue, we can use a presetRule field | // If speed of this test is ever an issue, we can use a presetRule field | ||||
// to avoid recompiling a pattern each time. | // to avoid recompiling a pattern each time. |
import static org.junit.Assume.assumeFalse; | import static org.junit.Assume.assumeFalse; | ||||
import static org.junit.Assume.assumeTrue; | import static org.junit.Assume.assumeTrue; | ||||
import java.util.Arrays; | |||||
import org.eclipse.jgit.junit.Assert; | import org.eclipse.jgit.junit.Assert; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.junit.runner.RunWith; | |||||
import org.junit.runners.Parameterized; | |||||
import org.junit.runners.Parameterized.Parameter; | |||||
import org.junit.runners.Parameterized.Parameters; | |||||
/** | /** | ||||
* Tests ignore pattern matches | * Tests ignore pattern matches | ||||
*/ | */ | ||||
@SuppressWarnings("deprecation") | |||||
@RunWith(Parameterized.class) | |||||
public class IgnoreMatcherParametrizedTest { | public class IgnoreMatcherParametrizedTest { | ||||
@Parameters(name = "OldRule? {0}") | |||||
public static Iterable<Boolean[]> data() { | |||||
return Arrays.asList(new Boolean[][] { { Boolean.FALSE }, | |||||
{ Boolean.TRUE } }); | |||||
} | |||||
@Parameter | |||||
public Boolean useOldRule; | |||||
@Test | @Test | ||||
public void testBasic() { | public void testBasic() { | ||||
String pattern = "/test.stp"; | String pattern = "/test.stp"; | ||||
@Test | @Test | ||||
public void testDirModeAndRegex1() { | public void testDirModeAndRegex1() { | ||||
// IgnoreRule was buggy for some cases below, therefore using "Assume" | |||||
Boolean assume = useOldRule; | |||||
String pattern = "a/*/src/"; | String pattern = "a/*/src/"; | ||||
assertMatched(pattern, "a/b/src/"); | assertMatched(pattern, "a/b/src/"); | ||||
assertMatched(pattern, "a/b/src/new"); | assertMatched(pattern, "a/b/src/new"); | ||||
assertMatched(pattern, "a/b/src/new/a.c"); | assertMatched(pattern, "a/b/src/new/a.c"); | ||||
assertMatched(pattern, "a/b/src/a.c"); | assertMatched(pattern, "a/b/src/a.c"); | ||||
// no match as a "file" pattern, because rule is for directories only | // no match as a "file" pattern, because rule is for directories only | ||||
assertNotMatched(pattern, "a/b/src", assume); | |||||
assertNotMatched(pattern, "a/b/src"); | |||||
assertNotMatched(pattern, "a/b/srcA/"); | assertNotMatched(pattern, "a/b/srcA/"); | ||||
} | } | ||||
@Test | @Test | ||||
public void testDirModeAndRegex2() { | public void testDirModeAndRegex2() { | ||||
// IgnoreRule was buggy for some cases below, therefore using "Assume" | |||||
Boolean assume = useOldRule; | |||||
String pattern = "a/[a-b]/src/"; | String pattern = "a/[a-b]/src/"; | ||||
assertMatched(pattern, "a/b/src/"); | assertMatched(pattern, "a/b/src/"); | ||||
assertMatched(pattern, "a/b/src/new"); | assertMatched(pattern, "a/b/src/new"); | ||||
assertMatched(pattern, "a/b/src/new/a.c"); | assertMatched(pattern, "a/b/src/new/a.c"); | ||||
assertMatched(pattern, "a/b/src/a.c"); | assertMatched(pattern, "a/b/src/a.c"); | ||||
// no match as a "file" pattern, because rule is for directories only | // no match as a "file" pattern, because rule is for directories only | ||||
assertNotMatched(pattern, "a/b/src", assume); | |||||
assertNotMatched(pattern, "a/b/src"); | |||||
assertNotMatched(pattern, "a/b/srcA/"); | assertNotMatched(pattern, "a/b/srcA/"); | ||||
} | } | ||||
@Test | @Test | ||||
public void testDirModeAndRegex3() { | public void testDirModeAndRegex3() { | ||||
// IgnoreRule was buggy for some cases below, therefore using "Assume" | |||||
Boolean assume = useOldRule; | |||||
String pattern = "**/src/"; | String pattern = "**/src/"; | ||||
assertMatched(pattern, "a/b/src/", assume); | |||||
assertMatched(pattern, "a/b/src/new", assume); | |||||
assertMatched(pattern, "a/b/src/new/a.c", assume); | |||||
assertMatched(pattern, "a/b/src/a.c", assume); | |||||
assertMatched(pattern, "a/b/src/"); | |||||
assertMatched(pattern, "a/b/src/new"); | |||||
assertMatched(pattern, "a/b/src/new/a.c"); | |||||
assertMatched(pattern, "a/b/src/a.c"); | |||||
// no match as a "file" pattern, because rule is for directories only | // no match as a "file" pattern, because rule is for directories only | ||||
assertNotMatched(pattern, "a/b/src", assume); | |||||
assertNotMatched(pattern, "a/b/srcA/", assume); | |||||
assertNotMatched(pattern, "a/b/src"); | |||||
assertNotMatched(pattern, "a/b/srcA/"); | |||||
} | } | ||||
@Test | @Test | ||||
private boolean match(String pattern, String target) { | private boolean match(String pattern, String target) { | ||||
boolean isDirectory = target.endsWith("/"); | boolean isDirectory = target.endsWith("/"); | ||||
boolean match; | boolean match; | ||||
if (useOldRule.booleanValue()) { | |||||
IgnoreRule r = new IgnoreRule(pattern); | |||||
match = r.isMatch(target, isDirectory); | |||||
} else { | |||||
FastIgnoreRule r = new FastIgnoreRule(pattern); | |||||
match = r.isMatch(target, isDirectory); | |||||
} | |||||
FastIgnoreRule r = new FastIgnoreRule(pattern); | |||||
match = r.isMatch(target, isDirectory); | |||||
if (isDirectory) { | if (isDirectory) { | ||||
boolean noTrailingSlash = matchAsDir(pattern, | boolean noTrailingSlash = matchAsDir(pattern, | ||||
*/ | */ | ||||
private boolean matchAsDir(String pattern, String target) { | private boolean matchAsDir(String pattern, String target) { | ||||
assertFalse(target.endsWith("/")); | assertFalse(target.endsWith("/")); | ||||
if (useOldRule.booleanValue()) { | |||||
IgnoreRule r = new IgnoreRule(pattern); | |||||
return r.isMatch(target, true); | |||||
} | |||||
FastIgnoreRule r = new FastIgnoreRule(pattern); | FastIgnoreRule r = new FastIgnoreRule(pattern); | ||||
return r.isMatch(target, true); | return r.isMatch(target, true); | ||||
} | } |
/* | |||||
* Copyright (C) 2010, Red Hat Inc. | |||||
* and other copyright owners as documented in the project's IP log. | |||||
* | |||||
* This program and the accompanying materials are made available | |||||
* under the terms of the Eclipse Distribution License v1.0 which | |||||
* accompanies this distribution, is reproduced below, and is | |||||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or | |||||
* without modification, are permitted provided that the following | |||||
* conditions are met: | |||||
* | |||||
* - Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* | |||||
* - Redistributions in binary form must reproduce the above | |||||
* copyright notice, this list of conditions and the following | |||||
* disclaimer in the documentation and/or other materials provided | |||||
* with the distribution. | |||||
* | |||||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||||
* names of its contributors may be used to endorse or promote | |||||
* products derived from this software without specific prior | |||||
* written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
package org.eclipse.jgit.ignore; | |||||
import static org.junit.Assert.assertEquals; | |||||
import static org.junit.Assert.assertFalse; | |||||
import static org.junit.Assert.assertTrue; | |||||
import org.junit.Test; | |||||
/** | |||||
* Tests ignore pattern matches | |||||
*/ | |||||
@SuppressWarnings("deprecation") | |||||
public class IgnoreMatcherTest { | |||||
@Test | |||||
public void testBasic() { | |||||
String pattern = "/test.stp"; | |||||
assertMatched(pattern, "/test.stp"); | |||||
pattern = "#/test.stp"; | |||||
assertNotMatched(pattern, "/test.stp"); | |||||
} | |||||
@Test | |||||
public void testFileNameWildcards() { | |||||
//Test basic * and ? for any pattern + any character | |||||
String pattern = "*.st?"; | |||||
assertMatched(pattern, "/test.stp"); | |||||
assertMatched(pattern, "/anothertest.stg"); | |||||
assertMatched(pattern, "/anothertest.st0"); | |||||
assertNotMatched(pattern, "/anothertest.sta1"); | |||||
//Check that asterisk does not expand to "/" | |||||
assertNotMatched(pattern, "/another/test.sta1"); | |||||
//Same as above, with a leading slash to ensure that doesn't cause problems | |||||
pattern = "/*.st?"; | |||||
assertMatched(pattern, "/test.stp"); | |||||
assertMatched(pattern, "/anothertest.stg"); | |||||
assertMatched(pattern, "/anothertest.st0"); | |||||
assertNotMatched(pattern, "/anothertest.sta1"); | |||||
//Check that asterisk does not expand to "/" | |||||
assertNotMatched(pattern, "/another/test.sta1"); | |||||
//Test for numbers | |||||
pattern = "*.sta[0-5]"; | |||||
assertMatched(pattern, "/test.sta5"); | |||||
assertMatched(pattern, "/test.sta4"); | |||||
assertMatched(pattern, "/test.sta3"); | |||||
assertMatched(pattern, "/test.sta2"); | |||||
assertMatched(pattern, "/test.sta1"); | |||||
assertMatched(pattern, "/test.sta0"); | |||||
assertMatched(pattern, "/anothertest.sta2"); | |||||
assertNotMatched(pattern, "test.stag"); | |||||
assertNotMatched(pattern, "test.sta6"); | |||||
//Test for letters | |||||
pattern = "/[tv]est.sta[a-d]"; | |||||
assertMatched(pattern, "/test.staa"); | |||||
assertMatched(pattern, "/test.stab"); | |||||
assertMatched(pattern, "/test.stac"); | |||||
assertMatched(pattern, "/test.stad"); | |||||
assertMatched(pattern, "/vest.stac"); | |||||
assertNotMatched(pattern, "test.stae"); | |||||
assertNotMatched(pattern, "test.sta9"); | |||||
//Test child directory/file is matched | |||||
pattern = "/src/ne?"; | |||||
assertMatched(pattern, "/src/new/"); | |||||
assertMatched(pattern, "/src/new"); | |||||
assertMatched(pattern, "/src/new/a.c"); | |||||
assertMatched(pattern, "/src/new/a/a.c"); | |||||
assertNotMatched(pattern, "/src/new.c"); | |||||
//Test name-only fnmatcher matches | |||||
pattern = "ne?"; | |||||
assertMatched(pattern, "/src/new/"); | |||||
assertMatched(pattern, "/src/new"); | |||||
assertMatched(pattern, "/src/new/a.c"); | |||||
assertMatched(pattern, "/src/new/a/a.c"); | |||||
assertMatched(pattern, "/neb"); | |||||
assertNotMatched(pattern, "/src/new.c"); | |||||
} | |||||
@Test | |||||
public void testTargetWithoutLeadingSlash() { | |||||
//Test basic * and ? for any pattern + any character | |||||
String pattern = "/*.st?"; | |||||
assertMatched(pattern, "test.stp"); | |||||
assertMatched(pattern, "anothertest.stg"); | |||||
assertMatched(pattern, "anothertest.st0"); | |||||
assertNotMatched(pattern, "anothertest.sta1"); | |||||
//Check that asterisk does not expand to "" | |||||
assertNotMatched(pattern, "another/test.sta1"); | |||||
//Same as above, with a leading slash to ensure that doesn't cause problems | |||||
pattern = "/*.st?"; | |||||
assertMatched(pattern, "test.stp"); | |||||
assertMatched(pattern, "anothertest.stg"); | |||||
assertMatched(pattern, "anothertest.st0"); | |||||
assertNotMatched(pattern, "anothertest.sta1"); | |||||
//Check that asterisk does not expand to "" | |||||
assertNotMatched(pattern, "another/test.sta1"); | |||||
//Test for numbers | |||||
pattern = "/*.sta[0-5]"; | |||||
assertMatched(pattern, "test.sta5"); | |||||
assertMatched(pattern, "test.sta4"); | |||||
assertMatched(pattern, "test.sta3"); | |||||
assertMatched(pattern, "test.sta2"); | |||||
assertMatched(pattern, "test.sta1"); | |||||
assertMatched(pattern, "test.sta0"); | |||||
assertMatched(pattern, "anothertest.sta2"); | |||||
assertNotMatched(pattern, "test.stag"); | |||||
assertNotMatched(pattern, "test.sta6"); | |||||
//Test for letters | |||||
pattern = "/[tv]est.sta[a-d]"; | |||||
assertMatched(pattern, "test.staa"); | |||||
assertMatched(pattern, "test.stab"); | |||||
assertMatched(pattern, "test.stac"); | |||||
assertMatched(pattern, "test.stad"); | |||||
assertMatched(pattern, "vest.stac"); | |||||
assertNotMatched(pattern, "test.stae"); | |||||
assertNotMatched(pattern, "test.sta9"); | |||||
//Test child directory/file is matched | |||||
pattern = "/src/ne?"; | |||||
assertMatched(pattern, "src/new/"); | |||||
assertMatched(pattern, "src/new"); | |||||
assertMatched(pattern, "src/new/a.c"); | |||||
assertMatched(pattern, "src/new/a/a.c"); | |||||
assertNotMatched(pattern, "src/new.c"); | |||||
//Test name-only fnmatcher matches | |||||
pattern = "ne?"; | |||||
assertMatched(pattern, "src/new/"); | |||||
assertMatched(pattern, "src/new"); | |||||
assertMatched(pattern, "src/new/a.c"); | |||||
assertMatched(pattern, "src/new/a/a.c"); | |||||
assertMatched(pattern, "neb"); | |||||
assertNotMatched(pattern, "src/new.c"); | |||||
} | |||||
@Test | |||||
public void testParentDirectoryGitIgnores() { | |||||
//Contains git ignore patterns such as might be seen in a parent directory | |||||
//Test for wildcards | |||||
String pattern = "/*/*.c"; | |||||
assertMatched(pattern, "/file/a.c"); | |||||
assertMatched(pattern, "/src/a.c"); | |||||
assertNotMatched(pattern, "/src/new/a.c"); | |||||
//Test child directory/file is matched | |||||
pattern = "/src/new"; | |||||
assertMatched(pattern, "/src/new/"); | |||||
assertMatched(pattern, "/src/new"); | |||||
assertMatched(pattern, "/src/new/a.c"); | |||||
assertMatched(pattern, "/src/new/a/a.c"); | |||||
assertNotMatched(pattern, "/src/new.c"); | |||||
//Test child directory is matched, slash after name | |||||
pattern = "/src/new/"; | |||||
assertMatched(pattern, "/src/new/"); | |||||
assertMatched(pattern, "/src/new/a.c"); | |||||
assertMatched(pattern, "/src/new/a/a.c"); | |||||
assertNotMatched(pattern, "/src/new"); | |||||
assertNotMatched(pattern, "/src/new.c"); | |||||
//Test directory is matched by name only | |||||
pattern = "b1"; | |||||
assertMatched(pattern, "/src/new/a/b1/a.c"); | |||||
assertNotMatched(pattern, "/src/new/a/b2/file.c"); | |||||
assertNotMatched(pattern, "/src/new/a/bb1/file.c"); | |||||
assertNotMatched(pattern, "/src/new/a/file.c"); | |||||
} | |||||
@Test | |||||
public void testTrailingSlash() { | |||||
String pattern = "/src/"; | |||||
assertMatched(pattern, "/src/"); | |||||
assertMatched(pattern, "/src/new"); | |||||
assertMatched(pattern, "/src/new/a.c"); | |||||
assertMatched(pattern, "/src/a.c"); | |||||
assertNotMatched(pattern, "/src"); | |||||
assertNotMatched(pattern, "/srcA/"); | |||||
} | |||||
@Test | |||||
public void testNameOnlyMatches() { | |||||
/* | |||||
* Name-only matches do not contain any path separators | |||||
*/ | |||||
//Test matches for file extension | |||||
String pattern = "*.stp"; | |||||
assertMatched(pattern, "/test.stp"); | |||||
assertMatched(pattern, "/src/test.stp"); | |||||
assertNotMatched(pattern, "/test.stp1"); | |||||
assertNotMatched(pattern, "/test.astp"); | |||||
//Test matches for name-only, applies to file name or folder name | |||||
pattern = "src"; | |||||
assertMatched(pattern, "/src"); | |||||
assertMatched(pattern, "/src/"); | |||||
assertMatched(pattern, "/src/a.c"); | |||||
assertMatched(pattern, "/src/new/a.c"); | |||||
assertMatched(pattern, "/new/src/a.c"); | |||||
assertMatched(pattern, "/file/src"); | |||||
//Test matches for name-only, applies only to folder names | |||||
pattern = "src/"; | |||||
assertMatched(pattern, "/src/"); | |||||
assertMatched(pattern, "/src/a.c"); | |||||
assertMatched(pattern, "/src/new/a.c"); | |||||
assertMatched(pattern, "/new/src/a.c"); | |||||
assertNotMatched(pattern, "/src"); | |||||
assertNotMatched(pattern, "/file/src"); | |||||
//Test matches for name-only, applies to file name or folder name | |||||
//With a small wildcard | |||||
pattern = "?rc"; | |||||
assertMatched(pattern, "/src/a.c"); | |||||
assertMatched(pattern, "/src/new/a.c"); | |||||
assertMatched(pattern, "/new/src/a.c"); | |||||
assertMatched(pattern, "/file/src"); | |||||
assertMatched(pattern, "/src/"); | |||||
//Test matches for name-only, applies to file name or folder name | |||||
//With a small wildcard | |||||
pattern = "?r[a-c]"; | |||||
assertMatched(pattern, "/src/a.c"); | |||||
assertMatched(pattern, "/src/new/a.c"); | |||||
assertMatched(pattern, "/new/src/a.c"); | |||||
assertMatched(pattern, "/file/src"); | |||||
assertMatched(pattern, "/src/"); | |||||
assertMatched(pattern, "/srb/a.c"); | |||||
assertMatched(pattern, "/grb/new/a.c"); | |||||
assertMatched(pattern, "/new/crb/a.c"); | |||||
assertMatched(pattern, "/file/3rb"); | |||||
assertMatched(pattern, "/xrb/"); | |||||
assertMatched(pattern, "/3ra/a.c"); | |||||
assertMatched(pattern, "/5ra/new/a.c"); | |||||
assertMatched(pattern, "/new/1ra/a.c"); | |||||
assertMatched(pattern, "/file/dra"); | |||||
assertMatched(pattern, "/era/"); | |||||
assertNotMatched(pattern, "/crg"); | |||||
assertNotMatched(pattern, "/cr3"); | |||||
} | |||||
@Test | |||||
public void testNegation() { | |||||
String pattern = "!/test.stp"; | |||||
assertMatched(pattern, "/test.stp"); | |||||
} | |||||
@Test | |||||
public void testGetters() { | |||||
IgnoreRule r = new IgnoreRule("/pattern/"); | |||||
assertFalse(r.getNameOnly()); | |||||
assertTrue(r.dirOnly()); | |||||
assertFalse(r.getNegation()); | |||||
assertEquals(r.getPattern(), "/pattern"); | |||||
r = new IgnoreRule("/patter?/"); | |||||
assertFalse(r.getNameOnly()); | |||||
assertTrue(r.dirOnly()); | |||||
assertFalse(r.getNegation()); | |||||
assertEquals(r.getPattern(), "/patter?"); | |||||
r = new IgnoreRule("patt*"); | |||||
assertTrue(r.getNameOnly()); | |||||
assertFalse(r.dirOnly()); | |||||
assertFalse(r.getNegation()); | |||||
assertEquals(r.getPattern(), "patt*"); | |||||
r = new IgnoreRule("pattern"); | |||||
assertTrue(r.getNameOnly()); | |||||
assertFalse(r.dirOnly()); | |||||
assertFalse(r.getNegation()); | |||||
assertEquals(r.getPattern(), "pattern"); | |||||
r = new IgnoreRule("!pattern"); | |||||
assertTrue(r.getNameOnly()); | |||||
assertFalse(r.dirOnly()); | |||||
assertTrue(r.getNegation()); | |||||
assertEquals(r.getPattern(), "pattern"); | |||||
r = new IgnoreRule("!/pattern"); | |||||
assertFalse(r.getNameOnly()); | |||||
assertFalse(r.dirOnly()); | |||||
assertTrue(r.getNegation()); | |||||
assertEquals(r.getPattern(), "/pattern"); | |||||
r = new IgnoreRule("!/patter?"); | |||||
assertFalse(r.getNameOnly()); | |||||
assertFalse(r.dirOnly()); | |||||
assertTrue(r.getNegation()); | |||||
assertEquals(r.getPattern(), "/patter?"); | |||||
} | |||||
@Test | |||||
public void testResetState() { | |||||
String pattern = "/build/*"; | |||||
String target = "/build"; | |||||
// Don't use the assert methods of this class, as we want to test | |||||
// whether the state in IgnoreRule is reset properly | |||||
IgnoreRule r = new IgnoreRule(pattern); | |||||
// Result should be the same for the same inputs | |||||
assertFalse(r.isMatch(target, true)); | |||||
assertFalse(r.isMatch(target, true)); | |||||
} | |||||
/** | |||||
* Check for a match. If target ends with "/", match will assume that the | |||||
* target is meant to be a directory. | |||||
* @param pattern | |||||
* Pattern as it would appear in a .gitignore file | |||||
* @param target | |||||
* Target file path relative to repository's GIT_DIR | |||||
*/ | |||||
public void assertMatched(String pattern, String target) { | |||||
boolean value = match(pattern, target); | |||||
assertTrue("Expected a match for: " + pattern + " with: " + target, | |||||
value); | |||||
} | |||||
/** | |||||
* Check for a match. If target ends with "/", match will assume that the | |||||
* target is meant to be a directory. | |||||
* @param pattern | |||||
* Pattern as it would appear in a .gitignore file | |||||
* @param target | |||||
* Target file path relative to repository's GIT_DIR | |||||
*/ | |||||
public void assertNotMatched(String pattern, String target) { | |||||
boolean value = match(pattern, target); | |||||
assertFalse("Expected no match for: " + pattern + " with: " + target, | |||||
value); | |||||
} | |||||
/** | |||||
* Check for a match. If target ends with "/", match will assume that the | |||||
* target is meant to be a directory. | |||||
* | |||||
* @param pattern | |||||
* Pattern as it would appear in a .gitignore file | |||||
* @param target | |||||
* Target file path relative to repository's GIT_DIR | |||||
* @return Result of IgnoreRule.isMatch(String, boolean) | |||||
*/ | |||||
private static boolean match(String pattern, String target) { | |||||
IgnoreRule r = new IgnoreRule(pattern); | |||||
//If speed of this test is ever an issue, we can use a presetRule field | |||||
//to avoid recompiling a pattern each time. | |||||
return r.isMatch(target, target.endsWith("/")); | |||||
} | |||||
} |
import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||
import static org.junit.Assume.assumeTrue; | import static org.junit.Assume.assumeTrue; | ||||
import java.util.Arrays; | |||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.junit.runner.RunWith; | |||||
import org.junit.runners.Parameterized; | |||||
import org.junit.runners.Parameterized.Parameter; | |||||
import org.junit.runners.Parameterized.Parameters; | |||||
@RunWith(Parameterized.class) | |||||
@SuppressWarnings({ "deprecation", "boxing" }) | |||||
@SuppressWarnings({ "boxing" }) | |||||
public class IgnoreRuleSpecialCasesTest { | public class IgnoreRuleSpecialCasesTest { | ||||
@Parameters(name = "OldRule? {0}") | |||||
public static Iterable<Boolean[]> data() { | |||||
return Arrays.asList(new Boolean[][] { { Boolean.FALSE }, | |||||
{ Boolean.TRUE } }); | |||||
} | |||||
@Parameter | |||||
public Boolean useOldRule; | |||||
private void assertMatch(final String pattern, final String input, | private void assertMatch(final String pattern, final String input, | ||||
final boolean matchExpected, Boolean... assume) { | final boolean matchExpected, Boolean... assume) { | ||||
boolean assumeDir = input.endsWith("/"); | boolean assumeDir = input.endsWith("/"); | ||||
if (useOldRule.booleanValue()) { | |||||
final IgnoreRule matcher = new IgnoreRule(pattern); | |||||
if (assume.length == 0 || !assume[0].booleanValue()) | |||||
assertEquals(matchExpected, matcher.isMatch(input, assumeDir)); | |||||
else | |||||
assumeTrue(matchExpected == matcher.isMatch(input, assumeDir)); | |||||
FastIgnoreRule matcher = new FastIgnoreRule(pattern); | |||||
if (assume.length == 0 || !assume[0].booleanValue()) { | |||||
assertEquals(matchExpected, matcher.isMatch(input, assumeDir)); | |||||
} else { | } else { | ||||
FastIgnoreRule matcher = new FastIgnoreRule(pattern); | |||||
if (assume.length == 0 || !assume[0].booleanValue()) | |||||
assertEquals(matchExpected, matcher.isMatch(input, assumeDir)); | |||||
else | |||||
assumeTrue(matchExpected == matcher.isMatch(input, assumeDir)); | |||||
assumeTrue(matchExpected == matcher.isMatch(input, assumeDir)); | |||||
} | } | ||||
} | } | ||||
private void assertFileNameMatch(final String pattern, final String input, | private void assertFileNameMatch(final String pattern, final String input, | ||||
final boolean matchExpected) { | final boolean matchExpected) { | ||||
boolean assumeDir = input.endsWith("/"); | boolean assumeDir = input.endsWith("/"); | ||||
if (useOldRule.booleanValue()) { | |||||
final IgnoreRule matcher = new IgnoreRule(pattern); | |||||
assertEquals(matchExpected, matcher.isMatch(input, assumeDir)); | |||||
} else { | |||||
FastIgnoreRule matcher = new FastIgnoreRule(pattern); | |||||
assertEquals(matchExpected, matcher.isMatch(input, assumeDir)); | |||||
} | |||||
FastIgnoreRule matcher = new FastIgnoreRule(pattern); | |||||
assertEquals(matchExpected, matcher.isMatch(input, assumeDir)); | |||||
} | } | ||||
@Test | @Test | ||||
public void testVerySimplePatternCase0() throws Exception { | public void testVerySimplePatternCase0() throws Exception { | ||||
if (useOldRule) | |||||
System.err | |||||
.println("IgnoreRule can't understand blank lines, skipping"); | |||||
Boolean assume = useOldRule; | |||||
assertMatch("", "", false, assume); | |||||
assertMatch("", "", false); | |||||
} | } | ||||
@Test | @Test | ||||
@Test | @Test | ||||
public void testSpecialGroupCase10() throws Exception { | public void testSpecialGroupCase10() throws Exception { | ||||
if (useOldRule) | |||||
System.err.println("IgnoreRule can't understand [[:], skipping"); | |||||
Boolean assume = useOldRule; | |||||
// Second bracket is threated literally, so both [ and : should match | // Second bracket is threated literally, so both [ and : should match | ||||
assertMatch("[[:]", ":", true, assume); | |||||
assertMatch("[[:]", "[", true, assume); | |||||
assertMatch("[[:]", ":", true); | |||||
assertMatch("[[:]", "[", true); | |||||
} | } | ||||
@Test | @Test | ||||
@Test | @Test | ||||
public void testEscapedBackslash() throws Exception { | public void testEscapedBackslash() throws Exception { | ||||
if (useOldRule) | |||||
System.err | |||||
.println("IgnoreRule can't understand escaped backslashes, skipping"); | |||||
Boolean assume = useOldRule; | |||||
// In Git CLI a\\b matches a\b file | // In Git CLI a\\b matches a\b file | ||||
assertMatch("a\\\\b", "a\\b", true, assume); | |||||
assertMatch("a\\\\b", "a\\b", true); | |||||
} | } | ||||
@Test | @Test |
/* | |||||
* Copyright (C) 2010, Red Hat Inc. | |||||
* and other copyright owners as documented in the project's IP log. | |||||
* | |||||
* This program and the accompanying materials are made available | |||||
* under the terms of the Eclipse Distribution License v1.0 which | |||||
* accompanies this distribution, is reproduced below, and is | |||||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or | |||||
* without modification, are permitted provided that the following | |||||
* conditions are met: | |||||
* | |||||
* - Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* | |||||
* - Redistributions in binary form must reproduce the above | |||||
* copyright notice, this list of conditions and the following | |||||
* disclaimer in the documentation and/or other materials provided | |||||
* with the distribution. | |||||
* | |||||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||||
* names of its contributors may be used to endorse or promote | |||||
* products derived from this software without specific prior | |||||
* written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
package org.eclipse.jgit.ignore; | |||||
import org.eclipse.jgit.errors.InvalidPatternException; | |||||
import org.eclipse.jgit.fnmatch.FileNameMatcher; | |||||
/** | |||||
* A single ignore rule corresponding to one line in a .gitignore or ignore | |||||
* file. Parses the ignore pattern | |||||
* | |||||
* Inspiration from: Ferry Huberts | |||||
* | |||||
* @deprecated this rule does not support double star pattern and is slow | |||||
* parsing glob expressions. Consider to use {@link FastIgnoreRule} | |||||
* instead. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=440732 | |||||
*/ | |||||
@Deprecated | |||||
public class IgnoreRule { | |||||
private String pattern; | |||||
private boolean negation; | |||||
private boolean nameOnly; | |||||
private boolean dirOnly; | |||||
private FileNameMatcher matcher; | |||||
/** | |||||
* Create a new ignore rule with the given pattern. Assumes that | |||||
* the pattern is already trimmed. | |||||
* | |||||
* @param pattern | |||||
* Base pattern for the ignore rule. This pattern will | |||||
* be parsed to generate rule parameters. | |||||
*/ | |||||
public IgnoreRule (String pattern) { | |||||
this.pattern = pattern; | |||||
negation = false; | |||||
nameOnly = false; | |||||
dirOnly = false; | |||||
matcher = null; | |||||
setup(); | |||||
} | |||||
/** | |||||
* Remove leading/trailing characters as needed. Set up | |||||
* rule variables for later matching. | |||||
*/ | |||||
private void setup() { | |||||
int startIndex = 0; | |||||
int endIndex = pattern.length(); | |||||
if (pattern.startsWith("!")) { //$NON-NLS-1$ | |||||
startIndex++; | |||||
negation = true; | |||||
} | |||||
if (pattern.endsWith("/")) { //$NON-NLS-1$ | |||||
endIndex --; | |||||
dirOnly = true; | |||||
} | |||||
pattern = pattern.substring(startIndex, endIndex); | |||||
boolean hasSlash = pattern.contains("/"); //$NON-NLS-1$ | |||||
if (!hasSlash) | |||||
nameOnly = true; | |||||
else if (!pattern.startsWith("/")) { //$NON-NLS-1$ | |||||
//Contains "/" but does not start with one | |||||
//Adding / to the start should not interfere with matching | |||||
pattern = "/" + pattern; //$NON-NLS-1$ | |||||
} | |||||
if (pattern.contains("*") || pattern.contains("?") || pattern.contains("[")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |||||
try { | |||||
matcher = new FileNameMatcher(pattern, Character.valueOf('/')); | |||||
} catch (InvalidPatternException e) { | |||||
// Ignore pattern exceptions | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* @return | |||||
* True if the pattern is just a file name and not a path | |||||
*/ | |||||
public boolean getNameOnly() { | |||||
return nameOnly; | |||||
} | |||||
/** | |||||
* | |||||
* @return | |||||
* True if the pattern should match directories only | |||||
*/ | |||||
public boolean dirOnly() { | |||||
return dirOnly; | |||||
} | |||||
/** | |||||
* | |||||
* @return | |||||
* True if the pattern had a "!" in front of it | |||||
*/ | |||||
public boolean getNegation() { | |||||
return negation; | |||||
} | |||||
/** | |||||
* @return | |||||
* The blob pattern to be used as a matcher | |||||
*/ | |||||
public String getPattern() { | |||||
return pattern; | |||||
} | |||||
/** | |||||
* Returns true if a match was made. | |||||
* <br> | |||||
* This function does NOT return the actual ignore status of the | |||||
* target! Please consult {@link #getResult()} for the ignore status. The actual | |||||
* ignore status may be true or false depending on whether this rule is | |||||
* an ignore rule or a negation rule. | |||||
* | |||||
* @param target | |||||
* Name pattern of the file, relative to the base directory of this rule | |||||
* @param isDirectory | |||||
* Whether the target file is a directory or not | |||||
* @return | |||||
* True if a match was made. This does not necessarily mean that | |||||
* the target is ignored. Call {@link IgnoreRule#getResult() getResult()} for the result. | |||||
*/ | |||||
public boolean isMatch(String target, boolean isDirectory) { | |||||
if (!target.startsWith("/")) //$NON-NLS-1$ | |||||
target = "/" + target; //$NON-NLS-1$ | |||||
if (matcher == null) { | |||||
if (target.equals(pattern)) { | |||||
//Exact match | |||||
if (dirOnly && !isDirectory) | |||||
//Directory expectations not met | |||||
return false; | |||||
else | |||||
//Directory expectations met | |||||
return true; | |||||
} | |||||
/* | |||||
* Add slashes for startsWith check. This avoids matching e.g. | |||||
* "/src/new" to /src/newfile" but allows "/src/new" to match | |||||
* "/src/new/newfile", as is the git standard | |||||
*/ | |||||
if ((target).startsWith(pattern + "/")) //$NON-NLS-1$ | |||||
return true; | |||||
if (nameOnly) { | |||||
//Iterate through each sub-name | |||||
final String[] segments = target.split("/"); //$NON-NLS-1$ | |||||
for (int idx = 0; idx < segments.length; idx++) { | |||||
final String segmentName = segments[idx]; | |||||
// String.split("/") creates empty segment for leading slash | |||||
if (segmentName.length() == 0) | |||||
continue; | |||||
if (segmentName.equals(pattern) && | |||||
doesMatchDirectoryExpectations(isDirectory, idx, segments.length)) | |||||
return true; | |||||
} | |||||
} | |||||
} else { | |||||
matcher.reset(); | |||||
matcher.append(target); | |||||
if (matcher.isMatch()) | |||||
return true; | |||||
final String[] segments = target.split("/"); //$NON-NLS-1$ | |||||
if (nameOnly) { | |||||
for (int idx = 0; idx < segments.length; idx++) { | |||||
final String segmentName = segments[idx]; | |||||
// String.split("/") creates empty segment for leading slash | |||||
if (segmentName.length() == 0) | |||||
continue; | |||||
//Iterate through each sub-directory | |||||
matcher.reset(); | |||||
matcher.append(segmentName); | |||||
if (matcher.isMatch() && | |||||
doesMatchDirectoryExpectations(isDirectory, idx, segments.length)) | |||||
return true; | |||||
} | |||||
} else { | |||||
//TODO: This is the slowest operation | |||||
//This matches e.g. "/src/ne?" to "/src/new/file.c" | |||||
matcher.reset(); | |||||
for (int idx = 0; idx < segments.length; idx++) { | |||||
final String segmentName = segments[idx]; | |||||
// String.split("/") creates empty segment for leading slash | |||||
if (segmentName.length() == 0) | |||||
continue; | |||||
matcher.append("/" + segmentName); //$NON-NLS-1$ | |||||
if (matcher.isMatch() | |||||
&& doesMatchDirectoryExpectations(isDirectory, idx, | |||||
segments.length)) | |||||
return true; | |||||
} | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* If a call to <code>isMatch(String, boolean)</code> was previously | |||||
* made, this will return whether or not the target was ignored. Otherwise | |||||
* this just indicates whether the rule is non-negation or negation. | |||||
* | |||||
* @return | |||||
* True if the target is to be ignored, false otherwise. | |||||
*/ | |||||
public boolean getResult() { | |||||
return !negation; | |||||
} | |||||
private boolean doesMatchDirectoryExpectations(boolean isDirectory, int segmentIdx, int segmentLength) { | |||||
// The segment we are checking is a directory, expectations are met. | |||||
if (segmentIdx < segmentLength - 1) { | |||||
return true; | |||||
} | |||||
// We are checking the last part of the segment for which isDirectory has to be considered. | |||||
return !dirOnly || isDirectory; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return pattern; | |||||
} | |||||
} |