package org.jbehave.eclipse.util;
import java.util.List;
import java.util.regex.Pattern;
import fj.F;
import fj.function.Booleans;
public class StringMatcher {
private final List<Pattern> includePatterns = New.arrayList();
private final List<Pattern> excludePatterns = New.arrayList();
private F<String,Boolean> cached;
public StringMatcher() {
}
public StringMatcher addRegexIncludes(String...regexes) {
compileRegexTo(includePatterns, regexes);
invalidateCached();
return this;
}
public StringMatcher addRegexExcludes(String...regexes) {
compileRegexTo(excludePatterns, regexes);
invalidateCached();
return this;
}
private static void compileRegexTo(List<Pattern> patterns, String... regexes) {
for(int i=0;i<regexes.length;i++) {
patterns.add(Pattern.compile(regexes[i]));
}
}
public StringMatcher addGlobIncludes(String...globs) {
compileGlobTo(includePatterns, globs);
invalidateCached();
return this;
}
public StringMatcher addGlobExcludes(String...globs) {
compileGlobTo(excludePatterns, globs);
invalidateCached();
return this;
}
private void invalidateCached() {
cached = null;
}
private static void compileGlobTo(List<Pattern> patterns, String... globs) {
for(int i=0;i<globs.length;i++) {
patterns.add(Strings.convertGlobToPattern(globs[i]));
}
}
public F<String,Boolean> compile () {
if(cached==null) {
F<String,Boolean> includesF = compileIncludes(includePatterns);
F<String,Boolean> excludesF = compileExcludes(excludePatterns);
cached = FJ.and(includesF, excludesF);
}
return cached;
}
public boolean isAccepted(String input) {
return compile().f(input);
}
public static F<String, Boolean> compileIncludes(List<Pattern> includePatterns) {
if(includePatterns.isEmpty())
return FJ.alwaysTrue();
final Pattern[] patterns = includePatterns.toArray(new Pattern[includePatterns.size()]);
return new F<String, Boolean> () {
@Override
public Boolean f(String value) {
// non empty case: null is rejected
if(value == null)
return false;
for(Pattern pattern : patterns) {
if(pattern.matcher(value).matches()) {
return true;
}
}
return false;
}
};
}
public static F<String, Boolean> compileExcludes(List<Pattern> excludePatterns) {
if(excludePatterns.isEmpty())
return FJ.alwaysTrue();
return Booleans.not(compileIncludes(excludePatterns));
}
}