KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ant > internal > core > ant > ProgressBuildListener


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ant.internal.core.ant;
12
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Enumeration JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Hashtable JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Set JavaDoc;
22
23 import org.apache.tools.ant.BuildEvent;
24 import org.apache.tools.ant.BuildListener;
25 import org.apache.tools.ant.Project;
26 import org.apache.tools.ant.Target;
27 import org.apache.tools.ant.Task;
28 import org.apache.tools.ant.taskdefs.Ant;
29 import org.apache.tools.ant.taskdefs.CallTarget;
30 import org.eclipse.ant.core.AntCorePlugin;
31 import org.eclipse.core.runtime.IProgressMonitor;
32 import org.eclipse.core.runtime.NullProgressMonitor;
33 import org.eclipse.core.runtime.OperationCanceledException;
34 import org.eclipse.core.runtime.SubProgressMonitor;
35
36 /**
37  * Reports progress and checks for cancelation of a script execution.
38  */

39 public class ProgressBuildListener implements BuildListener {
40
41     protected Map JavaDoc projects;
42     protected Project mainProject;
43     protected Project parentProject;
44     private Thread JavaDoc currentTaskThread;
45
46     /**
47      * Contains the progress monitor instances for the various
48      * projects in a chain.
49      */

50     protected class ProjectMonitors {
51         /**
52          * This field is null for the main project
53          */

54         private Target mainTarget;
55         private IProgressMonitor mainMonitor;
56         private IProgressMonitor targetMonitor;
57         private IProgressMonitor taskMonitor;
58         
59         protected IProgressMonitor getMainMonitor() {
60             return mainMonitor;
61         }
62
63         protected Target getMainTarget() {
64             return mainTarget;
65         }
66
67         protected IProgressMonitor getTargetMonitor() {
68             return targetMonitor;
69         }
70
71         protected IProgressMonitor getTaskMonitor() {
72             return taskMonitor;
73         }
74
75         protected void setMainMonitor(IProgressMonitor mainMonitor) {
76             this.mainMonitor = mainMonitor;
77         }
78
79         protected void setMainTarget(Target mainTarget) {
80             this.mainTarget = mainTarget;
81         }
82
83         protected void setTargetMonitor(IProgressMonitor targetMonitor) {
84             this.targetMonitor = targetMonitor;
85         }
86
87         protected void setTaskMonitor(IProgressMonitor taskMonitor) {
88             this.taskMonitor = taskMonitor;
89         }
90
91     }
92
93     public ProgressBuildListener(Project project, List JavaDoc targetNames, IProgressMonitor monitor) {
94         projects = new HashMap JavaDoc();
95         mainProject = project;
96         ProjectMonitors monitors = new ProjectMonitors();
97         if (monitor == null) {
98             monitor= new NullProgressMonitor();
99         }
100         monitors.setMainMonitor(monitor);
101         projects.put(mainProject, monitors);
102         List JavaDoc targets= new ArrayList JavaDoc(targetNames.size());
103         for (int i = 0; i < targetNames.size(); i++) {
104             String JavaDoc targetName = (String JavaDoc) targetNames.get(i);
105             Target target= (Target) mainProject.getTargets().get(targetName);
106             if (target != null) {
107                 targets.add(target);
108             }
109         }
110         int work = computeWork(targets);
111         monitors.getMainMonitor().beginTask("", work); //$NON-NLS-1$
112
}
113
114     /* (non-Javadoc)
115      * @see org.apache.tools.ant.BuildListener#buildStarted(org.apache.tools.ant.BuildEvent)
116      */

117     public void buildStarted(BuildEvent event) {
118         checkCanceled();
119     }
120
121     protected int computeWork(List JavaDoc targets) {
122         int result = 0;
123         for (int i = 0; i < targets.size(); i++) {
124             result = result + countTarget((Target)targets.get(i), new ArrayList JavaDoc());
125         }
126         return result;
127     }
128
129     protected int countTarget(Target target, List JavaDoc alreadySeen) {
130         int result = 1;
131         Project project = target.getProject();
132         Hashtable JavaDoc targets= project.getTargets();
133         String JavaDoc targetName;
134         Target dependency;
135         for (Enumeration JavaDoc dependencies = target.getDependencies(); dependencies.hasMoreElements();) {
136             targetName = (String JavaDoc) dependencies.nextElement();
137             if (alreadySeen.contains(targetName)) { //circular dependency or common dependancy
138
return result;
139             }
140             alreadySeen.add(targetName);
141             dependency = (Target)targets.get(targetName);
142             if (dependency != null) {
143                 result = result + countTarget(dependency, alreadySeen);
144             }
145         }
146         // we have to handle antcall tasks as well
147
Task[] tasks = target.getTasks();
148         for (int i = 0; i < tasks.length; i++) {
149             if (tasks[i] instanceof CallTarget) {
150                 // As we do not have access to the information (at least in Ant 1.4.1)
151
// describing what target is executed by this antcall task, we assume
152
// a scenario where it depends on all targets of the project but itself.
153
result = result + (targets.size() - 1);
154             }
155         }
156         return result;
157     }
158
159     /* (non-Javadoc)
160      * @see org.apache.tools.ant.BuildListener#buildFinished(org.apache.tools.ant.BuildEvent)
161      */

162     public void buildFinished(BuildEvent event) {
163         ProjectMonitors monitors = (ProjectMonitors) projects.get(mainProject);
164         monitors.getMainMonitor().done();
165         Set JavaDoc keys= projects.keySet();
166         Iterator JavaDoc itr= keys.iterator();
167         while (itr.hasNext()) {
168             Project project = (Project) itr.next();
169             project.removeBuildListener(this);
170             project.getReferences().remove(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR);
171         }
172     }
173
174     /* (non-Javadoc)
175      * @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent)
176      */

177     public void targetStarted(BuildEvent event) {
178         checkCanceled();
179         Project currentProject = event.getProject();
180         if (currentProject == null) {
181             return;
182         }
183         Target target = event.getTarget();
184         ProjectMonitors monitors = (ProjectMonitors) projects.get(currentProject);
185
186         // if monitors is null we are in a new script
187
if (monitors == null) {
188             monitors = createMonitors(currentProject, target);
189         }
190
191         monitors.setTargetMonitor(subMonitorFor(monitors.getMainMonitor(), 1));
192         int work = (target != null) ? target.getTasks().length : 100;
193         monitors.getTargetMonitor().beginTask("", work); //$NON-NLS-1$
194
}
195
196     protected ProjectMonitors createMonitors(Project currentProject, Target target) {
197         ProjectMonitors monitors = new ProjectMonitors();
198         // remember the target so we can remove this monitors object later
199
monitors.setMainTarget(target);
200         List JavaDoc targets= new ArrayList JavaDoc(1);
201         targets.add(target);
202         int work = computeWork(targets);
203         ProjectMonitors parentMonitors = null;
204         if (parentProject == null) {
205             parentMonitors = (ProjectMonitors) projects.get(mainProject);
206             monitors.setMainMonitor(subMonitorFor(parentMonitors.getMainMonitor(), 1));
207         } else {
208             parentMonitors = (ProjectMonitors) projects.get(parentProject);
209             parentProject = null;
210             monitors.setMainMonitor(subMonitorFor(parentMonitors.getTaskMonitor(), 1));
211         }
212         monitors.getMainMonitor().beginTask("", work); //$NON-NLS-1$
213
projects.put(currentProject, monitors);
214         return monitors;
215     }
216
217     /* (non-Javadoc)
218      * @see org.apache.tools.ant.BuildListener#targetFinished(org.apache.tools.ant.BuildEvent)
219      */

220     public void targetFinished(BuildEvent event) {
221         checkCanceled();
222         Project currentProject = event.getProject();
223         if (currentProject == null) {
224             return;
225         }
226         ProjectMonitors monitors = (ProjectMonitors) projects.get(currentProject);
227         if (monitors == null) {
228             return;
229         }
230         monitors.getTargetMonitor().done();
231         // if this is not the main project test if we are done with this project
232
if ((currentProject != mainProject) && (monitors.getMainTarget() == event.getTarget())) {
233             monitors.getMainMonitor().done();
234             projects.remove(currentProject);
235         }
236     }
237
238     /* (non-Javadoc)
239      * @see org.apache.tools.ant.BuildListener#taskStarted(org.apache.tools.ant.BuildEvent)
240      */

241     public void taskStarted(BuildEvent event) {
242         checkCanceled();
243         Project currentProject = event.getProject();
244         if (currentProject == null) {
245             return;
246         }
247         currentProject.getReferences().remove(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR);
248         ProjectMonitors monitors = (ProjectMonitors) projects.get(currentProject);
249         if (monitors == null) {
250             return;
251         }
252         Task task = event.getTask();
253         if (task == null) {
254             return;
255         }
256         currentTaskThread= Thread.currentThread();
257         monitors.setTaskMonitor(subMonitorFor(monitors.getTargetMonitor(), 1));
258         monitors.getTaskMonitor().beginTask("", 1); //$NON-NLS-1$
259
// If this script is calling another one, track the project chain.
260
if (task instanceof Ant) {
261             parentProject = currentProject;
262         } else {
263             currentProject.addReference(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR, monitors.getTaskMonitor());
264         }
265     }
266
267     /* (non-Javadoc)
268      * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent)
269      */

270     public void taskFinished(BuildEvent event) {
271         checkCanceled();
272         Project project = event.getProject();
273         if (project == null) {
274             return;
275         }
276         project.getReferences().remove(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR);
277         ProjectMonitors monitors = (ProjectMonitors) projects.get(project);
278         if (monitors == null) {
279             return;
280         }
281         monitors.getTaskMonitor().done();
282         currentTaskThread= null;
283     }
284
285     /* (non-Javadoc)
286      * @see org.apache.tools.ant.BuildListener#messageLogged(org.apache.tools.ant.BuildEvent)
287      */

288     public void messageLogged(BuildEvent event) {
289         checkCanceled();
290     }
291
292     protected void checkCanceled() {
293         //only cancel if the current task thread matches the current thread
294
//do not want to throw an exception in a separate thread or process
295
//see bug 32657
296
if (currentTaskThread != null && currentTaskThread != Thread.currentThread()) {
297             return;
298         }
299         ProjectMonitors monitors = (ProjectMonitors) projects.get(mainProject);
300         if (monitors.getMainMonitor().isCanceled()) {
301             currentTaskThread= null;
302             throw new OperationCanceledException(InternalAntMessages.ProgressBuildListener_Build_cancelled__5);
303         }
304     }
305
306     protected IProgressMonitor subMonitorFor(IProgressMonitor monitor, int ticks) {
307         if (monitor == null) {
308             return new NullProgressMonitor();
309         }
310         if (monitor instanceof NullProgressMonitor) {
311             return monitor;
312         }
313         return new SubProgressMonitor(monitor, ticks);
314     }
315 }
316
Popular Tags