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

aQute.lib.io.FileTree Maven / Gradle / Ivy

Go to download

A main program (executable JAR) that will listen to port 29998. At first, it can only answer that it is an Envoy (a limited agent). The only function it supports is installing a -runpath. It will then create a framework + agent and transfer the connection to the just installed agent who will then install the bundles. This JAR is a main command for JPM called bndremote. In JPM, it will start up with debug enabled. This JAR does some highly complicated class loading wizardy to ensure that it does not enforce any constraints on the -runpath.

The newest version!
package aQute.lib.io;

import static java.util.Objects.requireNonNull;

import java.io.File;
import java.nio.file.Path;
import java.text.CollationKey;
import java.text.Collator;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators.AbstractSpliterator;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import aQute.libg.glob.PathSet;

public class FileTree {
	private final List	files	= new ArrayList<>();
	private final PathSet		paths	= new PathSet();

	public FileTree() {}

	/**
	 * Can be used to add specific files to the return value of
	 * {@link #getFiles(File, String...)} and {@link #getFiles(File, List)}.
	 *
	 * @param file A file to include in the return value of
	 *            {@link #getFiles(File, String...)} and
	 *            {@link #getFiles(File, List)}.
	 */
	public void addFile(File file) {
		if (file == null) {
			return;
		}
		if (!files.contains(file)) {
			files.add(file);
		}
	}

	/**
	 * Add an Ant-style glob to the include patterns.
	 *
	 * @param includes Add an Ant-style glob
	 */
	public void addIncludes(List includes) {
		paths.includes(includes);
	}

	/**
	 * Add an Ant-style glob to the include patterns.
	 *
	 * @param includes Add an Ant-style glob
	 */
	public void addIncludes(String... includes) {
		paths.include(includes);
	}

	/**
	 * Add an Ant-style glob to the exclude patterns.
	 *
	 * @param excludes Add an Ant-style glob
	 */
	public void addExcludes(String... excludes) {
		paths.exclude(excludes);
	}

	/**
	 * Add an Ant-style glob to the exclude patterns.
	 *
	 * @param excludes Add an Ant-style glob
	 */
	public void addExcludes(List excludes) {
		paths.excludes(excludes);
	}

	/**
	 * Return a list of files using the specified baseDir and the configured
	 * include and exclude Ant-style glob expressions.
	 *
	 * @param baseDir The base directory for locating files.
	 * @param defaultIncludes The default include patterns to use if no include
	 *            patterns were configured.
	 * @return A list of files.
	 */
	public List getFiles(File baseDir, String... defaultIncludes) {
		return getFiles(baseDir, files.isEmpty() ? paths.matches(defaultIncludes) : paths.matches());
	}

	/**
	 * Return a list of files using the specified baseDir and the configured
	 * include and exclude Ant-style glob expressions.
	 *
	 * @param baseDir The base directory for locating files.
	 * @param defaultIncludes The default include patterns to use if no include
	 *            patterns were configured.
	 * @return A list of files.
	 */
	public List getFiles(File baseDir, List defaultIncludes) {
		return getFiles(baseDir, files.isEmpty() ? paths.matches(defaultIncludes) : paths.matches());
	}

	/**
	 * Return a list of files using the specified baseDir and the specified
	 * relative path matching predicate.
	 *
	 * @param baseDir The base directory for locating files.
	 * @param matches The path matching predicate. The predicate only matches
	 *            against the relative path from the specified baseDir.
	 * @return A list of files.
	 */
	public List getFiles(File baseDir, Predicate matches) {
		ArrayList result = new ArrayList<>();
		new FileTreeSpliterator(baseDir, matches, files).forEachRemaining(result::add);
		result.trimToSize();
		return result;
	}

	/**
	 * Return a stream of files using the specified baseDir and the configured
	 * include and exclude Ant-style glob expressions.
	 *
	 * @param baseDir The base directory for locating files.
	 * @param defaultIncludes The default include patterns to use if no include
	 *            patterns were configured.
	 * @return A stream of files.
	 */
	public Stream stream(File baseDir, String... defaultIncludes) {
		return stream(baseDir, files.isEmpty() ? paths.matches(defaultIncludes) : paths.matches());
	}

	/**
	 * Return a stream of files using the specified baseDir and the configured
	 * include and exclude Ant-style glob expressions.
	 *
	 * @param baseDir The base directory for locating files.
	 * @param defaultIncludes The default include patterns to use if no include
	 *            patterns were configured.
	 * @return A stream of files.
	 */
	public Stream stream(File baseDir, List defaultIncludes) {
		return stream(baseDir, files.isEmpty() ? paths.matches(defaultIncludes) : paths.matches());
	}

	/**
	 * Return a stream of files using the specified baseDir and the specified
	 * relative path matching predicate.
	 *
	 * @param baseDir The base directory for locating files.
	 * @param matches The path matching predicate. The predicate only matches
	 *            against the relative path from the specified baseDir.
	 * @return A stream of files.
	 */
	public Stream stream(File baseDir, Predicate matches) {
		return StreamSupport.stream(new FileTreeSpliterator(baseDir, matches, files), false);
	}

	// Spliterator which performs a depth-first walk.
	// Sorts entries within a directory using IO.fileCollator.
	final static class FileTreeSpliterator extends AbstractSpliterator {
		private final Path				basePath;
		private final Predicate	matches;
		private final List		files;
		private final Spliterator	extra;
		private final Collator			fileCollator	= IO.fileCollator();
		private final Deque		queue			= new ArrayDeque<>();

		FileTreeSpliterator(File baseDir, Predicate matches, List files) {
			super(Long.MAX_VALUE,
				Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.DISTINCT | Spliterator.NONNULL);
			basePath = baseDir.toPath();
			this.matches = requireNonNull(matches);
			List copy = new ArrayList<>(files); // mutable copy
			this.files = copy;
			extra = copy.spliterator(); // late-binding
			queueDirectoryContents(baseDir);
		}

		private void queueDirectoryContents(File dir) {
			if (dir.isDirectory()) {
				String[] names = dir.list();
				if (names != null) {
					final int length = names.length;
					CollationKey[] keys = new CollationKey[length];
					for (int i = 0; i < length; i++) {
						keys[i] = fileCollator.getCollationKey(names[i]);
					}
					Arrays.sort(keys);
					for (int i = length - 1; i >= 0; i--) {
						queue.addFirst(new File(dir, keys[i].getSourceString()));
					}
				}
			}
		}

		@Override
		public void forEachRemaining(Consumer action) {
			for (File next; (next = queue.pollFirst()) != null;) {
				queueDirectoryContents(next);
				Path path = basePath.relativize(next.toPath());
				if (matches.test(path.toString())) {
					files.remove(next);
					action.accept(next);
				}
			}
			extra.forEachRemaining(action);
		}

		@Override
		public boolean tryAdvance(Consumer action) {
			for (File next; (next = queue.pollFirst()) != null;) {
				queueDirectoryContents(next);
				Path path = basePath.relativize(next.toPath());
				if (matches.test(path.toString())) {
					files.remove(next);
					action.accept(next);
					return true;
				}
			}
			return extra.tryAdvance(action);
		}
	}

	@Override
	public String toString() {
		return String.format("[files: %s, paths: %s]", files, paths);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy