Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug/12065-refac-glob-matching #1

Closed
wants to merge 2 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Refactored Glob.globMatch by using iterative approach; added unit tes…
…ts (opensearch-project#12065)

Signed-off-by: Robin Friedmann <[email protected]>
robinf95 committed Feb 7, 2024

Verified

This commit was signed with the committer’s verified signature.
Xtansia Thomas Farr
commit fa59c6c607707f1c9bf2bbd8a40c22f5cf5bf4fa
63 changes: 33 additions & 30 deletions libs/common/src/main/java/org/opensearch/common/Glob.java
Original file line number Diff line number Diff line change
@@ -39,47 +39,50 @@
*/
public class Glob {

private Glob() {}
/**
* Match a String against the given pattern, supporting the following simple
* pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
* arbitrary number of pattern parts), as well as direct equality.
* Match a String against the given pattern, supporting the following simple pattern styles: "xxx*", "*xxx", "*xxx*"
* and "xxx*yyy" matches (with an arbitrary number of pattern parts), as well as direct equality.
*
* @param pattern the pattern to match against
* @param str the String to match
* @param str the String to match
* @return whether the String matches the given pattern
*/
public static boolean globMatch(String pattern, String str) {

if (pattern == null || str == null) {
return false;
}
int firstIndex = pattern.indexOf('*');
if (firstIndex == -1) {
return pattern.equals(str);
}
if (firstIndex == 0) {
if (pattern.length() == 1) {
return true;
}
int nextIndex = pattern.indexOf('*', firstIndex + 1);
if (nextIndex == -1) {
return str.endsWith(pattern.substring(1));
} else if (nextIndex == 1) {
// Double wildcard "**" - skipping the first "*"
return globMatch(pattern.substring(1), str);
}
String part = pattern.substring(1, nextIndex);
int partIndex = str.indexOf(part);
while (partIndex != -1) {
if (globMatch(pattern.substring(nextIndex), str.substring(partIndex + part.length()))) {
return true;
}
partIndex = str.indexOf(part, partIndex + 1);

int stringIndex=0;
int patternIndex = 0;
int wildcardIndex = -1;

while (stringIndex < str.length()) {
// pattern and string match
if (patternIndex < pattern.length() && str.charAt(stringIndex) == pattern.charAt(patternIndex)) {
stringIndex++;
patternIndex++;
} else if (patternIndex < pattern.length() && pattern.charAt(patternIndex) == '*') {
// wildcard found
wildcardIndex = patternIndex;
patternIndex++;
} else if (wildcardIndex != -1) {
// last pattern pointer was a wildcard
patternIndex = wildcardIndex + 1;
stringIndex++;
} else {
// characters do not match
return false;
}
return false;
}
return (str.length() >= firstIndex
&& pattern.substring(0, firstIndex).equals(str.substring(0, firstIndex))
&& globMatch(pattern.substring(firstIndex), str.substring(firstIndex)));

while (patternIndex < pattern.length() && pattern.charAt(patternIndex) == '*') {
patternIndex++;
}

return patternIndex == pattern.length();
}


}
24 changes: 24 additions & 0 deletions libs/common/src/test/java/org/opensearch/common/GlobTests.java
Original file line number Diff line number Diff line change
@@ -40,6 +40,30 @@ public void testGlobMatchWildcardAtMiddle() {
public void testGlobMatchMultipleWildcards() {
assertTrue(Glob.globMatch("*test*", "thisisatesting"));
assertFalse(Glob.globMatch("*test*", "thisisatesing"));
assertTrue(Glob.globMatch("*test*test", "thisisatestingtest"));
assertFalse(Glob.globMatch("*test*test", "thisisatesting"));
}

public void testGlobMatchMultipleCharactersWithSingleWildcard() {
assertTrue(Glob.globMatch("a*b", "acb"));
assertTrue(Glob.globMatch("a*b", "aab"));
assertTrue(Glob.globMatch("a*b", "aaab"));
assertFalse(Glob.globMatch("a*b", "ac"));
}

public void testGlobMatchWildcardWithEmptyString() {
assertTrue(Glob.globMatch("*", ""));
assertTrue(Glob.globMatch("a*", "a"));
assertFalse(Glob.globMatch("a*", ""));
}

public void testGlobMatchMultipleWildcardsWithMultipleCharacters() {
assertTrue(Glob.globMatch("a*b*c", "abc"));
assertTrue(Glob.globMatch("a*b*c", "axxxbxbc"));
assertTrue(Glob.globMatch("a*b*c", "aabc"));
assertTrue(Glob.globMatch("a*b*c", "abac"));
assertFalse(Glob.globMatch("a*b*c", "abca"));
assertFalse(Glob.globMatch("a*b*c", "ac"));
}