1 11 package org.eclipse.ui.internal.progress; 12 13 import java.util.Collection ; 14 import java.util.HashSet ; 15 import java.util.Iterator ; 16 17 import org.eclipse.core.runtime.IProgressMonitor; 18 import org.eclipse.core.runtime.IStatus; 19 import org.eclipse.core.runtime.Status; 20 import org.eclipse.core.runtime.jobs.Job; 21 import org.eclipse.ui.IWorkbenchPreferenceConstants; 22 import org.eclipse.ui.PlatformUI; 23 import org.eclipse.ui.internal.util.PrefUtil; 24 import org.eclipse.ui.progress.WorkbenchJob; 25 26 29 class ProgressViewUpdater implements IJobProgressManagerListener { 30 31 private static ProgressViewUpdater singleton; 32 33 private IProgressUpdateCollector[] collectors; 34 35 Job updateJob; 36 37 UpdatesInfo currentInfo = new UpdatesInfo(); 38 39 Object updateLock = new Object (); 40 41 boolean debug; 42 43 44 48 class UpdatesInfo { 49 50 Collection additions = new HashSet (); 51 52 Collection deletions = new HashSet (); 53 54 Collection refreshes = new HashSet (); 55 56 boolean updateAll = false; 57 58 private UpdatesInfo() { 59 } 61 62 67 void add(JobTreeElement addition) { 68 additions.add(addition); 69 } 70 71 76 void remove(JobTreeElement removal) { 77 deletions.add(removal); 78 } 79 80 85 void refresh(JobTreeElement refresh) { 86 refreshes.add(refresh); 87 } 88 89 92 void reset() { 93 additions.clear(); 94 deletions.clear(); 95 refreshes.clear(); 96 updateAll = false; 97 } 98 99 void processForUpdate() { 100 HashSet staleAdditions = new HashSet (); 101 102 Iterator additionsIterator = additions.iterator(); 103 while (additionsIterator.hasNext()) { 104 JobTreeElement treeElement = (JobTreeElement) additionsIterator 105 .next(); 106 if (!treeElement.isActive()) { 107 if (deletions.contains(treeElement)) { 108 staleAdditions.add(treeElement); 109 } 110 } 111 } 112 113 additions.removeAll(staleAdditions); 114 115 HashSet obsoleteRefresh = new HashSet (); 116 Iterator refreshIterator = refreshes.iterator(); 117 while (refreshIterator.hasNext()) { 118 JobTreeElement treeElement = (JobTreeElement) refreshIterator 119 .next(); 120 if (deletions.contains(treeElement) 121 || additions.contains(treeElement)) { 122 obsoleteRefresh.add(treeElement); 123 } 124 125 Object parent = treeElement.getParent(); 127 if(parent != null && (deletions.contains(parent) 128 || additions.contains(parent))){ 129 obsoleteRefresh.add(treeElement); 130 } 131 132 if (!treeElement.isActive()) { 133 obsoleteRefresh.add(treeElement); 135 deletions.add(treeElement); 136 } 137 } 138 139 refreshes.removeAll(obsoleteRefresh); 140 141 } 142 } 143 144 149 static ProgressViewUpdater getSingleton() { 150 if (singleton == null) { 151 singleton = new ProgressViewUpdater(); 152 } 153 return singleton; 154 } 155 156 163 static boolean hasSingleton() { 164 return singleton != null; 165 } 166 167 static void clearSingleton() { 168 if (singleton != null) { 169 ProgressManager.getInstance().removeListener(singleton); 170 } 171 singleton = null; 172 } 173 174 177 private ProgressViewUpdater() { 178 createUpdateJob(); 179 collectors = new IProgressUpdateCollector[0]; 180 ProgressManager.getInstance().addListener(this); 181 debug = 182 PrefUtil.getAPIPreferenceStore(). 183 getBoolean(IWorkbenchPreferenceConstants.SHOW_SYSTEM_JOBS); 184 } 185 186 191 void addCollector(IProgressUpdateCollector newCollector) { 192 IProgressUpdateCollector[] newCollectors = new IProgressUpdateCollector[collectors.length + 1]; 193 System.arraycopy(collectors, 0, newCollectors, 0, collectors.length); 194 newCollectors[collectors.length] = newCollector; 195 collectors = newCollectors; 196 } 197 198 203 void removeCollector(IProgressUpdateCollector provider) { 204 HashSet newCollectors = new HashSet (); 205 for (int i = 0; i < collectors.length; i++) { 206 if (!collectors[i].equals(provider)) { 207 newCollectors.add(collectors[i]); 208 } 209 } 210 IProgressUpdateCollector[] newArray = new IProgressUpdateCollector[newCollectors 211 .size()]; 212 newCollectors.toArray(newArray); 213 collectors = newArray; 214 if (collectors.length == 0) { 216 clearSingleton(); 217 } 218 } 219 220 223 void scheduleUpdate() { 224 if (PlatformUI.isWorkbenchRunning()) { 225 updateJob.schedule(100); 227 } 228 } 229 230 233 private void createUpdateJob() { 234 updateJob = new WorkbenchJob(ProgressMessages.ProgressContentProvider_UpdateProgressJob) { 235 240 public IStatus runInUIThread(IProgressMonitor monitor) { 241 242 if (collectors.length == 0) { 244 return Status.CANCEL_STATUS; 245 } 246 247 if (currentInfo.updateAll) { 248 synchronized (updateLock) { 249 currentInfo.reset(); 250 } 251 for (int i = 0; i < collectors.length; i++) { 252 collectors[i].refresh(); 253 } 254 255 } else { 256 Object [] updateItems; 258 Object [] additionItems; 259 Object [] deletionItems; 260 synchronized (updateLock) { 261 currentInfo.processForUpdate(); 262 263 updateItems = currentInfo.refreshes.toArray(); 264 additionItems = currentInfo.additions.toArray(); 265 deletionItems = currentInfo.deletions.toArray(); 266 267 currentInfo.reset(); 268 } 269 270 for (int v = 0; v < collectors.length; v++) { 271 IProgressUpdateCollector collector = collectors[v]; 272 273 if (updateItems.length > 0) { 274 collector.refresh(updateItems); 275 } 276 if (additionItems.length > 0) { 277 collector.add(additionItems); 278 } 279 if (deletionItems.length > 0) { 280 collector.remove(deletionItems); 281 } 282 } 283 } 284 285 return Status.OK_STATUS; 286 } 287 }; 288 updateJob.setSystem(true); 289 updateJob.setPriority(Job.DECORATE); 290 updateJob.setProperty(ProgressManagerUtil.INFRASTRUCTURE_PROPERTY, new Object ()); 291 292 } 293 294 299 UpdatesInfo getCurrentInfo() { 300 return currentInfo; 301 } 302 303 307 public void refresh(JobInfo info) { 308 309 if (isUpdateJob(info.getJob())) { 310 return; 311 } 312 313 synchronized (updateLock) { 314 currentInfo.refresh(info); 315 GroupInfo group = info.getGroupInfo(); 316 if (group != null) { 317 currentInfo.refresh(group); 318 } 319 } 320 scheduleUpdate(); 322 323 } 324 325 328 public void refreshJobInfo(JobInfo info) { 329 330 if (isUpdateJob(info.getJob())) { 331 return; 332 } 333 334 synchronized (updateLock) { 335 currentInfo.refresh(info); 336 } 337 scheduleUpdate(); 339 340 } 341 342 345 public void refreshGroup(GroupInfo info) { 346 synchronized (updateLock) { 347 currentInfo.refresh(info); 348 } 349 scheduleUpdate(); 351 352 } 353 354 357 public void addGroup(GroupInfo info) { 358 359 synchronized (updateLock) { 360 currentInfo.add(info); 361 } 362 scheduleUpdate(); 363 364 } 365 366 371 public void refreshAll() { 372 373 synchronized (updateLock) { 374 currentInfo.updateAll = true; 375 } 376 377 scheduleUpdate(); 379 380 } 381 382 387 public void addJob(JobInfo info) { 388 389 if (isUpdateJob(info.getJob())) { 390 return; 391 } 392 393 synchronized (updateLock) { 394 GroupInfo group = info.getGroupInfo(); 395 396 if (group == null) { 397 currentInfo.add(info); 398 } else { 399 currentInfo.refresh(group); 400 } 401 } 402 scheduleUpdate(); 403 404 } 405 406 411 public void removeJob(JobInfo info) { 412 413 if (isUpdateJob(info.getJob())) { 414 return; 415 } 416 417 synchronized (updateLock) { 418 GroupInfo group = info.getGroupInfo(); 419 if (group == null) { 420 currentInfo.remove(info); 421 } else { 422 group.removeJobInfo(info); 423 currentInfo.refresh(group); 424 } 425 } 426 scheduleUpdate(); 427 } 428 429 432 public void removeGroup(GroupInfo group) { 433 synchronized (updateLock) { 434 currentInfo.remove(group); 435 } 436 scheduleUpdate(); 437 438 } 439 440 445 public boolean showsDebug() { 446 return debug; 447 } 448 449 457 boolean isUpdateJob(Job job) { 458 return job.equals(updateJob); 459 } 460 } 461 | Popular Tags |