package org.rubypeople.rdt.internal.core.builder; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.SubMonitor; import org.rubypeople.rdt.core.IRubyProject; import org.rubypeople.rdt.core.RubyCore; import org.rubypeople.rdt.core.compiler.BuildContext; import org.rubypeople.rdt.core.compiler.CategorizedProblem; import org.rubypeople.rdt.core.compiler.CompilationParticipant; import org.rubypeople.rdt.internal.core.RubyModelManager; public abstract class AbstractRdtCompiler { protected final IProject project; protected final IMarkerManager markerManager; protected CompilationParticipant[] fParticipants; private IRubyProject fRubyProject; public AbstractRdtCompiler(IProject project, IMarkerManager markerManager) { this.project = project; this.markerManager = markerManager; this.fRubyProject = getRubyProject(); fParticipants = RubyModelManager.getRubyModelManager().compilationParticipants .getCompilationParticipants(fRubyProject); } protected abstract void removeMarkers(IMarkerManager markerManager, IProgressMonitor monitor); public void compile(IProgressMonitor monitor) throws CoreException { SubMonitor sub = SubMonitor.convert(monitor, "Building " + project.getName() + "...", 100); notifyParticipants(sub.newChild(5)); // traverse the delta BuildContext[] files = getBuildContexts(); sub.worked(5); int workUnitsPerTask = 90 / (fParticipants.length + 1); if (monitor.isCanceled()) throw new OperationCanceledException(); removeMarkers(markerManager, sub.newChild(workUnitsPerTask)); if (sub.isCanceled()) throw new OperationCanceledException(); compileFiles(files, sub.newChild(workUnitsPerTask * fParticipants.length)); monitor.done(); } private void notifyParticipants(IProgressMonitor monitor) { SubMonitor sub = SubMonitor.convert(monitor, "Notifying build participants", fParticipants.length); for (int i = 0; i < fParticipants.length; i++) { fParticipants[i].aboutToBuild(fRubyProject); sub.worked(1); } sub.done(); } private void compileFiles(BuildContext[] contexts, IProgressMonitor monitor) throws CoreException { SubMonitor sub = SubMonitor.convert(monitor, "Analyzing Files...", fParticipants.length + contexts.length); if (fParticipants != null) { for (int i = 0; i < fParticipants.length; i++) { if (monitor.isCanceled()) throw new OperationCanceledException(); try { long start = System.currentTimeMillis(); fParticipants[i].buildStarting(contexts, true, sub.newChild(1)); if (RubyBuilder.DEBUG) System.out.println(fParticipants[i].getClass().getSimpleName() + " took " + (System.currentTimeMillis() - start) + "ms"); } catch (Exception e) { RubyCore.log(e); } } } for (int i = 0; i < contexts.length; i++) { CategorizedProblem[] problems = contexts[i].getProblems(); if (problems == null || problems.length == 0) { sub.worked(1); continue; } for (int j = 0; j < problems.length; j++) { markerManager.addProblem(contexts[i].getFile(), problems[j]); } sub.worked(1); } sub.done(); } abstract protected BuildContext[] getBuildContexts() throws CoreException; private IRubyProject getRubyProject() { return RubyCore.create(project); } public void cleanStarting() { for (int i = 0; i < fParticipants.length; i++) { fParticipants[i].cleanStarting(fRubyProject); } } }