/* * JBoss, Home of Professional Open Source. * Copyright 2014, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.wildfly.core.launcher; import java.io.File; import java.io.IOException; import java.lang.ProcessBuilder.Redirect; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; /** * Builds a {@link java.lang.Process process} to launch a standalone or domain server based on the {@link * org.wildfly.core.launcher.CommandBuilder command builder}. * <p/> * The process is only created by the launcher and not managed. It's the responsibility of the consumer to manage the * process. * * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a> */ public class Launcher { private final CommandBuilder builder; private boolean redirectErrorStream; private Redirect outputDestination; private Redirect errorDestination; private File workingDirectory; private final Map<String, String> env; /** * Creates a new launcher. * * @param builder the builder to build the list of commands */ public Launcher(final CommandBuilder builder) { this.builder = builder; redirectErrorStream = false; outputDestination = null; errorDestination = null; env = new HashMap<>(); } /** * Creates a new launcher to create a {@link java.lang.Process process} based on the command builder. * * @param builder the builder used to launch the process * * @return the newly created launcher */ public static Launcher of(final CommandBuilder builder) { return new Launcher(builder); } /** * Sets the output and error streams to inherit the output and error streams from it's parent process. * * @return the launcher */ public Launcher inherit() { outputDestination = Redirect.INHERIT; errorDestination = Redirect.INHERIT; return this; } /** * Set to {@code true} if the error stream should be redirected to the output stream. * * @param redirectErrorStream {@code true} to merge the error stream into the output stream, otherwise {@code * false} * to keep the streams separate * * @return the launcher */ public Launcher setRedirectErrorStream(final boolean redirectErrorStream) { this.redirectErrorStream = redirectErrorStream; return this; } /** * Redirects the output of the process to a file. * * @param file the file to redirect the output to * * @return the launcher * * @see java.lang.ProcessBuilder.Redirect#to(java.io.File) */ public Launcher redirectOutput(final File file) { outputDestination = Redirect.to(file); return this; } /** * Redirects the output of the process to a file. * * @param path the path to redirect the output to * * @return the launcher * * @see java.lang.ProcessBuilder.Redirect#to(java.io.File) */ public Launcher redirectOutput(final Path path) { return redirectOutput(path.toFile()); } /** * Redirects the output of the process to the destination provided. * * @param destination the output destination * * @return the launcher * * @see java.lang.ProcessBuilder#redirectOutput(java.lang.ProcessBuilder.Redirect) */ public Launcher redirectOutput(final Redirect destination) { outputDestination = destination; return this; } /** * Redirects the error stream of the process to a file. * * @param file the file to redirect the error stream to * * @return the launcher * * @see java.lang.ProcessBuilder.Redirect#to(java.io.File) */ public Launcher redirectError(final File file) { errorDestination = Redirect.to(file); return this; } /** * Redirects the error stream of the process to the destination provided. * * @param destination the error stream destination * * @return the launcher * * @see java.lang.ProcessBuilder#redirectError(java.lang.ProcessBuilder.Redirect) */ public Launcher redirectError(final Redirect destination) { errorDestination = destination; return this; } /** * Sets the working directory for the process created. * * @param path the path to the working directory * * @return the launcher * * @see java.lang.ProcessBuilder#directory(java.io.File) */ public Launcher setDirectory(final Path path) { workingDirectory = path.toFile(); return this; } /** * Sets the working directory for the process created. * * @param dir the working directory * * @return the launcher * * @see java.lang.ProcessBuilder#directory(java.io.File) */ public Launcher setDirectory(final File dir) { workingDirectory = dir; return this; } /** * Sets the working directory for the process created. * * @param dir the working directory * * @return the launcher * * @see java.lang.ProcessBuilder#directory(java.io.File) */ public Launcher setDirectory(final String dir) { return setDirectory(AbstractCommandBuilder.validateAndNormalizeDir(dir, true)); } /** * Adds an environment variable to the process being created. * * @param key they key for the variable * @param value the value for the variable * * @return the launcher */ public Launcher addEnvironmentVariable(final String key, final String value) { env.put(key, value); return this; } /** * Adds the environment variables to the process being created. * * @param env the environment variables to add * * @return the launcher */ public Launcher addEnvironmentVariables(final Map<String, String> env) { this.env.putAll(env); return this; } /** * Launches a new process based on the commands from the {@link org.wildfly.core.launcher.CommandBuilder builder}. * * @return the newly created process * * @throws IOException if an error occurs launching the process */ public Process launch() throws IOException { final ProcessBuilder processBuilder = new ProcessBuilder(builder.build()); if (outputDestination != null) { processBuilder.redirectOutput(outputDestination); } if (errorDestination != null) { processBuilder.redirectError(errorDestination); } if (workingDirectory != null) { processBuilder.directory(workingDirectory); } if (!env.isEmpty()) { processBuilder.environment().putAll(env); } processBuilder.redirectErrorStream(redirectErrorStream); return processBuilder.start(); } }