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

org.wamblee.io.SimpleProcess Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2005-2010 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.wamblee.io;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 
 * @author $author$
 * @version $Revision$
 */
public class SimpleProcess {
    private static final Logger LOG = Logger.getLogger(SimpleProcess.class
        .getName());

    private File directory;

    private String[] cmd;

    private String stdout;

    private String stderr;

    /**
     * Creates a new SimpleProcess object.
     * 
     */
    public SimpleProcess(File aDirectory, String[] aCmd) {
        directory = aDirectory;
        cmd = Arrays.copyOf(aCmd, aCmd.length);
    }

    /**
     * 
     * @return the stdout
     */
    public String getStdout() {
        return stdout;
    }

    /**
     * 
     * @return the stderr
     */
    public String getStderr() {
        return stderr;
    }

    /**
     * Runs the process and blocks until it is done.
     * 
     * @return Exit status of the process.
     * 
     * @throws IOException
     *             In case of problems.
     */
    public int run() throws IOException {
        return runImpl();
    }

    private int runImpl() throws IOException {
        try {
            StringBuffer fullcmd = new StringBuffer();

            for (String part : cmd) {
                fullcmd.append(" " + part);
            }

            LOG.fine("Executing '" + fullcmd + "' in directory '" + directory +
                "'");

            java.lang.Process proc = Runtime.getRuntime().exec(cmd, null,
                directory);

            // Read standard output and error in separate threads to avoid
            // deadlock.
            StringWriter myStdout = new StringWriter();
            StringWriter myStderr = new StringWriter();
            Thread stdoutReader = readAndLogStream("STDOUT>  ", proc
                .getInputStream(), myStdout);
            Thread stderrReader = readAndLogStream("STDERR>  ", proc
                .getErrorStream(), myStderr);

            try {
                proc.waitFor();
            } catch (InterruptedException e) {
                IOException exception = new IOException(
                    "Process was terminated: " + this);
                exception.initCause(e);
                throw exception;
            }

            waitForReader(stdoutReader);
            waitForReader(stderrReader);

            stdout = myStdout.toString();
            stderr = myStderr.toString();

            if (proc.exitValue() != 0) {
                LOG.warning("Exit value was non-zero: " + this);
            } else {
                LOG.fine("Process finished");
            }

            return proc.exitValue();
        } catch (IOException e) {
            IOException exception = new IOException(
                "Error executing process: " + this);
            exception.initCause(e);
            throw exception;
        }
    }

    private void waitForReader(Thread aReaderThread) {
        try {
            aReaderThread.join();
        } catch (InterruptedException e) {
            LOG
                .log(
                    Level.WARNING,
                    this +
                        ": error waiting for output stream reader of process to finish",
                    e);
        }
    }

    private Thread readAndLogStream(final String aPrefix,
        final InputStream aStream, final Writer aOutput) {
        Thread inputReader = new Thread() {
            @Override
            public void run() {
                BufferedReader br = null;

                try {
                    br = new BufferedReader(new InputStreamReader(aStream));

                    String str;

                    while ((str = br.readLine()) != null) {
                        LOG.fine(aPrefix + str);
                        aOutput.write(str);
                    }
                } catch (IOException e) {
                    LOG.log(Level.FINE, SimpleProcess.this +
                        ": error reading input stream", e);
                } finally {
                    if (br != null) {
                        try {
                            br.close();
                        } catch (IOException e) {
                            LOG.log(Level.WARNING, "Error closing stream " +
                                aPrefix, e);
                        }
                    }
                }
            }
        };

        inputReader.start();

        return inputReader;
    }

    @Override
    public String toString() {
        StringBuffer fullcmd = new StringBuffer();

        for (String part : cmd) {
            fullcmd.append(part + " ");
        }

        return "process(dir = '" + directory + "', cmd = '" + fullcmd + "')";
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy