blob: 076573c65390474c3048b0b857d7065a4a5970cf [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2002 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.ant.internal.core.ant;
import java.util.*;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.tools.ant.*;
import org.apache.tools.ant.taskdefs.Ant;
import org.apache.tools.ant.taskdefs.CallTarget;
import org.eclipse.ant.core.AntCorePlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
/**
* Reports progress and checks for cancelation of a script execution.
*/
public class ProgressBuildListener implements BuildListener {
protected Hashtable projects;
protected Project mainProject;
protected Project parentProject;
// cointains the progress monitor instances for the various
// projects in a chain
protected class ProjectMonitors {
// this field is null for the main project
Target mainTarget;
IProgressMonitor mainMonitor;
IProgressMonitor targetMonitor;
IProgressMonitor taskMonitor;
}
public ProgressBuildListener(Project project, Vector targetNames, IProgressMonitor monitor) {
projects = new Hashtable();
this.mainProject = project;
ProjectMonitors monitors = new ProjectMonitors();
monitors.mainMonitor = Policy.monitorFor(monitor);
projects.put(this.mainProject, monitors);
Target[] targets = new Target[targetNames.size()];
for (int i = 0; i < targetNames.size(); i++) {
String targetName = (String) targetNames.get(i);
targets[i] = (Target) this.mainProject.getTargets().get(targetName);
}
int work = computeWork(this.mainProject, targets);
monitors.mainMonitor.beginTask("", work); //$NON-NLS-1$
}
public void buildStarted(BuildEvent event) {
checkCanceled();
}
protected int computeWork(Project project, Target[] targets) {
int result = 0;
for (int i = 0; i < targets.length; i++)
result = result + countTarget(targets[i]);
return result;
}
protected int countTarget(Target target) {
int result = 1;
Project project = target.getProject();
for(Enumeration dependencies = target.getDependencies(); dependencies.hasMoreElements();) {
String targetName = (String) dependencies.nextElement();
Target dependency = (Target) project.getTargets().get(targetName);
if (dependency != null)
result = result + countTarget(dependency);
}
// we have to handle antcall tasks as well
Task[] tasks = target.getTasks();
for (int i = 0; i < tasks.length; i++) {
if (tasks[i] instanceof CallTarget) {
// As we do not have access to the information (at least in Ant 1.4.1)
// describing what target is executed by this antcall task, we assume
// a scenario where it depends on all targets of the project but itself.
result = result + (project.getTargets().size()-1);
}
}
return result;
}
public void buildFinished(BuildEvent event) {
ProjectMonitors monitors = (ProjectMonitors) projects.get(mainProject);
monitors.mainMonitor.done();
}
public void targetStarted(BuildEvent event) {
checkCanceled();
Project currentProject = event.getProject();
if (currentProject == null)
return;
Target target = event.getTarget();
ProjectMonitors monitors = (ProjectMonitors) projects.get(currentProject);
// if monitors is null we are in a new script
if (monitors == null)
monitors = createMonitors(currentProject, target);
monitors.targetMonitor = Policy.subMonitorFor(monitors.mainMonitor, 1);
int work = (target != null) ? target.getTasks().length : 100;
monitors.targetMonitor.beginTask("", work); //$NON-NLS-1$
}
protected ProjectMonitors createMonitors(Project currentProject, Target target) {
ProjectMonitors monitors = new ProjectMonitors();
// remember the target so we can remove this monitors object later
monitors.mainTarget = target;
int work = computeWork(currentProject, new Target[]{ target });
ProjectMonitors parentMonitors = null;
if (parentProject == null) {
parentMonitors = (ProjectMonitors) projects.get(mainProject);
monitors.mainMonitor = Policy.subMonitorFor(parentMonitors.mainMonitor, 1);
} else {
parentMonitors = (ProjectMonitors) projects.get(parentProject);
parentProject = null;
monitors.mainMonitor = Policy.subMonitorFor(parentMonitors.taskMonitor, 1);
}
monitors.mainMonitor.beginTask("", work); //$NON-NLS-1$
projects.put(currentProject, monitors);
return monitors;
}
public void targetFinished(BuildEvent event) {
checkCanceled();
Project currentProject = event.getProject();
if (currentProject == null)
return;
ProjectMonitors monitors = (ProjectMonitors) projects.get(currentProject);
if (monitors == null)
return;
monitors.targetMonitor.done();
// if this is not the main project test if we are done with this project
if ((currentProject != mainProject) && (monitors.mainTarget == event.getTarget())) {
monitors.mainMonitor.done();
projects.remove(currentProject);
}
}
public void taskStarted(BuildEvent event) {
checkCanceled();
Project currentProject = event.getProject();
if (currentProject == null)
return;
currentProject.getReferences().remove(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR);
ProjectMonitors monitors = (ProjectMonitors) projects.get(currentProject);
if (monitors == null)
return;
Task task = event.getTask();
if (task == null)
return;
monitors.taskMonitor = Policy.subMonitorFor(monitors.targetMonitor, 1);
monitors.taskMonitor.beginTask("", 1); //$NON-NLS-1$
// If this script is calling another one, track the project chain.
if (task instanceof Ant)
parentProject = currentProject;
else
currentProject.addReference(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR, monitors.taskMonitor);
}
public void taskFinished(BuildEvent event) {
checkCanceled();
Project project = event.getProject();
if (project == null)
return;
project.getReferences().remove(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR);
ProjectMonitors monitors = (ProjectMonitors) projects.get(project);
if (monitors == null)
return;
monitors.taskMonitor.done();
}
public void messageLogged(BuildEvent event) {
}
protected void checkCanceled() {
ProjectMonitors monitors = (ProjectMonitors) projects.get(mainProject);
if (monitors.mainMonitor.isCanceled())
throw new OperationCanceledException(Policy.bind("exception.canceled")); //$NON-NLS-1$
}
}