| /******************************************************************************* |
| * Copyright (c) 2000, 2015 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Anton Leherbauer (Wind River) - [198591] Allow Builder to specify scheduling rule |
| * Anton Leherbauer (Wind River) - [305858] Allow Builder to return null rule |
| * James Blackburn (Broadcom) - [306822] Provide Context for Builder getRule() |
| * Broadcom Corporation - build configurations and references |
| *******************************************************************************/ |
| package org.eclipse.core.resources; |
| |
| import java.util.Map; |
| import org.eclipse.core.internal.events.InternalBuilder; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.jobs.ISchedulingRule; |
| |
| /** |
| * The abstract base class for all incremental project builders. This class |
| * provides the infrastructure for defining a builder and fulfills the contract |
| * specified by the <code>org.eclipse.core.resources.builders</code> standard |
| * extension point. |
| * <p> |
| * All builders must subclass this class according to the following guidelines: |
| * <ul> |
| * <li>must re-implement at least <code>build</code></li> |
| * <li>may implement other methods</li> |
| * <li>must supply a public, no-argument constructor</li> |
| * </ul> |
| * On creation, the <code>setInitializationData</code> method is called with |
| * any parameter data specified in the declaring plug-in's manifest. |
| */ |
| public abstract class IncrementalProjectBuilder extends InternalBuilder implements IExecutableExtension { |
| /** |
| * Build kind constant (value 6) indicating a full build request. A full |
| * build discards all previously built state and builds all resources again. |
| * Resource deltas are not applicable for this kind of build. |
| * <p> |
| * <strong>Note:</strong> If there is no previous delta, a request for {@link #INCREMENTAL_BUILD} |
| * or {@link #AUTO_BUILD} will result in the builder being called with {@link #FULL_BUILD} |
| * build kind. |
| * </p> |
| * |
| * @see IProject#build(int, IProgressMonitor) |
| * @see IProject#build(int, String, Map, IProgressMonitor) |
| * @see IWorkspace#build(int, IProgressMonitor) |
| */ |
| public static final int FULL_BUILD = 6; |
| /** |
| * Build kind constant (value 9) indicating an automatic build request. When |
| * autobuild is turned on, these builds are triggered automatically whenever |
| * resources change. Apart from the method by which autobuilds are triggered, |
| * they otherwise operate like an incremental build. |
| * |
| * @see IWorkspaceDescription#setAutoBuilding(boolean) |
| * @see IWorkspace#isAutoBuilding() |
| */ |
| public static final int AUTO_BUILD = 9; |
| /** |
| * Build kind constant (value 10) indicating an incremental build request. |
| * Incremental builds use an {@link IResourceDelta} that describes what |
| * resources have changed since the last build. The builder calculates |
| * what resources are affected by the delta, and rebuilds the affected resources. |
| * |
| * @see IProject#build(int, IProgressMonitor) |
| * @see IProject#build(int, String, Map, IProgressMonitor) |
| * @see IWorkspace#build(int, IProgressMonitor) |
| */ |
| public static final int INCREMENTAL_BUILD = 10; |
| /** |
| * Build kind constant (value 15) indicating a clean build request. A clean |
| * build discards any additional state that has been computed as a result of |
| * previous builds, and returns the project to a clean slate. Resource |
| * deltas are not applicable for this kind of build. |
| * |
| * @see IProject#build(int, IProgressMonitor) |
| * @see IProject#build(int, String, Map, IProgressMonitor) |
| * @see IWorkspace#build(int, IProgressMonitor) |
| * @see #clean(IProgressMonitor) |
| * @since 3.0 |
| */ |
| public static final int CLEAN_BUILD = 15; |
| |
| /** |
| * Runs this builder in the specified manner. Subclasses should implement |
| * this method to do the processing they require. |
| * <p> |
| * If the build kind is {@link #INCREMENTAL_BUILD} or |
| * {@link #AUTO_BUILD}, the <code>getDelta</code> method can be |
| * used during the invocation of this method to obtain information about |
| * what changes have occurred since the last invocation of this method. Any |
| * resource delta acquired is valid only for the duration of the invocation |
| * of this method. A {@link #FULL_BUILD} has no associated build delta. |
| * </p> |
| * <p> |
| * After completing a build, this builder may return a list of projects for |
| * which it requires a resource delta the next time it is run. This |
| * builder's project is implicitly included and need not be specified. The |
| * build mechanism will attempt to maintain and compute deltas relative to |
| * the identified projects when asked the next time this builder is run. |
| * Builders must re-specify the list of interesting projects every time they |
| * are run as this is not carried forward beyond the next build. Projects |
| * mentioned in return value but which do not exist will be ignored and no |
| * delta will be made available for them. |
| * </p> |
| * <p> |
| * This method is long-running; progress and cancellation are provided by |
| * the given progress monitor. All builders should report their progress and |
| * honor cancel requests in a timely manner. Cancelation requests should be |
| * propagated to the caller by throwing |
| * <code>OperationCanceledException</code>. |
| * </p> |
| * <p> |
| * All builders should try to be robust in the face of trouble. In |
| * situations where failing the build by throwing <code>CoreException</code> |
| * is the only option, a builder has a choice of how best to communicate the |
| * problem back to the caller. One option is to use the |
| * {@link IResourceStatus#BUILD_FAILED} status code along with a suitable message; |
| * another is to use a {@link MultiStatus} containing finer-grained problem |
| * diagnoses. |
| * </p> |
| * |
| * @param kind the kind of build being requested. Valid values are |
| * <ul> |
| * <li>{@link #FULL_BUILD} - indicates a full build.</li> |
| * <li>{@link #INCREMENTAL_BUILD}- indicates an incremental build.</li> |
| * <li>{@link #AUTO_BUILD} - indicates an automatically triggered |
| * incremental build (autobuilding on).</li> |
| * </ul> |
| * @param args a table of builder-specific arguments keyed by argument name |
| * (key type: <code>String</code>, value type: <code>String</code>); |
| * <code>null</code> is equivalent to an empty map |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting and cancellation are not desired |
| * @return the list of projects for which this builder would like deltas the |
| * next time it is run or <code>null</code> if none |
| * @exception CoreException if this build fails. |
| * @see IProject#build(int, String, Map, IProgressMonitor) |
| */ |
| @Override |
| protected abstract IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException; |
| |
| /** |
| * Clean is an opportunity for a builder to discard any additional state that has |
| * been computed as a result of previous builds. It is recommended that builders |
| * override this method to delete all derived resources created by previous builds, |
| * and to remove all markers of type {@link IMarker#PROBLEM} that |
| * were created by previous invocations of the builder. The platform will |
| * take care of discarding the builder's last built state (there is no need |
| * to call <code>forgetLastBuiltState</code>). |
| * <p> |
| * This method is called as a result of invocations of |
| * <code>IWorkspace.build</code> or <code>IProject.build</code> where |
| * the build kind is {@link #CLEAN_BUILD}. |
| * <p> |
| * This default implementation does nothing. Subclasses may override. |
| * <p> |
| * This method is long-running; progress and cancellation are provided by |
| * the given progress monitor. All builders should report their progress and |
| * honor cancel requests in a timely manner. Cancelation requests should be |
| * propagated to the caller by throwing |
| * <code>OperationCanceledException</code>. |
| * </p> |
| * |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting and cancellation are not desired |
| * @exception CoreException if this build fails. |
| * @see IWorkspace#build(int, IProgressMonitor) |
| * @see #CLEAN_BUILD |
| * @since 3.0 |
| */ |
| @Override |
| protected void clean(IProgressMonitor monitor) throws CoreException { |
| //default implementation does nothing |
| //thwart compiler warning |
| } |
| |
| /** |
| * Requests that this builder forget any state it may be retaining regarding |
| * previously built states. Typically this means that the next time the |
| * builder runs, it will have to do a full build since it does not have any |
| * state upon which to base an incremental build. |
| * This supersedes a call to {@link #rememberLastBuiltState()}. |
| */ |
| @Override |
| public final void forgetLastBuiltState() { |
| super.forgetLastBuiltState(); |
| } |
| |
| /** |
| * Requests that this builder remember any build invocation specific state. |
| * This means that the next time the builder runs, it will receive a delta |
| * which includes changes reported in the current {@link #getDelta(IProject)}. |
| *<p> |
| * This can be used to indicate that a builder didn't run, even though there |
| * are changes, and the builder wishes that the delta be preserved until its |
| * next invocation. |
| * </p> |
| * This is superseded by a call to {@link #forgetLastBuiltState()}. |
| * @since 3.7 |
| */ |
| @Override |
| public final void rememberLastBuiltState() { |
| super.rememberLastBuiltState(); |
| } |
| |
| /** |
| * Returns the build command associated with this builder. The returned |
| * command may or may not be in the build specification for the project |
| * on which this builder operates. |
| * <p> |
| * Any changes made to the returned command will only take effect if |
| * the modified command is installed on a project build spec. |
| * </p> |
| * |
| * @see IProjectDescription#setBuildSpec(ICommand []) |
| * @see IProject#setDescription(IProjectDescription, int, IProgressMonitor) |
| * @since 3.1 |
| */ |
| @Override |
| public final ICommand getCommand() { |
| return super.getCommand(); |
| } |
| |
| /** |
| * Returns the resource delta recording the changes in the given project |
| * since the last time this builder was run. <code>null</code> is returned |
| * if no such delta is available. An empty delta is returned if no changes |
| * have occurred, or if deltas are not applicable for the current build kind. |
| * If <code>null</code> is returned, clients should assume |
| * that unspecified changes have occurred and take the appropriate action. |
| * <p> |
| * The system reserves the right to trim old state in an effort to conserve |
| * space. As such, callers should be prepared to receive <code>null</code> |
| * even if they previously requested a delta for a particular project by |
| * returning that project from a <code>build</code> call. |
| * </p> |
| * <p> |
| * A non- <code>null</code> delta will only be supplied for the given |
| * project if either the result returned from the previous |
| * <code>build</code> included the project or the project is the one |
| * associated with this builder. |
| * </p> |
| * <p> |
| * If the given project was mentioned in the previous <code>build</code> |
| * and subsequently deleted, a non- <code>null</code> delta containing the |
| * deletion will be returned. If the given project was mentioned in the |
| * previous <code>build</code> and was subsequently created, the returned |
| * value will be <code>null</code>. |
| * </p> |
| * <p> |
| * A valid delta will be returned only when this method is called during a |
| * build. The delta returned will be valid only for the duration of the |
| * enclosing build execution. |
| * </p> |
| * <p> |
| * The delta does not include changes made while this builder is running. |
| * If {@link #getRule(int, Map)} is overridden to return a scheduling rule other than |
| * the workspace root, changes performed in other threads during the build |
| * will not appear in the resource delta. |
| * </p> |
| * |
| * @return the resource delta for the project or <code>null</code> |
| */ |
| @Override |
| public final IResourceDelta getDelta(IProject project) { |
| return super.getDelta(project); |
| } |
| |
| /** |
| * Returns the project for which this builder is defined. |
| * |
| * @return the project |
| */ |
| @Override |
| public final IProject getProject() { |
| return super.getProject(); |
| } |
| |
| /** |
| * Returns the build configuration for which this build was invoked. |
| * @return the build configuration |
| * @since 3.7 |
| */ |
| @Override |
| public final IBuildConfiguration getBuildConfig() { |
| return super.getBuildConfig(); |
| } |
| |
| /** |
| * Returns whether the given project has already been built during this |
| * build iteration. |
| * <p> |
| * When the entire workspace is being built, the projects are built in |
| * linear sequence. This method can be used to determine if another project |
| * precedes this builder's project in that build sequence. If only a single |
| * project is being built, then there is no build order and this method will |
| * always return <code>false</code>. |
| * </p> |
| * |
| * @param project the project to check against in the current build order |
| * @return <code>true</code> if the given project has been built in this |
| * iteration, and <code>false</code> otherwise. |
| * @see #needRebuild() |
| * @since 2.1 |
| */ |
| @Override |
| public final boolean hasBeenBuilt(IProject project) { |
| return super.hasBeenBuilt(project); |
| } |
| |
| /** |
| * Returns whether an interrupt request has been made for this build. |
| * Background autobuild is interrupted when another thread tries to modify |
| * the workspace concurrently with the build thread. When this occurs, the |
| * build cycle is flagged as interrupted and the build will be terminated at |
| * the earliest opportunity. This method allows long running builders to |
| * respond to this interruption in a timely manner. Builders are not |
| * required to respond to interruption requests. |
| * <p> |
| * |
| * @return <code>true</code> if the build cycle has been interrupted, and |
| * <code>false</code> otherwise. |
| * @since 3.0 |
| */ |
| @Override |
| public final boolean isInterrupted() { |
| return super.isInterrupted(); |
| } |
| |
| /** |
| * Indicates that this builder made changes that affect a build configuration that |
| * precedes this build configuration in the currently executing build order, and thus a |
| * rebuild will be necessary. |
| * <p> |
| * This is an advanced feature that builders should use with caution. This |
| * can cause workspace builds to iterate until no more builders require |
| * rebuilds. |
| * </p> |
| * |
| * @see #hasBeenBuilt(IProject) |
| * @since 2.1 |
| */ |
| @Override |
| public final void needRebuild() { |
| super.needRebuild(); |
| } |
| |
| /** |
| * Sets initialization data for this builder. |
| * <p> |
| * This method is part of the {@link IExecutableExtension} interface. |
| * </p> |
| * <p> |
| * Subclasses are free to extend this method to pick up initialization |
| * parameters from the plug-in plug-in manifest (<code>plugin.xml</code>) |
| * file, but should be sure to invoke this method on their superclass. |
| * </p><p> |
| * For example, the following method looks for a boolean-valued parameter |
| * named "trace": |
| * </p> |
| * |
| * <pre> |
| * public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) throws CoreException { |
| * super.setInitializationData(cfig, propertyName, data); |
| * if (data instanceof Hashtable) { |
| * Hashtable args = (Hashtable) data; |
| * String traceValue = (String) args.get("trace"); |
| * TRACING = (traceValue != null && traceValue.equals("true")); |
| * } |
| * } |
| * </pre> |
| * @throws CoreException if fails. |
| */ |
| @Override |
| public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { |
| //default implementation does nothing |
| //thwart compiler warning |
| } |
| |
| /** |
| * Informs this builder that it is being started by the build management |
| * infrastructure. By the time this method is run, the builder's project is |
| * available and <code>setInitializationData</code> has been called. The |
| * default implementation should be called by all overriding methods. |
| * |
| * @see #setInitializationData(IConfigurationElement, String, Object) |
| */ |
| @Override |
| protected void startupOnInitialize() { |
| // reserved for future use |
| } |
| |
| /** |
| * Returns the scheduling rule that is required for building |
| * the project build configuration for which this builder is defined. The default |
| * is the workspace root rule. |
| * <p> |
| * The scheduling rule determines which resources in the workspace are |
| * protected from being modified by other threads while the builder is running. Up until |
| * Eclipse 3.5, the entire workspace was always locked during a build; |
| * since Eclipse 3.6, builders can allow resources outside their scheduling |
| * rule to be modified. |
| * <p> |
| * <strong>Notes:</strong> |
| * </p> |
| * <ul> |
| * <li> |
| * The rule may be <i>relaxed</i> and in some cases let the builder be scheduled in |
| * parallel of any other operation using a rule based on {@link IResource}). A relaxed |
| * rule is a scheduling rule which does not contain the workspace root rule. |
| * </li> |
| * <li> |
| * The rule returned here may have no effect if the build is invoked within the |
| * scope of another operation that locks the entire workspace. |
| * </li> |
| * <li> |
| * If this method returns any rule other than the workspace root, |
| * resources outside of the rule scope can be modified concurrently with the build. |
| * The delta returned by {@link #getDelta(IProject)} for any project |
| * outside the scope of the builder's rule may not contain changes that occurred |
| * concurrently with the build. |
| * </li> |
| * </ul> |
| * <p> |
| * Subclasses may override this method. |
| * </p> |
| * @noreference This method is not intended to be referenced by clients. |
| * |
| * @param kind the kind of build being requested. Valid values include: |
| * <ul> |
| * <li>{@link #FULL_BUILD} - indicates a full build.</li> |
| * <li>{@link #INCREMENTAL_BUILD} - indicates an incremental build.</li> |
| * <li>{@link #AUTO_BUILD} - indicates an automatically triggered |
| * incremental build (autobuilding on).</li> |
| * <li>{@link #CLEAN_BUILD} - indicates a clean request.</li> |
| * </ul> |
| * @param args a table of builder-specific arguments keyed by argument name |
| * (key type: <code>String</code>, value type: <code>String</code>); |
| * <code>null</code> is equivalent to an empty map. |
| * @return a scheduling rule which is contained in the workspace root rule |
| * or <code>null</code> to indicate that no protection against resource |
| * modification during the build is needed. |
| * |
| * @since 3.6 |
| */ |
| public ISchedulingRule getRule(int kind, Map<String, String> args) { |
| return ResourcesPlugin.getWorkspace().getRoot(); |
| } |
| |
| /** |
| * Get the context for this invocation of the builder. This is only valid |
| * in the context of a call to |
| * {@link #build(int, Map, IProgressMonitor)} |
| * |
| * <p> |
| * This can be used to discover which build configurations are being built before |
| * and after this build configuration. |
| * </p> |
| * |
| * @return the context for the most recent invocation of the builder |
| * @since 3.7 |
| */ |
| @Override |
| public final IBuildContext getContext() { |
| return super.getContext(); |
| } |
| } |