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.compiler.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;
25 protected boolean cancelling;
26 protected float percentComplete;
27 protected float progressPerCompilationUnit;
28 protected int newErrorCount;
29 protected int fixedErrorCount;
30 protected int newWarningCount;
31 protected int fixedWarningCount;
32 protected int workDone;
33 protected int totalWork;
34 protected String previousSubtask;
36 public static int NewErrorCount = 0;
37 public static int FixedErrorCount = 0;
38 public static int NewWarningCount = 0;
39 public static int FixedWarningCount = 0;
41 public static void resetProblemCounters() {
45 FixedWarningCount = 0;
48 public BuildNotifier(IProgressMonitor monitor, IProject project) {
49 this.monitor = monitor;
50 this.cancelling = false;
51 this.newErrorCount = NewErrorCount;
52 this.fixedErrorCount = FixedErrorCount;
53 this.newWarningCount = NewWarningCount;
54 this.fixedWarningCount = FixedWarningCount;
56 this.totalWork = 1000000;
60 * Notification before a compile that a unit is about to be compiled.
62 public void aboutToCompile(SourceFile unit) {
63 String message = Util.bind("build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$
69 monitor.beginTask("", totalWork); //$NON-NLS-1$
70 this.previousSubtask = null;
74 * Check whether the build has been canceled.
76 public void checkCancel() {
77 if (monitor != null && monitor.isCanceled())
78 throw new OperationCanceledException();
82 * Check whether the build has been canceled.
83 * Must use this call instead of checkCancel() when within the compiler.
85 public void checkCancelWithinCompiler() {
86 if (monitor != null && monitor.isCanceled() && !cancelling) {
87 // Once the compiler has been canceled, don't check again.
89 // Only AbortCompilation can stop the compiler cleanly.
90 // We check cancelation again following the call to compile.
91 throw new AbortCompilation(true, null);
96 * Notification while within a compile that a unit has finished being compiled.
98 public void compiled(SourceFile unit) {
99 String message = Util.bind("build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$
101 updateProgressDelta(progressPerCompilationUnit);
102 checkCancelWithinCompiler();
106 NewErrorCount = this.newErrorCount;
107 FixedErrorCount = this.fixedErrorCount;
108 NewWarningCount = this.newWarningCount;
109 FixedWarningCount = this.fixedWarningCount;
111 updateProgress(1.0f);
112 subTask(Util.bind("build.done")); //$NON-NLS-1$
115 this.previousSubtask = null;
119 * Returns a string describing the problems.
121 protected String problemsMessage() {
122 int numNew = newErrorCount + newWarningCount;
123 int numFixed = fixedErrorCount + fixedWarningCount;
124 if (numNew == 0 && numFixed == 0) return ""; //$NON-NLS-1$
126 boolean displayBoth = numNew > 0 && numFixed > 0;
127 StringBuffer buffer = new StringBuffer();
130 // (Found x errors + y warnings)
131 buffer.append(Util.bind("build.foundHeader")); //$NON-NLS-1$
133 if (displayBoth || newErrorCount > 0) {
134 if (newErrorCount == 1)
135 buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$
137 buffer.append(Util.bind("build.multipleErrors", String.valueOf(newErrorCount))); //$NON-NLS-1$
138 if (displayBoth || newWarningCount > 0)
139 buffer.append(" + "); //$NON-NLS-1$
141 if (displayBoth || newWarningCount > 0) {
142 if (newWarningCount == 1)
143 buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$
145 buffer.append(Util.bind("build.multipleWarnings", String.valueOf(newWarningCount))); //$NON-NLS-1$
148 buffer.append(", "); //$NON-NLS-1$
151 // (Fixed x errors + y warnings) or (Found x errors + y warnings, Fixed x + y)
152 buffer.append(Util.bind("build.fixedHeader")); //$NON-NLS-1$
155 buffer.append(String.valueOf(fixedErrorCount));
156 buffer.append(" + "); //$NON-NLS-1$
157 buffer.append(String.valueOf(fixedWarningCount));
159 if (fixedErrorCount > 0) {
160 if (fixedErrorCount == 1)
161 buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$
163 buffer.append(Util.bind("build.multipleErrors", String.valueOf(fixedErrorCount))); //$NON-NLS-1$
164 if (fixedWarningCount > 0)
165 buffer.append(" + "); //$NON-NLS-1$
167 if (fixedWarningCount > 0) {
168 if (fixedWarningCount == 1)
169 buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$
171 buffer.append(Util.bind("build.multipleWarnings", String.valueOf(fixedWarningCount))); //$NON-NLS-1$
176 return buffer.toString();
180 * Sets the cancelling flag, which indicates we are in the middle
181 * of being cancelled. Certain places (those callable indirectly from the compiler)
182 * should not check cancel again while this is true, to avoid OperationCanceledException
183 * being thrown at an inopportune time.
185 public void setCancelling(boolean cancelling) {
186 this.cancelling = cancelling;
190 * Sets the amount of progress to report for compiling each compilation unit.
192 public void setProgressPerCompilationUnit(float progress) {
193 this.progressPerCompilationUnit = progress;
196 public void subTask(String message) {
197 String pm = problemsMessage();
198 String msg = pm.length() == 0 ? message : pm + " " + message; //$NON-NLS-1$
200 if (msg.equals(this.previousSubtask)) return; // avoid refreshing with same one
201 //if (JavaBuilder.DEBUG) System.out.println(msg);
203 monitor.subTask(msg);
205 this.previousSubtask = msg;
208 protected void updateProblemCounts(IProblem[] newProblems) {
209 for (int i = 0, l = newProblems.length; i < l; i++)
210 if (newProblems[i].isError()) newErrorCount++; else newWarningCount++;
214 * Update the problem counts from one compilation result given the old and new problems,
215 * either of which may be null.
217 protected void updateProblemCounts(IMarker[] oldProblems, IProblem[] newProblems) {
218 if (newProblems != null) {
219 next : for (int i = 0, l = newProblems.length; i < l; i++) {
220 IProblem newProblem = newProblems[i];
221 if (newProblem.getID() == IProblem.Task) continue; // skip task
222 boolean isError = newProblem.isError();
223 String message = newProblem.getMessage();
225 if (oldProblems != null) {
226 for (int j = 0, m = oldProblems.length; j < m; j++) {
227 IMarker pb = oldProblems[j];
228 if (pb == null) continue; // already matched up with a new problem
229 boolean wasError = IMarker.SEVERITY_ERROR
230 == pb.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
231 if (isError == wasError && message.equals(pb.getAttribute(IMarker.MESSAGE, ""))) { //$NON-NLS-1$
232 oldProblems[j] = null;
237 if (isError) newErrorCount++; else newWarningCount++;
240 if (oldProblems != null) {
241 next : for (int i = 0, l = oldProblems.length; i < l; i++) {
242 IMarker oldProblem = oldProblems[i];
243 if (oldProblem == null) continue next; // already matched up with a new problem
244 boolean wasError = IMarker.SEVERITY_ERROR
245 == oldProblem.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
246 String message = oldProblem.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$
248 if (newProblems != null) {
249 for (int j = 0, m = newProblems.length; j < m; j++) {
250 IProblem pb = newProblems[j];
251 if (pb.getID() == IProblem.Task) continue; // skip task
252 if (wasError == pb.isError() && message.equals(pb.getMessage()))
256 if (wasError) fixedErrorCount++; else fixedWarningCount++;
261 public void updateProgress(float percentComplete) {
262 if (percentComplete > this.percentComplete) {
263 this.percentComplete = Math.min(percentComplete, 1.0f);
264 int work = Math.round(this.percentComplete * this.totalWork);
265 if (work > this.workDone) {
267 monitor.worked(work - this.workDone);
268 //if (JavaBuilder.DEBUG)
269 //System.out.println(java.text.NumberFormat.getPercentInstance().format(this.percentComplete));
270 this.workDone = work;
275 public void updateProgressDelta(float percentWorked) {
276 updateProgress(percentComplete + percentWorked);