/** * */ package cn.bran.japid.rendererloader; import java.util.Arrays; import java.util.Comparator; import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.ICompilerRequestor; import cn.bran.japid.exceptions.JapidTemplateException; import cn.bran.japid.template.JapidRenderer; import cn.bran.japid.util.DirUtil; import cn.bran.japid.util.JapidFlags; /** * @author bran * */ final class CompilerRequestor implements ICompilerRequestor { @Override public void acceptResult(CompilationResult result) { // If error if (result.hasErrors()) { // bran: sort the problems and report the first one CategorizedProblem[] errors = result.getErrors(); Arrays.sort(errors, new Comparator<CategorizedProblem>() { @Override public int compare(CategorizedProblem o1, CategorizedProblem o2) { return o1.getSourceLineNumber() - o2.getSourceLineNumber(); } }); for (IProblem problem : errors) { String className = new String(problem.getOriginatingFileName()).replace("/", "."); className = className.substring(0, className.length() - 5); String message = problem.getMessage(); int line = problem.getSourceLineNumber(); String srcFile = new String(problem.getOriginatingFileName()); if (problem.getID() == IProblem.CannotImportPackage) { // Non sense ! message = problem.getArguments()[0] + " cannot be resolved"; } RendererClass rc = JapidRenderer.japidClasses.get(className); // if (rc.getScriptFile() == null) // throw new RuntimeException("no source file for compiling " + className); if (rc.getJapidSourceCode() == null) throw new RuntimeException("no original source code for compiling " + className); String descr = srcFile + "(" + line + "): " + message; String javaSourceCode = rc.getJavaSourceCode(); int oriSrcLineNum = DirUtil.mapJavaLineToSrcLine(javaSourceCode, problem.getSourceLineNumber()); String scriptPath = rc.getScriptPath(); if (oriSrcLineNum > 0) { // has a original script marker descr = scriptPath + "(line " + oriSrcLineNum + "): " + message; JapidTemplateException te = new JapidTemplateException("Japid Compilation Error", descr, oriSrcLineNum, scriptPath, rc.getJapidSourceCode()); throw te; } else { JapidTemplateException te = new JapidTemplateException("Japid Compilation Error", descr, line, srcFile, javaSourceCode); throw te; } } } // Something has been compiled ClassFile[] clazzFiles = result.getClassFiles(); for (int i = 0; i < clazzFiles.length; i++) { final ClassFile clazzFile = clazzFiles[i]; final char[][] compoundName = clazzFile.getCompoundName(); final StringBuffer clazzName = new StringBuffer(); for (int j = 0; j < compoundName.length; j++) { if (j != 0) { clazzName.append('.'); } clazzName.append(compoundName[j]); } byte[] bytes = clazzFile.getBytes(); JapidFlags.debug("compiled: " + clazzName); // XXX address anonymous inner class issue!! ....$1... String cname = clazzName.toString(); RendererClass rc = JapidRenderer.japidClasses.get(cname); if (rc == null) { if (cname.contains("$")) { // inner class rc = new RendererClass(); rc.className = cname; JapidRenderer.japidClasses.put(cname, rc); } else { throw new RuntimeException("name not in the classes container: " + cname); } } rc.setBytecode(bytes); rc.setClz(null); rc.setLastCompiled(System.currentTimeMillis()); } } }