blob: 69b1455eb100dd94c1afac8d6058d5bbae68235a [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2005, 2021 IBM Corporation and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0.
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# IBM Corporation - org.eclipse.jdt: initial API and implementation
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ecommons.resources.core;
import java.util.Objects;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
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.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.statet.ecommons.io.internal.Messages;
public class BuildUtils {
private static final class BuildJob extends Job {
private final IWorkspace workspace;
private final IProject project;
private BuildJob(final String name, final IProject project) {
super(name);
this.workspace= ResourcesPlugin.getWorkspace();
this.project= project;
setPriority(Job.BUILD);
setRule(this.project.getWorkspace().getRuleFactory().buildRule());
}
@Override
public boolean belongsTo(final Object family) {
return (family == ResourcesPlugin.FAMILY_MANUAL_BUILD);
}
public byte isCoveredBy(final BuildJob other) {
if (Objects.equals(this.project, other.project)) {
return 1;
}
if (other.project == null) {
return 2;
}
return 0;
}
@Override
protected IStatus run(final IProgressMonitor monitor) {
final SubMonitor m= SubMonitor.convert(monitor);
try {
synchronized (getClass()) {
if (m.isCanceled()) {
throw new OperationCanceledException();
}
final Job[] buildJobs= Job.getJobManager().find(ResourcesPlugin.FAMILY_MANUAL_BUILD);
for (final Job job : buildJobs) {
if (job != this && job instanceof BuildJob) {
final BuildJob buildJob= (BuildJob) job;
switch (buildJob.isCoveredBy(this)) {
case 1:
case 2:
buildJob.cancel();
continue;
default:
continue;
}
}
}
}
if (this.project != null) {
m.beginTask(NLS.bind(Messages.CoreUtility_Build_ProjectTask_name, this.project.getName()), 2);
this.project.build(IncrementalProjectBuilder.FULL_BUILD, m.newChild(1));
this.workspace.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, m.newChild(1));
}
else {
m.beginTask(Messages.CoreUtility_Build_AllTask_name, 1);
this.workspace.build(IncrementalProjectBuilder.FULL_BUILD, m.newChild(1));
}
}
catch (final CoreException e) {
return e.getStatus();
}
catch (final OperationCanceledException e) {
return Status.CANCEL_STATUS;
}
finally {
m.done();
}
return Status.OK_STATUS;
}
}
private static final class CleanJob extends Job {
private final IWorkspace workspace;
private final IProject project;
private boolean autoBuild;
private CleanJob(final String name, final IProject project, final boolean autoBuild) {
super(name);
this.workspace= ResourcesPlugin.getWorkspace();
this.project= project;
this.autoBuild= autoBuild;
setPriority(Job.LONG);
setRule(this.workspace.getRuleFactory().buildRule());
}
@Override
public boolean belongsTo(final Object family) {
return (family == ResourcesPlugin.FAMILY_MANUAL_BUILD);
}
public byte isCoveredBy(final CleanJob other) {
if (Objects.equals(this.project, other.project)) {
return 1;
}
if (other.project == null) {
return 2;
}
return 0;
}
@Override
protected IStatus run(final IProgressMonitor monitor) {
final SubMonitor m= SubMonitor.convert(monitor);
try {
synchronized (getClass()) {
if (m.isCanceled()) {
throw new OperationCanceledException();
}
final Job[] buildJobs= Job.getJobManager().find(ResourcesPlugin.FAMILY_MANUAL_BUILD);
for (final Job job : buildJobs) {
if (job != this && job instanceof CleanJob) {
final CleanJob buildJob= (CleanJob) job;
switch (buildJob.isCoveredBy(this)) {
case 1:
this.autoBuild|= buildJob.autoBuild;
buildJob.cancel();
continue;
case 2:
if (!this.autoBuild || buildJob.autoBuild) {
continue;
}
buildJob.cancel();
continue;
default:
continue;
}
}
}
}
if (this.project != null) {
m.beginTask(NLS.bind(Messages.CoreUtility_Clean_ProjectTask_name, this.project.getName()), 1);
this.project.build(IncrementalProjectBuilder.CLEAN_BUILD, m.newChild(1));
}
else {
m.beginTask(Messages.CoreUtility_Clean_AllTask_name, 1);
this.workspace.build(IncrementalProjectBuilder.CLEAN_BUILD, m.newChild(1));
}
if (this.autoBuild) {
final IWorkspaceDescription desc= this.workspace.getDescription();
if (!desc.isAutoBuilding()) {
getBuildJob(this.project).schedule();
}
}
}
catch (final CoreException e) {
return e.getStatus();
}
catch (final OperationCanceledException e) {
return Status.CANCEL_STATUS;
}
finally {
m.done();
}
return Status.OK_STATUS;
}
}
/**
* Returns a build job
* @param project The project to build or <code>null</code> to build the workspace.
*/
public static Job getBuildJob(final IProject project) {
final Job buildJob= new BuildJob(Messages.CoreUtility_Build_Job_title, project);
buildJob.setUser(true);
return buildJob;
}
/**
* Returns a clean job
* @param project The project to build or <code>null</code> to build the workspace.
*/
public static Job getCleanJob(final IProject project, final boolean autoBuild) {
final Job buildJob= new CleanJob(Messages.CoreUtility_Clean_Job_title, project, autoBuild);
buildJob.setUser(true);
return buildJob;
}
/**
* Starts a build in the background.
* @param project The project to build or <code>null</code> to build the workspace.
*/
public static void startBuildInBackground(final IProject project) {
getBuildJob(project).schedule();
}
/**
* Sets whether building automatically is enabled in the workspace or not and returns
* the old value.
*
* @param state <code>true</code> if automatically building is enabled,
* <code>false</code> otherwise
* @return the old state
* @throws CoreException thrown if the operation failed
*/
public static boolean setAutoBuilding(final boolean state) throws CoreException {
final IWorkspace workspace= ResourcesPlugin.getWorkspace();
final IWorkspaceDescription desc= workspace.getDescription();
final boolean isAutoBuilding= desc.isAutoBuilding();
if (isAutoBuilding != state) {
desc.setAutoBuilding(state);
workspace.setDescription(desc);
}
return isAutoBuilding;
}
private BuildUtils() {}
}