com.squeakysand.commons.cli.CommandLineExecutor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of squeakysand-commons Show documentation
Show all versions of squeakysand-commons Show documentation
Classes, interfaces and enums that assist with everyday Java development tasks.
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