/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.compiler.ij.api;
import gw.compiler.ij.api.messages.CompilationDoneMessage;
import gw.compiler.ij.api.messages.CompilationItem;
import gw.compiler.ij.api.messages.CompileIssueMessage;
import gw.compiler.ij.api.messages.CompiledMessage;
import gw.compiler.ij.api.messages.CompilingMessage;
import gw.compiler.ij.api.messages.RequestCompileMessage;
import gw.compiler.ij.api.messages.RequestTerminateMessage;
import gw.compiler.ij.api.messages.UncaughtExceptionMessage;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
public abstract class IDEDriver {
private static class State {
public final Process process;
public final ObjectClient client;
public State(Process process, ObjectClient client) {
this.process = process;
this.client = client;
}
}
private final AtomicReference<State> state = new AtomicReference();
protected static void close(State s, boolean force) {
if (force) {
s.process.destroy();
} else {
try {
s.client.write(RequestTerminateMessage.INSTANCE, true);
} catch (IOException e) {
s.process.destroy();
}
}
try {
s.process.waitFor();
} catch (InterruptedException e) {
Thread.interrupted();
}
}
protected abstract Process launchProcess() throws Exception;
public void compile(String moduleName, List<CompilationItem> items, IDECallback callback) {
State s = state.get();
if (s == null) {
try {
final Process process = launchProcess();
final ObjectClient client = new ObjectClient(process.getInputStream(), process.getOutputStream());
s = new State(process, client);
state.set(s);
} catch (Exception e) {
callback.fatalError("Can't launch external compiler: " + e.getMessage(), null);
return;
}
}
try {
s.client.write(new RequestCompileMessage(moduleName, items), true);
while (true) {
final Object message = s.client.read();
if ((message instanceof CompilingMessage)) {
callback.compiling(((CompilingMessage) message).item);
}
if ((message instanceof CompileIssueMessage)) {
final CompileIssueMessage m = (CompileIssueMessage) message;
callback.compileIssue(m.file, m.category, m.offset, m.line, m.column, m.message);
}
if ((message instanceof CompiledMessage)) {
final CompiledMessage m = (CompiledMessage) message;
callback.compiled(m.item, m.compilationTime, m.successfully, m.dependencies, m.displayKeyDependencies, m.fingerprint);
}
if ((message instanceof CompilationDoneMessage)) {
return;
}
if ((message instanceof UncaughtExceptionMessage)) {
close(s, true);
state.set(null);
callback.fatalError("Exception in remote compiler process", ((UncaughtExceptionMessage) message).e);
return;
}
}
} catch (IOException e) {
close(s, true);
state.set(null);
callback.fatalError("Exception during compilation", e);
}
}
public void close() {
final State s = state.getAndSet(null);
if (s != null) {
close(s, false);
}
}
}