blob: b60370ddb7e2703e69530daf654853899d87da68 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.actions;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.internal.ide.actions.BuildUtilities;
/**
* Standard action for full and incremental builds of all projects within the
* workspace.
* <p>
* This class may be instantiated; it is not intended to be subclassed.
* </p>
*/
public class GlobalBuildAction extends Action implements
ActionFactory.IWorkbenchAction {
/**
* The type of build performed by this action. Can be either
* <code>IncrementalProjectBuilder.INCREMENTAL_BUILD</code> or
* <code>IncrementalProjectBuilder.FULL_BUILD</code>.
*/
private int buildType;
/**
* The workbench window; or <code>null</code> if this action has been
* <code>dispose</code>d.
*/
private IWorkbenchWindow workbenchWindow;
/**
* Creates a new action of the appropriate type. The action id is
* <code>IWorkbenchActionConstants.BUILD</code> for incremental builds and
* <code>IWorkbenchActionConstants.REBUILD_ALL</code> for full builds.
*
* @param workbench
* the active workbench
* @param shell
* the shell for any dialogs
* @param type
* the type of build; one of
* <code>IncrementalProjectBuilder.INCREMENTAL_BUILD</code> or
* <code>IncrementalProjectBuilder.FULL_BUILD</code>
*
* @deprecated use GlobalBuildAction(IWorkbenchWindow, type) instead
*/
public GlobalBuildAction(IWorkbench workbench, Shell shell, int type) {
// always use active window; ignore shell
this(workbench.getActiveWorkbenchWindow(), type);
if (shell == null) {
throw new IllegalArgumentException();
}
}
/**
* Creates a new action of the appropriate type. The action id is
* <code>IWorkbenchActionConstants.BUILD</code> for incremental builds and
* <code>IWorkbenchActionConstants.REBUILD_ALL</code> for full builds.
*
* @param window
* the window in which this action appears
* @param type
* the type of build; one of
* <code>IncrementalProjectBuilder.INCREMENTAL_BUILD</code> or
* <code>IncrementalProjectBuilder.FULL_BUILD</code>
*/
public GlobalBuildAction(IWorkbenchWindow window, int type) {
if (window == null) {
throw new IllegalArgumentException();
}
this.workbenchWindow = window;
setBuildType(type);
}
/**
* Sets the build type.
*
* @param type
* the type of build; one of
* <code>IncrementalProjectBuilder.INCREMENTAL_BUILD</code> or
* <code>IncrementalProjectBuilder.FULL_BUILD</code>
*/
private void setBuildType(int type) {
// allow AUTO_BUILD as well for backwards compatibility, but treat it
// the same as INCREMENTAL_BUILD
switch (type) {
case IncrementalProjectBuilder.INCREMENTAL_BUILD:
case IncrementalProjectBuilder.AUTO_BUILD:
setText(IDEWorkbenchMessages.GlobalBuildAction_text);
setToolTipText(IDEWorkbenchMessages.GlobalBuildAction_toolTip);
setId("build"); //$NON-NLS-1$
workbenchWindow.getWorkbench().getHelpSystem().setHelp(this,
IIDEHelpContextIds.GLOBAL_INCREMENTAL_BUILD_ACTION);
setImageDescriptor(IDEInternalWorkbenchImages
.getImageDescriptor(IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC));
setDisabledImageDescriptor(IDEInternalWorkbenchImages
.getImageDescriptor(IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC_DISABLED));
setActionDefinitionId("org.eclipse.ui.project.buildAll"); //$NON-NLS-1$
break;
case IncrementalProjectBuilder.FULL_BUILD:
setText(IDEWorkbenchMessages.GlobalBuildAction_rebuildText);
setToolTipText(IDEWorkbenchMessages.GlobalBuildAction_rebuildToolTip);
setId("rebuildAll"); //$NON-NLS-1$
workbenchWindow.getWorkbench().getHelpSystem().setHelp(this,
IIDEHelpContextIds.GLOBAL_FULL_BUILD_ACTION);
setActionDefinitionId("org.eclipse.ui.project.rebuildAll"); //$NON-NLS-1$
break;
default:
throw new IllegalArgumentException("Invalid build type"); //$NON-NLS-1$
}
this.buildType = type;
}
/**
* Returns the shell to use.
*/
private Shell getShell() {
return workbenchWindow.getShell();
}
/**
* Returns the operation name to use
*/
private String getOperationMessage() {
if (buildType == IncrementalProjectBuilder.INCREMENTAL_BUILD)
return IDEWorkbenchMessages.GlobalBuildAction_buildOperationTitle;
return IDEWorkbenchMessages.GlobalBuildAction_rebuildAllOperationTitle;
}
/**
* Builds all projects within the workspace. Does not save any open editors.
*/
public void doBuild() {
doBuildOperation();
}
/**
* Invokes a build on all projects within the workspace. Reports any errors
* with the build to the user.
*/
/* package */void doBuildOperation() {
Job buildJob = new Job(IDEWorkbenchMessages.GlobalBuildAction_jobTitle) {
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
protected IStatus run(IProgressMonitor monitor) {
final MultiStatus status = new MultiStatus(
PlatformUI.PLUGIN_ID, 0, IDEWorkbenchMessages.GlobalBuildAction_buildProblems,
null);
monitor.beginTask(getOperationMessage(), 100);
try {
ResourcesPlugin.getWorkspace().build(buildType,
new SubProgressMonitor(monitor, 100));
} catch (CoreException e) {
status.add(e.getStatus());
} finally {
monitor.done();
}
return status;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object)
*/
public boolean belongsTo(Object family) {
return ResourcesPlugin.FAMILY_MANUAL_BUILD == family;
}
};
buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory()
.buildRule());
buildJob.setUser(true);
buildJob.schedule();
}
/**
* Returns an array of all projects in the workspace
*/
/* package */IProject[] getWorkspaceProjects() {
return ResourcesPlugin.getWorkspace().getRoot().getProjects();
}
/*
* (non-Javadoc) Method declared on IAction.
*
* Builds all projects within the workspace. Saves all editors prior to
* build depending on user's preference.
*/
public void run() {
if (workbenchWindow == null) {
// action has been disposed
return;
}
// Do nothing if there are no projects...
IProject[] roots = getWorkspaceProjects();
if (roots.length < 1)
return;
// Verify that there are builders registered on at
// least one project
if (!verifyBuildersAvailable(roots))
return;
if (!verifyNoManualRunning())
return;
// Save all resources prior to doing build
BuildUtilities.saveEditors(null);
// Perform the build on all the projects
doBuildOperation();
}
/**
* Checks that there is at least one project with a builder registered on
* it.
*/
/* package */boolean verifyBuildersAvailable(IProject[] roots) {
try {
for (int i = 0; i < roots.length; i++) {
if (roots[i].isAccessible())
if (roots[i].getDescription().getBuildSpec().length > 0)
return true;
}
} catch (CoreException e) {
IDEWorkbenchPlugin.log(getClass(), "verifyBuildersAvailable", e); //$NON-NLS-1$
ErrorDialog
.openError(
getShell(),
IDEWorkbenchMessages.GlobalBuildAction_buildProblems,
NLS.bind(IDEWorkbenchMessages.GlobalBuildAction_internalError, e.getMessage()),
e.getStatus());
return false;
}
return false;
}
/*
* (non-Javadoc) Method declared on ActionFactory.IWorkbenchAction.
*
* @since 3.0
*/
public void dispose() {
if (workbenchWindow == null) {
// action has already been disposed
return;
}
workbenchWindow = null;
}
/**
* Verify that no manual build is running. If it is then give the use the
* option to cancel. If they cancel, cancel the jobs and return true,
* otherwise return false.
*
* @return whether or not there is a manual build job running.
*/
private boolean verifyNoManualRunning() {
Job[] buildJobs = Platform.getJobManager().find(
ResourcesPlugin.FAMILY_MANUAL_BUILD);
if (buildJobs.length == 0)
return true;
boolean cancel = MessageDialog.openQuestion(workbenchWindow.getShell(),
IDEWorkbenchMessages.GlobalBuildAction_BuildRunningTitle,
IDEWorkbenchMessages.GlobalBuildAction_BuildRunningMessage);
if (cancel) {
for (int i = 0; i < buildJobs.length; i++) {
Job job = buildJobs[i];
job.cancel();
}
}
//If they cancelled get them to do it again.
return false;
}
}