org.ow2.mind.compilation.ExecutionHelper Maven / Gradle / Ivy
/**
* Copyright (C) 2009 STMicroelectronics
*
* This file is part of "Mind Compiler" 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 3 of the
* License, or (at your option) any later version.
*
* This program 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 program. If not, see .
*
* Contact: [email protected]
*
* Authors: Matthieu Leclercq
* Contributors:
*/
package org.ow2.mind.compilation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.objectweb.fractal.adl.ADLException;
import org.objectweb.fractal.adl.CompilerError;
import org.objectweb.fractal.adl.error.GenericErrors;
import org.objectweb.fractal.adl.util.FractalADLLogManager;
/**
* This helper class provides method to execute external commands.
*/
public final class ExecutionHelper {
private ExecutionHelper() {
}
public static class ExecutionResult {
final int rValue;
final String output;
protected ExecutionResult(final int rValue, final StringBuilder output) {
this.rValue = rValue;
if (output.length() == 0)
this.output = null;
else
this.output = output.toString();
}
public int getExitValue() {
return rValue;
}
public String getOutput() {
return output;
}
}
// The io logger
protected static Logger logger = FractalADLLogManager.getLogger("io");
/**
* Executes the given command line and returns the exit value. The given
* command is splited on space character boundary (this method is equivalent
* to exec(execTitle, command.split("\\s"))
)
* Note that the {@link #exec(String, List)} method is safer since it while
* not split command line on space character boundary which may produce
* unexpected result if arguments contains spaces.
*
* @param command the command to execute.
* @return if its exit value is zero, return null, otherwise returns a string
* that contains the process output.
* @throws ADLException If an error occurs while running the command.
* @throws InterruptedException if the calling thread has been interrupted
* while waiting for the process to finish.
* @see #exec(String, List)
*/
public static ExecutionResult exec(final String command) throws ADLException,
InterruptedException {
return exec(null, command);
}
/**
* Executes the given command line and returns the exit value. The given
* command is splited on space character boundary, unless the space is escaped
* by a backslash.
* Note that the {@link #exec(String, List)} method is safer since it while
* not split command line on space character boundary which may produce
* unexpected result if arguments contains spaces.
*
* @param execTitle the message to be logged as a header of the execution. May
* be null
.
* @param command the command to execute.
* @return if its exit value is zero, return null, otherwise returns a string
* that contains the process output.
* @throws ADLException If an error occurs while running the command.
* @throws InterruptedException if the calling thread has been interrupted
* while waiting for the process to finish.
* @see #exec(String, List)
*/
public static ExecutionResult exec(final String execTitle,
final String command) throws ADLException, InterruptedException {
return exec(execTitle, DirectiveHelper.splitOptionString(command));
}
/**
* Executes the given command line and returns the exit value.
* This method will issue some messages on the io
logger. If the
* {@link Level#FINE FINE} level is enabled, the full command line will be
* logged. If the {@link Level#INFO INFO} level is enabled, the given
* execTitle
will be logged.
*
* @param execTitle the message to be logged as a header of the execution. May
* be null
.
* @param cmdList the command to execute.
* @return if its exit value is zero, return null, otherwise returns a string
* that contains the process output.
* @throws ADLException If an error occurs while running the command.
* @throws InterruptedException if the calling thread has been interrupted
* while waiting for the process to finish.
*/
public static ExecutionResult exec(final String execTitle,
final List cmdList) throws ADLException, InterruptedException {
final boolean titleLogged;
if (logger.isLoggable(Level.INFO) && execTitle != null) {
logger.info(execTitle);
titleLogged = true;
} else {
titleLogged = false;
}
if (logger.isLoggable(Level.FINE)) {
String command = "";
for (final String cmd : cmdList) {
command += cmd + " ";
}
logger.fine(command);
}
final Process process;
try {
process = new ProcessBuilder(cmdList).redirectErrorStream(true).start();
} catch (final IOException e1) {
throw new ADLException(CompilerErrors.EXECUTION_ERROR, cmdList.get(0));
}
final StringBuilder processOutput = new StringBuilder();
// Read output produced by process in a parallel thread in order to avoid
// the process to block
final Thread readerThread = new Thread() {
@Override
public void run() {
// append output and error stream on the processOutput.
final BufferedReader reader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
try {
String line = reader.readLine();
if (line != null) {
// if the title has not been printed yet.
if (!titleLogged) {
String command = "";
for (final String cmd : cmdList) {
command += cmd + " ";
}
logger.severe((execTitle == null) ? command : execTitle);
}
do {
logger.severe(line);
processOutput.append(line).append("\n");
line = reader.readLine();
} while (line != null);
}
reader.close();
} catch (final IOException e) {
throw new CompilerError(GenericErrors.INTERNAL_ERROR, e,
"Can't read error stream of process");
}
}
};
readerThread.start();
final int rValue = process.waitFor();
readerThread.join();
return new ExecutionResult(rValue, processOutput);
}
/**
* Executes the given command line and returns the exit value.
*
* @param execTitle the message to be logged as a header of the execution. May
* be null
.
* @param cmdArray the command to execute.
* @return if its exit value is zero, return null, otherwise returns a string
* that contains the process output.
* @throws ADLException If an error occurs while running the command.
* @throws InterruptedException if the calling thread has been interrupted
* while waiting for the process to finish.
* @see #exec(String, List)
* @see Runtime#exec(String[])
*/
public static ExecutionResult exec(final String execTitle,
final String[] cmdArray) throws ADLException, InterruptedException {
return exec(execTitle, Arrays.asList(cmdArray));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy