package org.smoothbuild.builtin.file.match.testing;
import static org.smoothbuild.builtin.file.match.Constants.SINGLE_STAR;
import static org.smoothbuild.builtin.file.match.testing.HelpTester.endsWithThreeLetters;
import java.util.function.Consumer;
public class PathPatternGenerator {
/**
* Generates all patterns containing 'size' or less elements and pass it to
* given 'consumer'.
* <p/>
* Element is either "**" wildcard, "*" wildcard, one of the letters {a, b, b}
* or separator "/" (which is not taken into account when calculating pattern
* size).
*/
public static void generatePatterns(int maxSize, Consumer<String> consumer) {
for (int i = 1; i <= maxSize; i++) {
generatePatterns("", i, consumer);
}
}
private static void generatePatterns(String pattern, int size, Consumer<String> consumer) {
if (size == 0) {
consumer.accept(pattern);
} else {
if (!endsWithThreeLetters(pattern)) {
generatePatterns(pattern + "a", size - 1, consumer);
/*
* To reduce number of generated patterns by merging equivalent patterns
* (in terms of PathMatcher). This is done by making sure that each
* generated pattern, the first occurrence of a letter is letter 'a' and
* first occurrence of a letter different than 'a' is letter 'b'. This
* way pattern like "bcb*aa" won't be generated as it is equivalent to
* generated "aba*cc".
*/
if (pattern.contains("a")) {
generatePatterns(pattern + "b", size - 1, consumer);
if (pattern.contains("b")) {
generatePatterns(pattern + "c", size - 1, consumer);
}
}
}
if (pattern.length() != 0 && !pattern.endsWith("/")) {
// slash "/" is not counted as element
generatePatterns(pattern + "/", size, consumer);
}
if (!pattern.endsWith(SINGLE_STAR)) {
generatePatterns(pattern + SINGLE_STAR, size - 1, consumer);
}
if (!pattern.endsWith("/")) {
String start = pattern.isEmpty() ? "" : "/";
String end = size == 1 ? "" : "/";
generatePatterns(pattern + start + "**" + end, size - 1, consumer);
}
}
}
}