<commit_before>package uk.co.datumedge.redislauncher;

import static uk.co.datumedge.redislauncher.Configuration.defaultConfiguration;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.exec.DefaultExecuteResultHandler;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.Executor;
import org.apache.commons.exec.ProcessDestroyer;
import org.apache.commons.exec.PumpStreamHandler;

/**
 * An execution of a redis server.  Used by a {@link LocalRedisServer} to start and stop a redis server process.
 */
public final class Execution {
	private ExecutionProcessDestroyer executionProcessDestroyer;
	private final OutputStream outputStream;
	private final OutputStream errorStream;
	final Configuration configuration;

	public static Builder anExecution() {
		return new Builder();
	}

	private Execution(Configuration configuration, OutputStream outputStream, OutputStream errorStream) {
		this.configuration = configuration;
		this.outputStream = outputStream;
		this.errorStream = errorStream;
	}

	DefaultExecuteResultHandler start(ProcessDestroyer lifecyleProcessDestroyer) throws IOException {
		Executor executor = new DefaultExecutor();
		DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
		this.executionProcessDestroyer = new ExecutionProcessDestroyer();
		executor.setProcessDestroyer(new CompositeProcessDestroyer(
				this.executionProcessDestroyer, lifecyleProcessDestroyer));
		executor.setStreamHandler(new PumpStreamHandler(
				outputStream,
				errorStream,
				configuration.inputStream()));
		executor.execute(configuration.commandLine(), handler);
		return handler;
	}

	void destroy() {
		if (executionProcessDestroyer != null) {
			executionProcessDestroyer.destroy();
		}
	}
	
	/**
	 * A builder of {@code Execution} instances.
	 */
	public static final class Builder {
		private Configuration configuration;
		private OutputStream outputStream;
		private OutputStream errorStream;

		private Builder() { }

		public Builder withConfiguration(Configuration configuration) {
			this.configuration = configuration;
			return this;
		}
		
		public Builder withOutputStream(OutputStream outputStream) {
			this.outputStream = outputStream;
			return this;
		}
		
		public Builder withErrorStream(OutputStream errorStream) {
			this.errorStream = errorStream;
			return this;
		}

		/**
		 * @return an {@code Execution} instance
		 * @throws NullPointerException
		 */
		public Execution build() {
			if (configuration == null) configuration = defaultConfiguration();<commit_msg>add javadoc to Execution and its builder<commit_after>package uk.co.datumedge.redislauncher;

import static uk.co.datumedge.redislauncher.Configuration.defaultConfiguration;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.exec.DefaultExecuteResultHandler;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.Executor;
import org.apache.commons.exec.ProcessDestroyer;
import org.apache.commons.exec.PumpStreamHandler;

/**
 * An execution of a redis server.  Used by a {@link LocalRedisServer} to start and stop a redis server process.
 */
public final class Execution {
	private ExecutionProcessDestroyer executionProcessDestroyer;
	private final OutputStream outputStream;
	private final OutputStream errorStream;
	final Configuration configuration;

	/**
	 * Creates an {@code Execution} builder.
	 *
	 * @return an {@code Execution} builder instance
	 */
	public static Builder anExecution() {
		return new Builder();
	}

	private Execution(Configuration configuration, OutputStream outputStream, OutputStream errorStream) {
		this.configuration = configuration;
		this.outputStream = outputStream;
		this.errorStream = errorStream;
	}

	DefaultExecuteResultHandler start(ProcessDestroyer lifecyleProcessDestroyer) throws IOException {
		Executor executor = new DefaultExecutor();
		DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
		this.executionProcessDestroyer = new ExecutionProcessDestroyer();
		executor.setProcessDestroyer(new CompositeProcessDestroyer(
				this.executionProcessDestroyer, lifecyleProcessDestroyer));
		executor.setStreamHandler(new PumpStreamHandler(
				outputStream,
				errorStream,
				configuration.inputStream()));
		executor.execute(configuration.commandLine(), handler);
		return handler;
	}

	void destroy() {
		if (executionProcessDestroyer != null) {
			executionProcessDestroyer.destroy();
		}
	}

	/**
	 * A builder of {@code Execution} instances.
	 */
	public static final class Builder {
		private Configuration configuration;
		private OutputStream outputStream;
		private OutputStream errorStream;

		private Builder() { }

		/**
		 * Sets the {@code Configuration} used by the builder.
		 *
		 * @return the updated builder
		 */
		public Builder withConfiguration(Configuration configuration) {
			this.configuration = configuration;
			return this;
		}

		/**
		 * Sets the {@code OutputStream} to which {@code stdout} is sent.
		 *
		 * @return the updated builder
		 */
		public Builder withOutputStream(OutputStream outputStream) {
			this.outputStream = outputStream;
			return this;
		}

		/**
		 * Sets the {@code OutputStream} to which {@code stderr} is sent.
		 *
		 * @return the updated builder
		 */
		public Builder withErrorStream(OutputStream errorStream) {
			this.errorStream = errorStream;
			return this;
		}

		/**
		 * Creates an {@code Execution} instance from the current builder. If no {@code Configuration} was specified,
		 * {@linkplain Configuration.Builder#build() default configuration} is used. If no {@code outputStream} was
		 * specified, {@code stdout} is swallowed. If no {@code errorStream} was specified, {@code stderr} is swallowed.
		 *
		 * @return an {@code Execution} instance
		 * @throws NullPointerException
		 *             if no {@code Configuration} was specified and the {@code redislauncher.command} system
		 *             property does not exist
		 */
		public Execution build() {
			if (configuration == null) configuration = defaultConfiguration();
{'fraction_non_alphanumeric': 0.084640522875817, 'fraction_numerical': 0.0, 'mean_word_length': 4.763653483992467, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4624851', 'n_tokens_mistral': 1742, 'n_tokens_neox': 1534, 'n_words': 456}