Skip to content

Commit

Permalink
Refactored Glob.globMatch by using iterative approach; added unit tes…
Browse files Browse the repository at this point in the history
…ts (#12065)

Signed-off-by: Robin Friedmann <[email protected]>
  • Loading branch information
robinf95 committed Feb 7, 2024
1 parent 758a388 commit fa59c6c
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 30 deletions.
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
Expand Up @@ -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
Expand Up @@ -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"));
}


Expand Down

0 comments on commit fa59c6c

Please sign in to comment.