PathMatcher: fix handling of **/
**/ should match only directories, but not files Change-Id: I885c83e5912cac5bff338ba657faf6bb9ec94064 Signed-off-by: Marc Strapetz <marc.strapetz@syntevo.com>
This commit is contained in:
parent
0e20df710a
commit
49cb6ba5dd
|
@ -365,6 +365,34 @@ public void testDirectoryMatchSubRecursiveBacktrack6() throws Exception {
|
||||||
assertSameAsCGit();
|
assertSameAsCGit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectoryWildmatchDoesNotMatchFiles1() throws Exception {
|
||||||
|
createFiles("a", "dir/b", "dir/sub/c");
|
||||||
|
writeTrashFile(".gitattributes", "**/ bar\n");
|
||||||
|
assertSameAsCGit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectoryWildmatchDoesNotMatchFiles2() throws Exception {
|
||||||
|
createFiles("a", "dir/b", "dir/sub/c");
|
||||||
|
writeTrashFile(".gitattributes", "**/**/ bar\n");
|
||||||
|
assertSameAsCGit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectoryWildmatchDoesNotMatchFiles3() throws Exception {
|
||||||
|
createFiles("a", "x/b", "sub/x/c", "sub/x/d/e");
|
||||||
|
writeTrashFile(".gitattributes", "x/**/ bar\n");
|
||||||
|
assertSameAsCGit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectoryWildmatchDoesNotMatchFiles4() throws Exception {
|
||||||
|
createFiles("a", "dir/x", "dir/sub1/x", "dir/sub2/x/y");
|
||||||
|
writeTrashFile(".gitattributes", "x/**/ bar\n");
|
||||||
|
assertSameAsCGit();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDirectoryMatchSubComplex() throws Exception {
|
public void testDirectoryMatchSubComplex() throws Exception {
|
||||||
createFiles("src/new/foo.txt", "foo/src/new/foo.txt", "sub/src/new");
|
createFiles("src/new/foo.txt", "foo/src/new/foo.txt", "sub/src/new");
|
||||||
|
|
|
@ -266,6 +266,34 @@ public void testDirectoryMatchSubRecursiveBacktrack5() throws Exception {
|
||||||
assertSameAsCGit();
|
assertSameAsCGit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectoryWildmatchDoesNotMatchFiles1() throws Exception {
|
||||||
|
createFiles("a", "dir/b", "dir/sub/c");
|
||||||
|
writeTrashFile(".gitignore", "**/\n");
|
||||||
|
assertSameAsCGit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectoryWildmatchDoesNotMatchFiles2() throws Exception {
|
||||||
|
createFiles("a", "dir/b", "dir/sub/c");
|
||||||
|
writeTrashFile(".gitignore", "**/**/\n");
|
||||||
|
assertSameAsCGit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectoryWildmatchDoesNotMatchFiles3() throws Exception {
|
||||||
|
createFiles("a", "x/b", "sub/x/c", "sub/x/d/e");
|
||||||
|
writeTrashFile(".gitignore", "x/**/\n");
|
||||||
|
assertSameAsCGit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDirectoryWildmatchDoesNotMatchFiles4() throws Exception {
|
||||||
|
createFiles("a", "dir/x", "dir/sub1/x", "dir/sub2/x/y");
|
||||||
|
writeTrashFile(".gitignore", "**/x/\n");
|
||||||
|
assertSameAsCGit();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnescapedBracketsInGroup() throws Exception {
|
public void testUnescapedBracketsInGroup() throws Exception {
|
||||||
createFiles("[", "]", "[]", "][", "[[]", "[]]", "[[]]");
|
createFiles("[", "]", "[]", "][", "[[]", "[]]", "[[]]");
|
||||||
|
|
|
@ -48,10 +48,18 @@
|
||||||
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 org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class FastIgnoreRuleTest {
|
public class FastIgnoreRuleTest {
|
||||||
|
|
||||||
|
private boolean pathMatch;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
pathMatch = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleCharClass() {
|
public void testSimpleCharClass() {
|
||||||
assertMatched("][a]", "]a");
|
assertMatched("][a]", "]a");
|
||||||
|
@ -410,6 +418,19 @@ public void testWildmatch() {
|
||||||
|
|
||||||
assertMatched("a/**/b/**/c", "a/c/b/d/c");
|
assertMatched("a/**/b/**/c", "a/c/b/d/c");
|
||||||
assertMatched("a/**/**/b/**/**/c", "a/c/b/d/c");
|
assertMatched("a/**/**/b/**/**/c", "a/c/b/d/c");
|
||||||
|
|
||||||
|
assertMatched("**/", "a/");
|
||||||
|
assertMatched("**/", "a/b");
|
||||||
|
assertMatched("**/", "a/b/c");
|
||||||
|
assertMatched("**/**/", "a/");
|
||||||
|
assertMatched("**/**/", "a/b");
|
||||||
|
assertMatched("**/**/", "a/b/");
|
||||||
|
assertMatched("**/**/", "a/b/c");
|
||||||
|
assertMatched("x/**/", "x/a/");
|
||||||
|
assertMatched("x/**/", "x/a/b");
|
||||||
|
assertMatched("x/**/", "x/a/b/");
|
||||||
|
assertMatched("**/x/", "a/x/");
|
||||||
|
assertMatched("**/x/", "a/b/x/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -424,6 +445,10 @@ public void testWildmatchDoNotMatch() {
|
||||||
assertNotMatched("!/**/*.zip", "c/a/b.zip");
|
assertNotMatched("!/**/*.zip", "c/a/b.zip");
|
||||||
assertNotMatched("!**/*.zip", "c/a/b.zip");
|
assertNotMatched("!**/*.zip", "c/a/b.zip");
|
||||||
assertNotMatched("a/**/b", "a/c/bb");
|
assertNotMatched("a/**/b", "a/c/bb");
|
||||||
|
|
||||||
|
assertNotMatched("**/", "a");
|
||||||
|
assertNotMatched("**/**/", "a");
|
||||||
|
assertNotMatched("**/x/", "a/b/x");
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -465,6 +490,28 @@ public void testSplit() {
|
||||||
split("/a/b/c/", '/').toArray());
|
split("/a/b/c/", '/').toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPathMatch() {
|
||||||
|
pathMatch = true;
|
||||||
|
assertMatched("a", "a");
|
||||||
|
assertMatched("a/", "a/");
|
||||||
|
assertNotMatched("a/", "a/b");
|
||||||
|
|
||||||
|
assertMatched("**", "a");
|
||||||
|
assertMatched("**", "a/");
|
||||||
|
assertMatched("**", "a/b");
|
||||||
|
|
||||||
|
assertNotMatched("**/", "a");
|
||||||
|
assertNotMatched("**/", "a/b");
|
||||||
|
assertMatched("**/", "a/");
|
||||||
|
assertMatched("**/", "a/b/");
|
||||||
|
|
||||||
|
assertNotMatched("x/**/", "x/a");
|
||||||
|
assertNotMatched("x/**/", "x/a/b");
|
||||||
|
assertMatched("x/**/", "x/a/");
|
||||||
|
assertMatched("x/**/", "x/y/a/");
|
||||||
|
}
|
||||||
|
|
||||||
private void assertMatched(String pattern, String path) {
|
private 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")
|
||||||
|
@ -520,7 +567,7 @@ private boolean match(String pattern, String target) {
|
||||||
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.
|
||||||
boolean match = r.isMatch(target, isDirectory);
|
boolean match = r.isMatch(target, isDirectory, pathMatch);
|
||||||
if (r.getNegation())
|
if (r.getNegation())
|
||||||
match = !match;
|
match = !match;
|
||||||
return match;
|
return match;
|
||||||
|
|
|
@ -152,11 +152,35 @@ public FastIgnoreRule(String pattern) {
|
||||||
* result.
|
* result.
|
||||||
*/
|
*/
|
||||||
public boolean isMatch(String path, boolean directory) {
|
public boolean isMatch(String path, boolean directory) {
|
||||||
|
return isMatch(path, directory, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 negation status. The actual
|
||||||
|
* ignore status may be true or false depending on whether this rule is an
|
||||||
|
* ignore rule or a negation rule.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* Name pattern of the file, relative to the base directory of
|
||||||
|
* this rule
|
||||||
|
* @param directory
|
||||||
|
* Whether the target file is a directory or not
|
||||||
|
* @param pathMatch
|
||||||
|
* {@code true} if the match is for the full path: see
|
||||||
|
* {@link IMatcher#matches(String, int, int)}
|
||||||
|
* @return True if a match was made. This does not necessarily mean that the
|
||||||
|
* target is ignored. Call {@link #getResult() getResult()} for the
|
||||||
|
* result.
|
||||||
|
* @since 4.11
|
||||||
|
*/
|
||||||
|
public boolean isMatch(String path, boolean directory, boolean pathMatch) {
|
||||||
if (path == null)
|
if (path == null)
|
||||||
return false;
|
return false;
|
||||||
if (path.length() == 0)
|
if (path.length() == 0)
|
||||||
return false;
|
return false;
|
||||||
boolean match = matcher.matches(path, directory, false);
|
boolean match = matcher.matches(path, directory, pathMatch);
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,7 @@ public boolean matches(String path, boolean assumeDirectory,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String segment, int startIncl, int endExcl,
|
public boolean matches(String segment, int startIncl, int endExcl) {
|
||||||
boolean assumeDirectory) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -91,11 +90,7 @@ public boolean matches(String segment, int startIncl, int endExcl,
|
||||||
* start index, inclusive
|
* start index, inclusive
|
||||||
* @param endExcl
|
* @param endExcl
|
||||||
* end index, exclusive
|
* end index, exclusive
|
||||||
* @param assumeDirectory
|
|
||||||
* true to assume this path as directory (even if it doesn't end
|
|
||||||
* with a slash)
|
|
||||||
* @return true if this matcher pattern matches given string
|
* @return true if this matcher pattern matches given string
|
||||||
*/
|
*/
|
||||||
boolean matches(String segment, int startIncl, int endExcl,
|
boolean matches(String segment, int startIncl, int endExcl);
|
||||||
boolean assumeDirectory);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,7 @@ public class LeadingAsteriskMatcher extends NameMatcher {
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String segment, int startIncl, int endExcl,
|
public boolean matches(String segment, int startIncl, int endExcl) {
|
||||||
boolean assumeDirectory) {
|
|
||||||
// faster local access, same as in string.indexOf()
|
// faster local access, same as in string.indexOf()
|
||||||
String s = subPattern;
|
String s = subPattern;
|
||||||
|
|
||||||
|
|
|
@ -91,12 +91,12 @@ public boolean matches(String path, boolean assumeDirectory,
|
||||||
}
|
}
|
||||||
boolean match;
|
boolean match;
|
||||||
if (lastSlash < start) {
|
if (lastSlash < start) {
|
||||||
match = matches(path, start, stop, assumeDirectory);
|
match = matches(path, start, stop);
|
||||||
} else {
|
} else {
|
||||||
// Can't match if the path contains a slash if the pattern is
|
// Can't match if the path contains a slash if the pattern is
|
||||||
// anchored at the beginning
|
// anchored at the beginning
|
||||||
match = !beginning
|
match = !beginning
|
||||||
&& matches(path, lastSlash + 1, stop, assumeDirectory);
|
&& matches(path, lastSlash + 1, stop);
|
||||||
}
|
}
|
||||||
if (match && dirOnly) {
|
if (match && dirOnly) {
|
||||||
match = assumeDirectory;
|
match = assumeDirectory;
|
||||||
|
@ -108,7 +108,7 @@ public boolean matches(String path, boolean assumeDirectory,
|
||||||
if (end < 0) {
|
if (end < 0) {
|
||||||
end = stop;
|
end = stop;
|
||||||
}
|
}
|
||||||
if (end > start && matches(path, start, end, assumeDirectory)) {
|
if (end > start && matches(path, start, end)) {
|
||||||
// make sure the directory matches: either if we are done with
|
// make sure the directory matches: either if we are done with
|
||||||
// segment and there is next one, or if the directory is assumed
|
// segment and there is next one, or if the directory is assumed
|
||||||
return !dirOnly || assumeDirectory || end < stop;
|
return !dirOnly || assumeDirectory || end < stop;
|
||||||
|
@ -123,8 +123,7 @@ public boolean matches(String path, boolean assumeDirectory,
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String segment, int startIncl, int endExcl,
|
public boolean matches(String segment, int startIncl, int endExcl) {
|
||||||
boolean assumeDirectory) {
|
|
||||||
// faster local access, same as in string.indexOf()
|
// faster local access, same as in string.indexOf()
|
||||||
String s = subPattern;
|
String s = subPattern;
|
||||||
int length = s.length();
|
int length = s.length();
|
||||||
|
|
|
@ -61,7 +61,10 @@
|
||||||
*/
|
*/
|
||||||
public class PathMatcher extends AbstractMatcher {
|
public class PathMatcher extends AbstractMatcher {
|
||||||
|
|
||||||
private static final WildMatcher WILD = WildMatcher.INSTANCE;
|
private static final WildMatcher WILD_NO_DIRECTORY = new WildMatcher(false);
|
||||||
|
|
||||||
|
private static final WildMatcher WILD_ONLY_DIRECTORY = new WildMatcher(
|
||||||
|
true);
|
||||||
|
|
||||||
private final List<IMatcher> matchers;
|
private final List<IMatcher> matchers;
|
||||||
|
|
||||||
|
@ -94,11 +97,15 @@ private static List<IMatcher> createMatchers(List<String> segments,
|
||||||
for (int i = 0; i < segments.size(); i++) {
|
for (int i = 0; i < segments.size(); i++) {
|
||||||
String segment = segments.get(i);
|
String segment = segments.get(i);
|
||||||
IMatcher matcher = createNameMatcher0(segment, pathSeparator,
|
IMatcher matcher = createNameMatcher0(segment, pathSeparator,
|
||||||
dirOnly);
|
dirOnly, i == segments.size() - 1);
|
||||||
if (matcher == WILD && i > 0
|
if (i > 0) {
|
||||||
&& matchers.get(matchers.size() - 1) == WILD)
|
final IMatcher last = matchers.get(matchers.size() - 1);
|
||||||
// collapse wildmatchers **/** is same as **
|
if (isWild(matcher) && isWild(last))
|
||||||
continue;
|
// collapse wildmatchers **/** is same as **, but preserve
|
||||||
|
// dirOnly flag (i.e. always use the last wildmatcher)
|
||||||
|
matchers.remove(matchers.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
matchers.add(matcher);
|
matchers.add(matcher);
|
||||||
}
|
}
|
||||||
return matchers;
|
return matchers;
|
||||||
|
@ -126,7 +133,7 @@ public static IMatcher createPathMatcher(String pattern,
|
||||||
int slashIdx = pattern.indexOf(slash, 1);
|
int slashIdx = pattern.indexOf(slash, 1);
|
||||||
if (slashIdx > 0 && slashIdx < pattern.length() - 1)
|
if (slashIdx > 0 && slashIdx < pattern.length() - 1)
|
||||||
return new PathMatcher(pattern, pathSeparator, dirOnly);
|
return new PathMatcher(pattern, pathSeparator, dirOnly);
|
||||||
return createNameMatcher0(pattern, pathSeparator, dirOnly);
|
return createNameMatcher0(pattern, pathSeparator, dirOnly, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,12 +160,13 @@ private static String trim(String pattern) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IMatcher createNameMatcher0(String segment,
|
private static IMatcher createNameMatcher0(String segment,
|
||||||
Character pathSeparator, boolean dirOnly)
|
Character pathSeparator, boolean dirOnly, boolean lastSegment)
|
||||||
throws InvalidPatternException {
|
throws InvalidPatternException {
|
||||||
// check if we see /** or ** segments => double star pattern
|
// check if we see /** or ** segments => double star pattern
|
||||||
if (WildMatcher.WILDMATCH.equals(segment)
|
if (WildMatcher.WILDMATCH.equals(segment)
|
||||||
|| WildMatcher.WILDMATCH2.equals(segment))
|
|| WildMatcher.WILDMATCH2.equals(segment))
|
||||||
return WILD;
|
return dirOnly && lastSegment ? WILD_ONLY_DIRECTORY
|
||||||
|
: WILD_NO_DIRECTORY;
|
||||||
|
|
||||||
PatternState state = checkWildCards(segment);
|
PatternState state = checkWildCards(segment);
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
@ -218,8 +226,7 @@ private boolean simpleMatch(String path, boolean assumeDirectory,
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String segment, int startIncl, int endExcl,
|
public boolean matches(String segment, int startIncl, int endExcl) {
|
||||||
boolean assumeDirectory) {
|
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"Path matcher works only on entire paths"); //$NON-NLS-1$
|
"Path matcher works only on entire paths"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
@ -241,18 +248,18 @@ private boolean iterate(final String path, final int startIncl,
|
||||||
if (right == -1) {
|
if (right == -1) {
|
||||||
if (left < endExcl) {
|
if (left < endExcl) {
|
||||||
match = matches(matcher, path, left, endExcl,
|
match = matches(matcher, path, left, endExcl,
|
||||||
assumeDirectory);
|
assumeDirectory, pathMatch);
|
||||||
} else {
|
} else {
|
||||||
// a/** should not match a/ or a
|
// a/** should not match a/ or a
|
||||||
match = match && matchers.get(matcher) != WILD;
|
match = match && !isWild(matchers.get(matcher));
|
||||||
}
|
}
|
||||||
if (match) {
|
if (match) {
|
||||||
if (matcher < matchers.size() - 1
|
if (matcher < matchers.size() - 1
|
||||||
&& matchers.get(matcher) == WILD) {
|
&& isWild(matchers.get(matcher))) {
|
||||||
// ** can match *nothing*: a/**/b match also a/b
|
// ** can match *nothing*: a/**/b match also a/b
|
||||||
matcher++;
|
matcher++;
|
||||||
match = matches(matcher, path, left, endExcl,
|
match = matches(matcher, path, left, endExcl,
|
||||||
assumeDirectory);
|
assumeDirectory, pathMatch);
|
||||||
} else if (dirOnly && !assumeDirectory) {
|
} else if (dirOnly && !assumeDirectory) {
|
||||||
// Directory expectations not met
|
// Directory expectations not met
|
||||||
return false;
|
return false;
|
||||||
|
@ -264,14 +271,15 @@ private boolean iterate(final String path, final int startIncl,
|
||||||
wildmatchBacktrackPos = right;
|
wildmatchBacktrackPos = right;
|
||||||
}
|
}
|
||||||
if (right - left > 0) {
|
if (right - left > 0) {
|
||||||
match = matches(matcher, path, left, right, assumeDirectory);
|
match = matches(matcher, path, left, right, assumeDirectory,
|
||||||
|
pathMatch);
|
||||||
} else {
|
} else {
|
||||||
// path starts with slash???
|
// path starts with slash???
|
||||||
right++;
|
right++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (match) {
|
if (match) {
|
||||||
boolean wasWild = matchers.get(matcher) == WILD;
|
boolean wasWild = isWild(matchers.get(matcher));
|
||||||
if (wasWild) {
|
if (wasWild) {
|
||||||
lastWildmatch = matcher;
|
lastWildmatch = matcher;
|
||||||
wildmatchBacktrackPos = -1;
|
wildmatchBacktrackPos = -1;
|
||||||
|
@ -317,9 +325,19 @@ private boolean iterate(final String path, final int startIncl,
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean matches(int matcherIdx, String path, int startIncl,
|
private boolean matches(int matcherIdx, String path, int startIncl,
|
||||||
int endExcl,
|
int endExcl, boolean assumeDirectory, boolean pathMatch) {
|
||||||
boolean assumeDirectory) {
|
|
||||||
IMatcher matcher = matchers.get(matcherIdx);
|
IMatcher matcher = matchers.get(matcherIdx);
|
||||||
return matcher.matches(path, startIncl, endExcl, assumeDirectory);
|
|
||||||
|
final boolean matches = matcher.matches(path, startIncl, endExcl);
|
||||||
|
if (!matches || !pathMatch || matcherIdx < matchers.size() - 1
|
||||||
|
|| !(matcher instanceof AbstractMatcher)) {
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
return assumeDirectory || !((AbstractMatcher) matcher).dirOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isWild(IMatcher matcher) {
|
||||||
|
return matcher == WILD_NO_DIRECTORY || matcher == WILD_ONLY_DIRECTORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,7 @@ public class TrailingAsteriskMatcher extends NameMatcher {
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String segment, int startIncl, int endExcl,
|
public boolean matches(String segment, int startIncl, int endExcl) {
|
||||||
boolean assumeDirectory) {
|
|
||||||
// faster local access, same as in string.indexOf()
|
// faster local access, same as in string.indexOf()
|
||||||
String s = subPattern;
|
String s = subPattern;
|
||||||
// we don't need to count '*' character itself
|
// we don't need to count '*' character itself
|
||||||
|
|
|
@ -66,8 +66,7 @@ public class WildCardMatcher extends NameMatcher {
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String segment, int startIncl, int endExcl,
|
public boolean matches(String segment, int startIncl, int endExcl) {
|
||||||
boolean assumeDirectory) {
|
|
||||||
return p.matcher(segment.substring(startIncl, endExcl)).matches();
|
return p.matcher(segment.substring(startIncl, endExcl)).matches();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,24 +55,26 @@ public final class WildMatcher extends AbstractMatcher {
|
||||||
// double star for the beginning of pattern
|
// double star for the beginning of pattern
|
||||||
static final String WILDMATCH2 = "/**"; //$NON-NLS-1$
|
static final String WILDMATCH2 = "/**"; //$NON-NLS-1$
|
||||||
|
|
||||||
static final WildMatcher INSTANCE = new WildMatcher();
|
WildMatcher(boolean dirOnly) {
|
||||||
|
super(WILDMATCH, dirOnly);
|
||||||
private WildMatcher() {
|
|
||||||
super(WILDMATCH, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final boolean matches(String path, boolean assumeDirectory,
|
public final boolean matches(String path, boolean assumeDirectory,
|
||||||
boolean pathMatch) {
|
boolean pathMatch) {
|
||||||
return true;
|
return !dirOnly || assumeDirectory
|
||||||
|
|| !pathMatch && isSubdirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final boolean matches(String segment, int startIncl, int endExcl,
|
public final boolean matches(String segment, int startIncl, int endExcl) {
|
||||||
boolean assumeDirectory) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isSubdirectory(String path) {
|
||||||
|
final int slashIndex = path.indexOf('/');
|
||||||
|
return slashIndex >= 0 && slashIndex < path.length() - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue