package de.mxro.process.internal;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.ProcessBuilder.Redirect;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;
import de.mxro.process.ProcessListener;
import de.mxro.process.XProcess;
public class Engine {
public static XProcess startProcess(final String[] command,
final ProcessListener listener, final File folder) {
final ProcessBuilder pb;
final Process process;
try {
pb = new ProcessBuilder(command);
pb.directory(folder);
pb.redirectOutput(Redirect.PIPE);
pb.redirectInput(Redirect.PIPE);
process = pb.start();
} catch (final IOException e) {
throw new RuntimeException(e);
}
final AtomicLong lastOutput = new AtomicLong();
final long startTime = new Date().getTime();
lastOutput.set(0);
final OutputStream outputStream = process.getOutputStream();
final InputStream inputStream = process.getInputStream();
final InputStream errorStream = process.getErrorStream();
//BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
// String line;
// try {
// line = reader.readLine();
// while (line != null && !line.trim().equals("--EOF--")) {
// listener.onOutputLine(line);
// line = reader.readLine();
// }
// } catch (IOException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
final StreamReader streamReader = new StreamReader(inputStream,
new StreamListener() {
@Override
public void onOutputLine(final String line) {
//System.out.println("Receiving line");
lastOutput.set(new Date().getTime());
listener.onOutputLine(line);
}
@Override
public void onError(final Throwable t) {
listener.onError(new Exception(
"Error while reading standard output", t));
}
@Override
public void onClosed() {
}
});
final StreamReader errorStreamReader = new StreamReader(errorStream,
new StreamListener() {
@Override
public void onOutputLine(final String line) {
lastOutput.set(new Date().getTime());
listener.onErrorLine(line);
}
@Override
public void onError(final Throwable t) {
listener.onError(new Exception(
"Error while reading error output", t));
}
@Override
public void onClosed() {
}
});
new Thread() {
@Override
public void run() {
errorStreamReader.read();
}
}.start();
new Thread() {
@Override
public void run() {
try {
streamReader.read();
final int returnValue = process.waitFor();
//while (lastOutput.get() == 0 && new Date().getTime() - startTime < 500) {
// Thread.sleep(10);
//}
//while ( new Date().getTime() - lastOutput.get() < 1000) {
// System.out.println("DELAY ... "+(new Date().getTime() - lastOutput.get()));
// Thread.sleep(500);
//}
//System.out.println("processes finished with "+returnValue);
listener.onProcessQuit(returnValue);
} catch (final InterruptedException e) {
listener.onError(e);
return;
}
}
}.start();
return new XProcess() {
@Override
public synchronized void sendLine(final String line) {
final BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(outputStream));
try {
writer.append(line);
} catch (final IOException e) {
listener.onError(e);
}
}
@Override
public void destory() {
process.destroy();
try {
process.waitFor();
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
try {
errorStreamReader.stop();
outputStream.close();
inputStream.close();
errorStream.close();
} catch (final IOException e) {
listener.onError(e);
}
}
};
}
}