1 11 package org.eclipse.jdt.internal.core; 12 13 import java.io.File ; 14 import java.util.*; 15 16 import org.eclipse.core.resources.IFile; 17 import org.eclipse.core.resources.IFolder; 18 import org.eclipse.core.resources.IProject; 19 import org.eclipse.core.resources.IResource; 20 import org.eclipse.core.resources.IResourceChangeEvent; 21 import org.eclipse.core.resources.IResourceDelta; 22 import org.eclipse.core.resources.IResourceDeltaVisitor; 23 import org.eclipse.core.resources.IWorkspaceRoot; 24 import org.eclipse.core.resources.IWorkspaceRunnable; 25 import org.eclipse.core.resources.ResourcesPlugin; 26 import org.eclipse.core.runtime.*; 27 import org.eclipse.jdt.core.*; 28 import org.eclipse.jdt.core.compiler.CharOperation; 29 import org.eclipse.jdt.internal.compiler.SourceElementParser; 30 import org.eclipse.jdt.internal.core.builder.JavaBuilder; 31 import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy; 32 import org.eclipse.jdt.internal.core.search.AbstractSearchScope; 33 import org.eclipse.jdt.internal.core.search.JavaWorkspaceScope; 34 import org.eclipse.jdt.internal.core.search.indexing.IndexManager; 35 import org.eclipse.jdt.internal.core.util.Util; 36 37 57 public class DeltaProcessor { 58 59 static class OutputsInfo { 60 int outputCount; 61 IPath[] paths; 62 int[] traverseModes; 63 OutputsInfo(IPath[] paths, int[] traverseModes, int outputCount) { 64 this.paths = paths; 65 this.traverseModes = traverseModes; 66 this.outputCount = outputCount; 67 } 68 public String toString() { 69 if (this.paths == null) return "<none>"; StringBuffer buffer = new StringBuffer (); 71 for (int i = 0; i < this.outputCount; i++) { 72 buffer.append("path="); buffer.append(this.paths[i].toString()); 74 buffer.append("\n->traverse="); switch (this.traverseModes[i]) { 76 case BINARY: 77 buffer.append("BINARY"); break; 79 case IGNORE: 80 buffer.append("IGNORE"); break; 82 case SOURCE: 83 buffer.append("SOURCE"); break; 85 default: 86 buffer.append("<unknown>"); } 88 if (i+1 < this.outputCount) { 89 buffer.append('\n'); 90 } 91 } 92 return buffer.toString(); 93 } 94 } 95 96 static class RootInfo { 97 char[][] inclusionPatterns; 98 char[][] exclusionPatterns; 99 JavaProject project; 100 IPath rootPath; 101 int entryKind; 102 IPackageFragmentRoot root; 103 RootInfo(JavaProject project, IPath rootPath, char[][] inclusionPatterns, char[][] exclusionPatterns, int entryKind) { 104 this.project = project; 105 this.rootPath = rootPath; 106 this.inclusionPatterns = inclusionPatterns; 107 this.exclusionPatterns = exclusionPatterns; 108 this.entryKind = entryKind; 109 } 110 IPackageFragmentRoot getPackageFragmentRoot(IResource resource) { 111 if (this.root == null) { 112 if (resource != null) { 113 this.root = this.project.getPackageFragmentRoot(resource); 114 } else { 115 Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), this.rootPath, false); 116 if (target instanceof IResource) { 117 this.root = this.project.getPackageFragmentRoot((IResource)target); 118 } else { 119 this.root = this.project.getPackageFragmentRoot(this.rootPath.toOSString()); 120 } 121 } 122 } 123 return this.root; 124 } 125 boolean isRootOfProject(IPath path) { 126 return this.rootPath.equals(path) && this.project.getProject().getFullPath().isPrefixOf(path); 127 } 128 public String toString() { 129 StringBuffer buffer = new StringBuffer ("project="); if (this.project == null) { 131 buffer.append("null"); } else { 133 buffer.append(this.project.getElementName()); 134 } 135 buffer.append("\npath="); if (this.rootPath == null) { 137 buffer.append("null"); } else { 139 buffer.append(this.rootPath.toString()); 140 } 141 buffer.append("\nincluding="); if (this.inclusionPatterns == null) { 143 buffer.append("null"); } else { 145 for (int i = 0, length = this.inclusionPatterns.length; i < length; i++) { 146 buffer.append(new String (this.inclusionPatterns[i])); 147 if (i < length-1) { 148 buffer.append("|"); } 150 } 151 } 152 buffer.append("\nexcluding="); if (this.exclusionPatterns == null) { 154 buffer.append("null"); } else { 156 for (int i = 0, length = this.exclusionPatterns.length; i < length; i++) { 157 buffer.append(new String (this.exclusionPatterns[i])); 158 if (i < length-1) { 159 buffer.append("|"); } 161 } 162 } 163 return buffer.toString(); 164 } 165 } 166 167 private final static int IGNORE = 0; 168 private final static int SOURCE = 1; 169 private final static int BINARY = 2; 170 171 private final static String EXTERNAL_JAR_ADDED = "external jar added"; private final static String EXTERNAL_JAR_CHANGED = "external jar changed"; private final static String EXTERNAL_JAR_REMOVED = "external jar removed"; private final static String EXTERNAL_JAR_UNCHANGED = "external jar unchanged"; private final static String INTERNAL_JAR_IGNORE = "internal jar ignore"; 177 private final static int NON_JAVA_RESOURCE = -1; 178 public static boolean DEBUG = false; 179 public static boolean VERBOSE = false; 180 public static boolean PERF = false; 181 182 public static final int DEFAULT_CHANGE_EVENT = 0; 184 188 public static long getTimeStamp(File file) { 189 return file.lastModified() + file.length(); 190 } 191 192 195 private DeltaProcessingState state; 196 197 200 JavaModelManager manager; 201 202 205 private JavaElementDelta currentDelta; 206 207 210 private Openable currentElement; 211 212 216 public ArrayList javaModelDeltas= new ArrayList(); 217 218 222 public HashMap reconcileDeltas = new HashMap(); 223 224 227 private boolean isFiring= true; 228 229 232 private final ModelUpdater modelUpdater = new ModelUpdater(); 233 234 235 public HashSet projectCachesToReset = new HashSet(); 236 237 241 private HashSet refreshedElements; 242 243 246 public Map oldRoots; 247 248 249 private HashSet rootsToRefresh = new HashSet(); 250 251 254 public int overridenEventType = -1; 255 256 259 private SourceElementParser sourceElementParserCache; 260 261 264 public HashMap classpathChanges = new HashMap(); 265 266 public DeltaProcessor(DeltaProcessingState state, JavaModelManager manager) { 267 this.state = state; 268 this.manager = manager; 269 } 270 271 public ClasspathChange addClasspathChange(IProject project, IClasspathEntry[] oldRawClasspath, IPath oldOutputLocation, IClasspathEntry[] oldResolvedClasspath) { 272 ClasspathChange change = (ClasspathChange) this.classpathChanges.get(project); 273 if (change == null) { 274 change = new ClasspathChange((JavaProject) this.manager.getJavaModel().getJavaProject(project), oldRawClasspath, oldOutputLocation, oldResolvedClasspath); 275 this.classpathChanges.put(project, change); 276 } else { 277 if (change.oldRawClasspath == null) 278 change.oldRawClasspath = oldRawClasspath; 279 if (change.oldOutputLocation == null) 280 change.oldOutputLocation = oldOutputLocation; 281 if (change.oldResolvedClasspath == null) 282 change.oldResolvedClasspath = oldResolvedClasspath; 283 } 284 return change; 285 } 286 287 291 private void addDependentProjects(IJavaProject project, HashMap projectDependencies, HashSet result) { 292 IJavaProject[] dependents = (IJavaProject[]) projectDependencies.get(project); 293 if (dependents == null) return; 294 for (int i = 0, length = dependents.length; i < length; i++) { 295 IJavaProject dependent = dependents[i]; 296 if (result.contains(dependent)) 297 continue; result.add(dependent); 299 addDependentProjects(dependent, projectDependencies, result); 300 } 301 } 302 305 public void addForRefresh(IJavaElement element) { 306 if (this.refreshedElements == null) { 307 this.refreshedElements = new HashSet(); 308 } 309 this.refreshedElements.add(element); 310 } 311 314 private void addToParentInfo(Openable child) { 315 Openable parent = (Openable) child.getParent(); 316 if (parent != null && parent.isOpen()) { 317 try { 318 JavaElementInfo info = (JavaElementInfo)parent.getElementInfo(); 319 info.addChild(child); 320 } catch (JavaModelException e) { 321 } 323 } 324 } 325 328 private void addToRootsToRefreshWithDependents(IJavaProject javaProject) { 329 this.rootsToRefresh.add(javaProject); 330 this.addDependentProjects(javaProject, this.state.projectDependencies, this.rootsToRefresh); 331 } 332 336 public void checkExternalArchiveChanges(IJavaElement[] elementsToRefresh, IProgressMonitor monitor) throws JavaModelException { 337 if (monitor != null && monitor.isCanceled()) 338 throw new OperationCanceledException(); 339 try { 340 if (monitor != null) monitor.beginTask("", 1); 342 for (int i = 0, length = elementsToRefresh.length; i < length; i++) { 343 this.addForRefresh(elementsToRefresh[i]); 344 } 345 boolean hasDelta = this.createExternalArchiveDelta(monitor); 346 if (hasDelta){ 347 JavaModel.flushExternalFileCache(); 349 350 JavaModelManager.getJavaModelManager().resetJarTypeCache(); 352 353 IJavaElementDelta[] projectDeltas = this.currentDelta.getAffectedChildren(); 354 final int length = projectDeltas.length; 355 final IProject[] projectsToTouch = new IProject[length]; 356 for (int i = 0; i < length; i++) { 357 IJavaElementDelta delta = projectDeltas[i]; 358 JavaProject javaProject = (JavaProject)delta.getElement(); 359 projectsToTouch[i] = javaProject.getProject(); 360 } 361 362 IWorkspaceRunnable runnable = new IWorkspaceRunnable() { 366 public void run(IProgressMonitor progressMonitor) throws CoreException { 367 for (int i = 0; i < length; i++) { 368 IProject project = projectsToTouch[i]; 369 370 if (JavaBuilder.DEBUG) 372 System.out.println("Touching project " + project.getName() + " due to external jar file change"); project.touch(progressMonitor); 374 } 375 } 376 }; 377 try { 378 ResourcesPlugin.getWorkspace().run(runnable, monitor); 379 } catch (CoreException e) { 380 throw new JavaModelException(e); 381 } 382 383 if (this.currentDelta != null) { this.fire(this.currentDelta, DEFAULT_CHANGE_EVENT); 385 } 386 } 387 } finally { 388 this.currentDelta = null; 389 if (monitor != null) monitor.done(); 390 } 391 } 392 399 private void checkProjectsBeingAddedOrRemoved(IResourceDelta delta) { 400 IResource resource = delta.getResource(); 401 IResourceDelta[] children = null; 402 403 switch (resource.getType()) { 404 case IResource.ROOT : 405 this.state.getOldJavaProjecNames(); children = delta.getAffectedChildren(); 408 break; 409 case IResource.PROJECT : 410 IProject project = (IProject)resource; 414 JavaProject javaProject = (JavaProject)JavaCore.create(project); 415 switch (delta.getKind()) { 416 case IResourceDelta.ADDED : 417 this.manager.batchContainerInitializations = true; 418 419 addToRootsToRefreshWithDependents(javaProject); 421 422 if (JavaProject.hasJavaNature(project)) { 424 addToParentInfo(javaProject); 425 readRawClasspath(javaProject); 426 checkProjectReferenceChange(project, javaProject); 428 } 429 430 this.state.rootsAreStale = true; 431 break; 432 433 case IResourceDelta.CHANGED : 434 if ((delta.getFlags() & IResourceDelta.OPEN) != 0) { 435 this.manager.batchContainerInitializations = true; 436 437 addToRootsToRefreshWithDependents(javaProject); 439 440 if (project.isOpen()) { 442 if (JavaProject.hasJavaNature(project)) { 443 addToParentInfo(javaProject); 444 readRawClasspath(javaProject); 445 checkProjectReferenceChange(project, javaProject); 447 } 448 } else { 449 try { 450 javaProject.close(); 451 } catch (JavaModelException e) { 452 } 454 this.removeFromParentInfo(javaProject); 455 this.manager.removePerProjectInfo(javaProject); 456 this.manager.containerRemove(javaProject); 457 } 458 this.state.rootsAreStale = true; 459 } else if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) { 460 boolean wasJavaProject = this.state.findJavaProject(project.getName()) != null; 461 boolean isJavaProject = JavaProject.hasJavaNature(project); 462 if (wasJavaProject != isJavaProject) { 463 this.manager.batchContainerInitializations = true; 464 465 this.addToRootsToRefreshWithDependents(javaProject); 467 468 if (isJavaProject) { 470 this.addToParentInfo(javaProject); 471 readRawClasspath(javaProject); 472 checkProjectReferenceChange(project, javaProject); 474 } else { 475 this.manager.removePerProjectInfo(javaProject); 477 this.manager.containerRemove(javaProject); 479 try { 481 javaProject.close(); 482 } catch (JavaModelException e) { 483 } 485 this.removeFromParentInfo(javaProject); 486 } 487 this.state.rootsAreStale = true; 488 } else { 489 if (isJavaProject) { this.addToParentInfo(javaProject); 492 children = delta.getAffectedChildren(); 493 } 494 } 495 } else { 496 if (JavaProject.hasJavaNature(project)) { this.addToParentInfo(javaProject); 500 children = delta.getAffectedChildren(); 501 } 502 } 503 break; 504 505 case IResourceDelta.REMOVED : 506 this.manager.batchContainerInitializations = true; 507 508 this.manager.removePerProjectInfo(javaProject); 510 this.manager.containerRemove(javaProject); 512 513 this.state.rootsAreStale = true; 514 break; 515 } 516 517 addForRefresh(javaProject); 519 520 break; 521 case IResource.FILE : 522 IFile file = (IFile) resource; 523 524 if (file.getName().equals(JavaProject.CLASSPATH_FILENAME)) { 525 this.manager.batchContainerInitializations = true; 526 switch (delta.getKind()) { 527 case IResourceDelta.CHANGED : 528 int flags = delta.getFlags(); 529 if ((flags & IResourceDelta.CONTENT) == 0 && (flags & IResourceDelta.ENCODING) == 0 && (flags & IResourceDelta.MOVED_FROM) == 0) { break; 533 } 534 case IResourceDelta.ADDED : 536 javaProject = (JavaProject)JavaCore.create(file.getProject()); 537 538 try { 540 javaProject.getPerProjectInfo().readAndCacheClasspath(javaProject); 541 } catch (JavaModelException e) { 542 return; 544 } 545 break; 546 } 547 this.state.rootsAreStale = true; 548 } 549 break; 550 551 } 552 if (children != null) { 553 for (int i = 0; i < children.length; i++) { 554 checkProjectsBeingAddedOrRemoved(children[i]); 555 } 556 } 557 } 558 559 private void checkProjectReferenceChange(IProject project, JavaProject javaProject) { 560 ClasspathChange change = (ClasspathChange) this.classpathChanges.get(project); 561 this.state.addProjectReferenceChange(javaProject, change == null ? null : change.oldResolvedClasspath); 562 } 563 564 private void readRawClasspath(JavaProject javaProject) { 565 try { 566 javaProject.getPerProjectInfo().readAndCacheClasspath(javaProject); 568 } catch (JavaModelException e) { 569 if (VERBOSE) { 570 e.printStackTrace(); 571 } 572 } 573 } 574 private void checkSourceAttachmentChange(IResourceDelta delta, IResource res) { 575 IPath rootPath = (IPath)this.state.sourceAttachments.get(res.getFullPath()); 576 if (rootPath != null) { 577 RootInfo rootInfo = this.rootInfo(rootPath, delta.getKind()); 578 if (rootInfo != null) { 579 IJavaProject projectOfRoot = rootInfo.project; 580 IPackageFragmentRoot root = null; 581 try { 582 root = projectOfRoot.findPackageFragmentRoot(rootPath); 584 if (root != null) { 585 root.close(); 586 } 587 } catch (JavaModelException e) { 588 } 590 if (root == null) return; 591 switch (delta.getKind()) { 592 case IResourceDelta.ADDED: 593 currentDelta().sourceAttached(root); 594 break; 595 case IResourceDelta.CHANGED: 596 currentDelta().sourceDetached(root); 597 currentDelta().sourceAttached(root); 598 break; 599 case IResourceDelta.REMOVED: 600 currentDelta().sourceDetached(root); 601 break; 602 } 603 } 604 } 605 } 606 609 private void close(Openable element) { 610 try { 611 element.close(); 612 } catch (JavaModelException e) { 613 } 615 } 616 624 private void contentChanged(Openable element) { 625 626 boolean isPrimary = false; 627 boolean isPrimaryWorkingCopy = false; 628 if (element.getElementType() == IJavaElement.COMPILATION_UNIT) { 629 CompilationUnit cu = (CompilationUnit)element; 630 isPrimary = cu.isPrimary(); 631 isPrimaryWorkingCopy = isPrimary && cu.isWorkingCopy(); 632 } 633 if (isPrimaryWorkingCopy) { 634 currentDelta().changed(element, IJavaElementDelta.F_PRIMARY_RESOURCE); 637 } else { 638 close(element); 639 int flags = IJavaElementDelta.F_CONTENT; 640 if (element instanceof JarPackageFragmentRoot){ 641 flags |= IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED; 642 this.projectCachesToReset.add(element.getJavaProject()); 645 } 646 if (isPrimary) { 647 flags |= IJavaElementDelta.F_PRIMARY_RESOURCE; 648 } 649 currentDelta().changed(element, flags); 650 } 651 } 652 656 private Openable createElement(IResource resource, int elementType, RootInfo rootInfo) { 657 if (resource == null) return null; 658 659 IPath path = resource.getFullPath(); 660 IJavaElement element = null; 661 switch (elementType) { 662 663 case IJavaElement.JAVA_PROJECT: 664 665 if (resource instanceof IProject){ 668 669 this.popUntilPrefixOf(path); 670 671 if (this.currentElement != null 672 && this.currentElement.getElementType() == IJavaElement.JAVA_PROJECT 673 && ((IJavaProject)this.currentElement).getProject().equals(resource)) { 674 return this.currentElement; 675 } 676 if (rootInfo != null && rootInfo.project.getProject().equals(resource)){ 677 element = rootInfo.project; 678 break; 679 } 680 IProject proj = (IProject)resource; 681 if (JavaProject.hasJavaNature(proj)) { 682 element = JavaCore.create(proj); 683 } else { 684 element = this.state.findJavaProject(proj.getName()); 687 } 688 } 689 break; 690 case IJavaElement.PACKAGE_FRAGMENT_ROOT: 691 element = rootInfo == null ? JavaCore.create(resource) : rootInfo.getPackageFragmentRoot(resource); 692 break; 693 case IJavaElement.PACKAGE_FRAGMENT: 694 if (rootInfo != null) { 695 if (rootInfo.project.contains(resource)) { 696 PackageFragmentRoot root = (PackageFragmentRoot) rootInfo.getPackageFragmentRoot(null); 697 IPath pkgPath = path.removeFirstSegments(rootInfo.rootPath.segmentCount()); 699 String [] pkgName = pkgPath.segments(); 700 element = root.getPackageFragment(pkgName); 701 } 702 } else { 703 this.popUntilPrefixOf(path); 705 706 if (this.currentElement == null) { 707 element = JavaCore.create(resource); 708 } else { 709 PackageFragmentRoot root = this.currentElement.getPackageFragmentRoot(); 711 if (root == null) { 712 element = JavaCore.create(resource); 713 } else if (((JavaProject)root.getJavaProject()).contains(resource)) { 714 IPath pkgPath = path.removeFirstSegments(root.getPath().segmentCount()); 716 String [] pkgName = pkgPath.segments(); 717 element = root.getPackageFragment(pkgName); 718 } 719 } 720 } 721 break; 722 case IJavaElement.COMPILATION_UNIT: 723 case IJavaElement.CLASS_FILE: 724 this.popUntilPrefixOf(path); 726 727 if (this.currentElement == null) { 728 element = rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project); 729 } else { 730 IPackageFragment pkgFragment = null; 732 switch (this.currentElement.getElementType()) { 733 case IJavaElement.PACKAGE_FRAGMENT_ROOT: 734 PackageFragmentRoot root = (PackageFragmentRoot)this.currentElement; 735 IPath rootPath = root.getPath(); 736 IPath pkgPath = path.removeLastSegments(1); 737 String [] pkgName = pkgPath.removeFirstSegments(rootPath.segmentCount()).segments(); 738 pkgFragment = root.getPackageFragment(pkgName); 739 break; 740 case IJavaElement.PACKAGE_FRAGMENT: 741 Openable pkg = this.currentElement; 742 if (pkg.getPath().equals(path.removeLastSegments(1))) { 743 pkgFragment = (IPackageFragment)pkg; 744 } break; 746 case IJavaElement.COMPILATION_UNIT: 747 case IJavaElement.CLASS_FILE: 748 pkgFragment = (IPackageFragment)this.currentElement.getParent(); 749 break; 750 } 751 if (pkgFragment == null) { 752 element = rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project); 753 } else { 754 if (elementType == IJavaElement.COMPILATION_UNIT) { 755 String fileName = path.lastSegment(); 758 element = pkgFragment.getCompilationUnit(fileName); 759 } else { 760 String fileName = path.lastSegment(); 763 element = pkgFragment.getClassFile(fileName); 764 } 765 } 766 } 767 break; 768 } 769 if (element == null) return null; 770 this.currentElement = (Openable)element; 771 return this.currentElement; 772 } 773 777 private boolean createExternalArchiveDelta(IProgressMonitor monitor) { 778 779 if (this.refreshedElements == null) return false; 780 781 HashMap externalArchivesStatus = new HashMap(); 782 boolean hasDelta = false; 783 784 HashSet archivePathsToRefresh = new HashSet(); 786 Iterator iterator = this.refreshedElements.iterator(); 787 this.refreshedElements = null; while (iterator.hasNext()) { 789 IJavaElement element = (IJavaElement)iterator.next(); 790 switch(element.getElementType()){ 791 case IJavaElement.PACKAGE_FRAGMENT_ROOT : 792 archivePathsToRefresh.add(element.getPath()); 793 break; 794 case IJavaElement.JAVA_PROJECT : 795 JavaProject javaProject = (JavaProject) element; 796 if (!JavaProject.hasJavaNature(javaProject.getProject())) { 797 break; 799 } 800 IClasspathEntry[] classpath; 801 try { 802 classpath = javaProject.getResolvedClasspath(); 803 for (int j = 0, cpLength = classpath.length; j < cpLength; j++){ 804 if (classpath[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY){ 805 archivePathsToRefresh.add(classpath[j].getPath()); 806 } 807 } 808 } catch (JavaModelException e) { 809 } 811 break; 812 case IJavaElement.JAVA_MODEL : 813 Iterator projectNames = this.state.getOldJavaProjecNames().iterator(); 814 while (projectNames.hasNext()) { 815 String projectName = (String ) projectNames.next(); 816 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); 817 if (!JavaProject.hasJavaNature(project)) { 818 continue; 820 } 821 javaProject = (JavaProject) JavaCore.create(project); 822 try { 823 classpath = javaProject.getResolvedClasspath(); 824 } catch (JavaModelException e2) { 825 continue; 827 } 828 for (int k = 0, cpLength = classpath.length; k < cpLength; k++){ 829 if (classpath[k].getEntryKind() == IClasspathEntry.CPE_LIBRARY){ 830 archivePathsToRefresh.add(classpath[k].getPath()); 831 } 832 } 833 } 834 break; 835 } 836 } 837 838 Iterator projectNames = this.state.getOldJavaProjecNames().iterator(); 840 IWorkspaceRoot wksRoot = ResourcesPlugin.getWorkspace().getRoot(); 841 while (projectNames.hasNext()) { 842 843 if (monitor != null && monitor.isCanceled()) break; 844 845 String projectName = (String ) projectNames.next(); 846 IProject project = wksRoot.getProject(projectName); 847 if (!JavaProject.hasJavaNature(project)) { 848 continue; 850 } 851 JavaProject javaProject = (JavaProject) JavaCore.create(project); 852 IClasspathEntry[] entries; 853 try { 854 entries = javaProject.getResolvedClasspath(); 855 } catch (JavaModelException e1) { 856 continue; 858 } 859 for (int j = 0; j < entries.length; j++){ 860 if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) { 861 862 IPath entryPath = entries[j].getPath(); 863 864 if (!archivePathsToRefresh.contains(entryPath)) continue; 866 String status = (String )externalArchivesStatus.get(entryPath); 867 if (status == null){ 868 869 Object targetLibrary = JavaModel.getTarget(wksRoot, entryPath, true); 871 872 if (targetLibrary == null){ if (this.state.getExternalLibTimeStamps().remove(entryPath) != null){ 874 externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED); 875 this.manager.indexManager.removeIndex(entryPath); 877 } 878 879 } else if (targetLibrary instanceof File ){ 881 File externalFile = (File )targetLibrary; 882 883 Long oldTimestamp =(Long ) this.state.getExternalLibTimeStamps().get(entryPath); 885 long newTimeStamp = getTimeStamp(externalFile); 886 if (oldTimestamp != null){ 887 888 if (newTimeStamp == 0){ externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED); 890 this.state.getExternalLibTimeStamps().remove(entryPath); 891 this.manager.indexManager.removeIndex(entryPath); 893 894 } else if (oldTimestamp.longValue() != newTimeStamp){ 895 externalArchivesStatus.put(entryPath, EXTERNAL_JAR_CHANGED); 896 this.state.getExternalLibTimeStamps().put(entryPath, new Long (newTimeStamp)); 897 this.manager.indexManager.removeIndex(entryPath); 899 this.manager.indexManager.indexLibrary(entryPath, project.getProject()); 901 } else { 902 externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED); 903 } 904 } else { 905 if (newTimeStamp == 0){ externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED); 907 } else { 908 externalArchivesStatus.put(entryPath, EXTERNAL_JAR_ADDED); 909 this.state.getExternalLibTimeStamps().put(entryPath, new Long (newTimeStamp)); 910 this.manager.indexManager.indexLibrary(entryPath, project.getProject()); 912 } 913 } 914 } else { externalArchivesStatus.put(entryPath, INTERNAL_JAR_IGNORE); 916 } 917 } 918 status = (String )externalArchivesStatus.get(entryPath); 920 if (status != null){ 921 if (status == EXTERNAL_JAR_ADDED){ 922 PackageFragmentRoot root = (PackageFragmentRoot) javaProject.getPackageFragmentRoot(entryPath.toString()); 923 if (VERBOSE){ 924 System.out.println("- External JAR ADDED, affecting root: "+root.getElementName()); } 926 elementAdded(root, null, null); 927 this.state.addClasspathValidation(javaProject); hasDelta = true; 929 } else if (status == EXTERNAL_JAR_CHANGED) { 930 PackageFragmentRoot root = (PackageFragmentRoot) javaProject.getPackageFragmentRoot(entryPath.toString()); 931 if (VERBOSE){ 932 System.out.println("- External JAR CHANGED, affecting root: "+root.getElementName()); } 934 contentChanged(root); 935 hasDelta = true; 936 } else if (status == EXTERNAL_JAR_REMOVED) { 937 PackageFragmentRoot root = (PackageFragmentRoot) javaProject.getPackageFragmentRoot(entryPath.toString()); 938 if (VERBOSE){ 939 System.out.println("- External JAR REMOVED, affecting root: "+root.getElementName()); } 941 elementRemoved(root, null, null); 942 this.state.addClasspathValidation(javaProject); hasDelta = true; 944 } 945 } 946 } 947 } 948 } 949 return hasDelta; 950 } 951 private JavaElementDelta currentDelta() { 952 if (this.currentDelta == null) { 953 this.currentDelta = new JavaElementDelta(this.manager.getJavaModel()); 954 } 955 return this.currentDelta; 956 } 957 960 private void deleting(IProject project) { 961 962 try { 963 this.manager.indexManager.discardJobs(project.getName()); 966 967 JavaProject javaProject = (JavaProject)JavaCore.create(project); 968 969 if (this.oldRoots == null) { 971 this.oldRoots = new HashMap(); 972 } 973 if (javaProject.isOpen()) { 974 this.oldRoots.put(javaProject, javaProject.getPackageFragmentRoots()); 975 } else { 976 this.oldRoots.put( 978 javaProject, 979 javaProject.computePackageFragmentRoots( 980 javaProject.getResolvedClasspath(), 981 false, 982 null )); 983 } 984 985 javaProject.close(); 986 987 this.state.getOldJavaProjecNames(); 990 this.removeFromParentInfo(javaProject); 991 992 this.manager.resetProjectPreferences(javaProject); 994 } catch (JavaModelException e) { 995 } 997 } 998 1008 private void elementAdded(Openable element, IResourceDelta delta, RootInfo rootInfo) { 1009 int elementType = element.getElementType(); 1010 1011 if (elementType == IJavaElement.JAVA_PROJECT) { 1012 if (delta != null && JavaProject.hasJavaNature((IProject)delta.getResource())) { 1015 addToParentInfo(element); 1016 if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) { 1017 Openable movedFromElement = (Openable)element.getJavaModel().getJavaProject(delta.getMovedFromPath().lastSegment()); 1018 currentDelta().movedTo(element, movedFromElement); 1019 } else { 1020 close(element); 1030 1031 currentDelta().added(element); 1032 } 1033 this.state.updateRoots(element.getPath(), delta, this); 1034 1035 this.rootsToRefresh.add(element); 1037 this.projectCachesToReset.add(element); 1038 } 1039 } else { 1040 if (delta == null || (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) { 1041 if (isPrimaryWorkingCopy(element, elementType) ) { 1043 currentDelta().changed(element, IJavaElementDelta.F_PRIMARY_RESOURCE); 1046 } else { 1047 addToParentInfo(element); 1048 1049 close(element); 1059 1060 currentDelta().added(element); 1061 } 1062 } else { 1063 addToParentInfo(element); 1065 close(element); 1066 1067 IPath movedFromPath = delta.getMovedFromPath(); 1068 IResource res = delta.getResource(); 1069 IResource movedFromRes; 1070 if (res instanceof IFile) { 1071 movedFromRes = res.getWorkspace().getRoot().getFile(movedFromPath); 1072 } else { 1073 movedFromRes = res.getWorkspace().getRoot().getFolder(movedFromPath); 1074 } 1075 1076 RootInfo movedFromInfo = this.enclosingRootInfo(movedFromPath, IResourceDelta.REMOVED); 1078 int movedFromType = 1079 this.elementType( 1080 movedFromRes, 1081 IResourceDelta.REMOVED, 1082 element.getParent().getElementType(), 1083 movedFromInfo); 1084 1085 this.currentElement = null; 1087 1088 Openable movedFromElement = 1090 elementType != IJavaElement.JAVA_PROJECT && movedFromType == IJavaElement.JAVA_PROJECT ? 1091 null : this.createElement(movedFromRes, movedFromType, movedFromInfo); 1093 if (movedFromElement == null) { 1094 currentDelta().added(element); 1096 } else { 1097 currentDelta().movedTo(element, movedFromElement); 1098 } 1099 } 1100 1101 switch (elementType) { 1102 case IJavaElement.PACKAGE_FRAGMENT_ROOT : 1103 JavaProject project = (JavaProject) element.getJavaProject(); 1105 1106 this.rootsToRefresh.add(project); 1108 this.projectCachesToReset.add(project); 1109 1110 break; 1111 case IJavaElement.PACKAGE_FRAGMENT : 1112 project = (JavaProject) element.getJavaProject(); 1114 this.projectCachesToReset.add(project); 1115 1116 break; 1117 } 1118 } 1119 } 1120 1128 private void elementRemoved(Openable element, IResourceDelta delta, RootInfo rootInfo) { 1129 1130 int elementType = element.getElementType(); 1131 if (delta == null || (delta.getFlags() & IResourceDelta.MOVED_TO) == 0) { 1132 if (isPrimaryWorkingCopy(element, elementType) ) { 1134 currentDelta().changed(element, IJavaElementDelta.F_PRIMARY_RESOURCE); 1137 } else { 1138 close(element); 1139 removeFromParentInfo(element); 1140 currentDelta().removed(element); 1141 } 1142 } else { 1143 close(element); 1145 removeFromParentInfo(element); 1146 IPath movedToPath = delta.getMovedToPath(); 1147 IResource res = delta.getResource(); 1148 IResource movedToRes; 1149 switch (res.getType()) { 1150 case IResource.PROJECT: 1151 movedToRes = res.getWorkspace().getRoot().getProject(movedToPath.lastSegment()); 1152 break; 1153 case IResource.FOLDER: 1154 movedToRes = res.getWorkspace().getRoot().getFolder(movedToPath); 1155 break; 1156 case IResource.FILE: 1157 movedToRes = res.getWorkspace().getRoot().getFile(movedToPath); 1158 break; 1159 default: 1160 return; 1161 } 1162 1163 RootInfo movedToInfo = this.enclosingRootInfo(movedToPath, IResourceDelta.ADDED); 1165 int movedToType = 1166 this.elementType( 1167 movedToRes, 1168 IResourceDelta.ADDED, 1169 element.getParent().getElementType(), 1170 movedToInfo); 1171 1172 this.currentElement = null; 1174 1175 Openable movedToElement = 1177 elementType != IJavaElement.JAVA_PROJECT && movedToType == IJavaElement.JAVA_PROJECT ? 1178 null : this.createElement(movedToRes, movedToType, movedToInfo); 1180 if (movedToElement == null) { 1181 currentDelta().removed(element); 1183 } else { 1184 currentDelta().movedFrom(element, movedToElement); 1185 } 1186 } 1187 1188 switch (elementType) { 1189 case IJavaElement.JAVA_MODEL : 1190 this.manager.indexManager.reset(); 1191 break; 1192 case IJavaElement.JAVA_PROJECT : 1193 this.state.updateRoots(element.getPath(), delta, this); 1194 1195 this.rootsToRefresh.add(element); 1197 this.projectCachesToReset.add(element); 1198 1199 break; 1200 case IJavaElement.PACKAGE_FRAGMENT_ROOT : 1201 JavaProject project = (JavaProject) element.getJavaProject(); 1202 1203 this.rootsToRefresh.add(project); 1205 this.projectCachesToReset.add(project); 1206 1207 break; 1208 case IJavaElement.PACKAGE_FRAGMENT : 1209 project = (JavaProject) element.getJavaProject(); 1211 this.projectCachesToReset.add(project); 1212 1213 break; 1214 } 1215 } 1216 1220 private int elementType(IResource res, int kind, int parentType, RootInfo rootInfo) { 1221 switch (parentType) { 1222 case IJavaElement.JAVA_MODEL: 1223 return IJavaElement.JAVA_PROJECT; 1225 1226 case NON_JAVA_RESOURCE: 1227 case IJavaElement.JAVA_PROJECT: 1228 if (rootInfo == null) { 1229 rootInfo = this.enclosingRootInfo(res.getFullPath(), kind); 1230 } 1231 if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) { 1232 return IJavaElement.PACKAGE_FRAGMENT_ROOT; 1233 } 1234 1238 case IJavaElement.PACKAGE_FRAGMENT_ROOT: 1239 case IJavaElement.PACKAGE_FRAGMENT: 1240 if (rootInfo == null) { 1241 rootInfo = this.enclosingRootInfo(res.getFullPath(), kind); 1242 } 1243 if (rootInfo == null) { 1244 return NON_JAVA_RESOURCE; 1245 } 1246 if (Util.isExcluded(res, rootInfo.inclusionPatterns, rootInfo.exclusionPatterns)) { 1247 return NON_JAVA_RESOURCE; 1248 } 1249 if (res.getType() == IResource.FOLDER) { 1250 if (parentType == NON_JAVA_RESOURCE && !Util.isExcluded(res.getParent(), rootInfo.inclusionPatterns, rootInfo.exclusionPatterns)) { 1251 return NON_JAVA_RESOURCE; 1253 } 1254 String sourceLevel = rootInfo.project == null ? null : rootInfo.project.getOption(JavaCore.COMPILER_SOURCE, true); 1255 String complianceLevel = rootInfo.project == null ? null : rootInfo.project.getOption(JavaCore.COMPILER_COMPLIANCE, true); 1256 if (Util.isValidFolderNameForPackage(res.getName(), sourceLevel, complianceLevel)) { 1257 return IJavaElement.PACKAGE_FRAGMENT; 1258 } 1259 return NON_JAVA_RESOURCE; 1260 } 1261 String fileName = res.getName(); 1262 String sourceLevel = rootInfo.project == null ? null : rootInfo.project.getOption(JavaCore.COMPILER_SOURCE, true); 1263 String complianceLevel = rootInfo.project == null ? null : rootInfo.project.getOption(JavaCore.COMPILER_COMPLIANCE, true); 1264 if (Util.isValidCompilationUnitName(fileName, sourceLevel, complianceLevel)) { 1265 return IJavaElement.COMPILATION_UNIT; 1266 } else if (Util.isValidClassFileName(fileName, sourceLevel, complianceLevel)) { 1267 return IJavaElement.CLASS_FILE; 1268 } else if ((rootInfo = this.rootInfo(res.getFullPath(), kind)) != null 1269 && rootInfo.project.getProject().getFullPath().isPrefixOf(res.getFullPath()) ) { 1270 return IJavaElement.PACKAGE_FRAGMENT_ROOT; 1272 } else { 1273 return NON_JAVA_RESOURCE; 1274 } 1275 1276 default: 1277 return NON_JAVA_RESOURCE; 1278 } 1279 } 1280 1283 public void flush() { 1284 this.javaModelDeltas = new ArrayList(); 1285 } 1286 1287 private SourceElementParser getSourceElementParser(Openable element) { 1288 if (this.sourceElementParserCache == null) 1289 this.sourceElementParserCache = this.manager.indexManager.getSourceElementParser(element.getJavaProject(), null); 1290 return this.sourceElementParserCache; 1291 } 1292 1296 private RootInfo enclosingRootInfo(IPath path, int kind) { 1297 while (path != null && path.segmentCount() > 0) { 1298 RootInfo rootInfo = this.rootInfo(path, kind); 1299 if (rootInfo != null) return rootInfo; 1300 path = path.removeLastSegments(1); 1301 } 1302 return null; 1303 } 1304 1308 public void fire(IJavaElementDelta customDelta, int eventType) { 1309 if (!this.isFiring) return; 1310 1311 if (DEBUG) { 1312 System.out.println("-----------------------------------------------------------------------------------------------------------------------"); } 1314 1315 IJavaElementDelta deltaToNotify; 1316 if (customDelta == null){ 1317 deltaToNotify = this.mergeDeltas(this.javaModelDeltas); 1318 } else { 1319 deltaToNotify = customDelta; 1320 } 1321 1322 if (deltaToNotify != null) { 1324 Iterator scopes = this.manager.searchScopes.keySet().iterator(); 1325 while (scopes.hasNext()) { 1326 AbstractSearchScope scope = (AbstractSearchScope)scopes.next(); 1327 scope.processDelta(deltaToNotify); 1328 } 1329 JavaWorkspaceScope workspaceScope = this.manager.workspaceScope; 1330 if (workspaceScope != null) 1331 workspaceScope.processDelta(deltaToNotify); 1332 } 1333 1334 1336 IElementChangedListener[] listeners; 1339 int[] listenerMask; 1340 int listenerCount; 1341 synchronized (this.state) { 1342 listeners = this.state.elementChangedListeners; 1343 listenerMask = this.state.elementChangedListenerMasks; 1344 listenerCount = this.state.elementChangedListenerCount; 1345 } 1346 1347 switch (eventType) { 1348 case DEFAULT_CHANGE_EVENT: 1349 firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount); 1350 fireReconcileDelta(listeners, listenerMask, listenerCount); 1351 break; 1352 case ElementChangedEvent.POST_CHANGE: 1353 firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount); 1354 fireReconcileDelta(listeners, listenerMask, listenerCount); 1355 break; 1356 } 1357 } 1358 1359 private void firePostChangeDelta( 1360 IJavaElementDelta deltaToNotify, 1361 IElementChangedListener[] listeners, 1362 int[] listenerMask, 1363 int listenerCount) { 1364 1365 if (DEBUG){ 1367 System.out.println("FIRING POST_CHANGE Delta ["+Thread.currentThread()+"]:"); System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); } 1370 if (deltaToNotify != null) { 1371 this.flush(); 1373 1374 JavaModelOperation.setAttribute(JavaModelOperation.HAS_MODIFIED_RESOURCE_ATTR, null); 1376 1377 notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE, listeners, listenerMask, listenerCount); 1378 } 1379 } 1380 private void fireReconcileDelta( 1381 IElementChangedListener[] listeners, 1382 int[] listenerMask, 1383 int listenerCount) { 1384 1385 1386 IJavaElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas.values()); 1387 if (DEBUG){ 1388 System.out.println("FIRING POST_RECONCILE Delta ["+Thread.currentThread()+"]:"); System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); } 1391 if (deltaToNotify != null) { 1392 this.reconcileDeltas = new HashMap(); 1394 1395 notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE, listeners, listenerMask, listenerCount); 1396 } 1397 } 1398 1402 private boolean isAffectedBy(IResourceDelta rootDelta){ 1403 if (rootDelta != null) { 1406 class FoundRelevantDeltaException extends RuntimeException { 1408 private static final long serialVersionUID = 7137113252936111022L; } 1411 try { 1412 rootDelta.accept(new IResourceDeltaVisitor() { 1413 public boolean visit(IResourceDelta delta) { 1414 switch (delta.getKind()){ 1415 case IResourceDelta.ADDED : 1416 case IResourceDelta.REMOVED : 1417 throw new FoundRelevantDeltaException(); 1418 case IResourceDelta.CHANGED : 1419 if (delta.getAffectedChildren().length == 0 && (delta.getFlags() & ~(IResourceDelta.SYNC | IResourceDelta.MARKERS)) != 0) { 1422 throw new FoundRelevantDeltaException(); 1423 } 1424 } 1425 return true; 1426 } 1427 }); 1428 } catch(FoundRelevantDeltaException e) { 1429 return true; 1431 } catch(CoreException e) { } 1433 } 1434 return false; 1436 } 1437 1440 private boolean isPrimaryWorkingCopy(IJavaElement element, int elementType) { 1441 if (elementType == IJavaElement.COMPILATION_UNIT) { 1442 CompilationUnit cu = (CompilationUnit)element; 1443 return cu.isPrimary() && cu.isWorkingCopy(); 1444 } 1445 return false; 1446 } 1447 1451 private boolean isResFilteredFromOutput(RootInfo rootInfo, OutputsInfo info, IResource res, int elementType) { 1452 if (info != null) { 1453 JavaProject javaProject = null; 1454 String sourceLevel = null; 1455 String complianceLevel = null; 1456 IPath resPath = res.getFullPath(); 1457 for (int i = 0; i < info.outputCount; i++) { 1458 if (info.paths[i].isPrefixOf(resPath)) { 1459 if (info.traverseModes[i] != IGNORE) { 1460 if (info.traverseModes[i] == SOURCE && elementType == IJavaElement.CLASS_FILE) { 1462 return true; 1463 } 1464 if (elementType == IJavaElement.JAVA_PROJECT && res instanceof IFile) { 1467 if (sourceLevel == null) { 1468 javaProject = rootInfo == null ? 1470 (JavaProject)this.createElement(res.getProject(), IJavaElement.JAVA_PROJECT, null) : 1471 rootInfo.project; 1472 if (javaProject != null) { 1473 sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); 1474 complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); 1475 } 1476 } 1477 if (Util.isValidClassFileName(res.getName(), sourceLevel, complianceLevel)) { 1478 return true; 1479 } 1480 } 1481 } else { 1482 return true; 1483 } 1484 } 1485 } 1486 } 1487 return false; 1488 } 1489 1492 private IJavaElementDelta mergeDeltas(Collection deltas) { 1493 if (deltas.size() == 0) return null; 1494 if (deltas.size() == 1) return (IJavaElementDelta)deltas.iterator().next(); 1495 1496 if (VERBOSE) { 1497 System.out.println("MERGING " + deltas.size() + " DELTAS ["+Thread.currentThread()+"]"); } 1499 1500 Iterator iterator = deltas.iterator(); 1501 JavaElementDelta rootDelta = new JavaElementDelta(this.manager.javaModel); 1502 boolean insertedTree = false; 1503 while (iterator.hasNext()) { 1504 JavaElementDelta delta = (JavaElementDelta)iterator.next(); 1505 if (VERBOSE) { 1506 System.out.println(delta.toString()); 1507 } 1508 IJavaElement element = delta.getElement(); 1509 if (this.manager.javaModel.equals(element)) { 1510 IJavaElementDelta[] children = delta.getAffectedChildren(); 1511 for (int j = 0; j < children.length; j++) { 1512 JavaElementDelta projectDelta = (JavaElementDelta) children[j]; 1513 rootDelta.insertDeltaTree(projectDelta.getElement(), projectDelta); 1514 insertedTree = true; 1515 } 1516 IResourceDelta[] resourceDeltas = delta.getResourceDeltas(); 1517 if (resourceDeltas != null) { 1518 for (int i = 0, length = resourceDeltas.length; i < length; i++) { 1519 rootDelta.addResourceDelta(resourceDeltas[i]); 1520 insertedTree = true; 1521 } 1522 } 1523 } else { 1524 rootDelta.insertDeltaTree(element, delta); 1525 insertedTree = true; 1526 } 1527 } 1528 if (insertedTree) return rootDelta; 1529 return null; 1530 } 1531 private void notifyListeners(IJavaElementDelta deltaToNotify, int eventType, IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) { 1532 final ElementChangedEvent extraEvent = new ElementChangedEvent(deltaToNotify, eventType); 1533 for (int i= 0; i < listenerCount; i++) { 1534 if ((listenerMask[i] & eventType) != 0){ 1535 final IElementChangedListener listener = listeners[i]; 1536 long start = -1; 1537 if (VERBOSE) { 1538 System.out.print("Listener #" + (i+1) + "=" + listener.toString()); start = System.currentTimeMillis(); 1540 } 1541 SafeRunner.run(new ISafeRunnable() { 1543 public void handleException(Throwable exception) { 1544 Util.log(exception, "Exception occurred in listener of Java element change notification"); } 1546 public void run() throws Exception { 1547 PerformanceStats stats = null; 1548 if(PERF) { 1549 stats = PerformanceStats.getStats(JavaModelManager.DELTA_LISTENER_PERF, listener); 1550 stats.startRun(); 1551 } 1552 listener.elementChanged(extraEvent); 1553 if(PERF) { 1554 stats.endRun(); 1555 } 1556 } 1557 }); 1558 if (VERBOSE) { 1559 System.out.println(" -> " + (System.currentTimeMillis()-start) + "ms"); } 1561 } 1562 } 1563 } 1564 private void notifyTypeHierarchies(IElementChangedListener[] listeners, int listenerCount) { 1565 for (int i= 0; i < listenerCount; i++) { 1566 final IElementChangedListener listener = listeners[i]; 1567 if (!(listener instanceof TypeHierarchy)) continue; 1568 1569 SafeRunner.run(new ISafeRunnable() { 1571 public void handleException(Throwable exception) { 1572 Util.log(exception, "Exception occurred in listener of Java element change notification"); } 1574 public void run() throws Exception { 1575 TypeHierarchy typeHierarchy = (TypeHierarchy)listener; 1576 if (typeHierarchy.hasFineGrainChanges()) { 1577 typeHierarchy.needsRefresh = true; 1579 typeHierarchy.fireChange(); 1580 } 1581 } 1582 }); 1583 } 1584 } 1585 1592 private void nonJavaResourcesChanged(Openable element, IResourceDelta delta) 1593 throws JavaModelException { 1594 1595 if (element.isOpen()) { 1597 JavaElementInfo info = (JavaElementInfo)element.getElementInfo(); 1598 switch (element.getElementType()) { 1599 case IJavaElement.JAVA_MODEL : 1600 ((JavaModelInfo) info).nonJavaResources = null; 1601 currentDelta().addResourceDelta(delta); 1602 return; 1603 case IJavaElement.JAVA_PROJECT : 1604 ((JavaProjectElementInfo) info).setNonJavaResources(null); 1605 1606 JavaProject project = (JavaProject) element; 1608 PackageFragmentRoot projectRoot = 1609 (PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject()); 1610 if (projectRoot.isOpen()) { 1611 ((PackageFragmentRootInfo) projectRoot.getElementInfo()).setNonJavaResources( 1612 null); 1613 } 1614 break; 1615 case IJavaElement.PACKAGE_FRAGMENT : 1616 ((PackageFragmentInfo) info).setNonJavaResources(null); 1617 break; 1618 case IJavaElement.PACKAGE_FRAGMENT_ROOT : 1619 ((PackageFragmentRootInfo) info).setNonJavaResources(null); 1620 } 1621 } 1622 1623 JavaElementDelta current = currentDelta(); 1624 JavaElementDelta elementDelta = current.find(element); 1625 if (elementDelta == null) { 1626 elementDelta = current.changed(element, IJavaElementDelta.F_CONTENT); 1628 } 1629 elementDelta.addResourceDelta(delta); 1630 } 1631 1634 private ArrayList otherRootsInfo(IPath path, int kind) { 1635 if (kind == IResourceDelta.REMOVED) { 1636 return (ArrayList)this.state.oldOtherRoots.get(path); 1637 } 1638 return (ArrayList)this.state.otherRoots.get(path); 1639 } 1640 1641 private OutputsInfo outputsInfo(RootInfo rootInfo, IResource res) { 1642 try { 1643 JavaProject proj = 1644 rootInfo == null ? 1645 (JavaProject)this.createElement(res.getProject(), IJavaElement.JAVA_PROJECT, null) : 1646 rootInfo.project; 1647 if (proj != null) { 1648 IPath projectOutput = proj.getOutputLocation(); 1649 int traverseMode = IGNORE; 1650 if (proj.getProject().getFullPath().equals(projectOutput)){ return new OutputsInfo(new IPath[] {projectOutput}, new int[] {SOURCE}, 1); 1652 } 1653 IClasspathEntry[] classpath = proj.getResolvedClasspath(); 1654 IPath[] outputs = new IPath[classpath.length+1]; 1655 int[] traverseModes = new int[classpath.length+1]; 1656 int outputCount = 1; 1657 outputs[0] = projectOutput; 1658 traverseModes[0] = traverseMode; 1659 for (int i = 0, length = classpath.length; i < length; i++) { 1660 IClasspathEntry entry = classpath[i]; 1661 IPath entryPath = entry.getPath(); 1662 IPath output = entry.getOutputLocation(); 1663 if (output != null) { 1664 outputs[outputCount] = output; 1665 if (entryPath.equals(output)) { 1667 traverseModes[outputCount++] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY; 1668 } else { 1669 traverseModes[outputCount++] = IGNORE; 1670 } 1671 } 1672 1673 if (entryPath.equals(projectOutput)) { 1675 traverseModes[0] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY; 1676 } 1677 } 1678 return new OutputsInfo(outputs, traverseModes, outputCount); 1679 } 1680 } catch (JavaModelException e) { 1681 } 1683 return null; 1684 } 1685 private void popUntilPrefixOf(IPath path) { 1686 while (this.currentElement != null) { 1687 IPath currentElementPath = null; 1688 if (this.currentElement instanceof IPackageFragmentRoot) { 1689 currentElementPath = ((IPackageFragmentRoot)this.currentElement).getPath(); 1690 } else { 1691 IResource currentElementResource = this.currentElement.getResource(); 1692 if (currentElementResource != null) { 1693 currentElementPath = currentElementResource.getFullPath(); 1694 } 1695 } 1696 if (currentElementPath != null) { 1697 if (this.currentElement instanceof IPackageFragment 1698 && ((IPackageFragment) this.currentElement).isDefaultPackage() 1699 && currentElementPath.segmentCount() != path.segmentCount()-1) { 1700 this.currentElement = (Openable)this.currentElement.getParent(); 1702 } 1703 if (currentElementPath.isPrefixOf(path)) { 1704 return; 1705 } 1706 } 1707 this.currentElement = (Openable)this.currentElement.getParent(); 1708 } 1709 } 1710 1715 private IJavaElementDelta processResourceDelta(IResourceDelta changes) { 1716 1717 try { 1718 IJavaModel model = this.manager.getJavaModel(); 1719 if (!model.isOpen()) { 1720 try { 1722 model.open(null); 1723 } catch (JavaModelException e) { 1724 if (VERBOSE) { 1725 e.printStackTrace(); 1726 } 1727 return null; 1728 } 1729 } 1730 this.state.initializeRoots(); 1731 this.currentElement = null; 1732 1733 IResourceDelta[] deltas = changes.getAffectedChildren(); 1735 for (int i = 0; i < deltas.length; i++) { 1736 IResourceDelta delta = deltas[i]; 1737 IResource res = delta.getResource(); 1738 1739 RootInfo rootInfo = null; 1741 int elementType; 1742 IProject proj = (IProject)res; 1743 boolean wasJavaProject = this.state.findJavaProject(proj.getName()) != null; 1744 boolean isJavaProject = JavaProject.hasJavaNature(proj); 1745 if (!wasJavaProject && !isJavaProject) { 1746 elementType = NON_JAVA_RESOURCE; 1747 } else { 1748 rootInfo = this.enclosingRootInfo(res.getFullPath(), delta.getKind()); 1749 if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) { 1750 elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT; 1751 } else { 1752 elementType = IJavaElement.JAVA_PROJECT; 1753 } 1754 } 1755 1756 this.traverseDelta(delta, elementType, rootInfo, null); 1758 1759 if (elementType == NON_JAVA_RESOURCE 1760 || (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { try { 1762 nonJavaResourcesChanged((JavaModel)model, delta); 1764 } catch (JavaModelException e) { 1765 } 1767 } 1768 1769 } 1770 refreshPackageFragmentRoots(); 1771 resetProjectCaches(); 1772 1773 return this.currentDelta; 1774 } finally { 1775 this.currentDelta = null; 1776 this.rootsToRefresh.clear(); 1777 this.projectCachesToReset.clear(); 1778 } 1779 } 1780 1784 public void resetProjectCaches() { 1785 if (this.projectCachesToReset.size() == 0) 1786 return; 1787 1788 JavaModelManager.getJavaModelManager().resetJarTypeCache(); 1789 1790 Iterator iterator = this.projectCachesToReset.iterator(); 1791 HashMap projectDepencies = this.state.projectDependencies; 1792 HashSet affectedDependents = new HashSet(); 1793 while (iterator.hasNext()) { 1794 JavaProject project = (JavaProject)iterator.next(); 1795 project.resetCaches(); 1796 addDependentProjects(project, projectDepencies, affectedDependents); 1797 } 1798 iterator = affectedDependents.iterator(); 1800 while (iterator.hasNext()) { 1801 JavaProject project = (JavaProject) iterator.next(); 1802 project.resetCaches(); 1803 } 1804 } 1805 1808 private void refreshPackageFragmentRoots() { 1809 Iterator iterator = this.rootsToRefresh.iterator(); 1810 while (iterator.hasNext()) { 1811 JavaProject project = (JavaProject)iterator.next(); 1812 project.updatePackageFragmentRoots(); 1813 } 1814 } 1815 1818 public void registerJavaModelDelta(IJavaElementDelta delta) { 1819 this.javaModelDeltas.add(delta); 1820 } 1821 1826 private void removeFromParentInfo(Openable child) { 1827 1828 Openable parent = (Openable) child.getParent(); 1829 if (parent != null && parent.isOpen()) { 1830 try { 1831 JavaElementInfo info = (JavaElementInfo)parent.getElementInfo(); 1832 info.removeChild(child); 1833 } catch (JavaModelException e) { 1834 } 1836 } 1837 } 1838 1847 public void resourceChanged(IResourceChangeEvent event) { 1848 1849 int eventType = this.overridenEventType == -1 ? event.getType() : this.overridenEventType; 1850 IResource resource = event.getResource(); 1851 IResourceDelta delta = event.getDelta(); 1852 1853 switch(eventType){ 1854 case IResourceChangeEvent.PRE_DELETE : 1855 try { 1856 if(resource.getType() == IResource.PROJECT 1857 && ((IProject) resource).hasNature(JavaCore.NATURE_ID)) { 1858 1859 deleting((IProject)resource); 1860 } 1861 } catch(CoreException e){ 1862 } 1864 return; 1865 1866 case IResourceChangeEvent.POST_CHANGE : 1867 if (isAffectedBy(delta)) { try { 1869 try { 1870 stopDeltas(); 1871 checkProjectsBeingAddedOrRemoved(delta); 1872 1873 if (this.classpathChanges.size() > 0) { 1875 boolean hasDelta = this.currentDelta != null; 1876 JavaElementDelta javaDelta = currentDelta(); 1877 Iterator changes = this.classpathChanges.values().iterator(); 1878 while (changes.hasNext()) { 1879 ClasspathChange change = (ClasspathChange) changes.next(); 1880 int result = change.generateDelta(javaDelta); 1881 if ((result & ClasspathChange.HAS_DELTA) != 0) { 1882 hasDelta = true; 1883 change.requestIndexing(); 1884 this.state.addClasspathValidation(change.project); 1885 } 1886 if ((result & ClasspathChange.HAS_PROJECT_CHANGE) != 0) { 1887 this.state.addProjectReferenceChange(change.project, change.oldResolvedClasspath); 1888 } 1889 } 1890 this.classpathChanges.clear(); 1891 if (!hasDelta) 1892 this.currentDelta = null; 1893 } 1894 1895 if (this.refreshedElements != null) { 1897 createExternalArchiveDelta(null); 1898 } 1899 1900 IJavaElementDelta translatedDelta = processResourceDelta(delta); 1902 if (translatedDelta != null) { 1903 registerJavaModelDelta(translatedDelta); 1904 } 1905 } finally { 1906 this.sourceElementParserCache = null; startDeltas(); 1908 } 1909 IElementChangedListener[] listeners; 1910 int listenerCount; 1911 synchronized (this.state) { 1912 listeners = this.state.elementChangedListeners; 1913 listenerCount = this.state.elementChangedListenerCount; 1914 } 1915 notifyTypeHierarchies(listeners, listenerCount); 1916 fire(null, ElementChangedEvent.POST_CHANGE); 1917 } finally { 1918 this.state.resetOldJavaProjectNames(); 1920 this.oldRoots = null; 1921 } 1922 } 1923 return; 1924 1925 case IResourceChangeEvent.PRE_BUILD : 1926 if(!isAffectedBy(delta)) 1927 return; 1929 boolean needCycleValidation = validateClasspaths(delta); 1931 ClasspathValidation[] validations = this.state.removeClasspathValidations(); 1932 if (validations != null) { 1933 for (int i = 0, length = validations.length; i < length; i++) { 1934 ClasspathValidation validation = validations[i]; 1935 validation.validate(); 1936 } 1937 } 1938 1939 ProjectReferenceChange[] projectRefChanges = this.state.removeProjectReferenceChanges(); 1941 if (projectRefChanges != null) { 1942 for (int i = 0, length = projectRefChanges.length; i < length; i++) { 1943 try { 1944 projectRefChanges[i].updateProjectReferencesIfNecessary(); 1945 } catch(JavaModelException e) { 1946 } 1948 } 1949 } 1950 1951 if (needCycleValidation || projectRefChanges != null) { 1952 try { 1954 JavaProject.validateCycles(null); 1955 } catch (JavaModelException e) { 1956 } 1958 } 1959 1960 JavaModel.flushExternalFileCache(); 1961 JavaBuilder.buildStarting(); 1962 1963 return; 1965 1966 case IResourceChangeEvent.POST_BUILD : 1967 JavaBuilder.buildFinished(); 1968 return; 1969 } 1970 } 1971 1972 1975 private RootInfo rootInfo(IPath path, int kind) { 1976 if (kind == IResourceDelta.REMOVED) { 1977 return (RootInfo)this.state.oldRoots.get(path); 1978 } 1979 return (RootInfo)this.state.roots.get(path); 1980 } 1981 1985 private void startDeltas() { 1986 this.isFiring= true; 1987 } 1988 1992 private void stopDeltas() { 1993 this.isFiring= false; 1994 } 1995 1999 private void traverseDelta( 2000 IResourceDelta delta, 2001 int elementType, 2002 RootInfo rootInfo, 2003 OutputsInfo outputsInfo) { 2004 2005 IResource res = delta.getResource(); 2006 2007 if (this.currentElement == null && rootInfo != null) { 2009 this.currentElement = rootInfo.project; 2010 } 2011 2012 boolean processChildren = true; 2014 if (res instanceof IProject) { 2015 this.sourceElementParserCache = null; 2017 2018 processChildren = 2019 this.updateCurrentDeltaAndIndex( 2020 delta, 2021 elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ? 2022 IJavaElement.JAVA_PROJECT : elementType, 2024 rootInfo); 2025 } else if (rootInfo != null) { 2026 processChildren = this.updateCurrentDeltaAndIndex(delta, elementType, rootInfo); 2027 } else { 2028 processChildren = true; 2030 } 2031 2032 if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res); 2034 2035 if (processChildren) { 2037 IResourceDelta[] children = delta.getAffectedChildren(); 2038 boolean oneChildOnClasspath = false; 2039 int length = children.length; 2040 IResourceDelta[] orphanChildren = null; 2041 Openable parent = null; 2042 boolean isValidParent = true; 2043 for (int i = 0; i < length; i++) { 2044 IResourceDelta child = children[i]; 2045 IResource childRes = child.getResource(); 2046 2047 this.checkSourceAttachmentChange(child, childRes); 2049 2050 IPath childPath = childRes.getFullPath(); 2052 int childKind = child.getKind(); 2053 RootInfo childRootInfo = this.rootInfo(childPath, childKind); 2054 if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) { 2055 childRootInfo = null; 2057 } 2058 2059 int childType = 2061 this.elementType( 2062 childRes, 2063 childKind, 2064 elementType, 2065 rootInfo == null ? childRootInfo : rootInfo 2066 ); 2067 2068 boolean isResFilteredFromOutput = this.isResFilteredFromOutput(rootInfo, outputsInfo, childRes, childType); 2070 2071 boolean isNestedRoot = rootInfo != null && childRootInfo != null; 2072 if (!isResFilteredFromOutput 2073 && !isNestedRoot) { 2075 this.traverseDelta(child, childType, rootInfo == null ? childRootInfo : rootInfo, outputsInfo); 2077 if (childType == NON_JAVA_RESOURCE) { 2078 if (rootInfo != null) { if (!isValidParent) continue; 2080 if (parent == null) { 2081 if (this.currentElement == null 2083 || !rootInfo.project.equals(this.currentElement.getJavaProject())) { this.currentElement = rootInfo.project; 2086 } 2087 if (elementType == IJavaElement.JAVA_PROJECT 2088 || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT 2089 && res instanceof IProject)) { 2090 parent = rootInfo.project; 2092 } else { 2093 parent = this.createElement(res, elementType, rootInfo); 2094 } 2095 if (parent == null) { 2096 isValidParent = false; 2097 continue; 2098 } 2099 } 2100 try { 2102 nonJavaResourcesChanged(parent, child); 2103 } catch (JavaModelException e) { 2104 } 2106 } else { 2107 if (orphanChildren == null) orphanChildren = new IResourceDelta[length]; 2109 orphanChildren[i] = child; 2110 } 2111 } else { 2112 oneChildOnClasspath = true; 2113 } 2114 } else { 2115 oneChildOnClasspath = true; } 2117 2118 if (isNestedRoot 2122 || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath, childKind)) != null)) { 2123 this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); } 2125 2126 ArrayList rootList; 2128 if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) { 2129 Iterator iterator = rootList.iterator(); 2130 while (iterator.hasNext()) { 2131 childRootInfo = (RootInfo) iterator.next(); 2132 this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); } 2134 } 2135 } 2136 if (orphanChildren != null 2137 && (oneChildOnClasspath || res instanceof IProject)) { 2140 IProject rscProject = res.getProject(); 2142 JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject); 2143 if (adoptiveProject != null 2144 && JavaProject.hasJavaNature(rscProject)) { for (int i = 0; i < length; i++) { 2146 if (orphanChildren[i] != null) { 2147 try { 2148 nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]); 2149 } catch (JavaModelException e) { 2150 } 2152 } 2153 } 2154 } 2155 } } } 2158 2159 private void validateClasspaths(IResourceDelta delta, HashSet affectedProjects) { 2160 IResource resource = delta.getResource(); 2161 boolean processChildren = false; 2162 switch (resource.getType()) { 2163 case IResource.ROOT : 2164 if (delta.getKind() == IResourceDelta.CHANGED) { 2165 processChildren = true; 2166 } 2167 break; 2168 case IResource.PROJECT : 2169 IProject project = (IProject)resource; 2170 int kind = delta.getKind(); 2171 boolean isJavaProject = JavaProject.hasJavaNature(project); 2172 switch (kind) { 2173 case IResourceDelta.ADDED: 2174 processChildren = isJavaProject; 2175 affectedProjects.add(project.getFullPath()); 2176 break; 2177 case IResourceDelta.CHANGED: 2178 processChildren = isJavaProject; 2179 if ((delta.getFlags() & IResourceDelta.OPEN) != 0) { 2180 if (isJavaProject) { 2182 JavaProject javaProject = (JavaProject)JavaCore.create(project); 2183 this.state.addClasspathValidation(javaProject); } 2185 affectedProjects.add(project.getFullPath()); 2186 } else if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) { 2187 boolean wasJavaProject = this.state.findJavaProject(project.getName()) != null; 2188 if (wasJavaProject != isJavaProject) { 2189 JavaProject javaProject = (JavaProject)JavaCore.create(project); 2191 this.state.addClasspathValidation(javaProject); affectedProjects.add(project.getFullPath()); 2193 } 2194 } 2195 break; 2196 case IResourceDelta.REMOVED: 2197 affectedProjects.add(project.getFullPath()); 2198 break; 2199 } 2200 break; 2201 case IResource.FILE : 2202 2203 IFile file = (IFile) resource; 2204 String fileName = file.getName(); 2205 if (fileName.equals(JavaProject.CLASSPATH_FILENAME)) { 2206 JavaProject javaProject = (JavaProject)JavaCore.create(file.getProject()); 2207 this.state.addClasspathValidation(javaProject); 2208 affectedProjects.add(file.getProject().getFullPath()); 2209 } 2210 break; 2211 } 2212 if (processChildren) { 2213 IResourceDelta[] children = delta.getAffectedChildren(); 2214 for (int i = 0; i < children.length; i++) { 2215 validateClasspaths(children[i], affectedProjects); 2216 } 2217 } 2218 } 2219 2220 2225 private boolean validateClasspaths(IResourceDelta delta) { 2226 HashSet affectedProjects = new HashSet(5); 2227 validateClasspaths(delta, affectedProjects); 2228 boolean needCycleValidation = false; 2229 2230 if (!affectedProjects.isEmpty()) { 2233 IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); 2234 IProject[] projects = workspaceRoot.getProjects(); 2235 int length = projects.length; 2236 for (int i = 0; i < length; i++){ 2237 IProject project = projects[i]; 2238 JavaProject javaProject = (JavaProject)JavaCore.create(project); 2239 try { 2240 IPath projectPath = project.getFullPath(); 2241 IClasspathEntry[] classpath = javaProject.getResolvedClasspath(); for (int j = 0, cpLength = classpath.length; j < cpLength; j++) { 2243 IClasspathEntry entry = classpath[j]; 2244 switch (entry.getEntryKind()) { 2245 case IClasspathEntry.CPE_PROJECT: 2246 if (affectedProjects.contains(entry.getPath())) { 2247 this.state.addClasspathValidation(javaProject); 2248 needCycleValidation = true; 2249 } 2250 break; 2251 case IClasspathEntry.CPE_LIBRARY: 2252 IPath entryPath = entry.getPath(); 2253 IPath libProjectPath = entryPath.removeLastSegments(entryPath.segmentCount()-1); 2254 if (!libProjectPath.equals(projectPath) && affectedProjects.contains(libProjectPath)) { 2256 this.state.addClasspathValidation(javaProject); 2257 } 2258 break; 2259 } 2260 } 2261 } catch(JavaModelException e) { 2262 } 2264 } 2265 } 2266 return needCycleValidation; 2267 } 2268 2269 2274 public boolean updateCurrentDeltaAndIndex(IResourceDelta delta, int elementType, RootInfo rootInfo) { 2275 Openable element; 2276 switch (delta.getKind()) { 2277 case IResourceDelta.ADDED : 2278 IResource deltaRes = delta.getResource(); 2279 element = createElement(deltaRes, elementType, rootInfo); 2280 if (element == null) { 2281 this.state.updateRoots(deltaRes.getFullPath(), delta, this); 2283 return rootInfo != null && rootInfo.inclusionPatterns != null; 2284 } 2285 updateIndex(element, delta); 2286 elementAdded(element, delta, rootInfo); 2287 if (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT) 2288 this.state.addClasspathValidation(rootInfo.project); 2289 return elementType == IJavaElement.PACKAGE_FRAGMENT; 2290 case IResourceDelta.REMOVED : 2291 deltaRes = delta.getResource(); 2292 element = createElement(deltaRes, elementType, rootInfo); 2293 if (element == null) { 2294 this.state.updateRoots(deltaRes.getFullPath(), delta, this); 2296 return rootInfo != null && rootInfo.inclusionPatterns != null; 2297 } 2298 updateIndex(element, delta); 2299 elementRemoved(element, delta, rootInfo); 2300 if (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT) 2301 this.state.addClasspathValidation(rootInfo.project); 2302 2303 if (deltaRes.getType() == IResource.PROJECT){ 2304 if (JavaBuilder.DEBUG) 2306 System.out.println("Clearing last state for removed project : " + deltaRes); this.manager.setLastBuiltState((IProject)deltaRes, null ); 2308 2309 this.manager.previousSessionContainers.remove(element); 2311 } 2312 return elementType == IJavaElement.PACKAGE_FRAGMENT; 2313 case IResourceDelta.CHANGED : 2314 int flags = delta.getFlags(); 2315 if ((flags & IResourceDelta.CONTENT) != 0 || (flags & IResourceDelta.ENCODING) != 0) { 2316 element = createElement(delta.getResource(), elementType, rootInfo); 2318 if (element == null) return false; 2319 updateIndex(element, delta); 2320 contentChanged(element); 2321 } else if (elementType == IJavaElement.JAVA_PROJECT) { 2322 if ((flags & IResourceDelta.OPEN) != 0) { 2323 IProject res = (IProject)delta.getResource(); 2325 element = createElement(res, elementType, rootInfo); 2326 if (element == null) { 2327 this.state.updateRoots(res.getFullPath(), delta, this); 2329 return false; 2330 } 2331 if (res.isOpen()) { 2332 if (JavaProject.hasJavaNature(res)) { 2333 addToParentInfo(element); 2334 currentDelta().opened(element); 2335 this.state.updateRoots(element.getPath(), delta, this); 2336 2337 this.rootsToRefresh.add(element); 2339 this.projectCachesToReset.add(element); 2340 2341 this.manager.indexManager.indexAll(res); 2342 } 2343 } else { 2344 boolean wasJavaProject = this.state.findJavaProject(res.getName()) != null; 2345 if (wasJavaProject) { 2346 close(element); 2347 removeFromParentInfo(element); 2348 currentDelta().closed(element); 2349 this.manager.indexManager.discardJobs(element.getElementName()); 2350 this.manager.indexManager.removeIndexFamily(res.getFullPath()); 2351 } 2352 } 2353 return false; } 2355 if ((flags & IResourceDelta.DESCRIPTION) != 0) { 2356 IProject res = (IProject)delta.getResource(); 2357 boolean wasJavaProject = this.state.findJavaProject(res.getName()) != null; 2358 boolean isJavaProject = JavaProject.hasJavaNature(res); 2359 if (wasJavaProject != isJavaProject) { 2360 element = this.createElement(res, elementType, rootInfo); 2362 if (element == null) return false; if (isJavaProject) { 2364 elementAdded(element, delta, rootInfo); 2365 this.manager.indexManager.indexAll(res); 2366 } else { 2367 elementRemoved(element, delta, rootInfo); 2368 this.manager.indexManager.discardJobs(element.getElementName()); 2369 this.manager.indexManager.removeIndexFamily(res.getFullPath()); 2370 if (JavaBuilder.DEBUG) 2372 System.out.println("Clearing last state for project loosing Java nature: " + res); this.manager.setLastBuiltState(res, null ); 2374 } 2375 return false; } 2377 } 2378 } 2379 return true; 2380 } 2381 return true; 2382 } 2383 private void updateIndex(Openable element, IResourceDelta delta) { 2384 2385 IndexManager indexManager = this.manager.indexManager; 2386 if (indexManager == null) 2387 return; 2388 2389 switch (element.getElementType()) { 2390 case IJavaElement.JAVA_PROJECT : 2391 switch (delta.getKind()) { 2392 case IResourceDelta.ADDED : 2393 indexManager.indexAll(element.getJavaProject().getProject()); 2394 break; 2395 case IResourceDelta.REMOVED : 2396 indexManager.removeIndexFamily(element.getJavaProject().getProject().getFullPath()); 2397 break; 2399 } 2402 break; 2403 case IJavaElement.PACKAGE_FRAGMENT_ROOT : 2404 if (element instanceof JarPackageFragmentRoot) { 2405 JarPackageFragmentRoot root = (JarPackageFragmentRoot)element; 2406 IPath jarPath = root.getPath(); 2408 switch (delta.getKind()) { 2409 case IResourceDelta.ADDED: 2410 indexManager.indexLibrary(jarPath, root.getJavaProject().getProject()); 2412 break; 2413 case IResourceDelta.CHANGED: 2414 indexManager.removeIndex(jarPath); 2416 indexManager.indexLibrary(jarPath, root.getJavaProject().getProject()); 2418 break; 2419 case IResourceDelta.REMOVED: 2420 indexManager.discardJobs(jarPath.toString()); 2422 indexManager.removeIndex(jarPath); 2423 break; 2424 } 2425 break; 2426 } 2427 int kind = delta.getKind(); 2428 if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED) { 2429 PackageFragmentRoot root = (PackageFragmentRoot)element; 2430 this.updateRootIndex(root, CharOperation.NO_STRINGS, delta); 2431 break; 2432 } 2433 case IJavaElement.PACKAGE_FRAGMENT : 2435 switch (delta.getKind()) { 2436 case IResourceDelta.ADDED: 2437 case IResourceDelta.REMOVED: 2438 IPackageFragment pkg = null; 2439 if (element instanceof IPackageFragmentRoot) { 2440 PackageFragmentRoot root = (PackageFragmentRoot)element; 2441 pkg = root.getPackageFragment(CharOperation.NO_STRINGS); 2442 } else { 2443 pkg = (IPackageFragment)element; 2444 } 2445 RootInfo rootInfo = rootInfo(pkg.getParent().getPath(), delta.getKind()); 2446 boolean isSource = 2447 rootInfo == null || rootInfo.entryKind == IClasspathEntry.CPE_SOURCE; 2449 IResourceDelta[] children = delta.getAffectedChildren(); 2450 for (int i = 0, length = children.length; i < length; i++) { 2451 IResourceDelta child = children[i]; 2452 IResource resource = child.getResource(); 2453 if (resource instanceof IFile) { 2455 String name = resource.getName(); 2456 if (isSource) { 2457 if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(name)) { 2458 Openable cu = (Openable)pkg.getCompilationUnit(name); 2459 this.updateIndex(cu, child); 2460 } 2461 } else if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) { 2462 Openable classFile = (Openable)pkg.getClassFile(name); 2463 this.updateIndex(classFile, child); 2464 } 2465 } 2466 } 2467 break; 2468 } 2469 break; 2470 case IJavaElement.CLASS_FILE : 2471 IFile file = (IFile) delta.getResource(); 2472 IJavaProject project = element.getJavaProject(); 2473 IPath binaryFolderPath = element.getPackageFragmentRoot().getPath(); 2474 try { 2477 if (binaryFolderPath.equals(project.getOutputLocation())) { 2478 break; 2479 } 2480 } catch (JavaModelException e) { 2481 } 2483 switch (delta.getKind()) { 2484 case IResourceDelta.CHANGED : 2485 int flags = delta.getFlags(); 2487 if ((flags & IResourceDelta.CONTENT) == 0 && (flags & IResourceDelta.ENCODING) == 0) 2488 break; 2489 case IResourceDelta.ADDED : 2490 indexManager.addBinary(file, binaryFolderPath); 2491 break; 2492 case IResourceDelta.REMOVED : 2493 String containerRelativePath = Util.relativePath(file.getFullPath(), binaryFolderPath.segmentCount()); 2494 indexManager.remove(containerRelativePath, binaryFolderPath); 2495 break; 2496 } 2497 break; 2498 case IJavaElement.COMPILATION_UNIT : 2499 file = (IFile) delta.getResource(); 2500 switch (delta.getKind()) { 2501 case IResourceDelta.CHANGED : 2502 int flags = delta.getFlags(); 2504 if ((flags & IResourceDelta.CONTENT) == 0 && (flags & IResourceDelta.ENCODING) == 0) 2505 break; 2506 case IResourceDelta.ADDED : 2507 indexManager.addSource(file, file.getProject().getFullPath(), getSourceElementParser(element)); 2508 this.manager.secondaryTypesRemoving(file, false); 2510 break; 2511 case IResourceDelta.REMOVED : 2512 indexManager.remove(Util.relativePath(file.getFullPath(), 1), file.getProject().getFullPath()); 2513 this.manager.secondaryTypesRemoving(file, true); 2515 break; 2516 } 2517 } 2518 } 2519 2522 public void updateJavaModel(IJavaElementDelta customDelta) { 2523 2524 if (customDelta == null){ 2525 for (int i = 0, length = this.javaModelDeltas.size(); i < length; i++){ 2526 IJavaElementDelta delta = (IJavaElementDelta)this.javaModelDeltas.get(i); 2527 this.modelUpdater.processJavaDelta(delta); 2528 } 2529 } else { 2530 this.modelUpdater.processJavaDelta(customDelta); 2531 } 2532 } 2533 2537 private void updateRootIndex(PackageFragmentRoot root, String [] pkgName, IResourceDelta delta) { 2538 Openable pkg = root.getPackageFragment(pkgName); 2539 this.updateIndex(pkg, delta); 2540 IResourceDelta[] children = delta.getAffectedChildren(); 2541 for (int i = 0, length = children.length; i < length; i++) { 2542 IResourceDelta child = children[i]; 2543 IResource resource = child.getResource(); 2544 if (resource instanceof IFolder) { 2545 String [] subpkgName = Util.arrayConcat(pkgName, resource.getName()); 2546 this.updateRootIndex(root, subpkgName, child); 2547 } 2548 } 2549 } 2550} 2551 | Popular Tags |