aQute.libg.glob.PathSet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of biz.aQute.bndlib Show documentation
Show all versions of biz.aQute.bndlib Show documentation
bndlib: A Swiss Army Knife for OSGi
package aQute.libg.glob;
import static java.util.stream.Collectors.toList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
/**
* A reusable path set using Ant-style include and exclude globs.
*/
public class PathSet {
private final List includes = new ArrayList<>();
private final List excludes = new ArrayList<>();
/**
* Create a path set.
*/
public PathSet() {}
/**
* Create a path set with initial Ant-style globs for the include patterns.
*
* @param includes Add Ant-style globs.
*/
public PathSet(String... includes) {
include(includes);
}
/**
* Add Ant-style globs to the include patterns.
*
* @param includes Add Ant-style globs.
* @return This PathSet.
*/
public PathSet includes(List includes) {
if (includes != null) {
addPatterns(includes.stream(), this.includes);
}
return this;
}
/**
* Add Ant-style globs to the include patterns.
*
* @param includes Add Ant-style globs.
* @return This PathSet.
*/
public PathSet include(String... includes) {
if (includes != null) {
addPatterns(Arrays.stream(includes), this.includes);
}
return this;
}
/**
* Add Ant-style globs to the exclude patterns.
*
* @param excludes Add Ant-style globs.
* @return This PathSet.
*/
public PathSet exclude(String... excludes) {
if (excludes != null) {
addPatterns(Arrays.stream(excludes), this.excludes);
}
return this;
}
/**
* Add Ant-style globs to the exclude patterns.
*
* @param excludes Add Ant-style globs.
* @return This PathSet.
*/
public PathSet excludes(List excludes) {
if (excludes != null) {
addPatterns(excludes.stream(), this.excludes);
}
return this;
}
private static List addPatterns(Stream globs, List patterns) {
globs.filter(Objects::nonNull)
.map(AntGlob::toPattern)
.forEachOrdered(patterns::add);
return patterns;
}
/**
* Return a list of paths in the specified collection matching the
* configured include and exclude Ant-style glob expressions.
*
* @param defaultIncludes The default include patterns to use if no include
* patterns were configured.
* @return A list of paths in the specified collection which match the
* include and exclude Ant-style globs.
*/
public List paths(Collection paths, String... defaultIncludes) {
return paths(paths, matches(defaultIncludes));
}
/**
* Return a list of paths in the specified collection matching the
* configured include and exclude Ant-style glob expressions.
*
* @param defaultIncludes The default include patterns to use if no include
* patterns were configured.
* @return A list of paths in the specified collection which match the
* include and exclude Ant-style globs.
*/
public List paths(Collection paths, List defaultIncludes) {
return paths(paths, matches(defaultIncludes));
}
/**
* Return a list of paths in the specified collection matching the
* configured include and exclude Ant-style glob expressions.
*
* @return A list of paths in the specified collection which match the
* include and exclude Ant-style globs.
*/
public List paths(Collection paths) {
return paths(paths, matches());
}
private static List paths(Collection paths, Predicate matches) {
return paths.stream()
.filter(matches)
.collect(toList());
}
/**
* Return a predicate matching the configured include and exclude Ant-style
* glob expressions.
*
* @param defaultIncludes The default include patterns to use if no include
* patterns were configured.
* @return A predicate which matches the include and exclude Ant-style
* globs.
*/
public Predicate matches(String... defaultIncludes) {
return matcher(Matcher::matches, defaultIncludes);
}
/**
* Return a predicate matching the configured include and exclude Ant-style
* glob expressions.
*
* @param defaultIncludes The default include patterns to use if no include
* patterns were configured.
* @return A predicate which matches the include and exclude Ant-style
* globs.
*/
public Predicate matches(List defaultIncludes) {
return matcher(Matcher::matches, defaultIncludes);
}
/**
* Return a predicate matching the configured include and exclude Ant-style
* glob expressions.
*
* @return A predicate which matches the include and exclude Ant-style
* globs.
*/
public Predicate matches() {
return matcher(Matcher::matches);
}
/**
* Return a predicate finding the configured include and exclude Ant-style
* glob expressions.
*
* @param defaultIncludes The default include patterns to use if no include
* patterns were configured.
* @return A predicate which finds the include and exclude Ant-style globs.
*/
public Predicate find(String... defaultIncludes) {
return matcher(Matcher::find, defaultIncludes);
}
/**
* Return a predicate finding the configured include and exclude Ant-style
* glob expressions.
*
* @param defaultIncludes The default include patterns to use if no include
* patterns were configured.
* @return A predicate which finds the include and exclude Ant-style globs.
*/
public Predicate find(List defaultIncludes) {
return matcher(Matcher::find, defaultIncludes);
}
/**
* Return a predicate finding the configured include and exclude Ant-style
* glob expressions.
*
* @return A predicate which find the include and exclude Ant-style globs.
*/
public Predicate find() {
return matcher(Matcher::find);
}
private Predicate matcher(Predicate predicate, String... defaultIncludes) {
if (includes.isEmpty() && (defaultIncludes != null) && (defaultIncludes.length > 0)) {
return matcher(predicate, addPatterns(Arrays.stream(defaultIncludes), new ArrayList<>()), excludes);
}
return matcher(predicate, includes, excludes);
}
private Predicate matcher(Predicate predicate, List defaultIncludes) {
if (includes.isEmpty() && (defaultIncludes != null) && !defaultIncludes.isEmpty()) {
return matcher(predicate, addPatterns(defaultIncludes.stream(), new ArrayList<>()), excludes);
}
return matcher(predicate, includes, excludes);
}
private Predicate matcher(Predicate predicate) {
return matcher(predicate, includes, excludes);
}
private static Predicate matcher(Predicate predicate, List includePatterns,
List excludePatterns) {
if (includePatterns.isEmpty()) {
return path -> false;
}
if (excludePatterns.isEmpty()) {
if (includePatterns.size() == 1) {
Pattern include = includePatterns.get(0);
return path -> predicate.test(include.matcher(path));
}
List includes = new ArrayList<>(includePatterns);
return path -> includes.stream()
.anyMatch(include -> predicate.test(include.matcher(path)));
}
List includes = new ArrayList<>(includePatterns);
List excludes = new ArrayList<>(excludePatterns);
return path -> includes.stream()
.anyMatch(include -> predicate.test(include.matcher(path)))
&& excludes.stream()
.noneMatch(exclude -> predicate.test(exclude.matcher(path)));
}
@Override
public String toString() {
return String.format("[includes: %s, excludes: %s]", includes, excludes);
}
}