| /*=============================================================================# |
| # 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() {} |
| |
| } |