package externaltools;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
class StreamGobbler
extends Thread {
InputStream is;
String type;
Object lock;
boolean ready = false;
StreamGobbler (InputStream is, String type, Object lock) {
this.is = is;
this.type = type;
this.lock = lock;
}
@Override
public void run () {
int count = 0;
final int maxCount = 100000000;
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null ) {
count += line.length();
if(count > maxCount) {
System.err.println("ERROR: the output from the solver exceeds " + Integer.toString(maxCount)+ " characters."
+ "\n Your program has too many answer sets and we can't process all of them.");
// finish him!
Runtime.getRuntime().halt(0);
}
//System.out.println(type + ">" + line);
if(type.equals("STDOUT")) {
OsUtils.result.append(line).append("\n");
}
else if(type.equals("ERROR")) {
OsUtils.errors.append(line).append("\n");
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
synchronized (lock) {
ready = true;
lock.notifyAll();
}
}
public boolean isReady() {
return ready;
}
}
public class OsUtils {
public static StringBuffer result;
public static StringBuffer errors;
public static void runCommand(String path, String options,String input) {
Object lockStdOut = new Object();
Object lockStdErr = new Object();
Process process = null;
OsUtils.errors=new StringBuffer();
OsUtils.result = new StringBuffer();
try {
//create a new process for dlv
process = Runtime.getRuntime().exec(path+options);
} catch (IOException e) {
System.err.println(e.getMessage());
}
StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(),"ERROR",lockStdErr);
StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(),"STDOUT",lockStdOut);
// kick them off
errorGobbler.start();
outputGobbler.start();
try {
// write the provided input to the process
if(input != null) {
OutputStream stdin = process.getOutputStream();
stdin.write(input.getBytes(), 0, input.length());
stdin.flush();
stdin.close();
}
try {
process.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
// wait until error stream is ready:
synchronized(lockStdErr){
while (!errorGobbler.isReady()){
try {
lockStdErr.wait();
} catch (InterruptedException e) {
// This should never happen!
e.printStackTrace();
}
}
}
// wait until std out stream is ready:
synchronized(lockStdOut){
while (!outputGobbler.isReady()){
try {
lockStdOut.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (IOException ex) {
ex.printStackTrace(); // this exception should not occur!
}
}
}