package org.eclipse.ui.actions; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.internal.actions.BuildState; /** * A filter that selects which actions should be blocked during the build * process. */ public class BuildActionFilter { private static final String RUN_LAUNCH_ACTION_ID = "org.eclipse.debug.ui.runAction"; private static final String SAVE_ACTION_ID = "org.eclipse.ui.file.save"; private static final String COMMIT_ACTION_ID = "org.eclipse.team.ui.commitAction"; /** * Checks if the given action should be blocked during the build process. * * @param action the action to be checked * @param buildState the current state of the build process * @return `true` if the action should be blocked, `false` otherwise */ public static boolean shouldBlock(Action action, BuildState buildState) { String actionId = action.getId(); if (actionId.equals(RUN_LAUNCH_ACTION_ID)) { return buildState != BuildState.COMPLETE; } else if (actionId.equals(SAVE_ACTION_ID) || actionId.equals(COMMIT_ACTION_ID)) { return buildState == BuildState.BUILDING; } else { return false; } } /** * Waits for the current build process to finish. */ public static void waitForBuildToFinish() { Job buildJob = Job.getJobManager().find(BuildJob.class); if (buildJob != null && buildJob.getState() == Job.RUNNING) { buildJob.join(); } } } package org.eclipse.ui.internal.actions; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.actions.BuildActionFilter; import org.eclipse.ui.actions.BuildState; /** * The multithreaded build process. */ public class BuildProcess { private static BuildState buildState = BuildState.IDLE; /** * Starts the build process. */ public static void startBuild() { buildState = BuildState.BUILDING; // Start the build job. Job buildJob = new Job("Build") { @Override protected IStatus run(IProgressMonitor monitor) { // Perform the build process here. // ... return Status.OK_STATUS; } }; buildJob.schedule(); } /** * Checks if the build process is complete. * * @return `true` if the build process is complete, `false` otherwise */ public static boolean isComplete() { return buildState == BuildState.COMPLETE; } /** * Gets the next action to be executed. * * @return the next action to be executed, or `null` if there are no more actions to be executed */ public static Action getNextAction() { // Get the next action from the action queue. Action action = ActionFactory.find(BuildActionFactory.ID_BUILD_ACTION_QUEUE).getQueue().poll(); // If the action is not blocked, then return it. if (!BuildActionFilter.shouldBlock(action, buildState)) { return action; } else { // If the action is blocked, then wait for the build process to finish. BuildActionFilter.waitForBuildToFinish(); // Return the next action from the action queue. return ActionFactory.find(BuildActionFactory.ID_BUILD_ACTION_QUEUE).getQueue().poll(); } } /** * Blocks the given action. * * @param action the action to be blocked */ public static void blockAction(Action action) { // Add the action to the blocked action queue. ActionFactory.find(BuildActionFactory.ID_BUILD_ACTION_QUEUE).getBlockedQueue().add(action); } /** * Executes the given action. * * @param action the action to be executed */ public static void executeAction(Action action) { try { action.runWithEvent(null); } catch (Exception e) { e.printStackTrace(); } } /** * Finishes the build process. */ public static void finishBuild() { buildState = BuildState.COMPLETE; // Execute all of the blocked actions. while (!ActionFactory.find(BuildActionFactory.ID_BUILD_ACTION_QUEUE).getBlockedQueue().isEmpty()) { Action action = ActionFactory.find(BuildActionFactory.ID_BUILD_ACTION_QUEUE).getBlockedQueue().poll(); executeAction(action); } } } package org.eclipse.ui.internal.actions; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.actions.BuildActionFilter; import org.eclipse.ui.actions.BuildState; /** * The action context class. */ public class ActionContext { private final BuildState buildState; /** * Creates a new action context. * * @param buildState the current state of the build process */ public ActionContext(BuildState buildState) { this.buildState = buildState; } /** * Gets the current state of the build process. * * @return the current state of the build process */ public BuildState getBuildState() { return buildState; } /** * Checks if the current build process is blocked. * * @return `true` if the current build process is blocked, `false` otherwise */ public boolean isBuildBlocked() { return buildState == BuildState.BLOCKED; } /** * Blocks the current build process. */ public void blockBuild() { buildState = BuildState.BLOCKED; } /** * Unblocks the current build process. */ public void unblockBuild() { buildState = BuildState.RUNNING; } /** * Waits for the current build process to finish. */ public void waitForBuildToFinish() { Job buildJob = Job.getJobManager().find(BuildJob.class); if (buildJob != null && buildJob.getState() == Job.RUNNING) { buildJob.join(); } } } package org.eclipse.ui.internal.actions; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.BuildActionFilter; import org.eclipse.ui.actions.BuildState; /** * The Run/Launch action. */ public class RunLaunchAction extends Action { @Override public void runWithEvent(IEvent event) { ActionContext actionContext = new ActionContext(BuildState.RUNNING); // Check if the build process is blocked. if (BuildActionFilter.shouldBlock(this, actionContext.getBuildState())) { // Block the build process. actionContext.blockBuild(); // Wait for the build process to finish. actionContext.waitForBuildToFinish(); // Unblock the build process. actionContext.unblockBuild(); } // Execute the Run/Launch action. // ... } } package org.eclipse.ui.internal.actions; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.BuildActionFilter; import org.eclipse.ui.actions.BuildState; /** * The Save action. */ public class SaveAction extends Action { @Override public void runWithEvent(IEvent event) { ActionContext actionContext = new ActionContext(BuildState.RUNNING); // Check if the build process is blocked. if (BuildActionFilter.shouldBlock(this, actionContext.getBuildState())) { // Block the build process. actionContext.blockBuild(); // Wait for the build process to finish. actionContext.waitForBuildToFinish(); // Unblock the build process. actionContext.unblockBuild(); } // Save the file. // ... } } package org.eclipse.ui.internal.actions; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.BuildActionFilter; import org.eclipse.ui.actions.BuildState; /** * The Commit action. */ public class CommitAction extends Action { @Override public void runWithEvent(IEvent event) { ActionContext actionContext = new ActionContext(BuildState.RUNNING); // Check if the build process is blocked. if (BuildActionFilter.shouldBlock(this, actionContext.getBuildState())) { // Block the build process. actionContext.blockBuild(); // Wait for the build process to finish. actionContext.waitForBuildToFinish(); // Unblock the build process. actionContext.unblockBuild(); } // Commit the changes. // ... } } package org.eclipse.core.internal.events; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.Workspace; /** * The AutoBuildJob is responsible for automatically building the workspace * after changes have been made to the resources. */ public class AutoBuildJob extends Job { /** * The delay in milliseconds before the autobuild job is scheduled. */ private static final int AUTOBUILD_DELAY = 500; /** * Creates a new AutoBuildJob. */ public AutoBuildJob() { super("Autobuild"); setSystem(true); } @Override protected IStatus run(IProgressMonitor monitor) { // Check if autobuild is enabled. if (!ResourcesPlugin.getWorkspace().isAutoBuilding()) { return Status.OK_STATUS; } // Build the workspace. Workspace workspace = ResourcesPlugin.getWorkspace(); workspace.build(IncrementalProjectBuilder.AUTO_BUILD, monitor); return Status.OK_STATUS; } /** * Schedules the autobuild job to run after the specified delay. * * @param delay the delay in milliseconds */ public static void schedule(int delay) { AutoBuildJob job = new AutoBuildJob(); job.schedule(delay); } } package org.eclipse.core.tests.internal.builders; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.tests.harness.AbstractBuilderTest; /** * Tests the BuilderTest.build() method. */ public class BuilderTest extends AbstractBuilderTest { /** * Tests that the build() method blocks the autobuild job. */ public void testBuildBlocksAutobuildJob() throws Exception { // Register a listener to be notified when the autobuild job starts. final boolean[] autobuildStarted = new boolean[] {false}; ResourcesPlugin.getWorkspace().addResourceChangeListener(new IResourceChangeListener() { @Override public void resourceChanged(IResourceChangeEvent event) { if (event.getType() == IResourceChangeEvent.POST_CHANGE) { autobuildStarted[0] = true; } } }); // Start the autobuild job. AutoBuildJob.schedule(AUTOBUILD_DELAY); // Build the workspace. build(); // Wait for the autobuild job to start. while (!autobuildStarted[0]) { Thread.sleep(10); } // Assert that the autobuild job is blocked. Job autobuildJob = (Job) ResourcesPlugin.getWorkspace().getProperty(AutoBuildJob.PROPERTY_AUTOBUILD_JOB); assertTrue(autobuildJob.getState() == Job.WAITING); // Wait for the build to finish. waitForBuildToFinish(); // Assert that the autobuild job is now running. assertTrue(autobuildJob.getState() == Job.RUNNING); } } package org.eclipse.core.tests.internal.builders; import org.eclipse.core.resources.IncrementalProjectBuilder; public class BuilderWithCallback extends IncrementalProjectBuilder { private Runnable callback; public BuilderWithCallback(Runnable callback) { this.callback = callback; } @Override protected IProjectBuilderResult build(int kind, IProgressMonitor monitor) throws CoreException { if (callback != null) { callback.run(); } return super.build(kind, monitor); } } package org.eclipse.ui.actions; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.BuildActionFilter; import org.eclipse.ui.actions.BuildState; /** * A factory for creating workbench actions. */ public class ActionFactory { /** * The ID of the build action queue. */ public static final String ID_BUILD_ACTION_QUEUE = "org.eclipse.ui.actions.buildActionQueue"; /** * Registers a new action filter with the action factory. * * @param actionFilter the action filter to register */ public static void registerActionFilter(BuildActionFilter actionFilter) { // Get the list of registered action filters. List actionFilters = getRegisteredActionFilters(); // Add the new action filter to the list of registered action filters. actionFilters.add(actionFilter); // Set the list of registered action filters. setRegisteredActionFilters(actionFilters); } /** * Creates a new Run/Launch action. * * @param window the workbench window * @return a new Run/Launch action */ public static Action createRunLaunchAction(IWorkbenchWindow window) { RunLaunchAction action = new RunLaunchAction(); action.runWithEvent(null); return action; } /** * Creates a new Save action. * * @param window the workbench window * @return a new Save action */ public static Action createSaveAction(IWorkbenchWindow window) { SaveAction action = new SaveAction(); action.runWithEvent(null); return action; } /** * Creates a new Commit action. * * @param window the workbench window * @return a new Commit action */ public static Action createCommitAction(IWorkbenchWindow window) { CommitAction action = new CommitAction(); action.runWithEvent(null); return action; } } public class MyPlugin { public static void main(String[] args) { // Register the BuildActionFilter class with the action factory. myRegisterActionFilter(new BuildActionFilter()); // Register any other plugins here. // Start the workbench. PlatformUI.createAndRunWorkbench(null); } } org.eclipse.core.internal.resources.TestsScope .content .binaryContent