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

com.squeakysand.commons.cli.CommandLineExecutor Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2010-2012 Craig S. Dickson (http://craigsdickson.com)
 *
 * 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 com.squeakysand.commons.cli;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Allows easy execution of Operation System command lines from within a Java application. The class handles all issues associated with System.out and
 * System.err buffers becoming full and blocking further execution.
 * 
 * @author Craig S. Dickson
 */
public class CommandLineExecutor {

    /** Command Size. */
    public static final int CMD_SIZE = 3;

    /** Logging level. */
    public static final int DEBUG = 1;

    /** Logging level. */
    public static final int ERROR = 4;

    /** Logging level. */
    public static final int INFO = 2;

    /** Logging level. */
    public static final int TRACE = 0;

    /** Logging level. */
    public static final int WARN = 3;
    private static final Logger LOG = LoggerFactory.getLogger(CommandLineExecutor.class);
    private final String commandLine;
    private Logger systemErrorLog;
    private Logger systemOutLog;

    /**
     * Creates a new CommandLineExecutor object.
     * 
     * @param commandLine
     *            the command to execute.
     */
    public CommandLineExecutor(String commandLine) {
        this.commandLine = commandLine;
    }

    /**
     * Executes the supplied command line.
     * 
     * @return return value from OS indicating the result of the execution.
     * @throws java.io.IOException
     *             if there is an issue writing the output to the correct location.
     * @throws java.lang.InterruptedException
     *             if there is an issue while executing the command line.
     */
    public int execute() throws IOException, InterruptedException {
        String osName = System.getProperty("os.name");
        String[] cmd = new String[CMD_SIZE];
        if (osName.charAt(0) == 'W') {
            // Windows
            cmd[0] = "cmd.exe";
            cmd[1] = "/C";
            cmd[2] = commandLine;
        } else if (osName.charAt(0) == 'L') {
            // Linux
            cmd[0] = "sh";
            cmd[1] = "-c";
            cmd[2] = commandLine;
        } else {
            throw new InterruptedException("error unknown OS " + osName);
        }
        LOG.debug("executing: {} {} {}", new Object[] {cmd[0], cmd[1], cmd[2]});
        if (systemOutLog == null) {
            systemOutLog = LOG;
        }
        if (systemErrorLog == null) {
            systemErrorLog = LOG;
        }
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec(cmd);
        StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), systemErrorLog, ERROR);
        StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), systemOutLog, INFO);
        errorGobbler.start();
        outputGobbler.start();
        return process.waitFor();
    }

    /**
     * Accessor for the logger being used for error output.
     * 
     * @return the current logger.
     */
    public Logger getSystemErrorLog() {
        return systemErrorLog;
    }

    /**
     * Accessor for the logger being used for normal output.
     * 
     * @return the current logger.
     */
    public Logger getSystemOutLog() {
        return systemOutLog;
    }

    /**
     * Mutator for the log to be used for error output.
     * 
     * @param systemErrorLog
     *            the log to be used.
     */
    public void setSystemErrorLog(Logger systemErrorLog) {
        this.systemErrorLog = systemErrorLog;
    }

    /**
     * Mutator for the log to be used for normal output.
     * 
     * @param systemOutLog
     *            the log to be used.
     */
    public void setSystemOutLog(Logger systemOutLog) {
        this.systemOutLog = systemOutLog;
    }

    private class StreamGobbler extends Thread {

        private final InputStream is;
        private final int level;
        private final Logger log;

        /**
         * Creates a new StreamGobbler object.
         * 
         * @param is
         *            the stream to read.
         * @param log
         *            the log to write to.
         * @param level
         *            the log level to write at.
         */
        public StreamGobbler(InputStream is, Logger log, int level) {
            super();
            this.log = log;
            this.is = is;
            this.level = level;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void run() {
            try {
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                while ((line = br.readLine()) != null) {
                    switch (level) {

                        case TRACE:
                            log.trace(line);
                            break;

                        case DEBUG:
                            log.debug(line);
                            break;

                        case INFO:
                            log.info(line);
                            break;

                        case WARN:
                            log.warn(line);
                            break;

                        case ERROR:
                            log.error(line);
                            break;

                        default:
                            log.info(line);
                    }
                }
            } catch (IOException e) {
                LOG.error(e.getMessage(), e);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy