1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.Iterator;
21 import net.sourceforge.phpdt.core.ElementChangedEvent;
22 import net.sourceforge.phpdt.core.IClasspathEntry;
23 import net.sourceforge.phpdt.core.IElementChangedListener;
24 import net.sourceforge.phpdt.core.IJavaElement;
25 import net.sourceforge.phpdt.core.IJavaElementDelta;
26 import net.sourceforge.phpdt.core.IJavaModel;
27 import net.sourceforge.phpdt.core.IJavaProject;
28 import net.sourceforge.phpdt.core.JavaCore;
29 import net.sourceforge.phpdt.core.JavaModelException;
30 import net.sourceforge.phpdt.internal.core.builder.PHPBuilder;
31 import net.sourceforge.phpdt.internal.core.util.Util;
32 import net.sourceforge.phpdt.internal.core.util.PHPFileUtil;
33 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
35 import org.eclipse.core.resources.IFile;
36 import org.eclipse.core.resources.IProject;
37 import org.eclipse.core.resources.IResource;
38 import org.eclipse.core.resources.IResourceChangeEvent;
39 import org.eclipse.core.resources.IResourceChangeListener;
40 import org.eclipse.core.resources.IResourceDelta;
41 import org.eclipse.core.resources.IResourceDeltaVisitor;
42 import org.eclipse.core.resources.IWorkspace;
43 import org.eclipse.core.resources.ResourcesPlugin;
44 import org.eclipse.core.runtime.CoreException;
45 import org.eclipse.core.runtime.IPath;
46 import org.eclipse.core.runtime.ISafeRunnable;
47 import org.eclipse.core.runtime.Platform;
48 import org.eclipse.core.runtime.QualifiedName;
51 * This class is used by <code>JavaModelManager</code> to convert
52 * <code>IResourceDelta</code>s into <code>IJavaElementDelta</code>s. It
53 * also does some processing on the <code>JavaElement</code>s involved (e.g.
54 * closing them or updating classpaths).
56 public class DeltaProcessor implements IResourceChangeListener {
58 final static int IGNORE = 0;
60 final static int SOURCE = 1;
62 final static int BINARY = 2;
64 final static String EXTERNAL_JAR_ADDED = "external jar added"; //$NON-NLS-1$
66 final static String EXTERNAL_JAR_REMOVED = "external jar removed"; //$NON-NLS-1$
68 final static String EXTERNAL_JAR_CHANGED = "external jar changed"; //$NON-NLS-1$
70 final static String EXTERNAL_JAR_UNCHANGED = "external jar unchanged"; //$NON-NLS-1$
72 final static String INTERNAL_JAR_IGNORE = "internal jar ignore"; //$NON-NLS-1$
74 private final static int NON_JAVA_RESOURCE = -1;
76 public static boolean DEBUG = false;
78 public static boolean VERBOSE = false;
80 public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with
81 // ElementChangedEvent
85 * The <code>JavaElementDelta</code> corresponding to the
86 * <code>IResourceDelta</code> being translated.
88 protected JavaElementDelta currentDelta;
90 // protected IndexManager indexManager = new IndexManager();
92 /* A table from IPath (from a classpath entry) to RootInfo */
96 * A table from IPath (from a classpath entry) to ArrayList of RootInfo Used
97 * when an IPath corresponds to more than one root
101 /* Whether the roots tables should be recomputed */
102 public boolean rootsAreStale = true;
105 * A table from IPath (from a classpath entry) to RootInfo from the last
106 * time the delta processor was invoked.
111 * A table from IPath (from a classpath entry) to ArrayList of RootInfo from
112 * the last time the delta processor was invoked. Used when an IPath
113 * corresponds to more than one root
118 * A table from IPath (a source attachment path from a classpath entry) to
119 * IPath (a root path)
121 Map sourceAttachments;
124 * The java element that was last created (see createElement(IResource)).
125 * This is used as a stack of java elements (using getParent() to pop it,
126 * and using the various get*(...) to push it.
128 Openable currentElement;
131 * Queue of deltas created explicily by the Java Model that have yet to be
134 public ArrayList javaModelDeltas = new ArrayList();
137 * Queue of reconcile deltas on working copies that have yet to be fired.
138 * This is a table form IWorkingCopy to IJavaElementDelta
140 public HashMap reconcileDeltas = new HashMap();
143 * Turns delta firing on/off. By default it is on.
145 private boolean isFiring = true;
147 public HashMap externalTimeStamps = new HashMap();
149 public HashSet projectsToUpdate = new HashSet();
151 // list of root projects which namelookup caches need to be updated for
153 // TODO: (jerome) is it needed? projectsToUpdate might be sufficient
154 public HashSet projectsForDependentNamelookupRefresh = new HashSet();
157 * The global state of delta processing.
159 private DeltaProcessingState state;
162 * The Java model manager
164 private JavaModelManager manager;
167 * A table from IJavaProject to an array of IPackageFragmentRoot. This table
168 * contains the pkg fragment roots of the project that are being deleted.
173 * A list of IJavaElement used as a scope for external archives refresh
174 * during POST_CHANGE. This is null if no refresh is needed.
176 HashSet refreshedElements;
185 OutputsInfo(IPath[] paths, int[] traverseModes, int outputCount) {
187 this.traverseModes = traverseModes;
188 this.outputCount = outputCount;
191 public String toString() {
192 if (this.paths == null)
193 return "<none>"; //$NON-NLS-1$
194 StringBuffer buffer = new StringBuffer();
195 for (int i = 0; i < this.outputCount; i++) {
196 buffer.append("path="); //$NON-NLS-1$
197 buffer.append(this.paths[i].toString());
198 buffer.append("\n->traverse="); //$NON-NLS-1$
199 switch (this.traverseModes[i]) {
201 buffer.append("BINARY"); //$NON-NLS-1$
204 buffer.append("IGNORE"); //$NON-NLS-1$
207 buffer.append("SOURCE"); //$NON-NLS-1$
210 buffer.append("<unknown>"); //$NON-NLS-1$
212 if (i + 1 < this.outputCount) {
216 return buffer.toString();
221 IJavaProject project;
225 char[][] exclusionPatterns;
227 RootInfo(IJavaProject project, IPath rootPath,
228 char[][] exclusionPatterns) {
229 this.project = project;
230 this.rootPath = rootPath;
231 this.exclusionPatterns = exclusionPatterns;
234 boolean isRootOfProject(IPath path) {
235 return this.rootPath.equals(path)
236 && this.project.getProject().getFullPath().isPrefixOf(path);
239 public String toString() {
240 StringBuffer buffer = new StringBuffer("project="); //$NON-NLS-1$
241 if (this.project == null) {
242 buffer.append("null"); //$NON-NLS-1$
244 buffer.append(this.project.getElementName());
246 buffer.append("\npath="); //$NON-NLS-1$
247 if (this.rootPath == null) {
248 buffer.append("null"); //$NON-NLS-1$
250 buffer.append(this.rootPath.toString());
252 buffer.append("\nexcluding="); //$NON-NLS-1$
253 if (this.exclusionPatterns == null) {
254 buffer.append("null"); //$NON-NLS-1$
256 for (int i = 0, length = this.exclusionPatterns.length; i < length; i++) {
257 buffer.append(new String(this.exclusionPatterns[i]));
258 if (i < length - 1) {
259 buffer.append("|"); //$NON-NLS-1$
263 return buffer.toString();
267 // DeltaProcessor(JavaModelManager manager) {
268 // this.manager = manager;
272 * Type of event that should be processed no matter what the real event type
275 public int overridenEventType = -1;
277 public DeltaProcessor(DeltaProcessingState state, JavaModelManager manager) {
279 this.manager = manager;
283 * Adds the dependents of the given project to the list of the projects to
286 // void addDependentProjects(IPath projectPath, HashSet result) {
288 // IJavaProject[] projects = this.manager.getJavaModel().getJavaProjects();
289 // for (int i = 0, length = projects.length; i < length; i++) {
290 // IJavaProject project = projects[i];
291 // IClasspathEntry[] classpath =
292 // ((JavaProject)project).getExpandedClasspath(true);
293 // for (int j = 0, length2 = classpath.length; j < length2; j++) {
294 // IClasspathEntry entry = classpath[j];
295 // if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT
296 // && entry.getPath().equals(projectPath)) {
297 // result.add(project);
301 // } catch (JavaModelException e) {
305 * Adds the given element to the list of elements used as a scope for
306 * external jars refresh.
308 public void addForRefresh(IJavaElement element) {
309 if (this.refreshedElements == null) {
310 this.refreshedElements = new HashSet();
312 this.refreshedElements.add(element);
316 * Adds the given project and its dependents to the list of the projects to
319 void addToProjectsToUpdateWithDependents(IProject project) {
320 this.projectsToUpdate.add(JavaCore.create(project));
321 // this.addDependentProjects(project.getFullPath(),
322 // this.projectsToUpdate);
326 * Adds the given child handle to its parent's cache of children.
328 protected void addToParentInfo(Openable child) {
330 Openable parent = (Openable) child.getParent();
331 if (parent != null && parent.isOpen()) {
333 JavaElementInfo info = (JavaElementInfo) parent
335 info.addChild(child);
336 } catch (JavaModelException e) {
337 // do nothing - we already checked if open
343 * Check all external archive (referenced by given roots, projects or model)
344 * status and issue a corresponding root delta. Also triggers index updates
346 // public void checkExternalArchiveChanges(IJavaElement[] refreshedElements,
347 // IProgressMonitor monitor) throws JavaModelException {
349 // for (int i = 0, length = refreshedElements.length; i < length; i++) {
350 // this.addForRefresh(refreshedElements[i]);
352 // boolean hasDelta = this.createExternalArchiveDelta(monitor);
353 // if (monitor != null && monitor.isCanceled()) return;
355 // // force classpath marker refresh of affected projects
356 // JavaModel.flushExternalFileCache();
357 // IJavaElementDelta[] projectDeltas =
358 // this.currentDelta.getAffectedChildren();
359 // for (int i = 0, length = projectDeltas.length; i < length; i++) {
360 // IJavaElementDelta delta = projectDeltas[i];
361 // ((JavaProject)delta.getElement()).getResolvedClasspath(
362 // true, // ignoreUnresolvedEntry
363 // true); // generateMarkerOnError
365 // if (this.currentDelta != null) { // if delta has not been fired while
367 // this.manager.fire(this.currentDelta,
368 // JavaModelManager.DEFAULT_CHANGE_EVENT);
372 // this.currentDelta = null;
373 // if (monitor != null) monitor.done();
377 * Check if external archives have changed and create the corresponding
378 * deltas. Returns whether at least on delta was created.
380 // public boolean createExternalArchiveDelta(IProgressMonitor monitor)
381 // throws JavaModelException {
383 // if (this.refreshedElements == null) return false;
385 // HashMap externalArchivesStatus = new HashMap();
386 // boolean hasDelta = false;
388 // // find JARs to refresh
389 // HashSet archivePathsToRefresh = new HashSet();
391 // Iterator iterator = this.refreshedElements.iterator();
392 // while (iterator.hasNext()) {
393 // IJavaElement element = (IJavaElement)iterator.next();
394 // switch(element.getElementType()){
395 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
396 // archivePathsToRefresh.add(element.getPath());
398 // case IJavaElement.JAVA_PROJECT :
399 // IJavaProject project = (IJavaProject) element;
400 // if (!JavaProject.hasJavaNature(project.getProject())) {
401 // // project is not accessible or has lost its Java nature
404 // IClasspathEntry[] classpath = project.getResolvedClasspath(true);
405 // for (int j = 0, cpLength = classpath.length; j < cpLength; j++){
406 // if (classpath[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
407 // archivePathsToRefresh.add(classpath[j].getPath());
411 // case IJavaElement.JAVA_MODEL :
412 // IJavaProject[] projects =
413 // manager.getJavaModel().getOldJavaProjectsList();
414 // for (int j = 0, projectsLength = projects.length; j < projectsLength;
416 // project = projects[j];
417 // if (!JavaProject.hasJavaNature(project.getProject())) {
418 // // project is not accessible or has lost its Java nature
421 // classpath = project.getResolvedClasspath(true);
422 // for (int k = 0, cpLength = classpath.length; k < cpLength; k++){
423 // if (classpath[k].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
424 // archivePathsToRefresh.add(classpath[k].getPath());
432 // this.refreshedElements = null;
435 // // perform refresh
436 // IJavaProject[] projects =
437 // manager.getJavaModel().getOldJavaProjectsList();
438 // IWorkspaceRoot wksRoot = ResourcesPlugin.getWorkspace().getRoot();
439 // for (int i = 0, length = projects.length; i < length; i++) {
441 // if (monitor != null && monitor.isCanceled()) break;
443 // IJavaProject project = projects[i];
444 // if (!JavaProject.hasJavaNature(project.getProject())) {
445 // // project is not accessible or has lost its Java nature
448 // IClasspathEntry[] entries = project.getResolvedClasspath(true);
449 // for (int j = 0; j < entries.length; j++){
450 // if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
452 // IPath entryPath = entries[j].getPath();
454 // if (!archivePathsToRefresh.contains(entryPath)) continue; // not supposed
457 // String status = (String)externalArchivesStatus.get(entryPath);
458 // if (status == null){
460 // // compute shared status
461 // Object targetLibrary = JavaModel.getTarget(wksRoot, entryPath, true);
463 // if (targetLibrary == null){ // missing JAR
464 // if (this.externalTimeStamps.containsKey(entryPath)){
465 // this.externalTimeStamps.remove(entryPath);
466 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
467 // // the jar was physically removed: remove the index
468 // indexManager.removeIndex(entryPath);
471 // } else if (targetLibrary instanceof File){ // external JAR
473 // File externalFile = (File)targetLibrary;
475 // // check timestamp to figure if JAR has changed in some way
476 // Long oldTimestamp =(Long) this.externalTimeStamps.get(entryPath);
477 // long newTimeStamp = getTimeStamp(externalFile);
478 // if (oldTimestamp != null){
480 // if (newTimeStamp == 0){ // file doesn't exist
481 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
482 // this.externalTimeStamps.remove(entryPath);
483 // // remove the index
484 // indexManager.removeIndex(entryPath);
486 // } else if (oldTimestamp.longValue() != newTimeStamp){
487 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_CHANGED);
488 // this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
489 // // first remove the index so that it is forced to be re-indexed
490 // indexManager.removeIndex(entryPath);
491 // // then index the jar
492 // indexManager.indexLibrary(entryPath, project.getProject());
494 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
497 // if (newTimeStamp == 0){ // jar still doesn't exist
498 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
500 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_ADDED);
501 // this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
502 // // index the new jar
503 // indexManager.indexLibrary(entryPath, project.getProject());
506 // } else { // internal JAR
507 // externalArchivesStatus.put(entryPath, INTERNAL_JAR_IGNORE);
510 // // according to computed status, generate a delta
511 // status = (String)externalArchivesStatus.get(entryPath);
512 // if (status != null){
513 // if (status == EXTERNAL_JAR_ADDED){
514 // PackageFragmentRoot root =
515 // (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
517 // System.out.println("- External JAR ADDED, affecting root:
518 // "+root.getElementName()); //$NON-NLS-1$
520 // elementAdded(root, null, null);
522 // } else if (status == EXTERNAL_JAR_CHANGED) {
523 // PackageFragmentRoot root =
524 // (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
526 // System.out.println("- External JAR CHANGED, affecting root:
527 // "+root.getElementName()); //$NON-NLS-1$
529 // // reset the corresponding project built state, since the builder would
531 // this.manager.setLastBuiltState(project.getProject(), null /*no state*/);
532 // contentChanged(root, null);
534 // } else if (status == EXTERNAL_JAR_REMOVED) {
535 // PackageFragmentRoot root =
536 // (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
538 // System.out.println("- External JAR REMOVED, affecting root:
539 // "+root.getElementName()); //$NON-NLS-1$
541 // elementRemoved(root, null, null);
550 JavaElementDelta currentDelta() {
551 if (this.currentDelta == null) {
552 this.currentDelta = new JavaElementDelta(this.manager
555 return this.currentDelta;
559 * Process the given delta and look for projects being added, opened, closed
560 * or with a java nature being added or removed. Note that projects being
561 * deleted are checked in deleting(IProject). In all cases, add the
562 * project's dependents to the list of projects to update so that the
563 * classpath related markers can be updated.
565 // public void checkProjectsBeingAddedOrRemoved(IResourceDelta delta) {
566 // IResource resource = delta.getResource();
567 // switch (resource.getType()) {
568 // case IResource.ROOT :
569 // // workaround for bug 15168 circular errors not reported
570 // if (this.manager.javaProjectsCache == null) {
572 // this.manager.javaProjectsCache =
573 // this.manager.getJavaModel().getJavaProjects();
574 // } catch (JavaModelException e) {
578 // IResourceDelta[] children = delta.getAffectedChildren();
579 // for (int i = 0, length = children.length; i < length; i++) {
580 // this.checkProjectsBeingAddedOrRemoved(children[i]);
583 // case IResource.PROJECT :
584 // // NB: No need to check project's nature as if the project is not a java
586 // // - if the project is added or changed this is a noop for
587 // projectsBeingDeleted
588 // // - if the project is closed, it has already lost its java nature
589 // int deltaKind = delta.getKind();
590 // if (deltaKind == IResourceDelta.ADDED) {
591 // // remember project and its dependents
592 // IProject project = (IProject)resource;
593 // this.addToProjectsToUpdateWithDependents(project);
595 // // workaround for bug 15168 circular errors not reported
596 // if (JavaProject.hasJavaNature(project)) {
597 // this.addToParentInfo((JavaProject)JavaCore.create(project));
600 // } else if (deltaKind == IResourceDelta.CHANGED) {
601 // IProject project = (IProject)resource;
602 // if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
603 // // project opened or closed: remember project and its dependents
604 // this.addToProjectsToUpdateWithDependents(project);
606 // // workaround for bug 15168 circular errors not reported
607 // if (project.isOpen()) {
608 // if (JavaProject.hasJavaNature(project)) {
609 // this.addToParentInfo((JavaProject)JavaCore.create(project));
612 // JavaProject javaProject =
613 // (JavaProject)this.manager.getJavaModel().findJavaProject(project);
614 // if (javaProject != null) {
616 // javaProject.close();
617 // } catch (JavaModelException e) {
619 // this.removeFromParentInfo(javaProject);
622 // } else if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) {
623 // boolean wasJavaProject =
624 // this.manager.getJavaModel().findJavaProject(project) != null;
625 // boolean isJavaProject = JavaProject.hasJavaNature(project);
626 // if (wasJavaProject != isJavaProject) {
627 // // java nature added or removed: remember project and its dependents
628 // this.addToProjectsToUpdateWithDependents(project);
630 // // workaround for bug 15168 circular errors not reported
631 // if (isJavaProject) {
632 // this.addToParentInfo((JavaProject)JavaCore.create(project));
634 // JavaProject javaProject = (JavaProject)JavaCore.create(project);
636 // // flush classpath markers
638 // flushClasspathProblemMarkers(
639 // true, // flush cycle markers
640 // true //flush classpath format markers
643 // // remove problems and tasks created by the builder
644 // JavaBuilder.removeProblemsAndTasksFor(project);
648 // javaProject.close();
649 // } catch (JavaModelException e) {
651 // this.removeFromParentInfo(javaProject);
654 // // in case the project was removed then added then changed (see bug
656 // if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
657 // this.addToParentInfo((JavaProject)JavaCore.create(project));
661 // // workaround for bug 15168 circular errors not reported
662 // // in case the project was removed then added then changed
663 // if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
664 // this.addToParentInfo((JavaProject)JavaCore.create(project));
671 // private void checkSourceAttachmentChange(IResourceDelta delta, IResource
673 // IPath rootPath = (IPath)this.sourceAttachments.get(res.getFullPath());
674 // if (rootPath != null) {
675 // RootInfo rootInfo = this.rootInfo(rootPath, delta.getKind());
676 // if (rootInfo != null) {
677 // IJavaProject projectOfRoot = rootInfo.project;
678 // IPackageFragmentRoot root = null;
680 // // close the root so that source attachement cache is flushed
681 // root = projectOfRoot.findPackageFragmentRoot(rootPath);
682 // if (root != null) {
685 // } catch (JavaModelException e) {
687 // if (root == null) return;
688 // switch (delta.getKind()) {
689 // case IResourceDelta.ADDED:
690 // currentDelta().sourceAttached(root);
692 // case IResourceDelta.CHANGED:
693 // currentDelta().sourceDetached(root);
694 // currentDelta().sourceAttached(root);
696 // case IResourceDelta.REMOVED:
697 // currentDelta().sourceDetached(root);
704 * Closes the given element, which removes it from the cache of open
707 // protected static void close(Openable element) {
711 // } catch (JavaModelException e) {
716 * Generic processing for elements with changed contents:
718 * <li>The element is closed such that any subsequent accesses will re-open
719 * the element reflecting its new structure.
720 * <li>An entry is made in the delta reporting a content change (K_CHANGE
721 * with F_CONTENT flag set).
723 * Delta argument could be null if processing an external JAR change
725 // protected void contentChanged(Openable element, IResourceDelta delta) {
728 // int flags = IJavaElementDelta.F_CONTENT;
729 // if (element instanceof JarPackageFragmentRoot){
730 // flags |= IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED;
732 // currentDelta().changed(element, flags);
736 * Creates the openables corresponding to this resource. Returns null if
739 // protected Openable createElement(IResource resource, int elementType,
740 // RootInfo rootInfo) {
741 // if (resource == null) return null;
743 // IPath path = resource.getFullPath();
744 // IJavaElement element = null;
745 // switch (elementType) {
747 // case IJavaElement.JAVA_PROJECT:
749 // // note that non-java resources rooted at the project level will also
750 // enter this code with
751 // // an elementType JAVA_PROJECT (see #elementType(...)).
752 // if (resource instanceof IProject){
754 // this.popUntilPrefixOf(path);
756 // if (this.currentElement != null
757 // && this.currentElement.getElementType() == IJavaElement.JAVA_PROJECT
758 // && ((IJavaProject)this.currentElement).getProject().equals(resource)) {
759 // return this.currentElement;
761 // if (rootInfo != null && rootInfo.project.getProject().equals(resource)){
762 // element = (Openable)rootInfo.project;
765 // IProject proj = (IProject)resource;
766 // if (JavaProject.hasJavaNature(proj)) {
767 // element = JavaCore.create(proj);
769 // // java project may have been been closed or removed (look for
770 // // element amongst old java project s list).
771 // element = (Openable) manager.getJavaModel().findJavaProject(proj);
775 // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
776 // element = rootInfo == null ? JavaCore.create(resource) :
777 // rootInfo.project.getPackageFragmentRoot(resource);
779 // case IJavaElement.PACKAGE_FRAGMENT:
780 // // find the element that encloses the resource
781 // this.popUntilPrefixOf(path);
783 // if (this.currentElement == null) {
784 // element = rootInfo == null ? JavaCore.create(resource) :
785 // JavaModelManager.create(resource, rootInfo.project);
788 // IPackageFragmentRoot root = this.currentElement.getPackageFragmentRoot();
789 // if (root == null) {
790 // element = rootInfo == null ? JavaCore.create(resource) :
791 // JavaModelManager.create(resource, rootInfo.project);
792 // } else if (((JavaProject)root.getJavaProject()).contains(resource)) {
793 // // create package handle
794 // IPath pkgPath = path.removeFirstSegments(root.getPath().segmentCount());
795 // String pkg = ProjectPrefUtil.packageName(pkgPath);
796 // if (pkg == null) return null;
797 // element = root.getPackageFragment(pkg);
801 // case IJavaElement.COMPILATION_UNIT:
802 // case IJavaElement.CLASS_FILE:
803 // // find the element that encloses the resource
804 // this.popUntilPrefixOf(path);
806 // if (this.currentElement == null) {
807 // element = rootInfo == null ? JavaCore.create(resource) :
808 // JavaModelManager.create(resource, rootInfo.project);
810 // // find the package
811 // IPackageFragment pkgFragment = null;
812 // switch (this.currentElement.getElementType()) {
813 // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
814 // IPackageFragmentRoot root = (IPackageFragmentRoot)this.currentElement;
815 // IPath rootPath = root.getPath();
816 // IPath pkgPath = path.removeLastSegments(1);
818 // ProjectPrefUtil.packageName(pkgPath.removeFirstSegments(rootPath.segmentCount()));
819 // if (pkgName != null) {
820 // pkgFragment = root.getPackageFragment(pkgName);
823 // case IJavaElement.PACKAGE_FRAGMENT:
824 // Openable pkg = (Openable)this.currentElement;
825 // if (pkg.getPath().equals(path.removeLastSegments(1))) {
826 // pkgFragment = (IPackageFragment)pkg;
827 // } // else case of package x which is a prefix of x.y
829 // case IJavaElement.COMPILATION_UNIT:
830 // case IJavaElement.CLASS_FILE:
831 // pkgFragment = (IPackageFragment)this.currentElement.getParent();
834 // if (pkgFragment == null) {
835 // element = rootInfo == null ? JavaCore.create(resource) :
836 // JavaModelManager.create(resource, rootInfo.project);
838 // if (elementType == IJavaElement.COMPILATION_UNIT) {
839 // // create compilation unit handle
840 // // fileName validation has been done in elementType(IResourceDelta, int,
842 // String fileName = path.lastSegment();
843 // element = pkgFragment.getCompilationUnit(fileName);
845 // // create class file handle
846 // // fileName validation has been done in elementType(IResourceDelta, int,
848 // String fileName = path.lastSegment();
849 // element = pkgFragment.getClassFile(fileName);
855 // if (element == null) {
858 // this.currentElement = (Openable)element;
859 // return this.currentElement;
863 * Note that the project is about to be deleted.
865 // public void deleting(IProject project) {
868 // // discard indexing jobs that belong to this project so that the project
870 // // deleted without interferences from the index manager
871 // this.indexManager.discardJobs(project.getName());
873 // JavaProject javaProject = (JavaProject)JavaCore.create(project);
875 // // remember roots of this project
876 // if (this.removedRoots == null) {
877 // this.removedRoots = new HashMap();
879 // if (javaProject.isOpen()) {
880 // this.removedRoots.put(javaProject,
881 // javaProject.getPackageFragmentRoots());
883 // // compute roots without opening project
884 // this.removedRoots.put(
886 // javaProject.computePackageFragmentRoots(
887 // javaProject.getResolvedClasspath(true),
891 // javaProject.close();
893 // // workaround for bug 15168 circular errors not reported
894 // if (this.manager.javaProjectsCache == null) {
895 // this.manager.javaProjectsCache =
896 // this.manager.getJavaModel().getJavaProjects();
898 // this.removeFromParentInfo(javaProject);
900 // } catch (JavaModelException e) {
903 // this.addDependentProjects(project.getFullPath(), this.projectsToUpdate);
907 * Processing for an element that has been added:
909 * <li>If the element is a project, do nothing, and do not process
910 * children, as when a project is created it does not yet have any natures -
911 * specifically a java nature.
912 * <li>If the elemet is not a project, process it as added (see
913 * <code>basicElementAdded</code>.
915 * Delta argument could be null if processing an external JAR change
917 // protected void elementAdded(Openable element, IResourceDelta delta,
918 // RootInfo rootInfo) {
919 // int elementType = element.getElementType();
921 // if (elementType == IJavaElement.JAVA_PROJECT) {
922 // // project add is handled by JavaProject.configure() because
923 // // when a project is created, it does not yet have a java nature
924 // if (delta != null &&
925 // JavaProject.hasJavaNature((IProject)delta.getResource())) {
926 // addToParentInfo(element);
927 // if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
928 // Openable movedFromElement =
929 // (Openable)element.getJavaModel().getJavaProject(delta.getMovedFromPath().lastSegment());
930 // currentDelta().movedTo(element, movedFromElement);
932 // currentDelta().added(element);
934 // this.projectsToUpdate.add(element);
935 // this.updateRoots(element.getPath(), delta);
936 // this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
939 // addToParentInfo(element);
941 // // Force the element to be closed as it might have been opened
942 // // before the resource modification came in and it might have a new child
943 // // For example, in an IWorkspaceRunnable:
944 // // 1. create a package fragment p using a java model operation
945 // // 2. open package p
946 // // 3. add file X.java in folder p
947 // // When the resource delta comes in, only the addition of p is notified,
948 // // but the package p is already opened, thus its children are not
950 // // and it appears empty.
953 // if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_FROM) != 0)
955 // IPath movedFromPath = delta.getMovedFromPath();
956 // IResource res = delta.getResource();
957 // IResource movedFromRes;
958 // if (res instanceof IFile) {
959 // movedFromRes = res.getWorkspace().getRoot().getFile(movedFromPath);
961 // movedFromRes = res.getWorkspace().getRoot().getFolder(movedFromPath);
964 // // find the element type of the moved from element
965 // RootInfo movedFromInfo = this.enclosingRootInfo(movedFromPath,
966 // IResourceDelta.REMOVED);
967 // int movedFromType =
970 // IResourceDelta.REMOVED,
971 // element.getParent().getElementType(),
974 // // reset current element as it might be inside a nested root
975 // (popUntilPrefixOf() may use the outer root)
976 // this.currentElement = null;
978 // // create the moved from element
979 // Openable movedFromElement =
980 // elementType != IJavaElement.JAVA_PROJECT && movedFromType ==
981 // IJavaElement.JAVA_PROJECT ?
982 // null : // outside classpath
983 // this.createElement(movedFromRes, movedFromType, movedFromInfo);
984 // if (movedFromElement == null) {
985 // // moved from outside classpath
986 // currentDelta().added(element);
988 // currentDelta().movedTo(element, movedFromElement);
991 // currentDelta().added(element);
994 // switch (elementType) {
995 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
996 // // when a root is added, and is on the classpath, the project must be
998 // JavaProject project = (JavaProject) element.getJavaProject();
999 // this.projectsToUpdate.add(project);
1000 // this.projectsForDependentNamelookupRefresh.add(project);
1003 // case IJavaElement.PACKAGE_FRAGMENT :
1004 // // get rid of namelookup since it holds onto obsolete cached info
1005 // project = (JavaProject) element.getJavaProject();
1007 // project.getJavaProjectElementInfo().setNameLookup(null);
1008 // this.projectsForDependentNamelookupRefresh.add(project);
1009 // } catch (JavaModelException e) {
1011 // // add subpackages
1012 // if (delta != null){
1013 // PackageFragmentRoot root = element.getPackageFragmentRoot();
1014 // String name = element.getElementName();
1015 // IResourceDelta[] children = delta.getAffectedChildren();
1016 // for (int i = 0, length = children.length; i < length; i++) {
1017 // IResourceDelta child = children[i];
1018 // IResource resource = child.getResource();
1019 // if (resource instanceof IFolder) {
1020 // String folderName = resource.getName();
1021 // if (ProjectPrefUtil.isValidFolderNameForPackage(folderName)) {
1022 // String subpkgName =
1023 // name.length() == 0 ?
1025 // name + "." + folderName; //$NON-NLS-1$
1026 // Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
1027 // this.updateIndex(subpkg, child);
1028 // this.elementAdded(subpkg, child, rootInfo);
1038 * Generic processing for a removed element:
1040 * <li>Close the element, removing its structure from the cache
1041 * <li>Remove the element from its parent's cache of children
1042 * <li>Add a REMOVED entry in the delta
1044 * Delta argument could be null if processing an external JAR change
1046 // protected void elementRemoved(Openable element, IResourceDelta delta,
1047 // RootInfo rootInfo) {
1049 // if (element.isOpen()) {
1052 // removeFromParentInfo(element);
1053 // int elementType = element.getElementType();
1054 // if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
1055 // IPath movedToPath = delta.getMovedToPath();
1056 // IResource res = delta.getResource();
1057 // IResource movedToRes;
1058 // switch (res.getType()) {
1059 // case IResource.PROJECT:
1061 // res.getWorkspace().getRoot().getProject(movedToPath.lastSegment());
1063 // case IResource.FOLDER:
1064 // movedToRes = res.getWorkspace().getRoot().getFolder(movedToPath);
1066 // case IResource.FILE:
1067 // movedToRes = res.getWorkspace().getRoot().getFile(movedToPath);
1073 // // find the element type of the moved from element
1074 // RootInfo movedToInfo = this.enclosingRootInfo(movedToPath,
1075 // IResourceDelta.ADDED);
1076 // int movedToType =
1077 // this.elementType(
1079 // IResourceDelta.ADDED,
1080 // element.getParent().getElementType(),
1083 // // reset current element as it might be inside a nested root
1084 // (popUntilPrefixOf() may use the outer root)
1085 // this.currentElement = null;
1087 // // create the moved To element
1088 // Openable movedToElement =
1089 // elementType != IJavaElement.JAVA_PROJECT && movedToType ==
1090 // IJavaElement.JAVA_PROJECT ?
1091 // null : // outside classpath
1092 // this.createElement(movedToRes, movedToType, movedToInfo);
1093 // if (movedToElement == null) {
1094 // // moved outside classpath
1095 // currentDelta().removed(element);
1097 // currentDelta().movedFrom(element, movedToElement);
1100 // currentDelta().removed(element);
1103 // switch (elementType) {
1104 // case IJavaElement.JAVA_MODEL :
1105 // this.indexManager.reset();
1107 // case IJavaElement.JAVA_PROJECT :
1108 // this.manager.removePerProjectInfo(
1109 // (JavaProject) element);
1110 // this.updateRoots(element.getPath(), delta);
1111 // this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
1113 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
1114 // JavaProject project = (JavaProject) element.getJavaProject();
1115 // this.projectsToUpdate.add(project);
1116 // this.projectsForDependentNamelookupRefresh.add(project);
1118 // case IJavaElement.PACKAGE_FRAGMENT :
1119 // //1G1TW2T - get rid of namelookup since it holds onto obsolete cached
1121 // project = (JavaProject) element.getJavaProject();
1123 // project.getJavaProjectElementInfo().setNameLookup(null);
1124 // this.projectsForDependentNamelookupRefresh.add(project);
1125 // } catch (JavaModelException e) {
1127 // // remove subpackages
1128 // if (delta != null){
1129 // PackageFragmentRoot root = element.getPackageFragmentRoot();
1130 // String name = element.getElementName();
1131 // IResourceDelta[] children = delta.getAffectedChildren();
1132 // for (int i = 0, length = children.length; i < length; i++) {
1133 // IResourceDelta child = children[i];
1134 // IResource resource = child.getResource();
1135 // if (resource instanceof IFolder) {
1136 // String folderName = resource.getName();
1137 // if (ProjectPrefUtil.isValidFolderNameForPackage(folderName)) {
1138 // String subpkgName =
1139 // name.length() == 0 ?
1141 // name + "." + folderName; //$NON-NLS-1$
1142 // Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
1143 // this.updateIndex(subpkg, child);
1144 // this.elementRemoved(subpkg, child, rootInfo);
1153 * Returns the type of the java element the given delta matches to. Returns
1154 * NON_JAVA_RESOURCE if unknown (e.g. a non-java resource or excluded .java
1157 // private int elementType(IResource res, int kind, int parentType, RootInfo
1159 // switch (parentType) {
1160 // case IJavaElement.JAVA_MODEL:
1161 // // case of a movedTo or movedFrom project (other cases are handled in
1162 // processResourceDelta(...)
1163 // return IJavaElement.JAVA_PROJECT;
1164 // case NON_JAVA_RESOURCE:
1165 // case IJavaElement.JAVA_PROJECT:
1166 // if (rootInfo == null) {
1167 // rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
1169 // if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
1170 // return IJavaElement.PACKAGE_FRAGMENT_ROOT;
1172 // return NON_JAVA_RESOURCE; // not yet in a package fragment root or root
1173 // of another project
1175 // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
1176 // case IJavaElement.PACKAGE_FRAGMENT:
1177 // if (rootInfo == null) {
1178 // rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
1180 // if (rootInfo == null || ProjectPrefUtil.isExcluded(res,
1181 // rootInfo.exclusionPatterns)) {
1182 // return NON_JAVA_RESOURCE;
1184 // if (res instanceof IFolder) {
1185 // if (ProjectPrefUtil.isValidFolderNameForPackage(res.getName())) {
1186 // return IJavaElement.PACKAGE_FRAGMENT;
1188 // return NON_JAVA_RESOURCE;
1191 // String fileName = res.getName();
1192 // if (ProjectPrefUtil.isValidCompilationUnitName(fileName)) {
1193 // return IJavaElement.COMPILATION_UNIT;
1194 // } else if (ProjectPrefUtil.isValidClassFileName(fileName)) {
1195 // return IJavaElement.CLASS_FILE;
1196 // } else if (this.rootInfo(res.getFullPath(), kind) != null) {
1197 // // case of proj=src=bin and resource is a jar file on the classpath
1198 // return IJavaElement.PACKAGE_FRAGMENT_ROOT;
1200 // return NON_JAVA_RESOURCE;
1204 // return NON_JAVA_RESOURCE;
1208 * Answer a combination of the lastModified stamp and the size. Used for
1209 * detecting external JAR changes
1211 public static long getTimeStamp(File file) {
1212 return file.lastModified() + file.length();
1215 public void initializeRoots() {
1216 // remember roots infos as old roots infos
1217 this.oldRoots = this.roots == null ? new HashMap() : this.roots;
1218 this.oldOtherRoots = this.otherRoots == null ? new HashMap()
1221 // recompute root infos only if necessary
1225 this.roots = new HashMap();
1226 this.otherRoots = new HashMap();
1227 this.sourceAttachments = new HashMap();
1229 IJavaModel model = this.manager.getJavaModel();
1230 IJavaProject[] projects;
1232 projects = model.getJavaProjects();
1233 } catch (JavaModelException e) {
1234 // nothing can be done
1237 for (int i = 0, length = projects.length; i < length; i++) {
1238 IJavaProject project = projects[i];
1239 IClasspathEntry[] classpath;
1241 classpath = project.getResolvedClasspath(true);
1242 } catch (JavaModelException e) {
1243 // continue with next project
1246 for (int j = 0, classpathLength = classpath.length; j < classpathLength; j++) {
1247 IClasspathEntry entry = classpath[j];
1248 if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT)
1252 IPath path = entry.getPath();
1253 if (this.roots.get(path) == null) {
1254 this.roots.put(path, new RootInfo(project, path,
1255 ((ClasspathEntry) entry)
1256 .fullExclusionPatternChars()));
1258 ArrayList rootList = (ArrayList) this.otherRoots.get(path);
1259 if (rootList == null) {
1260 rootList = new ArrayList();
1261 this.otherRoots.put(path, rootList);
1263 rootList.add(new RootInfo(project, path,
1264 ((ClasspathEntry) entry)
1265 .fullExclusionPatternChars()));
1268 // source attachment path
1269 if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY)
1271 QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID,
1272 "sourceattachment: " + path.toOSString()); //$NON-NLS-1$;
1273 String propertyString = null;
1275 propertyString = ResourcesPlugin.getWorkspace().getRoot()
1276 .getPersistentProperty(qName);
1277 } catch (CoreException e) {
1280 IPath sourceAttachmentPath;
1281 // if (propertyString != null) {
1283 // propertyString.lastIndexOf(JarPackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER);
1284 // sourceAttachmentPath = (index < 0) ? new Path(propertyString)
1285 // : new Path(propertyString.substring(0, index));
1287 sourceAttachmentPath = entry.getSourceAttachmentPath();
1289 if (sourceAttachmentPath != null) {
1290 this.sourceAttachments.put(sourceAttachmentPath, path);
1294 this.rootsAreStale = false;
1298 * Returns whether a given delta contains some information relevant to the
1299 * JavaModel, in particular it will not consider SYNC or MARKER only deltas.
1301 public boolean isAffectedBy(IResourceDelta rootDelta) {
1302 // if (rootDelta == null) System.out.println("NULL DELTA");
1303 // long start = System.currentTimeMillis();
1304 if (rootDelta != null) {
1305 // use local exception to quickly escape from delta traversal
1306 class FoundRelevantDeltaException extends RuntimeException {
1309 rootDelta.accept(new IResourceDeltaVisitor() {
1310 public boolean visit(IResourceDelta delta)
1311 throws CoreException {
1312 switch (delta.getKind()) {
1313 case IResourceDelta.ADDED:
1314 case IResourceDelta.REMOVED:
1315 throw new FoundRelevantDeltaException();
1316 case IResourceDelta.CHANGED:
1317 // if any flag is set but SYNC or MARKER, this delta
1318 // should be considered
1319 if (delta.getAffectedChildren().length == 0 // only
1324 && (delta.getFlags() & ~(IResourceDelta.SYNC | IResourceDelta.MARKERS)) != 0) {
1325 throw new FoundRelevantDeltaException();
1331 } catch (FoundRelevantDeltaException e) {
1332 // System.out.println("RELEVANT DELTA detected in: "+
1333 // (System.currentTimeMillis() - start));
1335 } catch (CoreException e) { // ignore delta if not able to traverse
1338 // System.out.println("IGNORE SYNC DELTA took: "+
1339 // (System.currentTimeMillis() - start));
1344 * Returns whether the given resource is in one of the given output folders
1345 * and if it is filtered out from this output folder.
1347 private boolean isResFilteredFromOutput(OutputsInfo info, IResource res,
1350 IPath resPath = res.getFullPath();
1351 for (int i = 0; i < info.outputCount; i++) {
1352 if (info.paths[i].isPrefixOf(resPath)) {
1353 if (info.traverseModes[i] != IGNORE) {
1355 if (info.traverseModes[i] == SOURCE
1356 && elementType == IJavaElement.CLASS_FILE) {
1359 // case of .class file under project and no source
1362 if (elementType == IJavaElement.JAVA_PROJECT
1363 && res instanceof IFile
1364 && PHPFileUtil.isPHPFile((IFile) res)) {
1378 * Merges all awaiting deltas.
1380 private IJavaElementDelta mergeDeltas(Collection deltas) {
1381 if (deltas.size() == 0)
1383 if (deltas.size() == 1)
1384 return (IJavaElementDelta) deltas.iterator().next();
1388 .println("MERGING " + deltas.size() + " DELTAS [" + Thread.currentThread() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1391 Iterator iterator = deltas.iterator();
1392 JavaElementDelta rootDelta = new JavaElementDelta(
1393 this.manager.javaModel);
1394 boolean insertedTree = false;
1395 while (iterator.hasNext()) {
1396 JavaElementDelta delta = (JavaElementDelta) iterator.next();
1398 System.out.println(delta.toString());
1400 IJavaElement element = delta.getElement();
1401 if (this.manager.javaModel.equals(element)) {
1402 IJavaElementDelta[] children = delta.getAffectedChildren();
1403 for (int j = 0; j < children.length; j++) {
1404 JavaElementDelta projectDelta = (JavaElementDelta) children[j];
1405 rootDelta.insertDeltaTree(projectDelta.getElement(),
1407 insertedTree = true;
1409 IResourceDelta[] resourceDeltas = delta.getResourceDeltas();
1410 if (resourceDeltas != null) {
1411 for (int i = 0, length = resourceDeltas.length; i < length; i++) {
1412 rootDelta.addResourceDelta(resourceDeltas[i]);
1413 insertedTree = true;
1417 rootDelta.insertDeltaTree(element, delta);
1418 insertedTree = true;
1427 * Check whether the updated file is affecting some of the properties of a
1428 * given project (like its classpath persisted as a file). Also force
1429 * classpath problems to be refresh if not running in autobuild mode. NOTE:
1430 * It can induce resource changes, and cannot be called during POST_CHANGE
1434 // public void performPreBuildCheck(
1435 // IResourceDelta delta,
1436 // IJavaElement parent) {
1438 // IResource resource = delta.getResource();
1439 // IJavaElement element = null;
1440 // boolean processChildren = false;
1442 // switch (resource.getType()) {
1444 // case IResource.ROOT :
1445 // if (delta.getKind() == IResourceDelta.CHANGED) {
1446 // element = JavaCore.create(resource);
1447 // processChildren = true;
1450 // case IResource.PROJECT :
1451 // int kind = delta.getKind();
1453 // case IResourceDelta.CHANGED:
1454 // // do not visit non-java projects (see bug 16140 Non-java project gets
1456 // IProject project = (IProject)resource;
1457 // if (JavaProject.hasJavaNature(project)) {
1458 // element = JavaCore.create(resource);
1459 // processChildren = true;
1461 // (JavaModelManager.getJavaModelManager().getJavaModel().findJavaProject(project)
1463 // // project had the java nature
1464 // this.rootsAreStale = true;
1466 // // remove classpath cache so that initializeRoots() will not consider the
1467 // project has a classpath
1468 // this.manager.removePerProjectInfo((JavaProject)JavaCore.create(project));
1471 // case IResourceDelta.ADDED:
1472 // this.rootsAreStale = true;
1474 // case IResourceDelta.REMOVED:
1475 // // remove classpath cache so that initializeRoots() will not consider the
1476 // project has a classpath
1477 // this.manager.removePerProjectInfo((JavaProject)JavaCore.create(resource));
1479 // this.rootsAreStale = true;
1483 // case IResource.FILE :
1484 // if (parent.getElementType() == IJavaElement.JAVA_PROJECT) {
1485 // IFile file = (IFile) resource;
1486 // JavaProject project = (JavaProject) parent;
1488 // /* check classpath file change */
1489 // if (file.getName().equals(JavaProject.CLASSPATH_FILENAME)) {
1490 // reconcileClasspathFileUpdate(delta, file, project);
1491 // this.rootsAreStale = true;
1494 // // /* check custom preference file change */
1495 // // if (file.getName().equals(JavaProject.PREF_FILENAME)) {
1496 // // reconcilePreferenceFileUpdate(delta, file, project);
1502 // if (processChildren) {
1503 // IResourceDelta[] children = delta.getAffectedChildren();
1504 // for (int i = 0; i < children.length; i++) {
1505 // performPreBuildCheck(children[i], element);
1509 // private void popUntilPrefixOf(IPath path) {
1510 // while (this.currentElement != null) {
1511 // IPath currentElementPath = null;
1512 // if (this.currentElement instanceof IPackageFragmentRoot) {
1513 // currentElementPath =
1514 // ((IPackageFragmentRoot)this.currentElement).getPath();
1516 // IResource currentElementResource = this.currentElement.getResource();
1517 // if (currentElementResource != null) {
1518 // currentElementPath = currentElementResource.getFullPath();
1521 // if (currentElementPath != null) {
1522 // if (this.currentElement instanceof IPackageFragment
1523 // && this.currentElement.getElementName().length() == 0
1524 // && currentElementPath.segmentCount() != path.segmentCount()-1) {
1525 // // default package and path is not a direct child
1526 // this.currentElement = (Openable)this.currentElement.getParent();
1528 // if (currentElementPath.isPrefixOf(path)) {
1532 // this.currentElement = (Openable)this.currentElement.getParent();
1536 * Converts a <code>IResourceDelta</code> rooted in a
1537 * <code>Workspace</code> into the corresponding set of
1538 * <code>IJavaElementDelta</code>, rooted in the relevant
1539 * <code>JavaModel</code>s.
1543 * Update the JavaModel according to a .classpath file change. The file can
1544 * have changed as a result of a previous call to
1545 * JavaProject#setRawClasspath or as a result of some user update (through
1548 // void reconcileClasspathFileUpdate(IResourceDelta delta, IFile file,
1549 // JavaProject project) {
1551 // switch (delta.getKind()) {
1552 // case IResourceDelta.REMOVED : // recreate one based on in-memory
1555 // JavaModelManager.PerProjectInfo info =
1556 // JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
1557 // if (info.classpath != null) { // if there is an in-memory classpath
1558 // project.saveClasspath(info.classpath, info.outputLocation);
1560 // } catch (JavaModelException e) {
1561 // if (project.getProject().isAccessible()) {
1562 // ProjectPrefUtil.log(e, "Could not save classpath for "+
1563 // project.getPath()); //$NON-NLS-1$
1567 // case IResourceDelta.CHANGED :
1568 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0 // only consider
1570 // && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move
1571 // and overide scenario (see
1572 // http://dev.eclipse.org/bugs/show_bug.cgi?id=21420)
1574 // case IResourceDelta.ADDED :
1575 // // check if any actual difference
1576 // project.flushClasspathProblemMarkers(false, true);
1577 // boolean wasSuccessful = false; // flag recording if .classpath file
1578 // change got reflected
1580 // // force to (re)read the property file
1581 // IClasspathEntry[] fileEntries = project.readClasspathFile(true/*create
1582 // markers*/, false/*don't log problems*/);
1583 // if (fileEntries == null)
1584 // break; // could not read, ignore
1585 // JavaModelManager.PerProjectInfo info =
1586 // JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
1587 // if (info.classpath != null) { // if there is an in-memory classpath
1588 // if (project.isClasspathEqualsTo(info.classpath, info.outputLocation,
1590 // wasSuccessful = true;
1595 // // will force an update of the classpath/output location based on the
1597 // // extract out the output location
1598 // IPath outputLocation = null;
1599 // if (fileEntries != null && fileEntries.length > 0) {
1600 // IClasspathEntry entry = fileEntries[fileEntries.length - 1];
1601 // if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
1602 // outputLocation = entry.getPath();
1603 // IClasspathEntry[] copy = new IClasspathEntry[fileEntries.length - 1];
1604 // System.arraycopy(fileEntries, 0, copy, 0, copy.length);
1605 // fileEntries = copy;
1608 // // restore output location
1609 // if (outputLocation == null) {
1610 // outputLocation = SetClasspathOperation.ReuseOutputLocation;
1611 // // clean mode will also default to reusing current one
1613 // project.setRawClasspath(
1617 // true, // canChangeResource
1618 // project.getResolvedClasspath(true), // ignoreUnresolvedVariable
1619 // true, // needValidation
1620 // false); // no need to save
1622 // // if reach that far, the classpath file change got absorbed
1623 // wasSuccessful = true;
1624 // } catch (RuntimeException e) {
1625 // // setRawClasspath might fire a delta, and a listener may throw an
1627 // if (project.getProject().isAccessible()) {
1628 // ProjectPrefUtil.log(e, "Could not set classpath for "+
1629 // project.getPath()); //$NON-NLS-1$
1632 // } catch (JavaModelException e) { // CP failed validation
1633 // if (project.getProject().isAccessible()) {
1634 // if (e.getJavaModelStatus().getException() instanceof CoreException) {
1635 // // happens if the .classpath could not be written to disk
1636 // project.createClasspathProblemMarker(new JavaModelStatus(
1637 // IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1638 // ProjectPrefUtil.bind("classpath.couldNotWriteClasspathFile",
1639 // project.getElementName(), e.getMessage()))); //$NON-NLS-1$
1641 // project.createClasspathProblemMarker(new JavaModelStatus(
1642 // IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1643 // ProjectPrefUtil.bind("classpath.invalidClasspathInClasspathFile",
1644 // project.getElementName(), e.getMessage()))); //$NON-NLS-1$
1649 // if (!wasSuccessful) {
1651 // project.setRawClasspath0(JavaProject.INVALID_CLASSPATH);
1652 // project.updatePackageFragmentRoots();
1653 // } catch (JavaModelException e) {
1660 * Update the JavaModel according to a .jprefs file change. The file can
1661 * have changed as a result of a previous call to JavaProject#setOptions or
1662 * as a result of some user update (through repository) Unused until
1663 * preference file get shared (.jpref)
1665 // void reconcilePreferenceFileUpdate(IResourceDelta delta, IFile file,
1666 // JavaProject project) {
1668 // switch (delta.getKind()) {
1669 // case IResourceDelta.REMOVED : // flush project custom settings
1670 // project.setOptions(null);
1672 // case IResourceDelta.CHANGED :
1673 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0 // only consider
1675 // && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move
1676 // and overide scenario
1678 // identityCheck : { // check if any actual difference
1679 // // force to (re)read the property file
1680 // Preferences filePreferences = project.loadPreferences();
1681 // if (filePreferences == null){
1682 // project.setOptions(null); // should have got removed delta.
1685 // Preferences projectPreferences = project.getPreferences();
1686 // if (projectPreferences == null) return; // not a Java project
1688 // // compare preferences set to their default
1689 // String[] defaultProjectPropertyNames =
1690 // projectPreferences.defaultPropertyNames();
1691 // String[] defaultFilePropertyNames =
1692 // filePreferences.defaultPropertyNames();
1693 // if (defaultProjectPropertyNames.length ==
1694 // defaultFilePropertyNames.length) {
1695 // for (int i = 0; i < defaultProjectPropertyNames.length; i++){
1696 // String propertyName = defaultProjectPropertyNames[i];
1698 // (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1699 // break identityCheck;
1702 // } else break identityCheck;
1704 // // compare custom preferences not set to their default
1705 // String[] projectPropertyNames = projectPreferences.propertyNames();
1706 // String[] filePropertyNames = filePreferences.propertyNames();
1707 // if (projectPropertyNames.length == filePropertyNames.length) {
1708 // for (int i = 0; i < projectPropertyNames.length; i++){
1709 // String propertyName = projectPropertyNames[i];
1711 // (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1712 // break identityCheck;
1715 // } else break identityCheck;
1717 // // identical - do nothing
1720 // case IResourceDelta.ADDED :
1721 // // not identical, create delta and reset cached preferences
1722 // project.setPreferences(null);
1724 // //fCurrentDelta.changed(project, IJavaElementDelta.F_OPTIONS_CHANGED);
1728 * Registers the given delta with this delta processor.
1730 public void registerJavaModelDelta(IJavaElementDelta delta) {
1731 this.javaModelDeltas.add(delta);
1735 * Removes the given element from its parents cache of children. If the
1736 * element does not have a parent, or the parent is not currently open, this
1739 protected void removeFromParentInfo(Openable child) {
1741 Openable parent = (Openable) child.getParent();
1742 if (parent != null && parent.isOpen()) {
1744 JavaElementInfo info = (JavaElementInfo) parent
1746 info.removeChild(child);
1747 } catch (JavaModelException e) {
1748 // do nothing - we already checked if open
1754 * Notification that some resource changes have happened on the platform,
1755 * and that the Java Model should update any required internal structures
1756 * such that its elements remain consistent. Translates
1757 * <code>IResourceDeltas</code> into <code>IJavaElementDeltas</code>.
1759 * @see IResourceDelta
1762 public void resourceChanged(IResourceChangeEvent event) {
1763 if (event.getSource() instanceof IWorkspace) {
1764 int eventType = this.overridenEventType == -1 ? event.getType()
1765 : this.overridenEventType;
1766 IResource resource = event.getResource();
1767 IResourceDelta delta = event.getDelta();
1769 switch (eventType) {
1770 case IResourceChangeEvent.PRE_DELETE:
1772 if (resource.getType() == IResource.PROJECT
1773 && ((IProject) resource)
1774 .hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
1776 deleting((IProject) resource);
1778 } catch (CoreException e) {
1779 // project doesn't exist or is not open: ignore
1783 case IResourceChangeEvent.POST_CHANGE:
1784 if (isAffectedBy(delta)) { // avoid populating for SYNC or
1789 // checkProjectsBeingAddedOrRemoved(delta);
1790 // if (this.refreshedElements != null) {
1791 // createExternalArchiveDelta(null);
1793 IJavaElementDelta translatedDelta = processResourceDelta(delta);
1794 if (translatedDelta != null) {
1795 registerJavaModelDelta(translatedDelta);
1800 // notifyTypeHierarchies(this.state.elementChangedListeners,
1801 // this.state.elementChangedListenerCount);
1802 fire(null, ElementChangedEvent.POST_CHANGE);
1804 // workaround for bug 15168 circular errors not reported
1805 this.state.modelProjectsCache = null;
1806 this.removedRoots = null;
1811 case IResourceChangeEvent.PRE_BUILD:
1812 DeltaProcessingState.ProjectUpdateInfo[] updates = this.state
1813 .removeAllProjectUpdates();
1814 if (updates != null) {
1815 for (int i = 0, length = updates.length; i < length; i++) {
1817 updates[i].updateProjectReferencesIfNecessary();
1818 } catch (JavaModelException e) {
1823 // this.processPostChange = false;
1824 if (isAffectedBy(delta)) { // avoid populating for SYNC or
1826 // updateClasspathMarkers(delta);
1827 PHPBuilder.buildStarting();
1829 // does not fire any deltas
1832 case IResourceChangeEvent.POST_BUILD:
1833 PHPBuilder.buildFinished();
1837 // // jsurfer TODO compare 3.0 sources
1838 // if (event.getSource() instanceof IWorkspace) {
1839 // int eventType = this.overridenEventType == -1 ? event.getType() :
1840 // this.overridenEventType;
1841 // IResource resource = event.getResource();
1842 // IResourceDelta delta = event.getDelta();
1844 // switch(eventType){
1845 // case IResourceChangeEvent.PRE_DELETE :
1847 // if(resource.getType() == IResource.PROJECT
1848 // && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
1849 // // TODO jsurfer temp-del
1850 // // this.deleting((IProject)resource);
1852 // } catch(CoreException e){
1856 // case IResourceChangeEvent.PRE_BUILD :
1857 // // TODO jsurfer temp-del
1858 // // if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER
1860 // // this.checkProjectsBeingAddedOrRemoved(delta);
1862 // // // update the classpath related markers
1863 // // this.updateClasspathMarkers();
1865 // // // the following will close project if affected by the property
1868 // // // don't fire classpath change deltas right away, but batch them
1869 // // this.manager.stopDeltas();
1870 // // this.performPreBuildCheck(delta, null);
1872 // // this.manager.startDeltas();
1875 // // only fire already computed deltas (resource ones will be processed
1876 // in post change only)
1877 // this.manager.fire(null, ElementChangedEvent.PRE_AUTO_BUILD);
1880 // case IResourceChangeEvent.POST_BUILD :
1881 // // TODO jsurfer temp-del
1882 // // JavaBuilder.finishedBuilding(event);
1885 // case IResourceChangeEvent.POST_CHANGE :
1886 // // TODO jsurfer temp-del
1887 // // if (isAffectedBy(delta)) {
1889 // // if (this.refreshedElements != null) {
1891 // // createExternalArchiveDelta(null);
1892 // // } catch (JavaModelException e) {
1893 // // e.printStackTrace();
1896 // // IJavaElementDelta translatedDelta =
1897 // this.processResourceDelta(delta);
1898 // // if (translatedDelta != null) {
1899 // // this.manager.registerJavaModelDelta(translatedDelta);
1901 // // this.manager.fire(null, ElementChangedEvent.POST_CHANGE);
1903 // // // workaround for bug 15168 circular errors not reported
1904 // // this.manager.javaProjectsCache = null;
1905 // // this.removedRoots = null;
1913 * Turns the firing mode to on. That is, deltas that are/have been
1914 * registered will be fired.
1916 private void startDeltas() {
1917 this.isFiring = true;
1921 * Turns the firing mode to off. That is, deltas that are/have been
1922 * registered will not be fired until deltas are started again.
1924 private void stopDeltas() {
1925 this.isFiring = false;
1929 * Note that the project is about to be deleted.
1931 private void deleting(IProject project) {
1934 // discard indexing jobs that belong to this project so that the
1936 // deleted without interferences from the index manager
1937 // this.manager.indexManager.discardJobs(project.getName());
1939 JavaProject javaProject = (JavaProject) JavaCore.create(project);
1941 // remember roots of this project
1942 if (this.removedRoots == null) {
1943 this.removedRoots = new HashMap();
1945 if (javaProject.isOpen()) {
1946 this.removedRoots.put(javaProject, javaProject
1947 .getPackageFragmentRoots());
1949 // compute roots without opening project
1950 // this.removedRoots.put(
1952 // javaProject.computePackageFragmentRoots(
1953 // javaProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/,
1954 // false/*don't generateMarkerOnError*/, false/*don't
1955 // returnResolutionInProgress*/),
1959 javaProject.close();
1961 // workaround for bug 15168 circular errors not reported
1962 if (this.state.modelProjectsCache == null) {
1963 this.state.modelProjectsCache = this.manager.getJavaModel()
1966 this.removeFromParentInfo(javaProject);
1968 } catch (JavaModelException e) {
1969 // java project doesn't exist: ignore
1974 * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code>
1975 * into the corresponding set of <code>IJavaElementDelta</code>, rooted
1976 * in the relevant <code>JavaModel</code>s.
1978 private IJavaElementDelta processResourceDelta(IResourceDelta changes) {
1981 IJavaModel model = this.manager.getJavaModel();
1982 if (!model.isOpen()) {
1983 // force opening of java model so that java element delta are
1987 } catch (JavaModelException e) {
1989 e.printStackTrace();
1994 this.state.initializeRoots();
1995 this.currentElement = null;
1997 // get the workspace delta, and start processing there.
1998 IResourceDelta[] deltas = changes.getAffectedChildren();
1999 for (int i = 0; i < deltas.length; i++) {
2000 IResourceDelta delta = deltas[i];
2001 IResource res = delta.getResource();
2003 // find out the element type
2004 // RootInfo rootInfo = null;
2006 IProject proj = (IProject) res;
2007 boolean wasJavaProject = this.manager.getJavaModel()
2008 .findJavaProject(proj) != null;
2009 boolean isJavaProject = JavaProject.hasJavaNature(proj);
2010 if (!wasJavaProject && !isJavaProject) {
2011 elementType = NON_JAVA_RESOURCE;
2013 // rootInfo = this.enclosingRootInfo(res.getFullPath(),
2014 // delta.getKind());
2015 // if (rootInfo != null &&
2016 // rootInfo.isRootOfProject(res.getFullPath())) {
2017 // elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT;
2019 elementType = IJavaElement.JAVA_PROJECT;
2024 // this.traverseDelta(delta, elementType, rootInfo, null);
2026 if (elementType == NON_JAVA_RESOURCE
2027 || (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { // project
2035 // add child as non java resource
2036 nonJavaResourcesChanged((JavaModel) model, delta);
2037 } catch (JavaModelException e) {
2038 // java model could not be opened
2043 // refreshPackageFragmentRoots();
2044 // resetProjectCaches();
2046 return this.currentDelta;
2048 this.currentDelta = null;
2049 // this.rootsToRefresh.clear();
2050 // this.projectCachesToReset.clear();
2055 * Converts an <code>IResourceDelta</code> and its children into the
2056 * corresponding <code>IJavaElementDelta</code>s.
2058 // private void traverseDelta(
2059 // IResourceDelta delta,
2061 // RootInfo rootInfo,
2062 // OutputsInfo outputsInfo) {
2064 // IResource res = delta.getResource();
2066 // // set stack of elements
2067 // if (this.currentElement == null && rootInfo != null) {
2068 // // this.currentElement = rootInfo.project;
2071 // // process current delta
2072 // boolean processChildren = true;
2073 // if (res instanceof IProject) {
2074 // processChildren =
2075 // this.updateCurrentDeltaAndIndex(
2077 // elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ?
2078 // IJavaElement.JAVA_PROJECT : // case of prj=src
2081 // } else if (rootInfo != null) {
2082 // processChildren = this.updateCurrentDeltaAndIndex(delta, elementType,
2085 // // not yet inside a package fragment root
2086 // processChildren = true;
2089 // // get the project's output locations and traverse mode
2090 // if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
2092 // // process children if needed
2093 // if (processChildren) {
2094 // IResourceDelta[] children = delta.getAffectedChildren();
2095 // boolean oneChildOnClasspath = false;
2096 // int length = children.length;
2097 // IResourceDelta[] orphanChildren = null;
2098 // Openable parent = null;
2099 // boolean isValidParent = true;
2100 // for (int i = 0; i < length; i++) {
2101 // IResourceDelta child = children[i];
2102 // IResource childRes = child.getResource();
2104 // // check source attachment change
2105 // this.checkSourceAttachmentChange(child, childRes);
2107 // // find out whether the child is a package fragment root of the current
2109 // IPath childPath = childRes.getFullPath();
2110 // int childKind = child.getKind();
2111 // RootInfo childRootInfo = this.rootInfo(childPath, childKind);
2112 // if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
2113 // // package fragment root of another project (dealt with later)
2114 // childRootInfo = null;
2117 // // compute child type
2119 // this.elementType(
2123 // rootInfo == null ? childRootInfo : rootInfo
2126 // // is childRes in the output folder and is it filtered out ?
2127 // boolean isResFilteredFromOutput =
2128 // this.isResFilteredFromOutput(outputsInfo, childRes, childType);
2130 // boolean isNestedRoot = rootInfo != null && childRootInfo != null;
2131 // if (!isResFilteredFromOutput
2132 // && !isNestedRoot) { // do not treat as non-java rsc if nested root
2134 // this.traverseDelta(child, childType, rootInfo == null ? childRootInfo :
2135 // rootInfo, outputsInfo); // traverse delta for child in the same project
2137 // if (childType == NON_JAVA_RESOURCE) {
2138 // if (rootInfo != null) { // if inside a package fragment root
2139 // if (!isValidParent) continue;
2140 // if (parent == null) {
2141 // // find the parent of the non-java resource to attach to
2142 // if (this.currentElement == null
2143 // || !rootInfo.project.equals(this.currentElement.getJavaProject())) { //
2144 // note if currentElement is the IJavaModel, getJavaProject() is null
2145 // // force the currentProject to be used
2146 // this.currentElement = rootInfo.project;
2148 // if (elementType == IJavaElement.JAVA_PROJECT
2149 // || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT
2150 // && res instanceof IProject)) {
2151 // // NB: attach non-java resource to project (not to its package fragment
2153 // parent = rootInfo.project;
2155 // parent = this.createElement(res, elementType, rootInfo);
2157 // if (parent == null) {
2158 // isValidParent = false;
2162 // // add child as non java resource
2164 // nonJavaResourcesChanged(parent, child);
2165 // } catch (JavaModelException e) {
2169 // // the non-java resource (or its parent folder) will be attached to the
2171 // if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
2172 // orphanChildren[i] = child;
2175 // oneChildOnClasspath = true;
2178 // oneChildOnClasspath = true; // to avoid reporting child delta as non-java
2182 // // if child is a nested root
2183 // // or if it is not a package fragment root of the current project
2184 // // but it is a package fragment root of another project, traverse delta
2187 // || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath,
2188 // childKind)) != null)) {
2189 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT,
2190 // childRootInfo, null); // binary output of childRootInfo.project cannot be
2194 // // if the child is a package fragment root of one or several other
2196 // ArrayList rootList;
2197 // if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) {
2198 // Iterator iterator = rootList.iterator();
2199 // while (iterator.hasNext()) {
2200 // childRootInfo = (RootInfo) iterator.next();
2201 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT,
2202 // childRootInfo, null); // binary output of childRootInfo.project cannot be
2207 // if (orphanChildren != null
2208 // && (oneChildOnClasspath // orphan children are siblings of a package
2210 // || res instanceof IProject)) { // non-java resource directly under a
2213 // // attach orphan children
2214 // IProject rscProject = res.getProject();
2215 // JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
2216 // if (adoptiveProject != null
2217 // && JavaProject.hasJavaNature(rscProject)) { // delta iff Java project
2219 // for (int i = 0; i < length; i++) {
2220 // if (orphanChildren[i] != null) {
2222 // nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
2223 // } catch (JavaModelException e) {
2229 // } // else resource delta will be added by parent
2230 // } // else resource delta will be added by parent
2232 private void notifyListeners(IJavaElementDelta deltaToNotify,
2233 int eventType, IElementChangedListener[] listeners,
2234 int[] listenerMask, int listenerCount) {
2235 final ElementChangedEvent extraEvent = new ElementChangedEvent(
2236 deltaToNotify, eventType);
2237 for (int i = 0; i < listenerCount; i++) {
2238 if ((listenerMask[i] & eventType) != 0) {
2239 final IElementChangedListener listener = listeners[i];
2243 .print("Listener #" + (i + 1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
2244 start = System.currentTimeMillis();
2246 // wrap callbacks with Safe runnable for subsequent listeners to
2247 // be called when some are causing grief
2248 Platform.run(new ISafeRunnable() {
2249 public void handleException(Throwable exception) {
2252 "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
2255 public void run() throws Exception {
2256 listener.elementChanged(extraEvent);
2261 .println(" -> " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
2267 // private void notifyTypeHierarchies(IElementChangedListener[] listeners,
2268 // int listenerCount) {
2269 // for (int i= 0; i < listenerCount; i++) {
2270 // final IElementChangedListener listener = listeners[i];
2271 // if (!(listener instanceof TypeHierarchy)) continue;
2273 // // wrap callbacks with Safe runnable for subsequent listeners to be
2274 // called when some are causing grief
2275 // Platform.run(new ISafeRunnable() {
2276 // public void handleException(Throwable exception) {
2277 // ProjectPrefUtil.log(exception, "Exception occurred in listener of Java
2278 // element change notification"); //$NON-NLS-1$
2280 // public void run() throws Exception {
2281 // TypeHierarchy typeHierarchy = (TypeHierarchy)listener;
2282 // if (typeHierarchy.hasFineGrainChanges()) {
2283 // // case of changes in primary working copies
2284 // typeHierarchy.needsRefresh = true;
2285 // typeHierarchy.fireChange();
2292 * Generic processing for elements with changed contents:<ul> <li>The
2293 * element is closed such that any subsequent accesses will re-open the
2294 * element reflecting its new structure. <li>An entry is made in the delta
2295 * reporting a content change (K_CHANGE with F_CONTENT flag set). </ul>
2297 private void nonJavaResourcesChanged(Openable element, IResourceDelta delta)
2298 throws JavaModelException {
2300 // reset non-java resources if element was open
2301 if (element.isOpen()) {
2302 JavaElementInfo info = (JavaElementInfo) element.getElementInfo();
2303 switch (element.getElementType()) {
2304 case IJavaElement.JAVA_MODEL:
2305 ((JavaModelInfo) info).nonJavaResources = null;
2306 currentDelta().addResourceDelta(delta);
2308 case IJavaElement.JAVA_PROJECT:
2309 ((JavaProjectElementInfo) info).setNonJavaResources(null);
2311 // if a package fragment root is the project, clear it too
2312 JavaProject project = (JavaProject) element;
2313 PackageFragmentRoot projectRoot = (PackageFragmentRoot) project
2314 .getPackageFragmentRoot(project.getProject());
2315 if (projectRoot.isOpen()) {
2316 ((PackageFragmentRootInfo) projectRoot.getElementInfo())
2317 .setNonJavaResources(null);
2320 case IJavaElement.PACKAGE_FRAGMENT:
2321 ((PackageFragmentInfo) info).setNonJavaResources(null);
2323 case IJavaElement.PACKAGE_FRAGMENT_ROOT:
2324 ((PackageFragmentRootInfo) info).setNonJavaResources(null);
2328 JavaElementDelta current = currentDelta();
2329 JavaElementDelta elementDelta = current.find(element);
2330 if (elementDelta == null) {
2331 // don't use find after creating the delta as it can be null (see
2332 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=63434)
2333 elementDelta = current
2334 .changed(element, IJavaElementDelta.F_CONTENT);
2336 elementDelta.addResourceDelta(delta);
2340 * Flushes all deltas without firing them.
2342 public void flush() {
2343 this.javaModelDeltas = new ArrayList();
2347 * Finds the root info this path is included in. Returns null if not found.
2349 RootInfo enclosingRootInfo(IPath path, int kind) {
2350 while (path != null && path.segmentCount() > 0) {
2351 RootInfo rootInfo = this.rootInfo(path, kind);
2352 if (rootInfo != null)
2354 path = path.removeLastSegments(1);
2360 * Fire Java Model delta, flushing them after the fact after post_change
2361 * notification. If the firing mode has been turned off, this has no effect.
2363 public void fire(IJavaElementDelta customDelta, int eventType) {
2369 .println("-----------------------------------------------------------------------------------------------------------------------");//$NON-NLS-1$
2372 IJavaElementDelta deltaToNotify;
2373 if (customDelta == null) {
2374 deltaToNotify = this.mergeDeltas(this.javaModelDeltas);
2376 deltaToNotify = customDelta;
2379 // Refresh internal scopes
2380 // if (deltaToNotify != null) {
2381 // Iterator scopes = this.manager.searchScopes.keySet().iterator();
2382 // while (scopes.hasNext()) {
2383 // AbstractSearchScope scope = (AbstractSearchScope)scopes.next();
2384 // scope.processDelta(deltaToNotify);
2390 // Important: if any listener reacts to notification by updating the
2391 // listeners list or mask, these lists will
2392 // be duplicated, so it is necessary to remember original lists in a
2393 // variable (since field values may change under us)
2394 IElementChangedListener[] listeners = this.state.elementChangedListeners;
2395 int[] listenerMask = this.state.elementChangedListenerMasks;
2396 int listenerCount = this.state.elementChangedListenerCount;
2398 switch (eventType) {
2399 case DEFAULT_CHANGE_EVENT:
2400 firePostChangeDelta(deltaToNotify, listeners, listenerMask,
2402 fireReconcileDelta(listeners, listenerMask, listenerCount);
2404 case ElementChangedEvent.POST_CHANGE:
2405 firePostChangeDelta(deltaToNotify, listeners, listenerMask,
2407 fireReconcileDelta(listeners, listenerMask, listenerCount);
2412 private void firePostChangeDelta(IJavaElementDelta deltaToNotify,
2413 IElementChangedListener[] listeners, int[] listenerMask,
2414 int listenerCount) {
2416 // post change deltas
2419 .println("FIRING POST_CHANGE Delta [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
2421 .println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
2423 if (deltaToNotify != null) {
2424 // flush now so as to keep listener reactions to post their own
2425 // deltas for subsequent iteration
2428 notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE,
2429 listeners, listenerMask, listenerCount);
2433 private void fireReconcileDelta(IElementChangedListener[] listeners,
2434 int[] listenerMask, int listenerCount) {
2436 IJavaElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas
2440 .println("FIRING POST_RECONCILE Delta [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
2442 .println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
2444 if (deltaToNotify != null) {
2445 // flush now so as to keep listener reactions to post their own
2446 // deltas for subsequent iteration
2447 this.reconcileDeltas = new HashMap();
2449 notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE,
2450 listeners, listenerMask, listenerCount);
2455 * Returns the root info for the given path. Look in the old roots table if
2458 RootInfo rootInfo(IPath path, int kind) {
2459 if (kind == IResourceDelta.REMOVED) {
2460 return (RootInfo) this.oldRoots.get(path);
2462 return (RootInfo) this.roots.get(path);
2467 * Returns the other root infos for the given path. Look in the old other
2468 * roots table if kind is REMOVED.
2470 ArrayList otherRootsInfo(IPath path, int kind) {
2471 if (kind == IResourceDelta.REMOVED) {
2472 return (ArrayList) this.oldOtherRoots.get(path);
2474 return (ArrayList) this.otherRoots.get(path);
2479 * Converts an <code>IResourceDelta</code> and its children into the
2480 * corresponding <code>IJavaElementDelta</code>s. Return whether the
2481 * delta corresponds to a java element. If it is not a java element, it will
2482 * be added as a non-java resource by the sender of this method.
2484 // protected boolean traverseDelta(
2485 // IResourceDelta delta,
2487 // RootInfo rootInfo,
2488 // OutputsInfo outputsInfo) {
2490 // IResource res = delta.getResource();
2492 // // set stack of elements
2493 // if (this.currentElement == null && rootInfo != null) {
2494 // this.currentElement = (Openable)rootInfo.project;
2497 // // process current delta
2498 // boolean processChildren = true;
2499 // if (res instanceof IProject) {
2500 // processChildren =
2501 // this.updateCurrentDeltaAndIndex(
2503 // elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ?
2504 // IJavaElement.JAVA_PROJECT : // case of prj=src
2507 // } else if (rootInfo != null) {
2508 // processChildren = this.updateCurrentDeltaAndIndex(delta, elementType,
2511 // // not yet inside a package fragment root
2512 // processChildren = true;
2515 // // get the project's output locations and traverse mode
2516 // if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
2518 // // process children if needed
2519 // if (processChildren) {
2520 // IResourceDelta[] children = delta.getAffectedChildren();
2521 // boolean oneChildOnClasspath = false;
2522 // int length = children.length;
2523 // IResourceDelta[] orphanChildren = null;
2524 // Openable parent = null;
2525 // boolean isValidParent = true;
2526 // for (int i = 0; i < length; i++) {
2527 // IResourceDelta child = children[i];
2528 // IResource childRes = child.getResource();
2530 // // check source attachment change
2531 // this.checkSourceAttachmentChange(child, childRes);
2533 // // find out whether the child is a package fragment root of the current
2535 // IPath childPath = childRes.getFullPath();
2536 // int childKind = child.getKind();
2537 // RootInfo childRootInfo = this.rootInfo(childPath, childKind);
2538 // if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
2539 // // package fragment root of another project (dealt with later)
2540 // childRootInfo = null;
2543 // // compute child type
2545 // this.elementType(
2549 // rootInfo == null ? childRootInfo : rootInfo
2552 // // is childRes in the output folder and is it filtered out ?
2553 // boolean isResFilteredFromOutput =
2554 // this.isResFilteredFromOutput(outputsInfo, childRes, childType);
2556 // boolean isNestedRoot = rootInfo != null && childRootInfo != null;
2557 // if (!isResFilteredFromOutput
2558 // && !isNestedRoot) { // do not treat as non-java rsc if nested root
2559 // if (!this.traverseDelta(child, childType, rootInfo == null ?
2560 // childRootInfo : rootInfo, outputsInfo)) { // traverse delta for child in
2562 // // it is a non-java resource
2564 // if (rootInfo != null) { // if inside a package fragment root
2565 // if (!isValidParent) continue;
2566 // if (parent == null) {
2567 // // find the parent of the non-java resource to attach to
2568 // if (this.currentElement == null
2569 // || !this.currentElement.getJavaProject().equals(rootInfo.project)) {
2570 // // force the currentProject to be used
2571 // this.currentElement = (Openable)rootInfo.project;
2573 // if (elementType == IJavaElement.JAVA_PROJECT
2574 // || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT
2575 // && res instanceof IProject)) {
2576 // // NB: attach non-java resource to project (not to its package fragment
2578 // parent = (Openable)rootInfo.project;
2580 // parent = this.createElement(res, elementType, rootInfo);
2582 // if (parent == null) {
2583 // isValidParent = false;
2587 // // add child as non java resource
2588 // nonJavaResourcesChanged(parent, child);
2590 // // the non-java resource (or its parent folder) will be attached to the
2592 // if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
2593 // orphanChildren[i] = child;
2595 // } catch (JavaModelException e) {
2598 // oneChildOnClasspath = true;
2601 // oneChildOnClasspath = true; // to avoid reporting child delta as non-java
2605 // // if child is a nested root
2606 // // or if it is not a package fragment root of the current project
2607 // // but it is a package fragment root of another project, traverse delta
2610 // || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath,
2611 // childKind)) != null)) {
2612 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT,
2613 // childRootInfo, null); // binary output of childRootInfo.project cannot be
2615 // // NB: No need to check the return value as the child can only be on the
2619 // // if the child is a package fragment root of one or several other
2621 // ArrayList rootList;
2622 // if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) {
2623 // Iterator iterator = rootList.iterator();
2624 // while (iterator.hasNext()) {
2625 // childRootInfo = (RootInfo) iterator.next();
2626 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT,
2627 // childRootInfo, null); // binary output of childRootInfo.project cannot be
2632 // if (orphanChildren != null
2633 // && (oneChildOnClasspath // orphan children are siblings of a package
2635 // || res instanceof IProject)) { // non-java resource directly under a
2638 // // attach orphan children
2639 // IProject rscProject = res.getProject();
2640 // JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
2641 // if (adoptiveProject != null
2642 // && JavaProject.hasJavaNature(rscProject)) { // delta iff Java project
2644 // for (int i = 0; i < length; i++) {
2645 // if (orphanChildren[i] != null) {
2647 // nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
2648 // } catch (JavaModelException e) {
2653 // } // else resource delta will be added by parent
2654 // return elementType != NON_JAVA_RESOURCE; // TODO: (jerome) do we still
2655 // need to return? (check could be done by caller)
2657 // return elementType != NON_JAVA_RESOURCE;
2661 * Update the classpath markers and cycle markers for the projects to
2664 // void updateClasspathMarkers() {
2666 // if (!ResourcesPlugin.getWorkspace().isAutoBuilding()) {
2667 // Iterator iterator = this.projectsToUpdate.iterator();
2668 // while (iterator.hasNext()) {
2670 // JavaProject project = (JavaProject)iterator.next();
2672 // // force classpath marker refresh
2673 // project.getResolvedClasspath(
2674 // true, // ignoreUnresolvedEntry
2675 // true); // generateMarkerOnError
2677 // } catch (JavaModelException e) {
2681 // if (!this.projectsToUpdate.isEmpty()){
2683 // // update all cycle markers
2684 // JavaProject.updateAllCycleMarkers();
2685 // } catch (JavaModelException e) {
2689 // this.projectsToUpdate = new HashSet();
2693 * Update the current delta (ie. add/remove/change the given element) and
2694 * update the correponding index. Returns whether the children of the given
2695 * delta must be processed. @throws a JavaModelException if the delta
2696 * doesn't correspond to a java element of the given type.
2698 // private boolean updateCurrentDeltaAndIndex(IResourceDelta delta, int
2699 // elementType, RootInfo rootInfo) {
2700 // Openable element;
2701 // switch (delta.getKind()) {
2702 // case IResourceDelta.ADDED :
2703 // IResource deltaRes = delta.getResource();
2704 // element = this.createElement(deltaRes, elementType, rootInfo);
2705 // if (element == null) {
2706 // // resource might be containing shared roots (see bug 19058)
2707 // this.updateRoots(deltaRes.getFullPath(), delta);
2710 // this.updateIndex(element, delta);
2711 // this.elementAdded(element, delta, rootInfo);
2713 // case IResourceDelta.REMOVED :
2714 // deltaRes = delta.getResource();
2715 // element = this.createElement(deltaRes, elementType, rootInfo);
2716 // if (element == null) {
2717 // // resource might be containing shared roots (see bug 19058)
2718 // this.updateRoots(deltaRes.getFullPath(), delta);
2721 // this.updateIndex(element, delta);
2722 // this.elementRemoved(element, delta, rootInfo);
2724 // if (deltaRes.getType() == IResource.PROJECT){
2725 // // reset the corresponding project built state, since cannot reuse if
2727 // this.manager.setLastBuiltState((IProject)deltaRes, null /*no state*/);
2730 // case IResourceDelta.CHANGED :
2731 // int flags = delta.getFlags();
2732 // if ((flags & IResourceDelta.CONTENT) != 0) {
2733 // // content has changed
2734 // element = this.createElement(delta.getResource(), elementType, rootInfo);
2735 // if (element == null) return false;
2736 // this.updateIndex(element, delta);
2737 // this.contentChanged(element, delta);
2738 // } else if (elementType == IJavaElement.JAVA_PROJECT) {
2739 // if ((flags & IResourceDelta.OPEN) != 0) {
2740 // // project has been opened or closed
2741 // IProject res = (IProject)delta.getResource();
2742 // element = this.createElement(res, elementType, rootInfo);
2743 // if (element == null) {
2744 // // resource might be containing shared roots (see bug 19058)
2745 // this.updateRoots(res.getFullPath(), delta);
2748 // if (res.isOpen()) {
2749 // if (JavaProject.hasJavaNature(res)) {
2750 // this.elementAdded(element, delta, rootInfo);
2751 // this.indexManager.indexAll(res);
2754 // JavaModel javaModel = this.manager.getJavaModel();
2755 // boolean wasJavaProject = javaModel.findJavaProject(res) != null;
2756 // if (wasJavaProject) {
2757 // this.elementRemoved(element, delta, rootInfo);
2758 // this.indexManager.discardJobs(element.getElementName());
2759 // this.indexManager.removeIndexFamily(res.getFullPath());
2763 // return false; // when a project is open/closed don't process children
2765 // if ((flags & IResourceDelta.DESCRIPTION) != 0) {
2766 // IProject res = (IProject)delta.getResource();
2767 // JavaModel javaModel = this.manager.getJavaModel();
2768 // boolean wasJavaProject = javaModel.findJavaProject(res) != null;
2769 // boolean isJavaProject = JavaProject.hasJavaNature(res);
2770 // if (wasJavaProject != isJavaProject) {
2771 // // project's nature has been added or removed
2772 // element = this.createElement(res, elementType, rootInfo);
2773 // if (element == null) return false; // note its resources are still
2774 // visible as roots to other projects
2775 // if (isJavaProject) {
2776 // this.elementAdded(element, delta, rootInfo);
2777 // this.indexManager.indexAll(res);
2779 // this.elementRemoved(element, delta, rootInfo);
2780 // this.indexManager.discardJobs(element.getElementName());
2781 // this.indexManager.removeIndexFamily(res.getFullPath());
2782 // // reset the corresponding project built state, since cannot reuse if
2784 // this.manager.setLastBuiltState(res, null /*no state*/);
2786 // return false; // when a project's nature is added/removed don't process
2796 * Traverse the set of projects which have changed namespace, and refresh
2799 // public void updateDependentNamelookups() {
2800 // Iterator iterator;
2801 // // update namelookup of dependent projects
2802 // iterator = this.projectsForDependentNamelookupRefresh.iterator();
2803 // HashSet affectedDependents = new HashSet();
2804 // while (iterator.hasNext()) {
2805 // JavaProject project = (JavaProject)iterator.next();
2806 // addDependentProjects(project.getPath(), affectedDependents);
2808 // iterator = affectedDependents.iterator();
2809 // while (iterator.hasNext()) {
2810 // JavaProject project = (JavaProject) iterator.next();
2811 // if (project.isOpen()){
2813 // ((JavaProjectElementInfo)project.getElementInfo()).setNameLookup(null);
2814 // } catch (JavaModelException e) {
2819 // protected void updateIndex(Openable element, IResourceDelta delta) {
2821 // if (indexManager == null)
2824 // switch (element.getElementType()) {
2825 // case IJavaElement.JAVA_PROJECT :
2826 // switch (delta.getKind()) {
2827 // case IResourceDelta.ADDED :
2828 // this.indexManager.indexAll(element.getJavaProject().getProject());
2830 // case IResourceDelta.REMOVED :
2831 // this.indexManager.removeIndexFamily(element.getJavaProject().getProject().getFullPath());
2832 // // NB: Discarding index jobs belonging to this project was done during
2835 // // NB: Update of index if project is opened, closed, or its java nature
2836 // is added or removed
2837 // // is done in updateCurrentDeltaAndIndex
2840 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
2841 // if (element instanceof JarPackageFragmentRoot) {
2842 // JarPackageFragmentRoot root = (JarPackageFragmentRoot)element;
2843 // // index jar file only once (if the root is in its declaring project)
2844 // IPath jarPath = root.getPath();
2845 // switch (delta.getKind()) {
2846 // case IResourceDelta.ADDED:
2847 // // index the new jar
2848 // indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
2850 // case IResourceDelta.CHANGED:
2851 // // first remove the index so that it is forced to be re-indexed
2852 // indexManager.removeIndex(jarPath);
2853 // // then index the jar
2854 // indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
2856 // case IResourceDelta.REMOVED:
2857 // // the jar was physically removed: remove the index
2858 // this.indexManager.discardJobs(jarPath.toString());
2859 // this.indexManager.removeIndex(jarPath);
2864 // int kind = delta.getKind();
2865 // if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED) {
2866 // IPackageFragmentRoot root = (IPackageFragmentRoot)element;
2867 // this.updateRootIndex(root, root.getPackageFragment(""), delta);
2872 // // don't break as packages of the package fragment root can be indexed
2874 // case IJavaElement.PACKAGE_FRAGMENT :
2875 // switch (delta.getKind()) {
2876 // case IResourceDelta.ADDED:
2877 // case IResourceDelta.REMOVED:
2878 // IPackageFragment pkg = null;
2879 // if (element instanceof IPackageFragmentRoot) {
2880 // IPackageFragmentRoot root = (IPackageFragmentRoot)element;
2881 // pkg = root.getPackageFragment(""); //$NON-NLS-1$
2883 // pkg = (IPackageFragment)element;
2885 // IResourceDelta[] children = delta.getAffectedChildren();
2886 // for (int i = 0, length = children.length; i < length; i++) {
2887 // IResourceDelta child = children[i];
2888 // IResource resource = child.getResource();
2889 // if (resource instanceof IFile) {
2890 // String name = resource.getName();
2891 // if (ProjectPrefUtil.isJavaFileName(name)) {
2892 // Openable cu = (Openable)pkg.getCompilationUnit(name);
2893 // this.updateIndex(cu, child);
2894 // } else if (ProjectPrefUtil.isClassFileName(name)) {
2895 // Openable classFile = (Openable)pkg.getClassFile(name);
2896 // this.updateIndex(classFile, child);
2903 // case IJavaElement.CLASS_FILE :
2904 // IFile file = (IFile) delta.getResource();
2905 // IJavaProject project = element.getJavaProject();
2906 // IPath binaryFolderPath = element.getPackageFragmentRoot().getPath();
2907 // // if the class file is part of the binary output, it has been created by
2908 // // the java builder -> ignore
2910 // if (binaryFolderPath.equals(project.getOutputLocation())) {
2913 // } catch (JavaModelException e) {
2915 // switch (delta.getKind()) {
2916 // case IResourceDelta.CHANGED :
2917 // // no need to index if the content has not changed
2918 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
2920 // case IResourceDelta.ADDED :
2921 // indexManager.addBinary(file, binaryFolderPath);
2923 // case IResourceDelta.REMOVED :
2924 // indexManager.remove(file.getFullPath().toString(), binaryFolderPath);
2928 // case IJavaElement.COMPILATION_UNIT :
2929 // file = (IFile) delta.getResource();
2930 // switch (delta.getKind()) {
2931 // case IResourceDelta.CHANGED :
2932 // // no need to index if the content has not changed
2933 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
2935 // case IResourceDelta.ADDED :
2936 // indexManager.addSource(file,
2937 // file.getProject().getProject().getFullPath());
2939 // case IResourceDelta.REMOVED :
2940 // indexManager.remove(file.getFullPath().toString(),
2941 // file.getProject().getProject().getFullPath());
2947 * Upadtes the index of the given root (assuming it's an addition or a
2948 * removal). This is done recusively, pkg being the current package.
2950 // private void updateRootIndex(IPackageFragmentRoot root, IPackageFragment
2951 // pkg, IResourceDelta delta) {
2952 // this.updateIndex((Openable)pkg, delta);
2953 // IResourceDelta[] children = delta.getAffectedChildren();
2954 // String name = pkg.getElementName();
2955 // for (int i = 0, length = children.length; i < length; i++) {
2956 // IResourceDelta child = children[i];
2957 // IResource resource = child.getResource();
2958 // if (resource instanceof IFolder) {
2959 // String subpkgName =
2960 // name.length() == 0 ?
2961 // resource.getName() :
2962 // name + "." + resource.getName(); //$NON-NLS-1$
2963 // IPackageFragment subpkg = root.getPackageFragment(subpkgName);
2964 // this.updateRootIndex(root, subpkg, child);
2969 * Update the roots that are affected by the addition or the removal of the
2970 * given container resource.
2972 // private void updateRoots(IPath containerPath, IResourceDelta
2973 // containerDelta) {
2976 // if (containerDelta.getKind() == IResourceDelta.REMOVED) {
2977 // roots = this.oldRoots;
2978 // otherRoots = this.oldOtherRoots;
2980 // roots = this.roots;
2981 // otherRoots = this.otherRoots;
2983 // Iterator iterator = roots.keySet().iterator();
2984 // while (iterator.hasNext()) {
2985 // IPath path = (IPath)iterator.next();
2986 // if (containerPath.isPrefixOf(path) && !containerPath.equals(path)) {
2987 // IResourceDelta rootDelta =
2988 // containerDelta.findMember(path.removeFirstSegments(1));
2989 // if (rootDelta == null) continue;
2990 // RootInfo rootInfo = (RootInfo)roots.get(path);
2992 // if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider
2993 // roots that are not included in the container
2994 // this.updateCurrentDeltaAndIndex(rootDelta,
2995 // IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);
2998 // ArrayList rootList = (ArrayList)otherRoots.get(path);
2999 // if (rootList != null) {
3000 // Iterator otherProjects = rootList.iterator();
3001 // while (otherProjects.hasNext()) {
3002 // rootInfo = (RootInfo)otherProjects.next();
3003 // if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider
3004 // roots that are not included in the container
3005 // this.updateCurrentDeltaAndIndex(rootDelta,
3006 // IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);