package monolipse.core.runtime;
import java.io.*;
import java.nio.charset.*;
import java.util.*;
import monolipse.core.*;
import monolipse.core.foundation.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
public abstract class CompilerLauncher implements IMonoCompilerLauncher {
public static CompilerLauncher createLauncher(AssemblySourceLanguage language) throws IOException {
if (language.equals(AssemblySourceLanguage.BOO))
return new BooCompilerLauncher();
if (language.equals(AssemblySourceLanguage.BOOJAY))
return new BoojayCompilerLauncher();
return new CSharpCompilerLauncher(language);
}
public static CompilerLauncher createLauncher(IAssemblySource source) throws IOException, CoreException {
CompilerLauncher launcher = createLauncher(source.getLanguage());
launcher.setOutput(source.getOutputFile());
launcher.setOutputType(source.getOutputType());
launcher.add(source.getAdditionalOptions().split("\\s+"));
launcher.addReferences(source.getReferences());
if (source.getLanguage().equals(AssemblySourceLanguage.BOOJAY)) {
launcher.addReferences(classpathEntryReferencesFor(source));
}
return launcher;
}
private static String[] classpathEntryReferencesFor(IAssemblySource source) {
ArrayList<String> result = new ArrayList<String>();
try {
addClasspathEntriesTo(result, javaProjectFor(source).getResolvedClasspath(true));
} catch (JavaModelException e) {
BooCore.logException(e);
}
return result.toArray(new String[result.size()]);
}
private static IJavaProject javaProjectFor(IAssemblySource source) {
return JavaCore.create(source.getFolder().getProject());
}
private static void addClasspathEntriesTo(ArrayList<String> result, IClasspathEntry[] classpaths) {
for (IClasspathEntry classpath: classpaths)
addClasspathEntryTo(result, classpath);
}
private static void addClasspathEntryTo(ArrayList<String> result, IClasspathEntry classpath) {
int entryKind = classpath.getEntryKind();
if (entryKind == IClasspathEntry.CPE_LIBRARY) {
String ref = classpath.getPath().toOSString();
logInfo("Classpath " + classpath + " referenced as '" + ref + "'");
result.add(ref);
return;
}
logInfo("Skipping " + classpath);
}
private static void logInfo(String message) {
BooCore.logInfo(message);
}
private final IMonoLauncher _launcher;
private ResponseFile _responseFile;
protected CompilerLauncher(String compiler) throws IOException {
this(BooCore.createLauncher(compiler));
}
protected CompilerLauncher(final IMonoLauncher launcher) throws IOException {
_launcher = launcher;
enableDebugging();
enableResponseFile();
}
private void enableResponseFile() throws IOException {
_responseFile = new ResponseFile();
}
public void add(String[] args) {
for (int i = 0; i < args.length; i++) {
add(args[i]);
}
}
public void add(String arg) {
if (null != _responseFile) {
addToResponseFile(arg);
} else {
_launcher.add(arg);
}
}
private void addToResponseFile(String arg) {
try {
_responseFile.add(arg);
} catch (IOException e) {
BooCore.logException(e);
}
}
public void setWorkingDir(File workingDir) {
_launcher.setWorkingDir(workingDir);
}
public Process launch() throws IOException {
ensureResponseFile();
return _launcher.launch();
}
private void ensureResponseFile() {
if (null != _responseFile) {
_responseFile.close();
_launcher.add(_responseFile.toString());
_responseFile = null;
}
}
public void enableDebugging() {
add("-debug+");
}
public void setPipeline(String pipeline) {
add("-p:" + pipeline);
}
public void setOutputType(String outputType) {
add("-target:" + outputType);
}
public void setOutput(IResource output) {
add("-out:" + WorkspaceUtilities.getLocation(output));
}
public void setOutput(String output) {
add("-out:" + output);
}
public void addReferences(IAssemblyReference[] references) throws CoreException {
for (IAssemblyReference ref : references)
add("-r:" + ref.getCompilerReference());
}
public void addReferences(String[] references) {
for (int i=0; i<references.length; ++i) {
add("-r:" + references[i]);
}
}
public void addSourceFiles(IFile[] files) {
for (int i=0; i<files.length; ++i) {
add(WorkspaceUtilities.getLocation(files[i]));
}
}
public CompilerError[] run() throws IOException {
Process p = launch();
ArrayList<CompilerError> errors = new ArrayList<CompilerError>();
parseCompilerOutput(p.getErrorStream(), errors);
parseCompilerOutput(p.getInputStream(), errors);
return errors.toArray(new CompilerError[errors.size()]);
}
private void parseCompilerOutput(InputStream stream, ArrayList<CompilerError> errors) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, Charset.forName("utf-8")));
String line = null;
while (null != (line = reader.readLine())) {
CompilerError error = parseCompilerError(line);
if (null != error) errors.add(error);
}
}
protected abstract CompilerError parseCompilerError(String line);
}