1 11 package org.eclipse.ui.internal.navigator; 12 13 import java.util.ArrayList ; 14 import java.util.Collections ; 15 import java.util.Iterator ; 16 import java.util.LinkedHashSet ; 17 import java.util.LinkedList ; 18 import java.util.List ; 19 import java.util.Set ; 20 21 import org.eclipse.jface.viewers.ITreeContentProvider; 22 import org.eclipse.jface.viewers.ITreePathContentProvider; 23 import org.eclipse.jface.viewers.TreePath; 24 import org.eclipse.jface.viewers.Viewer; 25 import org.eclipse.osgi.util.NLS; 26 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptor; 27 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentExtension; 28 import org.eclipse.ui.internal.navigator.extensions.NavigatorViewerDescriptor; 29 import org.eclipse.ui.internal.navigator.extensions.OverridePolicy; 30 import org.eclipse.ui.navigator.CommonViewer; 31 import org.eclipse.ui.navigator.INavigatorContentDescriptor; 32 import org.eclipse.ui.navigator.INavigatorViewerDescriptor; 33 import org.eclipse.ui.navigator.IPipelinedTreeContentProvider; 34 35 64 public class NavigatorContentServiceContentProvider implements 65 ITreeContentProvider, ITreePathContentProvider { 66 67 private static final Object [] NO_CHILDREN = new Object [0]; 68 69 private final NavigatorContentService contentService; 70 71 private final boolean isContentServiceSelfManaged; 72 73 private final boolean enforceHasChildren; 74 75 private Viewer viewer; 76 77 88 public NavigatorContentServiceContentProvider(String aViewerId) { 89 super(); 90 contentService = new NavigatorContentService(aViewerId); 91 INavigatorViewerDescriptor vDesc = contentService.getViewerDescriptor(); 92 enforceHasChildren = vDesc.getBooleanConfigProperty(NavigatorViewerDescriptor.PROP_ENFORCE_HAS_CHILDREN); 93 isContentServiceSelfManaged = true; 94 } 95 96 105 public NavigatorContentServiceContentProvider( 106 NavigatorContentService aContentService) { 107 super(); 108 contentService = aContentService; 109 isContentServiceSelfManaged = false; 110 INavigatorViewerDescriptor vDesc = contentService.getViewerDescriptor(); 111 enforceHasChildren = vDesc.getBooleanConfigProperty(NavigatorViewerDescriptor.PROP_ENFORCE_HAS_CHILDREN); 112 } 113 114 142 public synchronized Object [] getElements(Object anInputElement) { 143 Set rootContentExtensions = contentService 144 .findRootContentExtensions(anInputElement); 145 if (rootContentExtensions.size() == 0) { 146 return NO_CHILDREN; 147 } 148 ContributorTrackingSet finalElementsSet = new ContributorTrackingSet(contentService); 149 ContributorTrackingSet localSet = new ContributorTrackingSet(contentService); 150 151 Object [] contributedChildren = null; 152 NavigatorContentExtension foundExtension; 153 NavigatorContentExtension[] overridingExtensions; 154 for (Iterator itr = rootContentExtensions.iterator(); itr.hasNext();) { 155 foundExtension = (NavigatorContentExtension) itr.next(); 156 try { 157 158 if (!isOverridingExtensionInSet(foundExtension.getDescriptor(), 159 rootContentExtensions)) { 160 161 contributedChildren = foundExtension.internalGetContentProvider() 162 .getElements(anInputElement); 163 164 localSet.setContents(contributedChildren); 165 166 overridingExtensions = foundExtension 167 .getOverridingExtensionsForTriggerPoint(anInputElement); 168 169 if (overridingExtensions.length > 0) { 170 localSet = pipelineElements(anInputElement, 171 overridingExtensions, localSet); 172 } 173 finalElementsSet.addAll(localSet); 174 } 175 } catch (RuntimeException re) { 176 NavigatorPlugin 177 .logError( 178 0, 179 NLS 180 .bind( 181 CommonNavigatorMessages.Could_not_provide_children_for_element, 182 new Object [] { foundExtension 183 .getDescriptor() 184 .getId() }), re); 185 } catch (Error e) { 186 NavigatorPlugin 187 .logError( 188 0, 189 NLS 190 .bind( 191 CommonNavigatorMessages.Could_not_provide_children_for_element, 192 new Object [] { foundExtension 193 .getDescriptor() 194 .getId() }), e); 195 196 } 197 } 198 return finalElementsSet.toArray(); 199 } 200 201 226 public synchronized Object [] getChildren(Object aParentElement) { 227 return internalGetChildren(aParentElement); 228 } 229 230 private Object [] internalGetChildren(Object aParentElementOrPath) { 231 Object aParentElement = internalAsElement(aParentElementOrPath); 232 Set enabledExtensions = contentService 233 .findContentExtensionsByTriggerPoint(aParentElement); 234 if (enabledExtensions.size() == 0) { 235 return NO_CHILDREN; 236 } 237 ContributorTrackingSet finalChildrenSet = new ContributorTrackingSet(contentService); 238 ContributorTrackingSet localSet = new ContributorTrackingSet(contentService); 239 240 Object [] contributedChildren = null; 241 NavigatorContentExtension foundExtension; 242 NavigatorContentExtension[] overridingExtensions; 243 for (Iterator itr = enabledExtensions.iterator(); itr.hasNext();) { 244 foundExtension = (NavigatorContentExtension) itr.next(); 245 try { 246 247 if (!isOverridingExtensionInSet(foundExtension.getDescriptor(), 248 enabledExtensions)) { 249 250 contributedChildren = foundExtension.internalGetContentProvider() 251 .getChildren(aParentElementOrPath); 252 253 overridingExtensions = foundExtension 254 .getOverridingExtensionsForTriggerPoint(aParentElement); 255 256 localSet.setContents(contributedChildren); 257 258 if (overridingExtensions.length > 0) { 259 localSet = pipelineChildren(aParentElement, 261 overridingExtensions, localSet); 262 } 263 finalChildrenSet.addAll(localSet); 264 } 265 } catch (RuntimeException re) { 266 NavigatorPlugin 267 .logError( 268 0, 269 NLS 270 .bind( 271 CommonNavigatorMessages.Could_not_provide_children_for_element, 272 new Object [] { foundExtension 273 .getDescriptor() 274 .getId() }), re); 275 } catch (Error e) { 276 NavigatorPlugin 277 .logError( 278 0, 279 NLS 280 .bind( 281 CommonNavigatorMessages.Could_not_provide_children_for_element, 282 new Object [] { foundExtension 283 .getDescriptor() 284 .getId() }), e); 285 286 } 287 } 288 return finalChildrenSet.toArray(); 289 } 290 291 305 private ContributorTrackingSet pipelineChildren(Object aParentOrPath, 306 NavigatorContentExtension[] theOverridingExtensions, 307 ContributorTrackingSet theCurrentChildren) { 308 IPipelinedTreeContentProvider pipelinedContentProvider; 309 NavigatorContentExtension[] overridingExtensions; 310 ContributorTrackingSet pipelinedChildren = theCurrentChildren; 311 for (int i = 0; i < theOverridingExtensions.length; i++) { 312 313 if (theOverridingExtensions[i].getContentProvider() instanceof IPipelinedTreeContentProvider) { 314 pipelinedContentProvider = (IPipelinedTreeContentProvider) theOverridingExtensions[i] 315 .getContentProvider(); 316 317 pipelinedChildren.setContributor((NavigatorContentDescriptor) theOverridingExtensions[i].getDescriptor()); 318 pipelinedContentProvider.getPipelinedChildren(aParentOrPath, 319 pipelinedChildren); 320 321 pipelinedChildren.setContributor(null); 322 323 overridingExtensions = theOverridingExtensions[i] 324 .getOverridingExtensionsForTriggerPoint(aParentOrPath); 325 if (overridingExtensions.length > 0) { 326 pipelinedChildren = pipelineChildren(aParentOrPath, 327 overridingExtensions, pipelinedChildren); 328 } 329 } 330 } 331 332 return pipelinedChildren; 333 334 } 335 336 350 private ContributorTrackingSet pipelineElements(Object anInputElement, 351 NavigatorContentExtension[] theOverridingExtensions, 352 ContributorTrackingSet theCurrentElements) { 353 IPipelinedTreeContentProvider pipelinedContentProvider; 354 NavigatorContentExtension[] overridingExtensions; 355 ContributorTrackingSet pipelinedElements = theCurrentElements; 356 for (int i = 0; i < theOverridingExtensions.length; i++) { 357 358 if (theOverridingExtensions[i].getContentProvider() instanceof IPipelinedTreeContentProvider) { 359 pipelinedContentProvider = (IPipelinedTreeContentProvider) theOverridingExtensions[i] 360 .getContentProvider(); 361 362 pipelinedElements.setContributor((NavigatorContentDescriptor) theOverridingExtensions[i].getDescriptor()); 363 pipelinedContentProvider.getPipelinedElements(anInputElement, 364 pipelinedElements); 365 pipelinedElements.setContributor(null); 366 367 overridingExtensions = theOverridingExtensions[i] 368 .getOverridingExtensionsForTriggerPoint(anInputElement); 369 if (overridingExtensions.length > 0) { 370 pipelinedElements = pipelineElements(anInputElement, 371 overridingExtensions, pipelinedElements); 372 } 373 } 374 } 375 return pipelinedElements; 376 } 377 378 390 private boolean isOverridingExtensionInSet( 391 INavigatorContentDescriptor aDescriptor, Set theEnabledExtensions) { 392 393 if (aDescriptor.getSuppressedExtensionId() != null 398 && aDescriptor.getOverridePolicy() == OverridePolicy.InvokeAlwaysRegardlessOfSuppressedExt) { 399 404 if (theEnabledExtensions.contains(contentService 405 .getExtension(aDescriptor.getOverriddenDescriptor()))) { 406 return true; 407 } 408 } 409 return false; 410 } 411 412 424 private boolean isOverridingDescriptorInSet( 425 INavigatorContentDescriptor aDescriptor, Set theEnabledDescriptors) { 426 427 if (aDescriptor.getSuppressedExtensionId() != null 432 && aDescriptor.getOverridePolicy() == OverridePolicy.InvokeAlwaysRegardlessOfSuppressedExt) { 433 438 if (theEnabledDescriptors.contains(aDescriptor.getOverriddenDescriptor())) { 439 return true; 440 } 441 } 442 return false; 443 } 444 445 446 447 466 public synchronized Object getParent(Object anElement) { 467 Set extensions = contentService 468 .findContentExtensionsWithPossibleChild(anElement); 469 470 Object parent; 471 NavigatorContentExtension foundExtension; 472 NavigatorContentExtension[] overridingExtensions; 473 for (Iterator itr = extensions.iterator(); itr.hasNext();) { 474 foundExtension = (NavigatorContentExtension) itr.next(); 475 try { 476 477 if (!isOverridingExtensionInSet(foundExtension.getDescriptor(), 478 extensions)) { 479 480 parent = foundExtension.internalGetContentProvider().getParent( 481 anElement); 482 483 overridingExtensions = foundExtension 484 .getOverridingExtensionsForPossibleChild(anElement); 485 486 if (overridingExtensions.length > 0) { 487 parent = pipelineParent(anElement, 488 overridingExtensions, parent); 489 } 490 491 if (parent != null) { 492 return parent; 493 } 494 } 495 } catch (RuntimeException re) { 496 NavigatorPlugin 497 .logError( 498 0, 499 NLS 500 .bind( 501 CommonNavigatorMessages.Could_not_provide_children_for_element, 502 new Object [] { foundExtension 503 .getDescriptor() 504 .getId() }), re); 505 } catch (Error e) { 506 NavigatorPlugin 507 .logError( 508 0, 509 NLS 510 .bind( 511 CommonNavigatorMessages.Could_not_provide_children_for_element, 512 new Object [] { foundExtension 513 .getDescriptor() 514 .getId() }), e); 515 516 } 517 } 518 519 return null; 520 } 521 522 536 private Object pipelineParent(Object anInputElement, 537 NavigatorContentExtension[] theOverridingExtensions, 538 Object theCurrentParent) { 539 IPipelinedTreeContentProvider pipelinedContentProvider; 540 NavigatorContentExtension[] overridingExtensions; 541 Object aSuggestedParent = null; 542 for (int i = 0; i < theOverridingExtensions.length; i++) { 543 544 if (theOverridingExtensions[i].getContentProvider() instanceof IPipelinedTreeContentProvider) { 545 pipelinedContentProvider = (IPipelinedTreeContentProvider) theOverridingExtensions[i] 546 .getContentProvider(); 547 548 aSuggestedParent = pipelinedContentProvider.getPipelinedParent( 549 anInputElement, aSuggestedParent); 550 551 overridingExtensions = theOverridingExtensions[i] 552 .getOverridingExtensionsForTriggerPoint(anInputElement); 553 if (overridingExtensions.length > 0) { 554 aSuggestedParent = pipelineParent(anInputElement, 555 overridingExtensions, aSuggestedParent); 556 } 557 } 558 } 559 return aSuggestedParent != null ? aSuggestedParent : theCurrentParent; 560 } 561 562 574 public synchronized boolean hasChildren(Object anElement) { 575 Set resultInstances = contentService 576 .findContentExtensionsByTriggerPoint(anElement); 577 578 NavigatorContentExtension ext; 579 for (Iterator itr = resultInstances.iterator(); itr.hasNext();) { 580 ext = (NavigatorContentExtension) itr.next(); 581 if (!ext.isLoaded() && !enforceHasChildren) { 582 return true; 583 } else if (ext.internalGetContentProvider().hasChildren(anElement)) { 584 return true; 585 } 586 } 587 588 return false; 589 } 590 591 604 public synchronized void dispose() { 605 if (isContentServiceSelfManaged) { 606 contentService.dispose(); 607 } 608 } 609 610 633 public synchronized void inputChanged(Viewer aViewer, Object anOldInput, 634 Object aNewInput) { 635 viewer = aViewer; 636 contentService.updateService(aViewer, anOldInput, aNewInput); 637 } 638 639 642 public Object [] getChildren(TreePath parentPath) { 643 return internalGetChildren(parentPath); 644 } 645 646 649 public boolean hasChildren(TreePath path) { 650 Object anElement = internalAsElement(path); 651 Set resultInstances = contentService 652 .findContentExtensionsByTriggerPoint(anElement); 653 654 NavigatorContentExtension ext; 655 for (Iterator itr = resultInstances.iterator(); itr.hasNext();) { 656 ext = (NavigatorContentExtension) itr.next(); 657 if (!ext.isLoaded() && !enforceHasChildren) 658 return true; 659 ITreeContentProvider cp = ext.internalGetContentProvider(); 660 if (cp instanceof ITreePathContentProvider) { 661 ITreePathContentProvider tpcp = (ITreePathContentProvider) cp; 662 if (tpcp.hasChildren(path)) { 663 return true; 664 } 665 } else if (cp.hasChildren(anElement)) 666 return true; 667 } 668 669 return false; 670 } 671 672 675 public TreePath[] getParents(Object anElement) { 676 677 List paths = new ArrayList (); 678 TreePathCompiler compiler = new TreePathCompiler(anElement); 679 Set compilers = findPaths(compiler); 680 for (Iterator iter = compilers.iterator(); iter.hasNext();) { 681 TreePathCompiler c = (TreePathCompiler) iter.next(); 682 paths.add(c.createParentPath()); 683 684 } 685 return (TreePath[]) paths.toArray(new TreePath[paths.size()]); 686 687 } 688 689 690 695 private Object internalAsElement(Object parentElementOrPath) { 696 if (parentElementOrPath instanceof TreePath) { 697 TreePath tp = (TreePath) parentElementOrPath; 698 if (tp.getSegmentCount() > 0) { 699 return tp.getLastSegment(); 700 } 701 return viewer.getInput(); 703 } 704 return parentElementOrPath; 705 } 706 707 708 class CyclicPathException extends Exception { 709 710 private static final long serialVersionUID = 2111962579612444989L; 711 712 protected CyclicPathException(TreePathCompiler compiler, Object invalidSegment, boolean asChild) { 713 super("Cannot add " + invalidSegment + " to the list of segments in " + compiler + (asChild ? " as a child." : " as a parent.") ); } 717 } 718 719 class TreePathCompiler { 720 721 722 private final LinkedList segments = new LinkedList (); 723 724 protected TreePathCompiler(Object segment) { 725 segments.add(segment); 726 } 727 728 protected TreePathCompiler(TreePathCompiler aCompiler) { 729 segments.addAll(aCompiler.segments); 730 } 731 732 protected TreePathCompiler(TreePath aPath) { 733 for (int i = 0; i < aPath.getSegmentCount(); i++) { 734 segments.addLast(aPath.getSegment(i)); 735 } 736 } 737 738 protected void addParent(Object segment) throws CyclicPathException { 739 if(segments.contains(segment)) { 740 throw new CyclicPathException(this, segment, false); 741 } 742 segments.addFirst(segment); 743 } 744 745 protected void addChild(Object segment) throws CyclicPathException { 746 if(segments.contains(segment)) { 747 throw new CyclicPathException(this, segment, false); 748 } 749 segments.addLast(segment); 750 } 751 752 757 public TreePath createPath() { 758 return new TreePath(segments.toArray()); 759 } 760 761 766 public TreePath createParentPath() { 767 LinkedList parentSegments = new LinkedList (segments); 768 parentSegments.removeLast(); 769 return new TreePath(parentSegments.toArray()); 770 } 771 772 public Object getLastSegment() { 773 return segments.getLast(); 774 } 775 776 public Object getFirstSegment() { 777 return segments.getFirst(); 778 } 779 780 783 public String toString() { 784 785 StringBuffer buffer = new StringBuffer (); 786 for (Iterator iter = segments.iterator(); iter.hasNext();) { 787 Object segment = iter.next(); 788 buffer.append(segment).append("::"); } 790 return buffer.toString(); 791 } 792 793 } 794 795 private Set findPaths(TreePathCompiler aPathCompiler) { 796 797 Set parents = findParents(aPathCompiler.getFirstSegment()); 798 Set parentPaths = new LinkedHashSet (); 799 Set foundPaths = Collections.EMPTY_SET; 800 if (parents.size() > 0) { 801 for (Iterator parentIter = parents.iterator(); parentIter.hasNext();) { 802 Object parent = (Object ) parentIter.next(); 803 TreePathCompiler c = new TreePathCompiler(aPathCompiler); 804 try { 805 c.addParent(parent); 806 foundPaths = findPaths(c); 807 } catch(CyclicPathException cpe) { 808 String msg = cpe.getMessage() != null ? cpe.getMessage() : cpe.toString(); 809 NavigatorPlugin.logError(0, msg, cpe); 810 } 811 if (foundPaths.isEmpty()) 812 parentPaths.add(c); 813 else 814 parentPaths.addAll(foundPaths); 815 } 816 } 817 return parentPaths; 818 819 } 820 821 private Set findParents(Object anElement) { 822 823 Set descriptors = contentService.findDescriptorsWithPossibleChild( 824 anElement, false); 825 Set parents = new LinkedHashSet (); 826 NavigatorContentDescriptor foundDescriptor; 827 NavigatorContentExtension foundExtension; 828 Object parent = null; 829 for (Iterator itr = descriptors.iterator(); itr.hasNext();) { 830 foundDescriptor = (NavigatorContentDescriptor) itr.next(); 831 foundExtension = contentService.getExtension(foundDescriptor); 832 try { 833 834 if (!isOverridingDescriptorInSet( 835 foundExtension.getDescriptor(), descriptors)) { 836 837 838 if (foundExtension.getContentProvider() instanceof ITreePathContentProvider) { 839 843 TreePath[] parentTreePaths = ((ITreePathContentProvider) foundExtension 844 .internalGetContentProvider()) 845 .getParents(anElement); 846 847 for (int i = 0; i < parentTreePaths.length; i++) { 848 849 parent = parentTreePaths[i].getLastSegment(); 850 if ((parent = findParent(foundExtension, anElement, 851 parent)) != null) 852 parents.add(parent); 853 } 854 855 } else { 856 857 parent = foundExtension.internalGetContentProvider() 858 .getParent(anElement); 859 if ((parent = findParent(foundExtension, anElement, 860 parent)) != null) 861 parents.add(parent); 862 } 863 } 864 865 } catch (RuntimeException re) { 866 NavigatorPlugin 867 .logError( 868 0, 869 NLS 870 .bind( 871 CommonNavigatorMessages.Could_not_provide_children_for_element, 872 new Object [] { foundExtension 873 .getDescriptor() 874 .getId() }), re); 875 } catch (Error e) { 876 NavigatorPlugin 877 .logError( 878 0, 879 NLS 880 .bind( 881 CommonNavigatorMessages.Could_not_provide_children_for_element, 882 new Object [] { foundExtension 883 .getDescriptor() 884 .getId() }), e); 885 886 } 887 } 888 889 return parents; 890 891 } 892 893 894 private Object findParent(NavigatorContentExtension anExtension, Object anElement, Object aSuggestedParent) { 895 896 897 Object lastValidParent = aSuggestedParent; 898 899 Object suggestedOverriddenParent = null; 900 IPipelinedTreeContentProvider piplineContentProvider; 901 NavigatorContentExtension[] overridingExtensions = anExtension.getOverridingExtensionsForPossibleChild(anElement); 902 for (int i = 0; i < overridingExtensions.length; i++) { 903 if(overridingExtensions[i].getContentProvider() instanceof IPipelinedTreeContentProvider) { 904 piplineContentProvider = (IPipelinedTreeContentProvider) overridingExtensions[i].getContentProvider(); 905 suggestedOverriddenParent = piplineContentProvider.getPipelinedParent(anElement, lastValidParent); 906 907 if(suggestedOverriddenParent != null) 908 lastValidParent = suggestedOverriddenParent; 909 910 lastValidParent = findParent(overridingExtensions[i], anElement, lastValidParent); 912 } 913 914 } 915 return lastValidParent; 916 } 917 918 } 919 | Popular Tags |