1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core.builder;
13 import net.sourceforge.phpdt.core.compiler.IProblem;
14 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
15 import net.sourceforge.phpdt.internal.core.util.Util;
17 import org.eclipse.core.resources.IMarker;
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.core.runtime.OperationCanceledException;
22 public class BuildNotifier {
24 protected IProgressMonitor monitor;
26 protected boolean cancelling;
28 protected float percentComplete;
30 protected float progressPerCompilationUnit;
32 protected int newErrorCount;
34 protected int fixedErrorCount;
36 protected int newWarningCount;
38 protected int fixedWarningCount;
40 protected int workDone;
42 protected int totalWork;
44 protected String previousSubtask;
46 public static int NewErrorCount = 0;
48 public static int FixedErrorCount = 0;
50 public static int NewWarningCount = 0;
52 public static int FixedWarningCount = 0;
54 public static void resetProblemCounters() {
58 FixedWarningCount = 0;
61 public BuildNotifier(IProgressMonitor monitor, IProject project) {
62 this.monitor = monitor;
63 this.cancelling = false;
64 this.newErrorCount = NewErrorCount;
65 this.fixedErrorCount = FixedErrorCount;
66 this.newWarningCount = NewWarningCount;
67 this.fixedWarningCount = FixedWarningCount;
69 this.totalWork = 1000000;
73 * Notification before a compile that a unit is about to be compiled.
75 public void aboutToCompile(SourceFile unit) {
78 "build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$
84 monitor.beginTask("", totalWork); //$NON-NLS-1$
85 this.previousSubtask = null;
89 * Check whether the build has been canceled.
91 public void checkCancel() {
92 if (monitor != null && monitor.isCanceled())
93 throw new OperationCanceledException();
97 * Check whether the build has been canceled. Must use this call instead of
98 * checkCancel() when within the compiler.
100 public void checkCancelWithinCompiler() {
101 if (monitor != null && monitor.isCanceled() && !cancelling) {
102 // Once the compiler has been canceled, don't check again.
104 // Only AbortCompilation can stop the compiler cleanly.
105 // We check cancelation again following the call to compile.
106 throw new AbortCompilation(true, null);
111 * Notification while within a compile that a unit has finished being
114 public void compiled(SourceFile unit) {
115 String message = Util
117 "build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$
119 updateProgressDelta(progressPerCompilationUnit);
120 checkCancelWithinCompiler();
124 NewErrorCount = this.newErrorCount;
125 FixedErrorCount = this.fixedErrorCount;
126 NewWarningCount = this.newWarningCount;
127 FixedWarningCount = this.fixedWarningCount;
129 updateProgress(1.0f);
130 subTask(Util.bind("build.done")); //$NON-NLS-1$
133 this.previousSubtask = null;
137 * Returns a string describing the problems.
139 protected String problemsMessage() {
140 int numNew = newErrorCount + newWarningCount;
141 int numFixed = fixedErrorCount + fixedWarningCount;
142 if (numNew == 0 && numFixed == 0)
143 return ""; //$NON-NLS-1$
145 boolean displayBoth = numNew > 0 && numFixed > 0;
146 StringBuffer buffer = new StringBuffer();
149 // (Found x errors + y warnings)
150 buffer.append(Util.bind("build.foundHeader")); //$NON-NLS-1$
152 if (displayBoth || newErrorCount > 0) {
153 if (newErrorCount == 1)
154 buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$
159 "build.multipleErrors", String.valueOf(newErrorCount))); //$NON-NLS-1$
160 if (displayBoth || newWarningCount > 0)
161 buffer.append(" + "); //$NON-NLS-1$
163 if (displayBoth || newWarningCount > 0) {
164 if (newWarningCount == 1)
165 buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$
170 "build.multipleWarnings", String.valueOf(newWarningCount))); //$NON-NLS-1$
173 buffer.append(", "); //$NON-NLS-1$
176 // (Fixed x errors + y warnings) or (Found x errors + y warnings,
178 buffer.append(Util.bind("build.fixedHeader")); //$NON-NLS-1$
181 buffer.append(String.valueOf(fixedErrorCount));
182 buffer.append(" + "); //$NON-NLS-1$
183 buffer.append(String.valueOf(fixedWarningCount));
185 if (fixedErrorCount > 0) {
186 if (fixedErrorCount == 1)
187 buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$
192 "build.multipleErrors", String.valueOf(fixedErrorCount))); //$NON-NLS-1$
193 if (fixedWarningCount > 0)
194 buffer.append(" + "); //$NON-NLS-1$
196 if (fixedWarningCount > 0) {
197 if (fixedWarningCount == 1)
198 buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$
203 "build.multipleWarnings", String.valueOf(fixedWarningCount))); //$NON-NLS-1$
208 return buffer.toString();
212 * Sets the cancelling flag, which indicates we are in the middle of being
213 * cancelled. Certain places (those callable indirectly from the compiler)
214 * should not check cancel again while this is true, to avoid
215 * OperationCanceledException being thrown at an inopportune time.
217 public void setCancelling(boolean cancelling) {
218 this.cancelling = cancelling;
222 * Sets the amount of progress to report for compiling each compilation
225 public void setProgressPerCompilationUnit(float progress) {
226 this.progressPerCompilationUnit = progress;
229 public void subTask(String message) {
230 String pm = problemsMessage();
231 String msg = pm.length() == 0 ? message : pm + " " + message; //$NON-NLS-1$
233 if (msg.equals(this.previousSubtask))
234 return; // avoid refreshing with same one
235 // if (JavaBuilder.DEBUG) System.out.println(msg);
237 monitor.subTask(msg);
239 this.previousSubtask = msg;
242 protected void updateProblemCounts(IProblem[] newProblems) {
243 for (int i = 0, l = newProblems.length; i < l; i++)
244 if (newProblems[i].isError())
251 * Update the problem counts from one compilation result given the old and
252 * new problems, either of which may be null.
254 protected void updateProblemCounts(IMarker[] oldProblems,
255 IProblem[] newProblems) {
256 if (newProblems != null) {
257 next: for (int i = 0, l = newProblems.length; i < l; i++) {
258 IProblem newProblem = newProblems[i];
259 if (newProblem.getID() == IProblem.Task)
260 continue; // skip task
261 boolean isError = newProblem.isError();
262 String message = newProblem.getMessage();
264 if (oldProblems != null) {
265 for (int j = 0, m = oldProblems.length; j < m; j++) {
266 IMarker pb = oldProblems[j];
268 continue; // already matched up with a new problem
269 boolean wasError = IMarker.SEVERITY_ERROR == pb
270 .getAttribute(IMarker.SEVERITY,
271 IMarker.SEVERITY_ERROR);
272 if (isError == wasError
273 && message.equals(pb.getAttribute(
274 IMarker.MESSAGE, ""))) { //$NON-NLS-1$
275 oldProblems[j] = null;
286 if (oldProblems != null) {
287 next: for (int i = 0, l = oldProblems.length; i < l; i++) {
288 IMarker oldProblem = oldProblems[i];
289 if (oldProblem == null)
290 continue next; // already matched up with a new problem
291 boolean wasError = IMarker.SEVERITY_ERROR == oldProblem
292 .getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
293 String message = oldProblem.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$
295 if (newProblems != null) {
296 for (int j = 0, m = newProblems.length; j < m; j++) {
297 IProblem pb = newProblems[j];
298 if (pb.getID() == IProblem.Task)
299 continue; // skip task
300 if (wasError == pb.isError()
301 && message.equals(pb.getMessage()))
313 public void updateProgress(float percentComplete) {
314 if (percentComplete > this.percentComplete) {
315 this.percentComplete = Math.min(percentComplete, 1.0f);
316 int work = Math.round(this.percentComplete * this.totalWork);
317 if (work > this.workDone) {
319 monitor.worked(work - this.workDone);
320 // if (JavaBuilder.DEBUG)
321 // System.out.println(java.text.NumberFormat.getPercentInstance().format(this.percentComplete));
322 this.workDone = work;
327 public void updateProgressDelta(float percentWorked) {
328 updateProgress(percentComplete + percentWorked);