1 11 package org.eclipse.jdt.internal.ui.model; 12 13 import java.util.ArrayList ; 14 import java.util.HashSet ; 15 import java.util.Iterator ; 16 import java.util.LinkedList ; 17 import java.util.List ; 18 import java.util.Set ; 19 20 import org.eclipse.core.runtime.CoreException; 21 import org.eclipse.core.runtime.IAdaptable; 22 import org.eclipse.core.runtime.IPath; 23 import org.eclipse.core.runtime.IProgressMonitor; 24 import org.eclipse.core.runtime.NullProgressMonitor; 25 26 import org.eclipse.core.resources.IFile; 27 import org.eclipse.core.resources.IFolder; 28 import org.eclipse.core.resources.IProject; 29 import org.eclipse.core.resources.IResource; 30 import org.eclipse.core.resources.ResourcesPlugin; 31 import org.eclipse.core.resources.mapping.ResourceMapping; 32 import org.eclipse.core.resources.mapping.ResourceMappingContext; 33 import org.eclipse.core.resources.mapping.ResourceTraversal; 34 35 import org.eclipse.swt.custom.BusyIndicator; 36 import org.eclipse.swt.widgets.Control; 37 import org.eclipse.swt.widgets.Tree; 38 import org.eclipse.swt.widgets.TreeItem; 39 40 import org.eclipse.jface.viewers.ITreeContentProvider; 41 import org.eclipse.jface.viewers.TreeViewer; 42 43 import org.eclipse.ui.navigator.IPipelinedTreeContentProvider; 44 import org.eclipse.ui.navigator.PipelinedShapeModification; 45 import org.eclipse.ui.navigator.PipelinedViewerUpdate; 46 47 import org.eclipse.team.core.diff.FastDiffFilter; 48 import org.eclipse.team.core.diff.IDiff; 49 import org.eclipse.team.core.diff.IDiffChangeEvent; 50 import org.eclipse.team.core.diff.IDiffTree; 51 import org.eclipse.team.core.diff.IDiffVisitor; 52 import org.eclipse.team.core.mapping.IResourceDiffTree; 53 import org.eclipse.team.core.mapping.ISynchronizationContext; 54 import org.eclipse.team.core.mapping.ISynchronizationScope; 55 import org.eclipse.team.core.mapping.provider.ResourceDiffTree; 56 57 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; 58 import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy; 59 import org.eclipse.ltk.core.refactoring.history.RefactoringHistory; 60 import org.eclipse.ltk.ui.refactoring.model.AbstractSynchronizationContentProvider; 61 62 import org.eclipse.jdt.core.ICompilationUnit; 63 import org.eclipse.jdt.core.IJavaElement; 64 import org.eclipse.jdt.core.IJavaProject; 65 import org.eclipse.jdt.core.IPackageFragment; 66 import org.eclipse.jdt.core.IPackageFragmentRoot; 67 import org.eclipse.jdt.core.JavaCore; 68 69 import org.eclipse.jdt.internal.corext.util.JavaElementResourceMapping; 70 71 import org.eclipse.jdt.internal.ui.JavaPlugin; 72 73 78 public final class JavaSynchronizationContentProvider extends AbstractSynchronizationContentProvider implements IPipelinedTreeContentProvider { 79 80 81 83 92 static IDiff[] getDiffs(final ISynchronizationContext context, final Object element) { 93 return context.getDiffTree().getDiffs(getResourceTraversals(element)); 94 } 95 96 103 static ResourceMapping getResourceMapping(final Object element) { 104 if (element instanceof IJavaElement) 105 return JavaElementResourceMapping.create((IJavaElement) element); 106 if (element instanceof IAdaptable) { 107 final IAdaptable adaptable= (IAdaptable) element; 108 final Object adapted= adaptable.getAdapter(ResourceMapping.class); 109 if (adapted instanceof ResourceMapping) 110 return (ResourceMapping) adapted; 111 } 112 return null; 113 } 114 115 122 static ResourceTraversal[] getResourceTraversals(final Object element) { 123 final ResourceMapping mapping= getResourceMapping(element); 124 if (mapping != null) 125 try { 126 return mapping.getTraversals(ResourceMappingContext.LOCAL_CONTEXT, new NullProgressMonitor()); 127 } catch (final CoreException exception) { 128 JavaPlugin.log(exception); 129 } 130 return new ResourceTraversal[0]; 131 } 132 133 134 private ITreeContentProvider fContentProvider= null; 135 136 137 private Object fModelRoot= null; 138 139 147 private IJavaProject asJavaProject(final IProject project) { 148 try { 149 if (project.getDescription().hasNature(JavaCore.NATURE_ID)) 150 return JavaCore.create(project); 151 } catch (final CoreException exception) { 152 if (project.isAccessible()) 154 JavaPlugin.log(exception); 155 } 156 return null; 157 } 158 159 165 private void convertToJavaElements(final PipelinedShapeModification modification) { 166 final Object parent= modification.getParent(); 167 if (parent instanceof IResource) { 168 final IJavaElement project= asJavaProject(((IResource) parent).getProject()); 169 if (project != null) { 170 modification.getChildren().clear(); 171 return; 172 } 173 } 174 if (parent instanceof ISynchronizationContext) { 175 final Set result= new HashSet (); 176 for (final Iterator iterator= modification.getChildren().iterator(); iterator.hasNext();) { 177 final Object element= iterator.next(); 178 if (element instanceof IProject) { 179 final IJavaElement project= asJavaProject((IProject) element); 180 if (project != null) { 181 iterator.remove(); 182 result.add(project); 183 } 184 } 185 } 186 modification.getChildren().addAll(result); 187 } 188 } 189 190 198 private boolean convertToJavaElements(final PipelinedViewerUpdate update) { 199 final Set result= new HashSet (); 200 for (final Iterator iterator= update.getRefreshTargets().iterator(); iterator.hasNext();) { 201 final Object element= iterator.next(); 202 if (element instanceof IProject) { 203 final IJavaElement project= asJavaProject((IProject) element); 204 if (project != null) { 205 iterator.remove(); 206 result.add(project); 207 } 208 } 209 } 210 update.getRefreshTargets().addAll(result); 211 return !result.isEmpty(); 212 } 213 214 217 public void diffsChanged(final IDiffChangeEvent event, final IProgressMonitor monitor) { 218 syncExec(new Runnable () { 219 220 public void run() { 221 handleChange(event); 222 } 223 }, getViewer().getControl()); 224 } 225 226 234 private IJavaProject[] getChangedProjects(final IDiffChangeEvent event) { 235 final Set result= new HashSet (); 236 final IDiff[] changes= event.getChanges(); 237 for (int index= 0; index < changes.length; index++) { 238 final IResource resource= ResourceDiffTree.getResourceFor(changes[index]); 239 if (resource != null) { 240 final IJavaProject project= asJavaProject(resource.getProject()); 241 if (project != null) 242 result.add(project); 243 } 244 } 245 final IDiff[] additions= event.getAdditions(); 246 for (int index= 0; index < additions.length; index++) { 247 final IResource resource= ResourceDiffTree.getResourceFor(additions[index]); 248 if (resource != null) { 249 final IJavaProject project= asJavaProject(resource.getProject()); 250 if (project != null) 251 result.add(project); 252 } 253 } 254 final IPath[] removals = event.getRemovals(); 255 for (int i = 0; i < removals.length; i++) { 256 IPath path = removals[i]; 257 if (path.segmentCount() > 0) { 258 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)); 259 if (project.exists()) { 261 final IJavaProject javaProject= asJavaProject(project.getProject()); 262 if (javaProject != null) 263 result.add(javaProject); 264 } 265 } 266 } 267 return (IJavaProject[]) result.toArray(new IJavaProject[result.size()]); 268 } 269 270 273 protected Object [] getChildrenInContext(final ISynchronizationContext context, final Object parent, final Object [] children) { 274 final Object [] elements= super.getChildrenInContext(context, parent, children); 275 if (parent instanceof IPackageFragment) 276 return getPackageFragmentChildren(context, parent, elements); 277 else if (parent instanceof IPackageFragmentRoot) 278 return getPackageFragmentRootChildren(context, parent, elements); 279 else if (parent instanceof IJavaProject) 280 return getJavaProjectChildren(context, parent, elements); 281 else if (parent instanceof RefactoringHistory) 282 return ((RefactoringHistory) parent).getDescriptors(); 283 return getFilteredElements(parent, elements); 286 } 287 288 297 private Object [] getFilteredElements(final Object parent, final Object [] children) { 298 final List result= new ArrayList (children.length); 299 for (int index= 0; index < children.length; index++) { 300 if (children[index] instanceof IFolder) { 301 if (!(JavaCore.create((IFolder) children[index]) instanceof IPackageFragmentRoot)) 302 result.add(children[index]); 303 } else 304 result.add(children[index]); 305 } 306 return result.toArray(); 307 } 308 309 312 protected ITreeContentProvider getDelegateContentProvider() { 313 if (fContentProvider == null) 314 fContentProvider= new JavaModelContentProvider(); 315 return fContentProvider; 316 } 317 318 326 private Set getDeletedProjects(final IDiffChangeEvent event) { 327 final Set result= new HashSet (); 328 final IPath[] deletions= event.getRemovals(); 329 for (int index= 0; index < deletions.length; index++) { 330 final IPath path= deletions[index]; 331 if (path.segmentCount() > 0) { 332 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)); 333 if (!project.isAccessible()) 334 result.add(project); 335 } 336 } 337 return result; 338 } 339 340 348 public Object [] getElements(Object parent) { 349 if (parent instanceof ISynchronizationContext) 350 parent= getModelRoot(); 352 return super.getElements(parent); 353 } 354 355 366 private Object [] getJavaProjectChildren(final ISynchronizationContext context, final Object parent, final Object [] children) { 367 final LinkedList list= new LinkedList (); 368 for (int index= 0; index < children.length; index++) { 369 if (children[index] instanceof IPackageFragment) { 370 final IPackageFragment fragment= (IPackageFragment) children[index]; 371 if (getChildren(fragment).length == 0) 372 continue; 373 } 374 if (children[index] instanceof IFolder) { 376 IFolder folder = (IFolder) children[index]; 377 if (getChildren(folder).length == 0) 378 continue; 379 } 380 list.add(children[index]); 381 } 382 383 final IResource resource= JavaModelProvider.getResource(parent); 384 if (resource != null) { 385 final IResourceDiffTree tree= context.getDiffTree(); 386 final IResource[] members= tree.members(resource); 387 for (int index= 0; index < members.length; index++) { 388 IResource child = members[index]; 389 if (isVisible(context, child)) { 390 if (hasPhantomFolder(tree, child)) { 391 list.add(child); 393 } 394 395 396 } 407 } 408 409 } 410 return list.toArray(new Object [list.size()]); 411 } 412 413 private boolean hasPhantomFolder(IResourceDiffTree tree, IResource child) { 414 if (!child.exists()) 415 return true; 416 final boolean[] found = new boolean[] { false }; 417 tree.accept(child.getFullPath(), new IDiffVisitor() { 418 public boolean visit(IDiff delta){ 419 IResource treeResource = ResourceDiffTree.getResourceFor(delta); 420 if (treeResource.getType()==IResource.FILE && !treeResource.getParent().exists()){ 421 found[0] = true; 422 return false; 423 } 424 425 return true; 426 }}, IResource.DEPTH_INFINITE); 427 return found[0]; 428 } 429 430 431 434 protected String getModelProviderId() { 435 return JavaModelProvider.JAVA_MODEL_PROVIDER_ID; 436 } 437 438 441 protected Object getModelRoot() { 442 if (fModelRoot == null) 443 fModelRoot= JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()); 444 return fModelRoot; 445 } 446 447 458 private Object [] getPackageFragmentChildren(final ISynchronizationContext context, final Object parent, final Object [] children) { 459 final Set set= new HashSet (); 460 for (int index= 0; index < children.length; index++) 461 set.add(children[index]); 462 final IResource resource= ((IPackageFragment) parent).getResource(); 463 if (resource != null) { 464 final IResourceDiffTree tree= context.getDiffTree(); 465 final IResource[] members= tree.members(resource); 466 for (int index= 0; index < members.length; index++) { 467 final int type= members[index].getType(); 468 if (type == IResource.FILE) { 469 final IDiff diff= tree.getDiff(members[index]); 470 if (diff != null && isVisible(diff)) 471 if (isInScope(context.getScope(), parent, members[index])) { 472 final IJavaElement element= JavaCore.create(members[index]); 473 if (element == null) { 474 set.add(members[index]); 475 } else { 476 set.add(element); 477 } 478 } 479 } 480 } 481 } 482 return set.toArray(new Object [set.size()]); 483 } 484 485 496 private Object [] getPackageFragmentRootChildren(final ISynchronizationContext context, final Object parent, final Object [] children) { 497 final Set set= new HashSet (); 498 for (int index= 0; index < children.length; index++) { 499 if (children[index] instanceof IPackageFragment) { 500 IPackageFragment fragment = (IPackageFragment) children[index]; 501 if (fragment.isOpen() && getChildren(fragment).length == 0) 502 continue; 504 } 505 set.add(children[index]); 506 } 507 final IResource resource= JavaModelProvider.getResource(parent); 508 if (resource != null) { 509 final IResourceDiffTree tree= context.getDiffTree(); 510 final IResource[] members= tree.members(resource); 511 for (int index= 0; index < members.length; index++) { 512 final int type= members[index].getType(); 513 final boolean contained= isInScope(context.getScope(), parent, members[index]); 514 final boolean visible= isVisible(context, members[index]); 515 if (type == IResource.FILE && contained && visible) { 516 final IJavaElement element= JavaCore.create((IFile) members[index]); 520 if (element == null) 521 set.add(members[index]); 522 } else if (type == IResource.FOLDER && contained && visible && tree.getDiff(members[index]) != null) { 523 final IJavaElement element= JavaCore.create(members[index]); 525 if (element != null) 526 set.add(element); 527 } 528 if (type == IResource.FOLDER) { 529 final IFolder folder= (IFolder) members[index]; 531 tree.accept(folder.getFullPath(), new IDiffVisitor() { 532 533 public final boolean visit(final IDiff diff) { 534 if (isVisible(diff)) { 535 final IResource current= tree.getResource(diff); 536 if (current != null) { 537 final int kind= current.getType(); 538 if (kind == IResource.FILE) { 539 final IJavaElement element= JavaCore.create(current.getParent()); 540 if (element != null) 541 set.add(element); 542 } else { 543 final IJavaElement element= JavaCore.create(current); 544 if (element != null) 545 set.add(element); 546 } 547 } 548 } 549 return true; 550 } 551 }, IResource.DEPTH_INFINITE); 552 } 553 } 554 return set.toArray(new Object [set.size()]); 555 } 556 return children; 557 } 558 559 562 public void getPipelinedChildren(final Object parent, final Set children) { 563 if (parent instanceof ISynchronizationContext) { 564 final Set result= new HashSet (children.size()); 568 for (final Iterator iterator= children.iterator(); iterator.hasNext();) { 569 final Object element= iterator.next(); 570 if (element instanceof IProject) { 571 final IJavaElement java= asJavaProject((IProject) element); 572 if (java != null) { 573 iterator.remove(); 574 result.add(java); 575 } 576 } 577 if (element instanceof IFolder) { 578 IFolder folder = (IFolder) element; 579 IJavaElement javaElement = JavaCore.create(folder); 580 if (javaElement instanceof IPackageFragmentRoot) { 583 iterator.remove(); 584 } 585 } 586 } 587 children.addAll(result); 588 } else if (parent instanceof ISynchronizationScope) { 589 children.add(getModelProvider()); 593 } else if (parent instanceof IFolder) { 594 for (final Iterator iterator= children.iterator(); iterator.hasNext();) { 597 final Object element= iterator.next(); 598 if (element instanceof IFolder) { 599 IFolder folder = (IFolder) element; 600 IJavaElement javaElement = JavaCore.create(folder); 601 if (javaElement instanceof IPackageFragmentRoot) { 602 iterator.remove(); 603 } 604 } 605 } 606 } 607 } 608 609 612 public void getPipelinedElements(final Object element, final Set elements) { 613 getPipelinedChildren(element, elements); 614 } 615 616 619 public Object getPipelinedParent(final Object element, final Object parent) { 620 if (element instanceof IJavaElement) 621 return getParent(element); 622 return parent; 623 } 624 625 628 protected ResourceTraversal[] getTraversals(final ISynchronizationContext context, final Object object) { 629 return getResourceTraversals(object); 630 } 631 632 637 private Set getVisibleProjects() { 638 final TreeItem[] children= ((TreeViewer) getViewer()).getTree().getItems(); 639 final Set result= new HashSet (); 640 for (int index= 0; index < children.length; index++) { 641 final Object data= children[index].getData(); 642 if (data instanceof IJavaProject) 643 result.add(data); 644 } 645 return result; 646 } 647 648 654 private void handleChange(final IDiffChangeEvent event) { 655 final Set existing= getVisibleProjects(); 656 final IJavaProject[] changed= getChangedProjects(event); 660 final List refreshes= new ArrayList (changed.length); 661 final List additions= new ArrayList (changed.length); 662 final List removals= new ArrayList (changed.length); 663 for (int index= 0; index < changed.length; index++) { 664 final IJavaProject project= changed[index]; 665 if (hasVisibleChanges(event.getTree(), project)) { 666 if (existing.contains(project)) 667 refreshes.add(project); 668 else 669 additions.add(project); 670 } else 671 removals.add(project); 672 } 673 final Set removed= getDeletedProjects(event); 675 for (final Iterator iterator= existing.iterator(); iterator.hasNext();) { 676 final IJavaProject element= (IJavaProject) iterator.next(); 677 if (removed.contains(element.getResource())) 678 removals.add(element); 679 } 680 681 if (!removals.isEmpty() || !additions.isEmpty() || !refreshes.isEmpty()) { 682 final TreeViewer viewer= (TreeViewer) getViewer(); 683 final Tree tree= viewer.getTree(); 684 try { 685 tree.setRedraw(false); 686 if (!additions.isEmpty()) 687 viewer.add(viewer.getInput(), additions.toArray()); 688 if (!removals.isEmpty()) 689 viewer.remove(viewer.getInput(), removals.toArray()); 690 if (!refreshes.isEmpty()) { 691 for (final Iterator iter= refreshes.iterator(); iter.hasNext();) 692 viewer.refresh(iter.next()); 693 } 694 } finally { 695 tree.setRedraw(true); 696 } 697 } 698 } 699 700 703 public boolean hasChildren(final Object element) { 704 if (element instanceof ICompilationUnit || element instanceof IFile || element instanceof RefactoringDescriptorProxy || element instanceof RefactoringDescriptor) 705 return false; 706 return super.hasChildren(element); 707 } 708 709 721 private boolean hasChildrenInScope(final ISynchronizationScope scope, final Object element, final IResource resource) { 722 final IResource[] roots= scope.getRoots(); 723 final IPath path= resource.getFullPath(); 724 if (element instanceof IPackageFragment) { 725 for (int index= 0; index < roots.length; index++) 726 if (path.equals(roots[index].getFullPath().removeLastSegments(1))) 727 return true; 728 return false; 729 } 730 for (int index= 0; index < roots.length; index++) 731 if (path.isPrefixOf(roots[index].getFullPath())) 732 return true; 733 return false; 734 } 735 736 746 private boolean hasVisibleChanges(final IDiffTree tree, final IJavaProject project) { 747 return tree.hasMatchingDiffs(project.getResource().getFullPath(), new FastDiffFilter() { 748 749 public boolean select(final IDiff diff) { 750 return isVisible(diff); 751 } 752 }); 753 } 754 755 758 public PipelinedShapeModification interceptAdd(final PipelinedShapeModification modification) { 759 convertToJavaElements(modification); 760 return modification; 761 } 762 763 766 public boolean interceptRefresh(final PipelinedViewerUpdate update) { 767 return convertToJavaElements(update); 768 } 769 770 773 public PipelinedShapeModification interceptRemove(final PipelinedShapeModification modification) { 774 convertToJavaElements(modification); 775 return modification; 776 } 777 778 781 public boolean interceptUpdate(final PipelinedViewerUpdate anUpdateSynchronization) { 782 return convertToJavaElements(anUpdateSynchronization); 783 } 784 785 788 protected boolean isInScope(final ISynchronizationScope scope, final Object parent, final Object element) { 789 final IResource resource= JavaModelProvider.getResource(element); 790 if (resource == null) 791 return false; 792 if (scope.contains(resource)) 793 return true; 794 if (hasChildrenInScope(scope, element, resource)) 795 return true; 796 return false; 797 } 798 799 807 private void syncExec(final Runnable runnable, final Control control) { 808 if (control != null && !control.isDisposed()) 809 control.getDisplay().syncExec(new Runnable () { 810 811 public void run() { 812 if (!control.isDisposed()) 813 BusyIndicator.showWhile(control.getDisplay(), runnable); 814 } 815 }); 816 } 817 } 818 | Popular Tags |