1 11 package org.eclipse.core.internal.events; 12 13 import org.eclipse.core.internal.resources.ResourceException; 14 import org.eclipse.core.internal.resources.Workspace; 15 import org.eclipse.core.internal.utils.Messages; 16 import org.eclipse.core.internal.utils.Policy; 17 import org.eclipse.core.resources.*; 18 import org.eclipse.core.runtime.*; 19 import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; 20 import org.eclipse.core.runtime.jobs.ISchedulingRule; 21 import org.eclipse.core.runtime.jobs.Job; 22 import org.osgi.framework.Bundle; 23 24 29 class AutoBuildJob extends Job implements Preferences.IPropertyChangeListener { 30 private boolean avoidBuild = false; 31 private boolean buildNeeded = false; 32 private boolean forceBuild = false; 33 38 private boolean interrupted = false; 39 private boolean isAutoBuilding = false; 40 private long lastBuild = 0L; 41 private Preferences preferences = ResourcesPlugin.getPlugin().getPluginPreferences(); 42 private final Bundle systemBundle = Platform.getBundle("org.eclipse.osgi"); private Workspace workspace; 44 45 AutoBuildJob(Workspace workspace) { 46 super(Messages.events_building_0); 47 setRule(workspace.getRoot()); 48 setPriority(BUILD); 49 isAutoBuilding = workspace.isAutoBuilding(); 50 this.workspace = workspace; 51 this.preferences.addPropertyChangeListener(this); 52 } 53 54 58 synchronized void avoidBuild() { 59 avoidBuild = true; 60 } 61 62 public boolean belongsTo(Object family) { 63 return family == ResourcesPlugin.FAMILY_AUTO_BUILD; 64 } 65 66 72 synchronized void build(boolean needsBuild) { 73 buildNeeded |= needsBuild; 74 long delay = computeScheduleDelay(); 75 int state = getState(); 76 if (Policy.DEBUG_BUILD_NEEDED) 77 Policy.debug("Build requested, needsBuild: " + needsBuild + " state: " + state + " delay: " + delay); if (needsBuild && Policy.DEBUG_BUILD_NEEDED_STACK && state != Job.RUNNING) 79 new RuntimeException ("Build Needed").printStackTrace(); if (state != Job.RUNNING) 82 setInterrupted(false); 83 switch (state) { 84 case Job.SLEEPING : 85 wakeUp(delay); 86 break; 87 case NONE : 88 setSystem(!isAutoBuilding); 89 schedule(delay); 90 break; 91 } 92 } 93 94 98 private long computeScheduleDelay() { 99 return Math.max(Policy.MIN_BUILD_DELAY, Policy.MAX_BUILD_DELAY + lastBuild - System.currentTimeMillis()); 100 } 101 102 111 private synchronized IStatus canceled() { 112 buildNeeded = true; 114 if (interrupted) { 116 if (Policy.DEBUG_BUILD_INTERRUPT) 117 System.out.println("Scheduling rebuild due to interruption"); setInterrupted(false); 119 schedule(computeScheduleDelay()); 120 } 121 return Status.CANCEL_STATUS; 122 } 123 124 private void doBuild(IProgressMonitor monitor) throws CoreException, OperationCanceledException { 125 monitor = Policy.monitorFor(monitor); 126 try { 127 monitor.beginTask("", Policy.opWork); final ISchedulingRule rule = workspace.getRuleFactory().buildRule(); 129 try { 130 workspace.prepareOperation(rule, monitor); 131 workspace.beginOperation(true); 132 final int trigger = IncrementalProjectBuilder.AUTO_BUILD; 133 workspace.broadcastBuildEvent(workspace, IResourceChangeEvent.PRE_BUILD, trigger); 134 IStatus result = Status.OK_STATUS; 135 try { 136 if (shouldBuild()) 137 result = workspace.getBuildManager().build(trigger, Policy.subMonitorFor(monitor, Policy.opWork)); 138 } finally { 139 workspace.broadcastBuildEvent(workspace, IResourceChangeEvent.POST_BUILD, trigger); 141 } 142 if (!result.isOK()) 143 throw new ResourceException(result); 144 buildNeeded = false; 145 } finally { 146 if (workspace.getElementTree().isImmutable()) 149 workspace.newWorkingTree(); 150 workspace.endOperation(rule, false, Policy.subMonitorFor(monitor, Policy.endOpWork)); 151 } 152 } finally { 153 monitor.done(); 154 } 155 } 156 157 161 public void forceBuild() { 162 forceBuild = true; 163 } 164 165 169 synchronized void interrupt() { 170 if (interrupted) 172 return; 173 switch (getState()) { 174 case NONE : 175 return; 176 case WAITING : 177 setInterrupted(!sleep()); 179 break; 180 case RUNNING : 181 if (Job.getJobManager().currentJob() == this) 183 return; 184 setInterrupted(true); 185 if (interrupted && Policy.DEBUG_BUILD_INTERRUPT) { 186 System.out.println("Autobuild was interrupted:"); new Exception ().fillInStackTrace().printStackTrace(); 188 } 189 break; 190 } 191 if (interrupted) 193 avoidBuild = false; 194 } 195 196 synchronized boolean isInterrupted() { 197 if (interrupted) 198 return true; 199 if (isBlocking()) 201 setInterrupted(true); 202 return interrupted; 203 } 204 205 208 public void propertyChange(PropertyChangeEvent event) { 209 if (!event.getProperty().equals(ResourcesPlugin.PREF_AUTO_BUILDING)) 210 return; 211 boolean wasAutoBuilding = isAutoBuilding; 213 isAutoBuilding = preferences.getBoolean(ResourcesPlugin.PREF_AUTO_BUILDING); 214 if (!forceBuild && !wasAutoBuilding && isAutoBuilding) { 216 forceBuild = true; 217 build(false); 218 } 219 } 220 221 224 public IStatus run(IProgressMonitor monitor) { 225 synchronized (this) { 227 if (monitor.isCanceled()) { 228 return canceled(); 229 } 230 } 231 if (systemBundle.getState() == Bundle.STOPPING) 233 return Status.OK_STATUS; 234 try { 235 doBuild(monitor); 236 lastBuild = System.currentTimeMillis(); 237 setInterrupted(false); 239 return Status.OK_STATUS; 240 } catch (OperationCanceledException e) { 241 return canceled(); 242 } catch (CoreException sig) { 243 return sig.getStatus(); 244 } 245 } 246 247 250 private synchronized void setInterrupted(boolean value) { 251 interrupted = value; 252 } 253 254 257 private synchronized boolean shouldBuild() { 258 try { 259 if (!workspace.isAutoBuilding()) 261 return false; 262 if (forceBuild) 264 return true; 265 if (avoidBuild) 266 return false; 267 return buildNeeded; 269 } finally { 270 forceBuild = avoidBuild = buildNeeded = false; 272 } 273 } 274 } 275 | Popular Tags |