package com.kre8orz.i18n.mockup;
import com.kre8orz.i18n.processor.I18NProcessor;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.tools.Diagnostic;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
public class ProcessorMockup {
private static final List<I18NProcessor> processors;
static {
processors = new ArrayList<I18NProcessor>();
processors.add(new I18NProcessor());
}
private List<JavaFileObject> classes;
private JavaCompiler compiler;
private ListenerMockup diag;
private String dir;
private StandardJavaFileManager filer;
private boolean finished;
private List<String> options;
public ProcessorMockup(final String tmpDir, List<String> options) throws IOException {
this.finished = false;
this.compiler = ToolProvider.getSystemJavaCompiler();
this.diag = new ListenerMockup();
this.dir = tmpDir;
initFiler(tmpDir);
this.classes = new ArrayList<JavaFileObject>();
this.options = options;
}
public List<Diagnostic<? extends JavaFileObject>> getReport() {
return diag.getData();
}
public void process(String fqResourcePath) throws IOException {
if (finished) {
String msg = "Harnesses cannot be reused.";
throw new IllegalStateException(msg);
}
try {
CompilationTask task;
SourceInputFileMockup in = new SourceInputFileMockup(fqResourcePath);
classes.add(in);
task = compiler.getTask(null, filer, diag, options, null, classes);
task.setProcessors(processors);
if (task.call() && !diag.hasErrors()) {
Location loc = StandardLocation.CLASS_OUTPUT;
String ext = Kind.SOURCE.extension;
ClassLoader loader = filer.getClassLoader(loc);
String path = in.toUri().getPath();
String data = in.getCharContent(true).toString();
String line;
BufferedReader br = new BufferedReader(new StringReader(data));
String pkg = "";
Pattern pat = Pattern.compile("package\\s*(\\S+);.*");
while ((line = br.readLine()) != null) {
Matcher m = pat.matcher(line);
if (m.matches()) {
pkg = m.group(1);
break;
}
}
path = path.substring(path.lastIndexOf("/") + 1);
int idx = path.lastIndexOf(ext);
path = path.substring(0, idx);
path += "$Main";
if (!pkg.isEmpty()) {
path = pkg.replaceAll("\\\\", "\\.") + "." + path;
}
String cp = System.getProperty("java.class.path");
String exe = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
String[] cmd = new String[] { exe, "-classpath", "\"." + File.pathSeparator + dir+ File.pathSeparator + cp + "\" ", path};
ProcessWrapper wrapper = new ProcessWrapper(cmd, new String[]{}, dir);
wrapper.run(5000);
if (wrapper.getRetCode() != 0) {
throw new RuntimeException(wrapper.getStdErr());
}
} else {
diag.printDiagnostics();
throw new RuntimeException("Compilation failed");
} // end if-else
} finally {
classes.clear();
finished = true;
} // end try-finally
}
private void initFiler(final String tmpDir) throws IOException {
this.filer = compiler.getStandardFileManager(diag, null, null);
this.filer.setLocation(StandardLocation.SOURCE_OUTPUT, Arrays.asList(new File[] { new File(tmpDir) }));
this.filer.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File[] { new File(tmpDir) }));
}
}