Skip to content

Commit

Permalink
Add ability to escape stars
Browse files Browse the repository at this point in the history
  • Loading branch information
dnestoro committed May 29, 2024
1 parent 70814c4 commit 52a5fba
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ private void parsePatternEntry(Object data, BiConsumer<C, String> resourceRegist
private void parseGlobEntry(Object data, GlobPatternConsumer<C, String, String> resourceRegistry) {
EconomicMap<String, Object> globObject = asMap(data, "Elements of 'globs' list must be a glob descriptor objects");
checkAttributes(globObject, "resource and resource bundle descriptor object", Collections.singletonList(GLOB_KEY), List.of(CONDITIONAL_KEY, MODULE_KEY));
TypeResult<C> resolvedConfigurationCondition = conditionResolver.resolveCondition(parseCondition(globObject));
TypeResult<C> resolvedConfigurationCondition = conditionResolver.resolveCondition(parseCondition(globObject, false));
if (!resolvedConfigurationCondition.isPresent()) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,17 @@ public static List<String> getAdditionalContentIfMatched(GlobTrieNode root, Stri
* Returns whether given text can be matched with any glob pattern in the Trie or not.
*/
public static boolean match(GlobTrieNode root, String text) {
/* in this case text is a plain text without special meanings, so stars must be escaped */
String escapedText = escapeAllStars(text);
List<GlobTrieNode> tmp = new ArrayList<>();
getAllPatterns(root, getPatternParts(text), 0, tmp);
getAllPatterns(root, getPatternParts(escapedText), 0, tmp);
return !tmp.isEmpty();
}

private static String escapeAllStars(String text) {
return text.replace("*", "\\*");
}

private static final Pattern threeConsecutiveStarsRegex = Pattern.compile(".*[*]{3,}.*");
private static final Pattern emptyLevelsRegex = Pattern.compile(".*/{2,}.*");

Expand Down Expand Up @@ -434,24 +440,26 @@ public static List<GlobTrieNode> getPatternParts(String pattern) {
* this level contains at least one star, but maybe it has more example:
* something/a*b*c*d/else
*/
List<String> starLevelParts = Arrays.stream(level.split("\\*")).toList();
for (int i = 0; i < starLevelParts.size(); i++) {
GlobTrieNode newNode;
if ((i == starLevelParts.size() - 1) && !level.endsWith(STAR)) {
/*
* only the last part on this level can be literal (if it doesn't contain *)
*/
newNode = new LiteralNode(starLevelParts.get(i));
} else {
newNode = new StarTrieNode(starLevelParts.get(i) + STAR);
}

if (i == 0) {
newNode.setNewLevel();
List<GlobTrieNode> thisLevelParts = new ArrayList<>();
StringBuilder currentPart = new StringBuilder();
StarCollectorMode currentMode = StarCollectorMode.NORMAL;
for (char c : level.toCharArray()) {
currentPart.append(c);
if (c == STAR.charAt(0) && currentMode == StarCollectorMode.NORMAL) {
thisLevelParts.add(new StarTrieNode(currentPart.toString()));
currentPart.setLength(0);
}

parts.add(newNode);
currentMode = c == '\\' ? StarCollectorMode.ESCAPE : StarCollectorMode.NORMAL;
}

if (!currentPart.isEmpty()) {
/* this level ends with some literal node */
thisLevelParts.add(new LiteralNode(currentPart.toString()));
}
thisLevelParts.get(0).setNewLevel();
parts.addAll(thisLevelParts);
continue;
}

Expand All @@ -463,6 +471,11 @@ public static List<GlobTrieNode> getPatternParts(String pattern) {
return parts;
}

private enum StarCollectorMode {
NORMAL,
ESCAPE
};

private static void getAllPatterns(GlobTrieNode node, List<GlobTrieNode> parts, int i, List<GlobTrieNode> matches) {
if (patternReachedEnd(i, parts)) {
if (node.isLeaf()) {
Expand Down Expand Up @@ -552,14 +565,28 @@ private static List<MatchedNode> getAllAvailablePaths(DoubleStarNode node, List<
return successors;
}

private static int getIndexOfFirstUnescapedStar(String level) {
StarCollectorMode currentMode = StarCollectorMode.NORMAL;
for (int i = 0; i < level.length(); i++) {
char c = level.charAt(i);
if (c == STAR.charAt(0) && currentMode == StarCollectorMode.NORMAL) {
return i;
}

currentMode = c == '\\' ? StarCollectorMode.ESCAPE : StarCollectorMode.NORMAL;
}

return -1;
}

private static List<GlobTrieNode> matchOneLevel(StarTrieNode node, String wholeLevel) {
if (node.isMatchingWholeLevel()) {
return List.of(node);
}

/* match prefix first */
String nodeContent = node.getContent();
String prefix = nodeContent.substring(0, nodeContent.indexOf(STAR.charAt(0)));
String prefix = nodeContent.substring(0, getIndexOfFirstUnescapedStar(nodeContent));
if (!prefix.equals(STAR) && !wholeLevel.startsWith(prefix)) {
/* can't match prefix */
return Collections.emptyList();
Expand Down

0 comments on commit 52a5fba

Please sign in to comment.