1 11 package org.eclipse.ui.internal; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Collection ; 16 import java.util.Collections ; 17 import java.util.HashMap ; 18 import java.util.HashSet ; 19 import java.util.Hashtable ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.Map ; 23 import java.util.Set ; 24 25 import org.eclipse.core.runtime.IAdaptable; 26 import org.eclipse.core.runtime.IAdapterManager; 27 import org.eclipse.core.runtime.IConfigurationElement; 28 import org.eclipse.core.runtime.IExtension; 29 import org.eclipse.core.runtime.Platform; 30 import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler; 31 import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; 32 import org.eclipse.jface.viewers.IStructuredSelection; 33 import org.eclipse.ui.PlatformUI; 34 import org.eclipse.ui.internal.util.Util; 35 36 55 public abstract class ObjectContributorManager implements IExtensionChangeHandler { 56 57 60 private class ContributorRecord { 61 65 public ContributorRecord(IObjectContributor contributor, String targetType) { 66 this.contributor = contributor; 67 this.objectClassName = targetType; 68 } 69 70 String objectClassName; 71 IObjectContributor contributor; 72 } 73 74 75 protected Map contributors; 76 77 78 protected Map objectLookup; 79 80 81 protected Map resourceAdapterLookup; 82 83 84 protected Map adaptableLookup; 85 86 protected Set contributorRecordSet; 87 88 91 public ObjectContributorManager() { 92 contributors = new Hashtable (5); 93 contributorRecordSet = new HashSet (5); 94 objectLookup = null; 95 resourceAdapterLookup = null; 96 adaptableLookup = null; 97 if(canHandleExtensionTracking()){ 98 IExtensionTracker tracker = PlatformUI.getWorkbench().getExtensionTracker(); 99 tracker.registerHandler(this, null); 100 } 101 } 102 103 109 protected boolean canHandleExtensionTracking() { 110 return true; 111 } 112 113 116 private void addContributorsFor(List types, List result) { 117 for (Iterator classes = types.iterator(); classes.hasNext();) { 118 Class clazz = (Class ) classes.next(); 119 List contributorList = (List ) contributors.get(clazz.getName()); 120 if (contributorList != null) { 121 result.addAll(contributorList); 122 } 123 } 124 } 125 126 130 protected final List computeClassOrder(Class extensibleClass) { 131 ArrayList result = new ArrayList (4); 132 Class clazz = extensibleClass; 133 while (clazz != null) { 134 result.add(clazz); 135 clazz = clazz.getSuperclass(); 136 } 137 return result; 138 } 139 140 145 protected final List computeInterfaceOrder(List classList) { 146 ArrayList result = new ArrayList (4); 147 Map seen = new HashMap (4); 148 for (Iterator list = classList.iterator(); list.hasNext();) { 149 Class [] interfaces = ((Class ) list.next()).getInterfaces(); 150 internalComputeInterfaceOrder(interfaces, result, seen); 151 } 152 return result; 153 } 154 155 162 public void flushLookup() { 163 objectLookup = null; 164 resourceAdapterLookup = null; 165 adaptableLookup = null; 166 } 167 168 171 private void cacheResourceAdapterLookup(Class adapterClass, List results) { 172 if (resourceAdapterLookup == null) { 173 resourceAdapterLookup = new HashMap (); 174 } 175 resourceAdapterLookup.put(adapterClass, results); 176 } 177 178 181 private void cacheAdaptableLookup(String adapterClass, List results) { 182 if (adaptableLookup == null) { 183 adaptableLookup = new HashMap (); 184 } 185 adaptableLookup.put(adapterClass, results); 186 } 187 188 191 private void cacheObjectLookup(Class objectClass, List results) { 192 if (objectLookup == null) { 193 objectLookup = new HashMap (); 194 } 195 objectLookup.put(objectClass, results); 196 } 197 198 206 public Collection getContributors() { 207 return Collections.unmodifiableCollection(contributors.values()); 208 } 209 210 213 protected List addContributorsFor(Class objectClass) { 214 215 List classList = computeClassOrder(objectClass); 216 List result = new ArrayList (); 217 addContributorsFor(classList, result); 218 classList = computeInterfaceOrder(classList); addContributorsFor(classList, result); 220 return result; 221 } 222 223 231 public boolean hasContributorsFor(Object object) { 232 233 List contributors = getContributors(object); 234 return contributors.size() > 0; 235 } 236 237 242 private void internalComputeInterfaceOrder(Class [] interfaces, List result, 243 Map seen) { 244 List newInterfaces = new ArrayList (seen.size()); 245 for (int i = 0; i < interfaces.length; i++) { 246 Class interfac = interfaces[i]; 247 if (seen.get(interfac) == null) { 248 result.add(interfac); 249 seen.put(interfac, interfac); 250 newInterfaces.add(interfac); 251 } 252 } 253 for (Iterator newList = newInterfaces.iterator(); newList.hasNext();) { 254 internalComputeInterfaceOrder(((Class ) newList.next()) 255 .getInterfaces(), result, seen); 256 } 257 } 258 259 269 public boolean isApplicableTo(IStructuredSelection selection, 270 IObjectContributor contributor) { 271 Iterator elements = selection.iterator(); 272 while (elements.hasNext()) { 273 if (contributor.isApplicableTo(elements.next()) == false) { 274 return false; 275 } 276 } 277 return true; 278 } 279 280 290 291 public boolean isApplicableTo(List list, IObjectContributor contributor) { 292 Iterator elements = list.iterator(); 293 while (elements.hasNext()) { 294 if (contributor.isApplicableTo(elements.next()) == false) { 295 return false; 296 } 297 } 298 return true; 299 } 300 301 307 public void registerContributor(IObjectContributor contributor, 308 String targetType) { 309 List contributorList = (List ) contributors.get(targetType); 310 if (contributorList == null) { 311 contributorList = new ArrayList (5); 312 contributors.put(targetType, contributorList); 313 } 314 contributorList.add(contributor); 315 flushLookup(); 316 317 IConfigurationElement element = (IConfigurationElement) Util.getAdapter(contributor, 318 IConfigurationElement.class); 319 320 if (element != null) { 322 ContributorRecord contributorRecord = new ContributorRecord( 323 contributor, targetType); 324 contributorRecordSet.add(contributorRecord); 325 PlatformUI.getWorkbench().getExtensionTracker().registerObject( 326 element.getDeclaringExtension(), contributorRecord, 327 IExtensionTracker.REF_WEAK); 328 } 329 } 330 331 334 public void unregisterAllContributors() { 335 contributors = new Hashtable (5); 336 flushLookup(); 337 } 338 339 345 public void unregisterContributor(IObjectContributor contributor, 346 String targetType) { 347 List contributorList = (List ) contributors.get(targetType); 348 if (contributorList == null) { 349 return; 350 } 351 contributorList.remove(contributor); 352 if (contributorList.isEmpty()) { 353 contributors.remove(targetType); 354 } 355 flushLookup(); 356 } 357 358 359 364 public void unregisterContributors(String targetType) { 365 contributors.remove(targetType); 366 flushLookup(); 367 } 368 369 protected List getContributors(Object object) { 370 Object resource = LegacyResourceSupport.getAdaptedContributorResource(object); 372 373 List adapters = new ArrayList (Arrays.asList(Platform.getAdapterManager().computeAdapterTypes(object.getClass()))); 375 removeCommonAdapters(adapters, Arrays.asList(new Class [] {object.getClass()})); 376 377 List contributors = new ArrayList (); 378 379 addAll(contributors, getObjectContributors(object.getClass())); 381 if(resource != null) { 383 addAll(contributors, getResourceContributors(resource.getClass())); 384 } 385 if(adapters != null) { 387 for (Iterator it = adapters.iterator(); it.hasNext();) { 388 String adapter = (String ) it.next(); 389 addAll(contributors, getAdaptableContributors(adapter)); 390 } 391 } 392 393 contributors = removeDups(contributors); 395 396 return contributors.isEmpty() ? Collections.EMPTY_LIST : new ArrayList (contributors); 397 } 398 399 409 protected List getObjectContributors(Class objectClass) { 410 List objectList = null; 411 if (objectLookup != null) { 413 objectList = (List ) objectLookup.get(objectClass); 414 } 415 if (objectList == null) { 416 objectList = addContributorsFor(objectClass); 417 if (objectList.size() == 0) { 418 objectList = Collections.EMPTY_LIST; 419 } 420 else { 421 objectList = Collections.unmodifiableList(objectList); 422 } 423 cacheObjectLookup(objectClass, objectList); 424 } 425 return objectList; 426 } 427 428 439 protected List getResourceContributors(Class resourceClass) { 440 List resourceList = null; 441 if (resourceAdapterLookup != null) { 442 resourceList = (List ) resourceAdapterLookup.get(resourceClass); 443 } 444 if (resourceList == null) { 445 resourceList = addContributorsFor(resourceClass); 446 if (resourceList.size() == 0) { 447 resourceList = Collections.EMPTY_LIST; 448 } else { 449 resourceList = Collections.unmodifiableList(filterOnlyAdaptableContributors(resourceList)); 450 } 451 cacheResourceAdapterLookup(resourceClass, resourceList); 452 } 453 return resourceList; 454 } 455 456 465 protected List getAdaptableContributors(String adapterType) { 466 List adaptableList = null; 467 if (adaptableLookup != null) { 471 adaptableList = (List ) adaptableLookup.get(adapterType); 472 } 473 if (adaptableList == null) { 474 if (LegacyResourceSupport.isResourceType(adapterType) || LegacyResourceSupport.isResourceMappingType(adapterType)) { 477 adaptableList = Collections.EMPTY_LIST; 478 } 479 else { 480 adaptableList = (List ) contributors.get(adapterType); 481 if (adaptableList == null || adaptableList.size() == 0) { 482 adaptableList = Collections.EMPTY_LIST; 483 } else { 484 adaptableList = Collections.unmodifiableList(filterOnlyAdaptableContributors(adaptableList)); 485 } 486 } 487 cacheAdaptableLookup(adapterType, adaptableList); 488 } 489 return adaptableList; 490 } 491 492 499 protected void removeCommonAdapters(List adapters, List results) { 500 for (Iterator it = results.iterator(); it.hasNext();) { 501 Class clazz = ((Class ) it.next()); 502 List commonTypes = computeCombinedOrder(clazz); 503 for (Iterator it2 = commonTypes.iterator(); it2.hasNext();) { 504 Class type = (Class ) it2.next(); 505 adapters.remove(type.getName()); 506 } 507 } 508 } 509 510 514 protected List computeCombinedOrder(Class inputClass) { 515 List result = new ArrayList (4); 516 Class clazz = inputClass; 517 while (clazz != null) { 518 result.add(clazz); 520 Class [] interfaces = clazz.getInterfaces(); 522 for (int i = 0; i < interfaces.length; i++) { 523 result.add(interfaces[i]); 524 } 525 clazz = clazz.getSuperclass(); 527 } 528 return result; 529 } 530 531 private List filterOnlyAdaptableContributors(List contributors) { 532 List adaptableContributors = null; 533 for (Iterator it = contributors.iterator(); it.hasNext();) { 534 IObjectContributor c = (IObjectContributor) it.next(); 535 if(c.canAdapt()) { 536 if(adaptableContributors == null) { 537 adaptableContributors = new ArrayList (); 538 } 539 adaptableContributors.add(c); 540 } 541 } 542 return adaptableContributors == null ? Collections.EMPTY_LIST : adaptableContributors; 543 } 544 545 548 public void removeExtension(IExtension source, Object [] objects) { 549 for (int i = 0; i < objects.length; i++) { 550 if (objects[i] instanceof ContributorRecord) { 551 ContributorRecord contributorRecord = (ContributorRecord) objects[i]; 552 unregisterContributor((contributorRecord).contributor, (contributorRecord).objectClassName); 553 contributorRecordSet.remove(contributorRecord); 554 } 555 } 556 } 557 558 563 public void dispose() { 564 if(canHandleExtensionTracking()) { 565 PlatformUI.getWorkbench().getExtensionTracker().unregisterHandler(this); 566 } 567 } 568 569 575 protected List getContributors(List elements) { 576 List commonAdapters = new ArrayList (); 579 List commonClasses = getCommonClasses(elements, commonAdapters); 580 581 Class resourceClass = getCommonResourceClass(elements); 585 Class resourceMappingClass = getResourceMappingClass(elements); 586 587 589 List contributors = new ArrayList (); 590 591 if (resourceClass != null) { 593 addAll(contributors, getResourceContributors(resourceClass)); 594 } 595 if (commonClasses != null && !commonClasses.isEmpty()) { 596 for (int i = 0; i < commonClasses.size(); i++) { 597 List results = getObjectContributors((Class ) commonClasses 598 .get(i)); 599 addAll(contributors, results); 600 } 601 } 602 if (resourceMappingClass == null) { 604 resourceMappingClass = LegacyResourceSupport 607 .getResourceMappingClass(); 608 if (resourceMappingClass != null 609 && commonAdapters.contains(resourceMappingClass.getName())) { 610 addAll(contributors, getResourceContributors(resourceMappingClass)); 611 } 612 } else { 613 contributors.addAll(getResourceContributors(resourceMappingClass)); 614 } 615 if (!commonAdapters.isEmpty()) { 616 for (Iterator it = commonAdapters.iterator(); it.hasNext();) { 617 String adapter = (String ) it.next(); 618 addAll(contributors, getAdaptableContributors(adapter)); 619 } 620 } 621 622 contributors = removeDups(contributors); 624 625 return contributors.isEmpty() ? Collections.EMPTY_LIST : new ArrayList (contributors); 626 } 627 628 633 private static void addAll(Collection collection, List toAdd) { 634 for (int i = 0, size = toAdd.size(); i < size; ++i) { 635 collection.add(toAdd.get(i)); 636 } 637 } 638 639 642 private static List removeDups(List list) { 643 if (list.size() <= 1) { 644 return list; 645 } 646 HashSet set = new HashSet (list); 647 if (set.size() == list.size()) { 648 return list; 649 } 650 ArrayList result = new ArrayList (set.size()); 651 for (Iterator i = list.iterator(); i.hasNext();) { 652 Object o = i.next(); 653 if (set.remove(o)) { 654 result.add(o); 655 } 656 } 657 return result; 658 } 659 660 664 private List getCommonClasses(List objects, List commonAdapters) { 665 if (objects == null || objects.size() == 0) { 666 return null; 667 } 668 669 if (allSameClass(objects)) { 673 674 Class clazz = objects.get(0).getClass(); 675 commonAdapters.addAll(Arrays.asList(Platform.getAdapterManager().computeAdapterTypes(clazz))); 676 List result = new ArrayList (1); 677 result.add(clazz); 678 return result; 679 } 680 681 List classes = computeClassOrder(objects.get(0).getClass()); 684 List adapters = computeAdapterOrder(classes); 685 List interfaces = computeInterfaceOrder(classes); 686 687 List lastCommonTypes = new ArrayList (); 690 691 boolean classesEmpty = classes.isEmpty(); 692 boolean interfacesEmpty = interfaces.isEmpty(); 693 694 for (int i = 1; i < objects.size(); i++) { 696 List otherClasses = computeClassOrder(objects.get(i).getClass()); 698 if (!classesEmpty) { 699 classesEmpty = extractCommonClasses(classes, otherClasses); 700 } 701 702 List otherInterfaces = computeInterfaceOrder(otherClasses); 705 if (!interfacesEmpty) { 706 interfacesEmpty = extractCommonClasses(interfaces, 707 otherInterfaces); 708 } 709 710 List classesAndInterfaces = new ArrayList (otherClasses); 713 if (otherInterfaces != null) { 714 classesAndInterfaces.addAll(otherInterfaces); 715 } 716 List otherAdapters = computeAdapterOrder(classesAndInterfaces); 717 718 if (otherAdapters.isEmpty() && !adapters.isEmpty()) { 725 removeNonCommonAdapters(adapters, classesAndInterfaces); 726 } else { 727 if (adapters.isEmpty()) { 728 removeNonCommonAdapters(otherAdapters, lastCommonTypes); 729 if (!otherAdapters.isEmpty()) { 730 adapters.addAll(otherAdapters); 731 } 732 } else { 733 for (Iterator it = adapters.iterator(); it.hasNext();) { 736 String adapter = (String ) it.next(); 737 if (!otherAdapters.contains(adapter)) { 738 it.remove(); 739 } 740 } 741 } 742 } 743 744 lastCommonTypes.clear(); 747 lastCommonTypes.addAll(classes); 748 lastCommonTypes.addAll(interfaces); 749 750 if (interfacesEmpty && classesEmpty && adapters.isEmpty()) { 751 return null; 753 } 754 } 755 756 ArrayList results = new ArrayList (4); 759 ArrayList superClasses = new ArrayList (4); 760 if (!classesEmpty) { 761 for (int j = 0; j < classes.size(); j++) { 762 if (classes.get(j) != null) { 763 superClasses.add(classes.get(j)); 764 } 765 } 766 if (!superClasses.isEmpty()) { 768 results.add(superClasses.get(0)); 769 } 770 } 771 772 if (!interfacesEmpty) { 773 removeCommonInterfaces(superClasses, interfaces, results); 774 } 775 776 if (!adapters.isEmpty()) { 778 removeCommonAdapters(adapters, results); 779 commonAdapters.addAll(adapters); 780 } 781 return results; 782 } 783 784 788 private boolean allSameClass(List objects) { 789 int size = objects.size(); 790 if (size <= 1) return true; 791 Class clazz = objects.get(0).getClass(); 792 for (int i = 1; i < size; ++i) { 793 if (!objects.get(i).getClass().equals(clazz)) { 794 return false; 795 } 796 } 797 return true; 798 } 799 800 private boolean extractCommonClasses(List classes, List otherClasses) { 801 boolean classesEmpty = true; 802 if (otherClasses.isEmpty()) { 803 classes.clear(); 807 } else { 808 for (int j = 0; j < classes.size(); j++) { 811 if (classes.get(j) != null) { 812 classesEmpty = false; if (!otherClasses.contains(classes.get(j))) { 814 classes.set(j, null); 815 } 816 } 817 } 818 } 819 return classesEmpty; 820 } 821 822 private void removeNonCommonAdapters(List adapters, List classes) { 823 for (int i = 0; i < classes.size(); i++) { 824 Object o = classes.get(i); 825 if (o != null) { 826 Class clazz = (Class ) o; 827 String name = clazz.getName(); 828 if (adapters.contains(name)) { 829 return; 830 } 831 } 832 } 833 adapters.clear(); 834 } 835 836 private void removeCommonInterfaces(List superClasses, List types, 837 List results) { 838 List dropInterfaces = null; 839 if (!superClasses.isEmpty()) { 840 dropInterfaces = computeInterfaceOrder(superClasses); 841 } 842 for (int j = 0; j < types.size(); j++) { 843 if (types.get(j) != null) { 844 if (dropInterfaces != null 845 && !dropInterfaces.contains(types.get(j))) { 846 results.add(types.get(j)); 847 } 848 } 849 } 850 } 851 852 private List computeAdapterOrder(List classList) { 853 Set result = new HashSet (4); 854 IAdapterManager adapterMgr = Platform.getAdapterManager(); 855 for (Iterator list = classList.iterator(); list.hasNext();) { 856 Class clazz = ((Class ) list.next()); 857 String [] adapters = adapterMgr.computeAdapterTypes(clazz); 858 for (int i = 0; i < adapters.length; i++) { 859 String adapter = adapters[i]; 860 if (!result.contains(adapter)) { 861 result.add(adapter); 862 } 863 } 864 } 865 return new ArrayList (result); 866 } 867 868 874 private Class getCommonResourceClass(List objects) { 875 if (objects == null || objects.size() == 0) { 876 return null; 877 } 878 Class resourceClass = LegacyResourceSupport.getResourceClass(); 879 if (resourceClass == null) { 880 return null; 882 } 883 884 List testList = new ArrayList (objects.size()); 885 886 for (int i = 0; i < objects.size(); i++) { 887 Object object = objects.get(i); 888 889 if (object instanceof IAdaptable) { 890 if (resourceClass.isInstance(object)) { 891 continue; 892 } 893 894 Object resource = LegacyResourceSupport 895 .getAdaptedContributorResource(object); 896 897 if (resource == null) { 898 return null; 900 } 901 testList.add(resource); 902 } else { 903 return null; 904 } 905 } 906 907 return getCommonClass(testList); 908 } 909 910 913 private Class getResourceMappingClass(List objects) { 914 if (objects == null || objects.size() == 0) { 915 return null; 916 } 917 Class resourceMappingClass = LegacyResourceSupport 918 .getResourceMappingClass(); 919 if (resourceMappingClass == null) { 920 return null; 922 } 923 924 for (int i = 0; i < objects.size(); i++) { 925 Object object = objects.get(i); 926 927 if (object instanceof IAdaptable) { 928 if (resourceMappingClass.isInstance(object)) { 929 continue; 930 } 931 932 Object resourceMapping = LegacyResourceSupport 933 .getAdaptedContributorResourceMapping(object); 934 935 if (resourceMapping == null) { 936 return null; 938 } 939 } else { 940 return null; 941 } 942 } 943 return resourceMappingClass; 945 } 946 947 951 private Class getCommonClass(List objects) { 952 if (objects == null || objects.size() == 0) { 953 return null; 954 } 955 Class commonClass = objects.get(0).getClass(); 956 if (objects.size() == 1) { 958 return commonClass; 959 } 961 962 for (int i = 1; i < objects.size(); i++) { 963 Object object = objects.get(i); 964 Class newClass = object.getClass(); 965 if (newClass.equals(commonClass)) { 967 continue; 968 } 969 commonClass = getCommonClass(commonClass, newClass); 971 if (commonClass == null) { 973 return null; 974 } 975 } 976 return commonClass; 977 } 978 979 983 private Class getCommonClass(Class class1, Class class2) { 984 List list1 = computeCombinedOrder(class1); 985 List list2 = computeCombinedOrder(class2); 986 for (int i = 0; i < list1.size(); i++) { 987 for (int j = 0; j < list2.size(); j++) { 988 Class candidate1 = (Class ) list1.get(i); 989 Class candidate2 = (Class ) list2.get(j); 990 if (candidate1.equals(candidate2)) { 991 return candidate1; 992 } 993 } 994 } 995 return null; 997 } 998 } 999 | Popular Tags |