1 11 package org.eclipse.ui.internal; 12 13 import java.io.File ; 14 import java.io.FileOutputStream ; 15 import java.io.IOException ; 16 import java.io.OutputStreamWriter ; 17 import java.util.ArrayList ; 18 import java.util.HashMap ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Map ; 22 import java.util.SortedSet ; 23 import java.util.TreeSet ; 24 25 import org.eclipse.core.commands.common.EventManager; 26 import org.eclipse.core.runtime.Assert; 27 import org.eclipse.core.runtime.IAdaptable; 28 import org.eclipse.core.runtime.IExtension; 29 import org.eclipse.core.runtime.IExtensionPoint; 30 import org.eclipse.core.runtime.ISafeRunnable; 31 import org.eclipse.core.runtime.Platform; 32 import org.eclipse.core.runtime.SafeRunner; 33 import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker; 34 import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler; 35 import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; 36 import org.eclipse.jface.util.IPropertyChangeListener; 37 import org.eclipse.jface.util.PropertyChangeEvent; 38 import org.eclipse.swt.widgets.Display; 39 import org.eclipse.swt.widgets.Shell; 40 import org.eclipse.ui.IElementFactory; 41 import org.eclipse.ui.IMemento; 42 import org.eclipse.ui.IPersistableElement; 43 import org.eclipse.ui.IWorkingSet; 44 import org.eclipse.ui.IWorkingSetElementAdapter; 45 import org.eclipse.ui.IWorkingSetManager; 46 import org.eclipse.ui.IWorkingSetUpdater; 47 import org.eclipse.ui.PlatformUI; 48 import org.eclipse.ui.XMLMemento; 49 import org.eclipse.ui.dialogs.IWorkingSetEditWizard; 50 import org.eclipse.ui.dialogs.IWorkingSetNewWizard; 51 import org.eclipse.ui.dialogs.IWorkingSetPage; 52 import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog; 53 import org.eclipse.ui.internal.dialogs.WorkingSetEditWizard; 54 import org.eclipse.ui.internal.dialogs.WorkingSetNewWizard; 55 import org.eclipse.ui.internal.dialogs.WorkingSetSelectionDialog; 56 import org.eclipse.ui.internal.misc.StatusUtil; 57 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; 58 import org.eclipse.ui.internal.registry.WorkingSetDescriptor; 59 import org.eclipse.ui.internal.registry.WorkingSetRegistry; 60 import org.eclipse.ui.statushandlers.StatusManager; 61 import org.osgi.framework.Bundle; 62 import org.osgi.framework.BundleContext; 63 import org.osgi.framework.BundleEvent; 64 import org.osgi.framework.BundleListener; 65 66 67 70 public abstract class AbstractWorkingSetManager extends EventManager implements 71 IWorkingSetManager, BundleListener, IExtensionChangeHandler { 72 73 private SortedSet workingSets = new TreeSet (WorkingSetComparator.INSTANCE); 74 75 78 private static final int MRU_SIZE = 5; 79 private List recentWorkingSets = new ArrayList (); 80 81 private BundleContext bundleContext; 82 private Map updaters= new HashMap (); 83 84 private Map elementAdapters = new HashMap (); 85 86 private static final IWorkingSetUpdater NULL_UPDATER= new IWorkingSetUpdater() { 87 public void add(IWorkingSet workingSet) { 88 } 89 public boolean remove(IWorkingSet workingSet) { 90 return true; 91 } 92 public boolean contains(IWorkingSet workingSet) { 93 return true; 94 } 95 public void dispose() { 96 } 97 }; 98 99 private static final IWorkingSetElementAdapter IDENTITY_ADAPTER = new IWorkingSetElementAdapter() { 100 101 public IAdaptable[] adaptElements(IWorkingSet ws, IAdaptable[] elements) { 102 return elements; 103 } 104 105 public void dispose() { 106 } 107 }; 108 109 121 private static WorkingSetDescriptor[] getSupportedEditableDescriptors( 122 String [] supportedWorkingSetIds) { 123 WorkingSetRegistry registry = WorkbenchPlugin.getDefault() 124 .getWorkingSetRegistry(); 125 if (supportedWorkingSetIds == null) { 126 return registry.getNewPageWorkingSetDescriptors(); 127 } 128 List result = new ArrayList (supportedWorkingSetIds.length); 129 for (int i = 0; i < supportedWorkingSetIds.length; i++) { 130 WorkingSetDescriptor desc = registry 131 .getWorkingSetDescriptor(supportedWorkingSetIds[i]); 132 if (desc != null && desc.isEditable()) { 133 result.add(desc); 134 } 135 } 136 return (WorkingSetDescriptor[]) result 137 .toArray(new WorkingSetDescriptor[result.size()]); 138 } 139 140 protected AbstractWorkingSetManager(BundleContext context) { 141 bundleContext= context; 142 bundleContext.addBundleListener(this); 143 PlatformUI.getWorkbench().getExtensionTracker().registerHandler(this, ExtensionTracker 144 .createExtensionPointFilter(getExtensionPointFilter())); 145 } 146 147 152 private IExtensionPoint getExtensionPointFilter() { 153 return Platform.getExtensionRegistry().getExtensionPoint( 154 PlatformUI.PLUGIN_ID, 155 IWorkbenchRegistryConstants.PL_WORKINGSETS); 156 } 157 158 public void dispose() { 159 bundleContext.removeBundleListener(this); 160 for (Iterator iter= updaters.values().iterator(); iter.hasNext();) { 161 ((IWorkingSetUpdater)iter.next()).dispose(); 162 } 163 164 for (Iterator iter= elementAdapters.values().iterator(); iter.hasNext();) { 165 ((IWorkingSetElementAdapter)iter.next()).dispose(); 166 } 167 } 168 169 171 174 public IWorkingSet createWorkingSet(String name, IAdaptable[] elements) { 175 return new WorkingSet(name, name, elements); 176 } 177 178 public IWorkingSet createAggregateWorkingSet(String name, String label, 179 IWorkingSet[] components) { 180 return new AggregateWorkingSet(name, label, components); 181 } 182 183 188 public IWorkingSet createWorkingSet(IMemento memento) { 189 return restoreWorkingSet(memento); 190 } 191 192 194 197 public void addWorkingSet(IWorkingSet workingSet) { 198 Assert.isTrue(!workingSets.contains(workingSet), 199 "working set already registered"); internalAddWorkingSet(workingSet); 201 } 202 203 private void internalAddWorkingSet(IWorkingSet workingSet) { 204 workingSets.add(workingSet); 205 ((AbstractWorkingSet)workingSet).connect(this); 206 addToUpdater(workingSet); 207 firePropertyChange(CHANGE_WORKING_SET_ADD, null, workingSet); 208 } 209 210 213 protected boolean internalRemoveWorkingSet(IWorkingSet workingSet) { 214 boolean workingSetRemoved = workingSets.remove(workingSet); 215 boolean recentWorkingSetRemoved = recentWorkingSets.remove(workingSet); 216 217 if (workingSetRemoved) { 218 ((AbstractWorkingSet)workingSet).disconnect(); 219 removeFromUpdater(workingSet); 220 firePropertyChange(CHANGE_WORKING_SET_REMOVE, workingSet, null); 221 } 222 return workingSetRemoved || recentWorkingSetRemoved; 223 } 224 225 228 public IWorkingSet[] getWorkingSets() { 229 SortedSet visibleSubset = new TreeSet (WorkingSetComparator.INSTANCE); 230 for (Iterator i = workingSets.iterator(); i.hasNext();) { 231 IWorkingSet workingSet = (IWorkingSet) i.next(); 232 if (workingSet.isVisible()) { 233 visibleSubset.add(workingSet); 234 } 235 } 236 return (IWorkingSet[]) visibleSubset.toArray(new IWorkingSet[visibleSubset.size()]); 237 } 238 239 public IWorkingSet[] getAllWorkingSets() { 240 return (IWorkingSet[]) workingSets.toArray(new IWorkingSet[workingSets.size()]); 241 } 242 243 246 public IWorkingSet getWorkingSet(String name) { 247 if (name == null || workingSets == null) { 248 return null; 249 } 250 251 Iterator iter = workingSets.iterator(); 252 while (iter.hasNext()) { 253 IWorkingSet workingSet = (IWorkingSet) iter.next(); 254 if (name.equals(workingSet.getName())) { 255 return workingSet; 256 } 257 } 258 return null; 259 } 260 261 263 266 public IWorkingSet[] getRecentWorkingSets() { 267 return (IWorkingSet[]) recentWorkingSets.toArray(new IWorkingSet[recentWorkingSets.size()]); 268 } 269 270 277 protected void internalAddRecentWorkingSet(IWorkingSet workingSet) { 278 if (!workingSet.isVisible()) { 279 return; 280 } 281 recentWorkingSets.remove(workingSet); 282 recentWorkingSets.add(0, workingSet); 283 if (recentWorkingSets.size() > MRU_SIZE) { 284 recentWorkingSets.remove(MRU_SIZE); 285 } 286 } 287 288 290 297 public boolean equals(Object object) { 298 if (this == object) { 299 return true; 300 } 301 if (!getClass().getName().equals(object.getClass().getName())) { 302 return false; 303 } 304 AbstractWorkingSetManager other= (AbstractWorkingSetManager)object; 305 return other.workingSets.equals(workingSets); 306 } 307 308 313 public int hashCode() { 314 return workingSets.hashCode(); 315 } 316 317 319 322 public void addPropertyChangeListener(IPropertyChangeListener listener) { 323 addListenerObject(listener); 324 } 325 326 329 public void removePropertyChangeListener(IPropertyChangeListener listener) { 330 removeListenerObject(listener); 331 } 332 333 347 protected void firePropertyChange(String changeId, Object oldValue, 348 Object newValue) { 349 final Object [] listeners = getListeners(); 350 351 if (listeners.length == 0) { 352 return; 353 } 354 355 final PropertyChangeEvent event = new PropertyChangeEvent(this, 356 changeId, oldValue, newValue); 357 Runnable notifier = new Runnable () { 358 public void run() { 359 for (int i = 0; i < listeners.length; i++) { 360 final IPropertyChangeListener listener = (IPropertyChangeListener) listeners[i]; 361 ISafeRunnable safetyWrapper = new ISafeRunnable() { 362 363 public void run() throws Exception { 364 listener.propertyChange(event); 365 } 366 367 public void handleException(Throwable exception) { 368 } 370 }; 371 SafeRunner.run(safetyWrapper); 372 } 373 } 374 }; 375 if (Display.getCurrent() != null) { 377 notifier.run(); 378 } else { 379 Display.getDefault().asyncExec(notifier); 381 } 382 } 383 384 398 public void workingSetChanged(IWorkingSet changedWorkingSet, 399 String propertyChangeId, Object oldValue) { 400 firePropertyChange(propertyChangeId, oldValue, changedWorkingSet); 401 } 402 403 406 412 public void saveWorkingSetState(IMemento memento) { 413 Iterator iterator = workingSets.iterator(); 414 415 418 ArrayList standardSets = new ArrayList (); 419 ArrayList aggregateSets = new ArrayList (); 420 while (iterator.hasNext()) { 421 IWorkingSet set = (IWorkingSet) iterator.next(); 422 if (set instanceof AggregateWorkingSet) { 423 aggregateSets.add(set); 424 } else { 425 standardSets.add(set); 426 } 427 } 428 429 saveWorkingSetState(memento, standardSets); 430 saveWorkingSetState(memento, aggregateSets); 431 } 432 433 438 private void saveWorkingSetState(IMemento memento, List list) { 439 for (Iterator i = list.iterator(); i.hasNext();) { 440 IPersistableElement persistable = (IWorkingSet) i.next(); 441 IMemento workingSetMemento = memento 442 .createChild(IWorkbenchConstants.TAG_WORKING_SET); 443 workingSetMemento.putString(IWorkbenchConstants.TAG_FACTORY_ID, 444 persistable.getFactoryId()); 445 persistable.saveState(workingSetMemento); 446 } 447 } 448 449 455 protected void restoreWorkingSetState(IMemento memento) { 456 IMemento[] children = memento 457 .getChildren(IWorkbenchConstants.TAG_WORKING_SET); 458 for (int i = 0; i < children.length; i++) { 459 IWorkingSet workingSet = restoreWorkingSet(children[i]); 460 if (workingSet != null) { 461 internalAddWorkingSet(workingSet); 462 } 463 } 464 } 465 466 473 protected IWorkingSet restoreWorkingSet(IMemento memento) { 474 String factoryID = memento 475 .getString(IWorkbenchConstants.TAG_FACTORY_ID); 476 477 if (factoryID == null) { 478 factoryID = AbstractWorkingSet.FACTORY_ID; 482 } 483 IElementFactory factory = PlatformUI.getWorkbench().getElementFactory( 484 factoryID); 485 if (factory == null) { 486 WorkbenchPlugin 487 .log("Unable to restore working set - cannot instantiate factory: " + factoryID); return null; 489 } 490 IAdaptable adaptable = factory.createElement(memento); 491 if (adaptable == null) { 492 WorkbenchPlugin 493 .log("Unable to restore working set - cannot instantiate working set: " + factoryID); return null; 495 } 496 if ((adaptable instanceof IWorkingSet) == false) { 497 WorkbenchPlugin 498 .log("Unable to restore working set - element is not an IWorkingSet: " + factoryID); return null; 500 } 501 return (IWorkingSet) adaptable; 502 } 503 504 510 protected void saveMruList(IMemento memento) { 511 Iterator iterator = recentWorkingSets.iterator(); 512 513 while (iterator.hasNext()) { 514 IWorkingSet workingSet = (IWorkingSet) iterator.next(); 515 IMemento mruMemento = memento 516 .createChild(IWorkbenchConstants.TAG_MRU_LIST); 517 518 mruMemento.putString(IWorkbenchConstants.TAG_NAME, workingSet 519 .getName()); 520 } 521 } 522 523 529 protected void restoreMruList(IMemento memento) { 530 IMemento[] mruWorkingSets = memento 531 .getChildren(IWorkbenchConstants.TAG_MRU_LIST); 532 533 for (int i = mruWorkingSets.length - 1; i >= 0; i--) { 534 String workingSetName = mruWorkingSets[i] 535 .getString(IWorkbenchConstants.TAG_NAME); 536 if (workingSetName != null) { 537 IWorkingSet workingSet = getWorkingSet(workingSetName); 538 if (workingSet != null) { 539 internalAddRecentWorkingSet(workingSet); 540 } 541 } 542 } 543 } 544 545 547 551 public IWorkingSetEditWizard createWorkingSetEditWizard( 552 IWorkingSet workingSet) { 553 String editPageId = workingSet.getId(); 554 WorkingSetRegistry registry = WorkbenchPlugin.getDefault() 555 .getWorkingSetRegistry(); 556 IWorkingSetPage editPage = null; 557 558 if (editPageId != null) { 559 editPage = registry.getWorkingSetPage(editPageId); 560 } 561 562 565 if (editPage == null) { 566 editPage = registry.getDefaultWorkingSetPage(); 567 if (editPage == null) { 568 return null; 569 } 570 } 571 572 WorkingSetEditWizard editWizard = new WorkingSetEditWizard(editPage); 573 editWizard.setSelection(workingSet); 574 return editWizard; 575 } 576 577 580 public IWorkingSetSelectionDialog createWorkingSetSelectionDialog( 581 Shell parent) { 582 return createWorkingSetSelectionDialog(parent, true); 583 } 584 585 588 public IWorkingSetSelectionDialog createWorkingSetSelectionDialog( 589 Shell parent, boolean multi) { 590 return createWorkingSetSelectionDialog(parent, multi, null); 591 } 592 593 596 public IWorkingSetNewWizard createWorkingSetNewWizard(String [] workingSetIds) { 597 WorkingSetDescriptor[] descriptors= getSupportedEditableDescriptors(workingSetIds); 598 if (descriptors.length == 0) { 599 return null; 600 } 601 return new WorkingSetNewWizard(descriptors); 602 } 603 604 606 public void bundleChanged(BundleEvent event) { 607 if (event.getBundle().getSymbolicName() == null) 608 return; 609 if (!Workbench.getInstance().isRunning()) { 611 return; 612 } 613 614 if (event.getBundle().getState() == Bundle.ACTIVE) { 615 WorkingSetDescriptor[] descriptors = WorkbenchPlugin.getDefault() 616 .getWorkingSetRegistry().getUpdaterDescriptorsForNamespace( 617 event.getBundle().getSymbolicName()); 618 synchronized (updaters) { 619 for (int i = 0; i < descriptors.length; i++) { 620 WorkingSetDescriptor descriptor = descriptors[i]; 621 List workingSets = getWorkingSetsForId(descriptor.getId()); 622 if (workingSets.size() == 0) { 623 continue; 624 } 625 IWorkingSetUpdater updater = getUpdater(descriptor); 626 for (Iterator iter = workingSets.iterator(); iter.hasNext();) { 627 IWorkingSet workingSet = (IWorkingSet) iter.next(); 628 if (!updater.contains(workingSet)) { 629 updater.add(workingSet); 630 } 631 } 632 } 633 } 634 } 635 } 636 637 private List getWorkingSetsForId(String id) { 638 List result= new ArrayList (); 639 for (Iterator iter= workingSets.iterator(); iter.hasNext();) { 640 IWorkingSet ws= (IWorkingSet)iter.next(); 641 if (id.equals(ws.getId())) { 642 result.add(ws); 643 } 644 } 645 return result; 646 } 647 648 private void addToUpdater(IWorkingSet workingSet) { 649 WorkingSetDescriptor descriptor= WorkbenchPlugin.getDefault() 650 .getWorkingSetRegistry().getWorkingSetDescriptor(workingSet.getId()); 651 if (descriptor == null || !descriptor.isUpdaterClassLoaded()) { 652 return; 653 } 654 synchronized(updaters) { 655 IWorkingSetUpdater updater= getUpdater(descriptor); 656 if (!updater.contains(workingSet)) { 657 updater.add(workingSet); 658 } 659 } 660 } 661 662 private IWorkingSetUpdater getUpdater(WorkingSetDescriptor descriptor) { 663 IWorkingSetUpdater updater= (IWorkingSetUpdater)updaters.get(descriptor.getId()); 664 if (updater == null) { 665 updater= descriptor.createWorkingSetUpdater(); 666 if (updater == null) { 667 updater= NULL_UPDATER; 668 } else { 669 firePropertyChange(CHANGE_WORKING_SET_UPDATER_INSTALLED, null, updater); 670 PlatformUI.getWorkbench().getExtensionTracker().registerObject( 671 descriptor.getConfigurationElement() 672 .getDeclaringExtension(), updater, 673 IExtensionTracker.REF_WEAK); 674 675 } 676 updaters.put(descriptor.getId(), updater); 677 } 678 return updater; 679 } 680 681 IWorkingSetElementAdapter getElementAdapter(WorkingSetDescriptor descriptor) { 682 IWorkingSetElementAdapter elementAdapter = (IWorkingSetElementAdapter) elementAdapters 683 .get(descriptor.getId()); 684 if (elementAdapter == null) { 685 elementAdapter = descriptor.createWorkingSetElementAdapter(); 686 if (elementAdapter == null) { 687 elementAdapter = IDENTITY_ADAPTER; 688 } else { 689 elementAdapters.put(descriptor.getId(), elementAdapter); 690 } 691 } 692 return elementAdapter; 693 } 694 695 private void removeFromUpdater(IWorkingSet workingSet) { 696 synchronized (updaters) { 697 IWorkingSetUpdater updater = (IWorkingSetUpdater) updaters 698 .get(workingSet.getId()); 699 if (updater != null) { 700 updater.remove(workingSet); 701 } 702 } 703 } 704 705 706 709 public IWorkingSetSelectionDialog createWorkingSetSelectionDialog(Shell parent, boolean multi, String [] workingsSetIds) { 710 return new WorkingSetSelectionDialog(parent, multi, workingsSetIds); 711 } 712 713 719 public void saveState(File stateFile) throws IOException { 720 XMLMemento memento = XMLMemento 721 .createWriteRoot(IWorkbenchConstants.TAG_WORKING_SET_MANAGER); 722 saveWorkingSetState(memento); 723 saveMruList(memento); 724 725 FileOutputStream stream = new FileOutputStream (stateFile); 726 OutputStreamWriter writer = new OutputStreamWriter (stream, "utf-8"); memento.save(writer); 728 writer.close(); 729 730 } 731 732 735 public void addExtension(IExtensionTracker tracker, IExtension extension) { 736 738 } 739 740 743 public void removeExtension(IExtension extension, Object [] objects) { 744 for (int i = 0; i < objects.length; i++) { 745 Object object = objects[i]; 746 if (object instanceof IWorkingSetUpdater) { 747 removeUpdater((IWorkingSetUpdater)object); 748 749 } 750 if (object instanceof IWorkingSetElementAdapter) { 751 removeElementAdapter((IWorkingSetElementAdapter) object); 752 } 753 } 754 } 755 756 762 private void removeElementAdapter( 763 final IWorkingSetElementAdapter elementAdapter) { 764 SafeRunner.run(new ISafeRunnable() { 765 766 public void handleException(Throwable exception) { 767 StatusManager.getManager().handle( 768 StatusUtil.newStatus(PlatformUI.PLUGIN_ID, exception)); 769 } 770 771 public void run() throws Exception { 772 elementAdapter.dispose(); 773 774 } 775 }); 776 synchronized (elementAdapters) { 777 elementAdapters.values().remove(elementAdapter); 778 } 779 } 780 781 787 private void removeUpdater(final IWorkingSetUpdater updater) { 788 SafeRunner.run(new ISafeRunnable() { 789 790 public void handleException(Throwable exception) { 791 StatusManager.getManager().handle( 792 StatusUtil.newStatus(PlatformUI.PLUGIN_ID, exception)); 793 } 794 795 public void run() throws Exception { 796 updater.dispose(); 797 798 } 799 }); 800 synchronized (updaters) { 801 updaters.values().remove(updater); 802 } 803 firePropertyChange(IWorkingSetManager.CHANGE_WORKING_SET_UPDATER_UNINSTALLED, updater, null); 804 } 805 } 806 | Popular Tags |