A massive organize imports and formatting of the sources using default Eclipse code...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / builder / BuildNotifier.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core.builder;
12
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;
16
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;
21
22 public class BuildNotifier {
23
24         protected IProgressMonitor monitor;
25
26         protected boolean cancelling;
27
28         protected float percentComplete;
29
30         protected float progressPerCompilationUnit;
31
32         protected int newErrorCount;
33
34         protected int fixedErrorCount;
35
36         protected int newWarningCount;
37
38         protected int fixedWarningCount;
39
40         protected int workDone;
41
42         protected int totalWork;
43
44         protected String previousSubtask;
45
46         public static int NewErrorCount = 0;
47
48         public static int FixedErrorCount = 0;
49
50         public static int NewWarningCount = 0;
51
52         public static int FixedWarningCount = 0;
53
54         public static void resetProblemCounters() {
55                 NewErrorCount = 0;
56                 FixedErrorCount = 0;
57                 NewWarningCount = 0;
58                 FixedWarningCount = 0;
59         }
60
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;
68                 this.workDone = 0;
69                 this.totalWork = 1000000;
70         }
71
72         /**
73          * Notification before a compile that a unit is about to be compiled.
74          */
75         public void aboutToCompile(SourceFile unit) {
76                 String message = Util
77                                 .bind(
78                                                 "build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$
79                 subTask(message);
80         }
81
82         public void begin() {
83                 if (monitor != null)
84                         monitor.beginTask("", totalWork); //$NON-NLS-1$
85                 this.previousSubtask = null;
86         }
87
88         /**
89          * Check whether the build has been canceled.
90          */
91         public void checkCancel() {
92                 if (monitor != null && monitor.isCanceled())
93                         throw new OperationCanceledException();
94         }
95
96         /**
97          * Check whether the build has been canceled. Must use this call instead of
98          * checkCancel() when within the compiler.
99          */
100         public void checkCancelWithinCompiler() {
101                 if (monitor != null && monitor.isCanceled() && !cancelling) {
102                         // Once the compiler has been canceled, don't check again.
103                         setCancelling(true);
104                         // Only AbortCompilation can stop the compiler cleanly.
105                         // We check cancelation again following the call to compile.
106                         throw new AbortCompilation(true, null);
107                 }
108         }
109
110         /**
111          * Notification while within a compile that a unit has finished being
112          * compiled.
113          */
114         public void compiled(SourceFile unit) {
115                 String message = Util
116                                 .bind(
117                                                 "build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$
118                 subTask(message);
119                 updateProgressDelta(progressPerCompilationUnit);
120                 checkCancelWithinCompiler();
121         }
122
123         public void done() {
124                 NewErrorCount = this.newErrorCount;
125                 FixedErrorCount = this.fixedErrorCount;
126                 NewWarningCount = this.newWarningCount;
127                 FixedWarningCount = this.fixedWarningCount;
128
129                 updateProgress(1.0f);
130                 subTask(Util.bind("build.done")); //$NON-NLS-1$
131                 if (monitor != null)
132                         monitor.done();
133                 this.previousSubtask = null;
134         }
135
136         /**
137          * Returns a string describing the problems.
138          */
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$
144
145                 boolean displayBoth = numNew > 0 && numFixed > 0;
146                 StringBuffer buffer = new StringBuffer();
147                 buffer.append('(');
148                 if (numNew > 0) {
149                         // (Found x errors + y warnings)
150                         buffer.append(Util.bind("build.foundHeader")); //$NON-NLS-1$
151                         buffer.append(' ');
152                         if (displayBoth || newErrorCount > 0) {
153                                 if (newErrorCount == 1)
154                                         buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$
155                                 else
156                                         buffer
157                                                         .append(Util
158                                                                         .bind(
159                                                                                         "build.multipleErrors", String.valueOf(newErrorCount))); //$NON-NLS-1$
160                                 if (displayBoth || newWarningCount > 0)
161                                         buffer.append(" + "); //$NON-NLS-1$
162                         }
163                         if (displayBoth || newWarningCount > 0) {
164                                 if (newWarningCount == 1)
165                                         buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$
166                                 else
167                                         buffer
168                                                         .append(Util
169                                                                         .bind(
170                                                                                         "build.multipleWarnings", String.valueOf(newWarningCount))); //$NON-NLS-1$
171                         }
172                         if (numFixed > 0)
173                                 buffer.append(", "); //$NON-NLS-1$
174                 }
175                 if (numFixed > 0) {
176                         // (Fixed x errors + y warnings) or (Found x errors + y warnings,
177                         // Fixed x + y)
178                         buffer.append(Util.bind("build.fixedHeader")); //$NON-NLS-1$
179                         buffer.append(' ');
180                         if (displayBoth) {
181                                 buffer.append(String.valueOf(fixedErrorCount));
182                                 buffer.append(" + "); //$NON-NLS-1$
183                                 buffer.append(String.valueOf(fixedWarningCount));
184                         } else {
185                                 if (fixedErrorCount > 0) {
186                                         if (fixedErrorCount == 1)
187                                                 buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$
188                                         else
189                                                 buffer
190                                                                 .append(Util
191                                                                                 .bind(
192                                                                                                 "build.multipleErrors", String.valueOf(fixedErrorCount))); //$NON-NLS-1$
193                                         if (fixedWarningCount > 0)
194                                                 buffer.append(" + "); //$NON-NLS-1$
195                                 }
196                                 if (fixedWarningCount > 0) {
197                                         if (fixedWarningCount == 1)
198                                                 buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$
199                                         else
200                                                 buffer
201                                                                 .append(Util
202                                                                                 .bind(
203                                                                                                 "build.multipleWarnings", String.valueOf(fixedWarningCount))); //$NON-NLS-1$
204                                 }
205                         }
206                 }
207                 buffer.append(')');
208                 return buffer.toString();
209         }
210
211         /**
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.
216          */
217         public void setCancelling(boolean cancelling) {
218                 this.cancelling = cancelling;
219         }
220
221         /**
222          * Sets the amount of progress to report for compiling each compilation
223          * unit.
224          */
225         public void setProgressPerCompilationUnit(float progress) {
226                 this.progressPerCompilationUnit = progress;
227         }
228
229         public void subTask(String message) {
230                 String pm = problemsMessage();
231                 String msg = pm.length() == 0 ? message : pm + " " + message; //$NON-NLS-1$
232
233                 if (msg.equals(this.previousSubtask))
234                         return; // avoid refreshing with same one
235                 // if (JavaBuilder.DEBUG) System.out.println(msg);
236                 if (monitor != null)
237                         monitor.subTask(msg);
238
239                 this.previousSubtask = msg;
240         }
241
242         protected void updateProblemCounts(IProblem[] newProblems) {
243                 for (int i = 0, l = newProblems.length; i < l; i++)
244                         if (newProblems[i].isError())
245                                 newErrorCount++;
246                         else
247                                 newWarningCount++;
248         }
249
250         /**
251          * Update the problem counts from one compilation result given the old and
252          * new problems, either of which may be null.
253          */
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();
263
264                                 if (oldProblems != null) {
265                                         for (int j = 0, m = oldProblems.length; j < m; j++) {
266                                                 IMarker pb = oldProblems[j];
267                                                 if (pb == null)
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;
276                                                         continue next;
277                                                 }
278                                         }
279                                 }
280                                 if (isError)
281                                         newErrorCount++;
282                                 else
283                                         newWarningCount++;
284                         }
285                 }
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$
294
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()))
302                                                         continue next;
303                                         }
304                                 }
305                                 if (wasError)
306                                         fixedErrorCount++;
307                                 else
308                                         fixedWarningCount++;
309                         }
310                 }
311         }
312
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) {
318                                 if (monitor != null)
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;
323                         }
324                 }
325         }
326
327         public void updateProgressDelta(float percentWorked) {
328                 updateProgress(percentComplete + percentWorked);
329         }
330 }