package tests;
import java.io.StringWriter;
import java.util.*;
import javax.tools.*;
import java.io.*;
public class TestInput {
public boolean debug = false;
private JavaCompiler compiler;
private StandardJavaFileManager fileManager;
private Iterable<? extends JavaFileObject> files;
private Iterable<String> processors;
private List<String> options;
private static final String OUTDIR = System.getProperty("tests.outputDir",
"tests" + File.separator + "build" + File.separator + "testclasses");
static { ensureExistance(OUTDIR); }
public TestInput(Iterable<? extends JavaFileObject> files,
Iterable<String> processors, String[] options) {
this.compiler = ToolProvider.getSystemJavaCompiler();
this.fileManager = compiler.getStandardFileManager(null, null, null);
this.files = files;
this.processors = processors;
this.options = new LinkedList<String>();
String classpath = System.getProperty("tests.classpath",
"tests" + File.separator + "build");
String globalclasspath = System.getProperty("java.class.path", "");
this.options.add("-Xmaxerrs");
this.options.add("9999");
this.options.add("-g");
this.options.add("-d");
this.options.add(OUTDIR);
this.options.add("-classpath");
this.options.add("build" + File.pathSeparator + "junit.jar"
+ File.pathSeparator + classpath + File.pathSeparator
+ globalclasspath);
this.options.addAll(Arrays.asList(options));
}
private static void ensureExistance(String path) {
File file = new File(path);
if (!file.exists())
file.mkdirs();
}
public TestRun run() {
StringWriter output = new StringWriter();
DiagnosticCollector<JavaFileObject> diagnostics = new
DiagnosticCollector<JavaFileObject>();
if (debug) {
System.out.printf("TestInput.run:%n options: %s%n processors: %s%n files: %s%n",
this.options, this.processors, this.files);
}
JavaCompiler.CompilationTask task = compiler.getTask(output, fileManager,
diagnostics, this.options, this.processors, this.files);
// Method
// com.sun.tools.javac.main.Main.apMessage(AnnotationProcessingError ex)
// may print the stack trace of an exception to standard output,
// even though the exception is later handled. (Why is that
// printed to standard out whereas diagnostic messages are not?
// And why does it happen here but not when javac is run from the
// command line?) We need to figure out how to redirect that stack
// trace elsewhere, to avoid looking like it was thrown during
// execution of the test. (There's a javac option -Xstdout, but it
// isn't recognized by JavacTool.)
Boolean result = task.call();
return new TestRun(result, output.toString(), diagnostics.getDiagnostics());
}
public static TestRun compileAndCheck(Iterable<? extends JavaFileObject> files,
String processor, String[] options) {
List<String> opts = new LinkedList<String>();
if (processor != null) {
opts.add("-processor");
opts.add(processor);
}
opts.add("-source");
opts.add("1.7");
for (String option : options)
opts.add(option);
TestInput input = new TestInput(files,
Collections.<String>emptySet(),
opts.toArray(new String[opts.size()]));
return input.run();
}
}