All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aQute.libg.glob.PathSet Maven / Gradle / Ivy

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);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy