1 11 package org.eclipse.jdt.internal.ui.browsing; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Collection ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 19 import org.eclipse.core.resources.IResource; 20 21 import org.eclipse.swt.widgets.Control; 22 import org.eclipse.swt.widgets.Display; 23 24 import org.eclipse.jface.viewers.AbstractTreeViewer; 25 import org.eclipse.jface.viewers.IBasicPropertyConstants; 26 import org.eclipse.jface.viewers.ListViewer; 27 import org.eclipse.jface.viewers.StructuredViewer; 28 import org.eclipse.jface.viewers.TableViewer; 29 import org.eclipse.jface.viewers.Viewer; 30 31 import org.eclipse.jdt.core.ElementChangedEvent; 32 import org.eclipse.jdt.core.IClassFile; 33 import org.eclipse.jdt.core.ICompilationUnit; 34 import org.eclipse.jdt.core.IElementChangedListener; 35 import org.eclipse.jdt.core.IImportContainer; 36 import org.eclipse.jdt.core.IJavaElement; 37 import org.eclipse.jdt.core.IJavaElementDelta; 38 import org.eclipse.jdt.core.IJavaProject; 39 import org.eclipse.jdt.core.IPackageDeclaration; 40 import org.eclipse.jdt.core.IPackageFragment; 41 import org.eclipse.jdt.core.IPackageFragmentRoot; 42 import org.eclipse.jdt.core.IParent; 43 import org.eclipse.jdt.core.ISourceReference; 44 import org.eclipse.jdt.core.IType; 45 import org.eclipse.jdt.core.IWorkingCopy; 46 import org.eclipse.jdt.core.JavaCore; 47 import org.eclipse.jdt.core.JavaModelException; 48 49 import org.eclipse.jdt.ui.StandardJavaElementContentProvider; 50 51 import org.eclipse.jdt.internal.ui.JavaPlugin; 52 53 class JavaBrowsingContentProvider extends StandardJavaElementContentProvider implements IElementChangedListener { 54 55 private StructuredViewer fViewer; 56 private Object fInput; 57 private JavaBrowsingPart fBrowsingPart; 58 private int fReadsInDisplayThread; 59 60 61 public JavaBrowsingContentProvider(boolean provideMembers, JavaBrowsingPart browsingPart) { 62 super(provideMembers); 63 fBrowsingPart= browsingPart; 64 fViewer= fBrowsingPart.getViewer(); 65 JavaCore.addElementChangedListener(this); 66 } 67 68 public boolean hasChildren(Object element) { 69 startReadInDisplayThread(); 70 try{ 71 return super.hasChildren(element); 72 } finally { 73 finishedReadInDisplayThread(); 74 } 75 } 76 77 public Object [] getChildren(Object element) { 78 if (!exists(element)) 79 return NO_CHILDREN; 80 81 startReadInDisplayThread(); 82 try { 83 if (element instanceof Collection ) { 84 Collection elements= (Collection )element; 85 if (elements.isEmpty()) 86 return NO_CHILDREN; 87 Object [] result= new Object [0]; 88 Iterator iter= ((Collection )element).iterator(); 89 while (iter.hasNext()) { 90 Object [] children= getChildren(iter.next()); 91 if (children != NO_CHILDREN) 92 result= concatenate(result, children); 93 } 94 return result; 95 } 96 if (element instanceof IPackageFragment) 97 return getPackageContents((IPackageFragment)element); 98 if (fProvideMembers && element instanceof IType) 99 return getChildren((IType)element); 100 if (fProvideMembers && element instanceof ISourceReference && element instanceof IParent) 101 return removeImportAndPackageDeclarations(super.getChildren(element)); 102 if (element instanceof IJavaProject) 103 return getPackageFragmentRoots((IJavaProject)element); 104 return super.getChildren(element); 105 } catch (JavaModelException e) { 106 return NO_CHILDREN; 107 } finally { 108 finishedReadInDisplayThread(); 109 } 110 } 111 112 private Object [] getPackageContents(IPackageFragment fragment) throws JavaModelException { 113 ISourceReference[] sourceRefs; 114 if (fragment.getKind() == IPackageFragmentRoot.K_SOURCE) { 115 sourceRefs= fragment.getCompilationUnits(); 116 } 117 else { 118 IClassFile[] classFiles= fragment.getClassFiles(); 119 List topLevelClassFile= new ArrayList (); 120 for (int i= 0; i < classFiles.length; i++) { 121 IType type= classFiles[i].getType(); 122 if (type != null && type.getDeclaringType() == null && !type.isAnonymous() && !type.isLocal()) 123 topLevelClassFile.add(classFiles[i]); 124 } 125 sourceRefs= (ISourceReference[])topLevelClassFile.toArray(new ISourceReference[topLevelClassFile.size()]); 126 } 127 128 Object [] result= new Object [0]; 129 for (int i= 0; i < sourceRefs.length; i++) 130 result= concatenate(result, removeImportAndPackageDeclarations(getChildren(sourceRefs[i]))); 131 return concatenate(result, fragment.getNonJavaResources()); 132 } 133 134 private Object [] removeImportAndPackageDeclarations(Object [] members) { 135 ArrayList tempResult= new ArrayList (members.length); 136 for (int i= 0; i < members.length; i++) 137 if (!(members[i] instanceof IImportContainer) && !(members[i] instanceof IPackageDeclaration)) 138 tempResult.add(members[i]); 139 return tempResult.toArray(); 140 } 141 142 private Object [] getChildren(IType type) throws JavaModelException{ 143 IParent parent; 144 if (type.isBinary()) 145 parent= type.getClassFile(); 146 else { 147 parent= type.getCompilationUnit(); 148 } 149 if (type.getDeclaringType() != null) 150 return type.getChildren(); 151 152 IJavaElement[] members= parent.getChildren(); 154 ArrayList tempResult= new ArrayList (members.length); 155 for (int i= 0; i < members.length; i++) 156 if ((members[i] instanceof IImportContainer)) 157 tempResult.add(members[i]); 158 tempResult.addAll(Arrays.asList(type.getChildren())); 159 return tempResult.toArray(); 160 } 161 162 protected Object [] getPackageFragmentRoots(IJavaProject project) throws JavaModelException { 163 if (!project.getProject().isOpen()) 164 return NO_CHILDREN; 165 166 IPackageFragmentRoot[] roots= project.getPackageFragmentRoots(); 167 List list= new ArrayList (roots.length); 168 for (int i= 0; i < roots.length; i++) { 171 IPackageFragmentRoot root= roots[i]; 172 if (!root.isExternal()) { 173 Object [] children= root.getChildren(); 174 for (int k= 0; k < children.length; k++) 175 list.add(children[k]); 176 } 177 else if (hasChildren(root)) { 178 list.add(root); 179 } 180 } 181 return concatenate(list.toArray(), project.getNonJavaResources()); 182 } 183 184 186 189 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 190 super.inputChanged(viewer, oldInput, newInput); 191 192 if (newInput instanceof Collection ) { 193 Collection col= (Collection )newInput; 195 if (!col.isEmpty()) 196 newInput= col.iterator().next(); 197 else 198 newInput= null; 199 } 200 fInput= newInput; 201 } 202 203 206 public void dispose() { 207 super.dispose(); 208 JavaCore.removeElementChangedListener(this); 209 } 210 211 214 public void elementChanged(final ElementChangedEvent event) { 215 try { 216 processDelta(event.getDelta()); 217 } catch(JavaModelException e) { 218 JavaPlugin.log(e.getStatus()); 219 } 220 } 221 222 223 228 protected void processDelta(IJavaElementDelta delta) throws JavaModelException { 229 int kind= delta.getKind(); 230 int flags= delta.getFlags(); 231 final IJavaElement element= delta.getElement(); 232 final boolean isElementValidForView= fBrowsingPart.isValidElement(element); 233 234 if (!getProvideWorkingCopy() && element instanceof IWorkingCopy && ((IWorkingCopy)element).isWorkingCopy()) 235 return; 236 237 if (element != null && element.getElementType() == IJavaElement.COMPILATION_UNIT && !isOnClassPath((ICompilationUnit)element)) 238 return; 239 240 if (((flags & IJavaElementDelta.F_CLOSED) != 0) || ((flags & IJavaElementDelta.F_OPENED) != 0)) { 242 postRefresh(null); 243 return; 244 } 245 246 if (kind == IJavaElementDelta.REMOVED) { 247 Object parent= internalGetParent(element); 248 if (isElementValidForView) { 249 if (element instanceof IClassFile) { 250 postRemove(((IClassFile)element).getType()); 251 } else if (element instanceof ICompilationUnit && !((ICompilationUnit)element).isWorkingCopy()) { 252 postRefresh(null); 253 } else if (element instanceof ICompilationUnit && ((ICompilationUnit)element).isWorkingCopy()) { 254 if (getProvideWorkingCopy()) 255 postRefresh(null); 256 } else if (parent instanceof ICompilationUnit && getProvideWorkingCopy() && !((ICompilationUnit)parent).isWorkingCopy()) { 257 if (element instanceof IWorkingCopy && ((IWorkingCopy)element).isWorkingCopy()) { 258 postRefresh(null); 260 } 261 } else if (element instanceof IWorkingCopy && ((IWorkingCopy)element).isWorkingCopy() && parent != null && parent.equals(fInput)) 262 postRefresh(null); 264 else 265 postRemove(element); 266 } 267 268 if (fBrowsingPart.isAncestorOf(element, fInput)) { 269 if (element instanceof IWorkingCopy && ((IWorkingCopy)element).isWorkingCopy()) { 270 postAdjustInputAndSetSelection(((IJavaElement) fInput).getPrimaryElement()); 271 } else 272 postAdjustInputAndSetSelection(null); 273 } 274 275 if (fInput != null && fInput.equals(element)) 276 postRefresh(null); 277 278 if (parent instanceof IPackageFragment && fBrowsingPart.isValidElement(parent)) { 279 if (isPackageFragmentEmpty((IPackageFragment)parent) && fViewer.testFindItem(parent) != null) 281 postRefresh(null); 282 } 283 284 return; 285 } 286 if (kind == IJavaElementDelta.ADDED && delta.getMovedFromElement() != null && element instanceof ICompilationUnit) 287 return; 288 289 if (kind == IJavaElementDelta.ADDED) { 290 if (isElementValidForView) { 291 Object parent= internalGetParent(element); 292 if (element instanceof IClassFile) { 293 postAdd(parent, ((IClassFile)element).getType()); 294 } else if (element instanceof ICompilationUnit && !((ICompilationUnit)element).isWorkingCopy()) { 295 postAdd(parent, ((ICompilationUnit)element).getTypes()); 296 } else if (parent instanceof ICompilationUnit && getProvideWorkingCopy() && !((ICompilationUnit)parent).isWorkingCopy()) { 297 } else if (element instanceof IWorkingCopy && ((IWorkingCopy)element).isWorkingCopy()) { 299 postRefresh(null); 301 } else 302 postAdd(parent, element); 303 } else if (fInput == null) { 304 IJavaElement newInput= fBrowsingPart.findInputForJavaElement(element); 305 if (newInput != null) 306 postAdjustInputAndSetSelection(element); 307 } else if (element instanceof IType && fBrowsingPart.isValidInput(element)) { 308 IJavaElement cu1= element.getAncestor(IJavaElement.COMPILATION_UNIT); 309 IJavaElement cu2= ((IJavaElement)fInput).getAncestor(IJavaElement.COMPILATION_UNIT); 310 if (cu1 != null && cu2 != null && cu1.equals(cu2)) 311 postAdjustInputAndSetSelection(element); 312 } 313 return; 314 } 315 316 if (kind == IJavaElementDelta.CHANGED) { 317 if (fInput != null && fInput.equals(element) && (flags & IJavaElementDelta.F_CHILDREN) != 0 && (flags & IJavaElementDelta.F_FINE_GRAINED) != 0) { 318 postRefresh(null, true); 319 return; 320 } 321 if (isElementValidForView && (flags & IJavaElementDelta.F_MODIFIERS) != 0) { 322 postUpdateIcon(element); 323 } 324 } 325 326 if (isClassPathChange(delta)) 327 postRefresh(null); 329 330 if ((flags & IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED) != 0 && fInput instanceof IJavaElement) { 331 IPackageFragmentRoot pkgRoot= (IPackageFragmentRoot)element; 332 IJavaElement inputsParent= ((IJavaElement)fInput).getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); 333 if (pkgRoot.equals(inputsParent)) 334 postRefresh(null); 335 } 336 337 if (element instanceof IPackageFragmentRoot && (((flags & IJavaElementDelta.F_SOURCEATTACHED) != 0 || ((flags & IJavaElementDelta.F_SOURCEDETACHED)) != 0))) 339 postUpdateIcon(element); 340 341 IJavaElementDelta[] affectedChildren= delta.getAffectedChildren(); 342 if (affectedChildren.length > 1) { 343 if (element instanceof IPackageFragment) { 345 IJavaElement parent= (IJavaElement)internalGetParent(element); 346 if (element.equals(fInput)) { 348 postRefresh(element); 349 } else { 350 postRefresh(parent); 351 } 352 } 353 if (element instanceof IPackageFragmentRoot && isElementValidForView) { 355 postRefresh(skipProjectPackageFragmentRoot((IPackageFragmentRoot)element)); 356 return; 357 } 358 } 359 for (int i= 0; i < affectedChildren.length; i++) { 360 processDelta(affectedChildren[i]); 361 } 362 } 363 364 private boolean isOnClassPath(ICompilationUnit element) throws JavaModelException { 365 IJavaProject project= element.getJavaProject(); 366 if (project == null || !project.exists()) 367 return false; 368 return project.isOnClasspath(element); 369 } 370 371 374 private void postUpdateIcon(final IJavaElement element) { 375 postRunnable(new Runnable () { 376 public void run() { 377 Control ctrl= fViewer.getControl(); 378 if (ctrl != null && !ctrl.isDisposed()) 379 fViewer.update(element, new String []{IBasicPropertyConstants.P_IMAGE}); 380 } 381 }); 382 } 383 384 private void postRefresh(final Object root, final boolean updateLabels) { 385 postRunnable(new Runnable () { 386 public void run() { 387 Control ctrl= fViewer.getControl(); 388 if (ctrl != null && !ctrl.isDisposed()) 389 fViewer.refresh(root, updateLabels); 390 } 391 }); 392 } 393 394 private void postRefresh(final Object root) { 395 postRefresh(root, false); 396 } 397 398 private void postAdd(final Object parent, final Object element) { 399 postAdd(parent, new Object [] {element}); 400 } 401 402 private void postAdd(final Object parent, final Object [] elements) { 403 if (elements == null || elements.length <= 0) 404 return; 405 406 postRunnable(new Runnable () { 407 public void run() { 408 Control ctrl= fViewer.getControl(); 409 if (ctrl != null && !ctrl.isDisposed()) { 410 Object [] newElements= getNewElements(elements); 411 if (fViewer instanceof AbstractTreeViewer) { 412 if (fViewer.testFindItem(parent) == null) { 413 Object root= ((AbstractTreeViewer)fViewer).getInput(); 414 if (root != null) 415 ((AbstractTreeViewer)fViewer).add(root, newElements); 416 } 417 else 418 ((AbstractTreeViewer)fViewer).add(parent, newElements); 419 } 420 else if (fViewer instanceof ListViewer) 421 ((ListViewer)fViewer).add(newElements); 422 else if (fViewer instanceof TableViewer) 423 ((TableViewer)fViewer).add(newElements); 424 if (fViewer.testFindItem(elements[0]) != null) 425 fBrowsingPart.adjustInputAndSetSelection(elements[0]); 426 } 427 } 428 }); 429 } 430 431 private Object [] getNewElements(Object [] elements) { 432 int elementsLength= elements.length; 433 ArrayList result= new ArrayList (elementsLength); 434 for (int i= 0; i < elementsLength; i++) { 435 Object element= elements[i]; 436 if (fViewer.testFindItem(element) == null) 437 result.add(element); 438 } 439 return result.toArray(); 440 } 441 442 private void postRemove(final Object element) { 443 postRemove(new Object [] {element}); 444 } 445 446 private void postRemove(final Object [] elements) { 447 if (elements.length <= 0) 448 return; 449 450 postRunnable(new Runnable () { 451 public void run() { 452 Control ctrl= fViewer.getControl(); 453 if (ctrl != null && !ctrl.isDisposed()) { 454 if (fViewer instanceof AbstractTreeViewer) 455 ((AbstractTreeViewer)fViewer).remove(elements); 456 else if (fViewer instanceof ListViewer) 457 ((ListViewer)fViewer).remove(elements); 458 else if (fViewer instanceof TableViewer) 459 ((TableViewer)fViewer).remove(elements); 460 } 461 } 462 }); 463 } 464 465 private void postAdjustInputAndSetSelection(final Object element) { 466 postRunnable(new Runnable () { 467 public void run() { 468 Control ctrl= fViewer.getControl(); 469 if (ctrl != null && !ctrl.isDisposed()) { 470 ctrl.setRedraw(false); 471 fBrowsingPart.adjustInputAndSetSelection(element); 472 ctrl.setRedraw(true); 473 } 474 } 475 }); 476 } 477 478 protected void startReadInDisplayThread() { 479 if (isDisplayThread()) 480 fReadsInDisplayThread++; 481 } 482 483 protected void finishedReadInDisplayThread() { 484 if (isDisplayThread()) 485 fReadsInDisplayThread--; 486 } 487 488 private boolean isDisplayThread() { 489 Control ctrl= fViewer.getControl(); 490 if (ctrl == null) 491 return false; 492 493 Display currentDisplay= Display.getCurrent(); 494 return currentDisplay != null && currentDisplay.equals(ctrl.getDisplay()); 495 } 496 497 private void postRunnable(final Runnable r) { 498 Control ctrl= fViewer.getControl(); 499 if (ctrl != null && !ctrl.isDisposed()) { 500 fBrowsingPart.setProcessSelectionEvents(false); 501 try { 502 if (isDisplayThread() && fReadsInDisplayThread == 0) 503 ctrl.getDisplay().syncExec(r); 504 else 505 ctrl.getDisplay().asyncExec(r); 506 } finally { 507 fBrowsingPart.setProcessSelectionEvents(true); 508 } 509 } 510 } 511 512 520 protected Object internalGetParent(Object element) { 521 if (element instanceof IJavaProject) { 522 return ((IJavaProject)element).getJavaModel(); 523 } 524 if (element instanceof IResource) { 526 IResource parent= ((IResource)element).getParent(); 527 Object jParent= JavaCore.create(parent); 528 if (jParent != null) 529 return jParent; 530 return parent; 531 } 532 533 if (element instanceof IPackageFragment) { 536 IPackageFragmentRoot parent= (IPackageFragmentRoot)((IPackageFragment)element).getParent(); 537 return skipProjectPackageFragmentRoot(parent); 538 } 539 if (element instanceof IJavaElement) 540 return ((IJavaElement)element).getParent(); 541 542 return null; 543 } 544 } 545 | Popular Tags |