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;
13 //import java.io.File;
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;
49 import org.eclipse.core.runtime.SafeRunner;
52 * This class is used by <code>JavaModelManager</code> to convert
53 * <code>IResourceDelta</code>s into <code>IJavaElementDelta</code>s. It
54 * also does some processing on the <code>JavaElement</code>s involved (e.g.
55 * closing them or updating classpaths).
57 public class DeltaProcessor implements IResourceChangeListener {
59 final static int IGNORE = 0;
61 final static int SOURCE = 1;
63 final static int BINARY = 2;
65 final static String EXTERNAL_JAR_ADDED = "external jar added"; //$NON-NLS-1$
67 final static String EXTERNAL_JAR_REMOVED = "external jar removed"; //$NON-NLS-1$
69 final static String EXTERNAL_JAR_CHANGED = "external jar changed"; //$NON-NLS-1$
71 final static String EXTERNAL_JAR_UNCHANGED = "external jar unchanged"; //$NON-NLS-1$
73 final static String INTERNAL_JAR_IGNORE = "internal jar ignore"; //$NON-NLS-1$
75 private final static int NON_JAVA_RESOURCE = -1;
77 public static boolean DEBUG = false;
79 public static boolean VERBOSE = false;
81 public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with
82 // ElementChangedEvent
86 * The <code>JavaElementDelta</code> corresponding to the
87 * <code>IResourceDelta</code> being translated.
89 protected JavaElementDelta currentDelta;
91 // protected IndexManager indexManager = new IndexManager();
93 /* A table from IPath (from a classpath entry) to RootInfo */
97 * A table from IPath (from a classpath entry) to ArrayList of RootInfo Used
98 * when an IPath corresponds to more than one root
102 /* Whether the roots tables should be recomputed */
103 public boolean rootsAreStale = true;
106 * A table from IPath (from a classpath entry) to RootInfo from the last
107 * time the delta processor was invoked.
112 * A table from IPath (from a classpath entry) to ArrayList of RootInfo from
113 * the last time the delta processor was invoked. Used when an IPath
114 * corresponds to more than one root
119 * A table from IPath (a source attachment path from a classpath entry) to
120 * IPath (a root path)
122 Map sourceAttachments;
125 * The java element that was last created (see createElement(IResource)).
126 * This is used as a stack of java elements (using getParent() to pop it,
127 * and using the various get*(...) to push it.
129 Openable currentElement;
132 * Queue of deltas created explicily by the Java Model that have yet to be
135 public ArrayList javaModelDeltas = new ArrayList();
138 * Queue of reconcile deltas on working copies that have yet to be fired.
139 * This is a table form IWorkingCopy to IJavaElementDelta
141 public HashMap reconcileDeltas = new HashMap();
144 * Turns delta firing on/off. By default it is on.
146 private boolean isFiring = true;
148 public HashMap externalTimeStamps = new HashMap();
150 public HashSet projectsToUpdate = new HashSet();
152 // list of root projects which namelookup caches need to be updated for
154 // TODO: (jerome) is it needed? projectsToUpdate might be sufficient
155 public HashSet projectsForDependentNamelookupRefresh = new HashSet();
158 * The global state of delta processing.
160 private DeltaProcessingState state;
163 * The Java model manager
165 private JavaModelManager manager;
168 * A table from IJavaProject to an array of IPackageFragmentRoot. This table
169 * contains the pkg fragment roots of the project that are being deleted.
174 * A list of IJavaElement used as a scope for external archives refresh
175 * during POST_CHANGE. This is null if no refresh is needed.
177 HashSet refreshedElements;
186 OutputsInfo(IPath[] paths, int[] traverseModes, int outputCount) {
188 this.traverseModes = traverseModes;
189 this.outputCount = outputCount;
192 public String toString() {
193 if (this.paths == null)
194 return "<none>"; //$NON-NLS-1$
195 StringBuffer buffer = new StringBuffer();
196 for (int i = 0; i < this.outputCount; i++) {
197 buffer.append("path="); //$NON-NLS-1$
198 buffer.append(this.paths[i].toString());
199 buffer.append("\n->traverse="); //$NON-NLS-1$
200 switch (this.traverseModes[i]) {
202 buffer.append("BINARY"); //$NON-NLS-1$
205 buffer.append("IGNORE"); //$NON-NLS-1$
208 buffer.append("SOURCE"); //$NON-NLS-1$
211 buffer.append("<unknown>"); //$NON-NLS-1$
213 if (i + 1 < this.outputCount) {
217 return buffer.toString();
222 IJavaProject project;
226 char[][] exclusionPatterns;
228 RootInfo(IJavaProject project, IPath rootPath,
229 char[][] exclusionPatterns) {
230 this.project = project;
231 this.rootPath = rootPath;
232 this.exclusionPatterns = exclusionPatterns;
235 boolean isRootOfProject(IPath path) {
236 return this.rootPath.equals(path)
237 && this.project.getProject().getFullPath().isPrefixOf(path);
240 public String toString() {
241 StringBuffer buffer = new StringBuffer("project="); //$NON-NLS-1$
242 if (this.project == null) {
243 buffer.append("null"); //$NON-NLS-1$
245 buffer.append(this.project.getElementName());
247 buffer.append("\npath="); //$NON-NLS-1$
248 if (this.rootPath == null) {
249 buffer.append("null"); //$NON-NLS-1$
251 buffer.append(this.rootPath.toString());
253 buffer.append("\nexcluding="); //$NON-NLS-1$
254 if (this.exclusionPatterns == null) {
255 buffer.append("null"); //$NON-NLS-1$
257 for (int i = 0, length = this.exclusionPatterns.length; i < length; i++) {
258 buffer.append(new String(this.exclusionPatterns[i]));
259 if (i < length - 1) {
260 buffer.append("|"); //$NON-NLS-1$
264 return buffer.toString();
268 // DeltaProcessor(JavaModelManager manager) {
269 // this.manager = manager;
273 * Type of event that should be processed no matter what the real event type
276 public int overridenEventType = -1;
278 public DeltaProcessor(DeltaProcessingState state, JavaModelManager manager) {
280 this.manager = manager;
284 * Adds the dependents of the given project to the list of the projects to
287 // void addDependentProjects(IPath projectPath, HashSet result) {
289 // IJavaProject[] projects = this.manager.getJavaModel().getJavaProjects();
290 // for (int i = 0, length = projects.length; i < length; i++) {
291 // IJavaProject project = projects[i];
292 // IClasspathEntry[] classpath =
293 // ((JavaProject)project).getExpandedClasspath(true);
294 // for (int j = 0, length2 = classpath.length; j < length2; j++) {
295 // IClasspathEntry entry = classpath[j];
296 // if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT
297 // && entry.getPath().equals(projectPath)) {
298 // result.add(project);
302 // } catch (JavaModelException e) {
306 * Adds the given element to the list of elements used as a scope for
307 * external jars refresh.
309 public void addForRefresh(IJavaElement element) {
310 if (this.refreshedElements == null) {
311 this.refreshedElements = new HashSet();
313 this.refreshedElements.add(element);
317 * Adds the given project and its dependents to the list of the projects to
320 // void addToProjectsToUpdateWithDependents(IProject project) {
321 // this.projectsToUpdate.add(JavaCore.create(project));
322 // // this.addDependentProjects(project.getFullPath(),
323 // // this.projectsToUpdate);
327 * Adds the given child handle to its parent's cache of children.
329 // protected void addToParentInfo(Openable child) {
331 // Openable parent = (Openable) child.getParent();
332 // if (parent != null && parent.isOpen()) {
334 // JavaElementInfo info = (JavaElementInfo) parent
335 // .getElementInfo();
336 // info.addChild(child);
337 // } catch (JavaModelException e) {
338 // // do nothing - we already checked if open
344 * Check all external archive (referenced by given roots, projects or model)
345 * status and issue a corresponding root delta. Also triggers index updates
347 // public void checkExternalArchiveChanges(IJavaElement[] refreshedElements,
348 // IProgressMonitor monitor) throws JavaModelException {
350 // for (int i = 0, length = refreshedElements.length; i < length; i++) {
351 // this.addForRefresh(refreshedElements[i]);
353 // boolean hasDelta = this.createExternalArchiveDelta(monitor);
354 // if (monitor != null && monitor.isCanceled()) return;
356 // // force classpath marker refresh of affected projects
357 // JavaModel.flushExternalFileCache();
358 // IJavaElementDelta[] projectDeltas =
359 // this.currentDelta.getAffectedChildren();
360 // for (int i = 0, length = projectDeltas.length; i < length; i++) {
361 // IJavaElementDelta delta = projectDeltas[i];
362 // ((JavaProject)delta.getElement()).getResolvedClasspath(
363 // true, // ignoreUnresolvedEntry
364 // true); // generateMarkerOnError
366 // if (this.currentDelta != null) { // if delta has not been fired while
368 // this.manager.fire(this.currentDelta,
369 // JavaModelManager.DEFAULT_CHANGE_EVENT);
373 // this.currentDelta = null;
374 // if (monitor != null) monitor.done();
378 * Check if external archives have changed and create the corresponding
379 * deltas. Returns whether at least on delta was created.
381 // public boolean createExternalArchiveDelta(IProgressMonitor monitor)
382 // throws JavaModelException {
384 // if (this.refreshedElements == null) return false;
386 // HashMap externalArchivesStatus = new HashMap();
387 // boolean hasDelta = false;
389 // // find JARs to refresh
390 // HashSet archivePathsToRefresh = new HashSet();
392 // Iterator iterator = this.refreshedElements.iterator();
393 // while (iterator.hasNext()) {
394 // IJavaElement element = (IJavaElement)iterator.next();
395 // switch(element.getElementType()){
396 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
397 // archivePathsToRefresh.add(element.getPath());
399 // case IJavaElement.JAVA_PROJECT :
400 // IJavaProject project = (IJavaProject) element;
401 // if (!JavaProject.hasJavaNature(project.getProject())) {
402 // // project is not accessible or has lost its Java nature
405 // IClasspathEntry[] classpath = project.getResolvedClasspath(true);
406 // for (int j = 0, cpLength = classpath.length; j < cpLength; j++){
407 // if (classpath[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
408 // archivePathsToRefresh.add(classpath[j].getPath());
412 // case IJavaElement.JAVA_MODEL :
413 // IJavaProject[] projects =
414 // manager.getJavaModel().getOldJavaProjectsList();
415 // for (int j = 0, projectsLength = projects.length; j < projectsLength;
417 // project = projects[j];
418 // if (!JavaProject.hasJavaNature(project.getProject())) {
419 // // project is not accessible or has lost its Java nature
422 // classpath = project.getResolvedClasspath(true);
423 // for (int k = 0, cpLength = classpath.length; k < cpLength; k++){
424 // if (classpath[k].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
425 // archivePathsToRefresh.add(classpath[k].getPath());
433 // this.refreshedElements = null;
436 // // perform refresh
437 // IJavaProject[] projects =
438 // manager.getJavaModel().getOldJavaProjectsList();
439 // IWorkspaceRoot wksRoot = ResourcesPlugin.getWorkspace().getRoot();
440 // for (int i = 0, length = projects.length; i < length; i++) {
442 // if (monitor != null && monitor.isCanceled()) break;
444 // IJavaProject project = projects[i];
445 // if (!JavaProject.hasJavaNature(project.getProject())) {
446 // // project is not accessible or has lost its Java nature
449 // IClasspathEntry[] entries = project.getResolvedClasspath(true);
450 // for (int j = 0; j < entries.length; j++){
451 // if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
453 // IPath entryPath = entries[j].getPath();
455 // if (!archivePathsToRefresh.contains(entryPath)) continue; // not supposed
458 // String status = (String)externalArchivesStatus.get(entryPath);
459 // if (status == null){
461 // // compute shared status
462 // Object targetLibrary = JavaModel.getTarget(wksRoot, entryPath, true);
464 // if (targetLibrary == null){ // missing JAR
465 // if (this.externalTimeStamps.containsKey(entryPath)){
466 // this.externalTimeStamps.remove(entryPath);
467 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
468 // // the jar was physically removed: remove the index
469 // indexManager.removeIndex(entryPath);
472 // } else if (targetLibrary instanceof File){ // external JAR
474 // File externalFile = (File)targetLibrary;
476 // // check timestamp to figure if JAR has changed in some way
477 // Long oldTimestamp =(Long) this.externalTimeStamps.get(entryPath);
478 // long newTimeStamp = getTimeStamp(externalFile);
479 // if (oldTimestamp != null){
481 // if (newTimeStamp == 0){ // file doesn't exist
482 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
483 // this.externalTimeStamps.remove(entryPath);
484 // // remove the index
485 // indexManager.removeIndex(entryPath);
487 // } else if (oldTimestamp.longValue() != newTimeStamp){
488 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_CHANGED);
489 // this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
490 // // first remove the index so that it is forced to be re-indexed
491 // indexManager.removeIndex(entryPath);
492 // // then index the jar
493 // indexManager.indexLibrary(entryPath, project.getProject());
495 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
498 // if (newTimeStamp == 0){ // jar still doesn't exist
499 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
501 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_ADDED);
502 // this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
503 // // index the new jar
504 // indexManager.indexLibrary(entryPath, project.getProject());
507 // } else { // internal JAR
508 // externalArchivesStatus.put(entryPath, INTERNAL_JAR_IGNORE);
511 // // according to computed status, generate a delta
512 // status = (String)externalArchivesStatus.get(entryPath);
513 // if (status != null){
514 // if (status == EXTERNAL_JAR_ADDED){
515 // PackageFragmentRoot root =
516 // (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
518 // System.out.println("- External JAR ADDED, affecting root:
519 // "+root.getElementName()); //$NON-NLS-1$
521 // elementAdded(root, null, null);
523 // } else if (status == EXTERNAL_JAR_CHANGED) {
524 // PackageFragmentRoot root =
525 // (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
527 // System.out.println("- External JAR CHANGED, affecting root:
528 // "+root.getElementName()); //$NON-NLS-1$
530 // // reset the corresponding project built state, since the builder would
532 // this.manager.setLastBuiltState(project.getProject(), null /*no state*/);
533 // contentChanged(root, null);
535 // } else if (status == EXTERNAL_JAR_REMOVED) {
536 // PackageFragmentRoot root =
537 // (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
539 // System.out.println("- External JAR REMOVED, affecting root:
540 // "+root.getElementName()); //$NON-NLS-1$
542 // elementRemoved(root, null, null);
551 JavaElementDelta currentDelta() {
552 if (this.currentDelta == null) {
553 this.currentDelta = new JavaElementDelta(this.manager
556 return this.currentDelta;
560 * Process the given delta and look for projects being added, opened, closed
561 * or with a java nature being added or removed. Note that projects being
562 * deleted are checked in deleting(IProject). In all cases, add the
563 * project's dependents to the list of projects to update so that the
564 * classpath related markers can be updated.
566 // public void checkProjectsBeingAddedOrRemoved(IResourceDelta delta) {
567 // IResource resource = delta.getResource();
568 // switch (resource.getType()) {
569 // case IResource.ROOT :
570 // // workaround for bug 15168 circular errors not reported
571 // if (this.manager.javaProjectsCache == null) {
573 // this.manager.javaProjectsCache =
574 // this.manager.getJavaModel().getJavaProjects();
575 // } catch (JavaModelException e) {
579 // IResourceDelta[] children = delta.getAffectedChildren();
580 // for (int i = 0, length = children.length; i < length; i++) {
581 // this.checkProjectsBeingAddedOrRemoved(children[i]);
584 // case IResource.PROJECT :
585 // // NB: No need to check project's nature as if the project is not a java
587 // // - if the project is added or changed this is a noop for
588 // projectsBeingDeleted
589 // // - if the project is closed, it has already lost its java nature
590 // int deltaKind = delta.getKind();
591 // if (deltaKind == IResourceDelta.ADDED) {
592 // // remember project and its dependents
593 // IProject project = (IProject)resource;
594 // this.addToProjectsToUpdateWithDependents(project);
596 // // workaround for bug 15168 circular errors not reported
597 // if (JavaProject.hasJavaNature(project)) {
598 // this.addToParentInfo((JavaProject)JavaCore.create(project));
601 // } else if (deltaKind == IResourceDelta.CHANGED) {
602 // IProject project = (IProject)resource;
603 // if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
604 // // project opened or closed: remember project and its dependents
605 // this.addToProjectsToUpdateWithDependents(project);
607 // // workaround for bug 15168 circular errors not reported
608 // if (project.isOpen()) {
609 // if (JavaProject.hasJavaNature(project)) {
610 // this.addToParentInfo((JavaProject)JavaCore.create(project));
613 // JavaProject javaProject =
614 // (JavaProject)this.manager.getJavaModel().findJavaProject(project);
615 // if (javaProject != null) {
617 // javaProject.close();
618 // } catch (JavaModelException e) {
620 // this.removeFromParentInfo(javaProject);
623 // } else if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) {
624 // boolean wasJavaProject =
625 // this.manager.getJavaModel().findJavaProject(project) != null;
626 // boolean isJavaProject = JavaProject.hasJavaNature(project);
627 // if (wasJavaProject != isJavaProject) {
628 // // java nature added or removed: remember project and its dependents
629 // this.addToProjectsToUpdateWithDependents(project);
631 // // workaround for bug 15168 circular errors not reported
632 // if (isJavaProject) {
633 // this.addToParentInfo((JavaProject)JavaCore.create(project));
635 // JavaProject javaProject = (JavaProject)JavaCore.create(project);
637 // // flush classpath markers
639 // flushClasspathProblemMarkers(
640 // true, // flush cycle markers
641 // true //flush classpath format markers
644 // // remove problems and tasks created by the builder
645 // JavaBuilder.removeProblemsAndTasksFor(project);
649 // javaProject.close();
650 // } catch (JavaModelException e) {
652 // this.removeFromParentInfo(javaProject);
655 // // in case the project was removed then added then changed (see bug
657 // if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
658 // this.addToParentInfo((JavaProject)JavaCore.create(project));
662 // // workaround for bug 15168 circular errors not reported
663 // // in case the project was removed then added then changed
664 // if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
665 // this.addToParentInfo((JavaProject)JavaCore.create(project));
672 // private void checkSourceAttachmentChange(IResourceDelta delta, IResource
674 // IPath rootPath = (IPath)this.sourceAttachments.get(res.getFullPath());
675 // if (rootPath != null) {
676 // RootInfo rootInfo = this.rootInfo(rootPath, delta.getKind());
677 // if (rootInfo != null) {
678 // IJavaProject projectOfRoot = rootInfo.project;
679 // IPackageFragmentRoot root = null;
681 // // close the root so that source attachement cache is flushed
682 // root = projectOfRoot.findPackageFragmentRoot(rootPath);
683 // if (root != null) {
686 // } catch (JavaModelException e) {
688 // if (root == null) return;
689 // switch (delta.getKind()) {
690 // case IResourceDelta.ADDED:
691 // currentDelta().sourceAttached(root);
693 // case IResourceDelta.CHANGED:
694 // currentDelta().sourceDetached(root);
695 // currentDelta().sourceAttached(root);
697 // case IResourceDelta.REMOVED:
698 // currentDelta().sourceDetached(root);
705 * Closes the given element, which removes it from the cache of open
708 // protected static void close(Openable element) {
712 // } catch (JavaModelException e) {
717 * Generic processing for elements with changed contents:
719 * <li>The element is closed such that any subsequent accesses will re-open
720 * the element reflecting its new structure.
721 * <li>An entry is made in the delta reporting a content change (K_CHANGE
722 * with F_CONTENT flag set).
724 * Delta argument could be null if processing an external JAR change
726 // protected void contentChanged(Openable element, IResourceDelta delta) {
729 // int flags = IJavaElementDelta.F_CONTENT;
730 // if (element instanceof JarPackageFragmentRoot){
731 // flags |= IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED;
733 // currentDelta().changed(element, flags);
737 * Creates the openables corresponding to this resource. Returns null if
740 // protected Openable createElement(IResource resource, int elementType,
741 // RootInfo rootInfo) {
742 // if (resource == null) return null;
744 // IPath path = resource.getFullPath();
745 // IJavaElement element = null;
746 // switch (elementType) {
748 // case IJavaElement.JAVA_PROJECT:
750 // // note that non-java resources rooted at the project level will also
751 // enter this code with
752 // // an elementType JAVA_PROJECT (see #elementType(...)).
753 // if (resource instanceof IProject){
755 // this.popUntilPrefixOf(path);
757 // if (this.currentElement != null
758 // && this.currentElement.getElementType() == IJavaElement.JAVA_PROJECT
759 // && ((IJavaProject)this.currentElement).getProject().equals(resource)) {
760 // return this.currentElement;
762 // if (rootInfo != null && rootInfo.project.getProject().equals(resource)){
763 // element = (Openable)rootInfo.project;
766 // IProject proj = (IProject)resource;
767 // if (JavaProject.hasJavaNature(proj)) {
768 // element = JavaCore.create(proj);
770 // // java project may have been been closed or removed (look for
771 // // element amongst old java project s list).
772 // element = (Openable) manager.getJavaModel().findJavaProject(proj);
776 // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
777 // element = rootInfo == null ? JavaCore.create(resource) :
778 // rootInfo.project.getPackageFragmentRoot(resource);
780 // case IJavaElement.PACKAGE_FRAGMENT:
781 // // find the element that encloses the resource
782 // this.popUntilPrefixOf(path);
784 // if (this.currentElement == null) {
785 // element = rootInfo == null ? JavaCore.create(resource) :
786 // JavaModelManager.create(resource, rootInfo.project);
789 // IPackageFragmentRoot root = this.currentElement.getPackageFragmentRoot();
790 // if (root == null) {
791 // element = rootInfo == null ? JavaCore.create(resource) :
792 // JavaModelManager.create(resource, rootInfo.project);
793 // } else if (((JavaProject)root.getJavaProject()).contains(resource)) {
794 // // create package handle
795 // IPath pkgPath = path.removeFirstSegments(root.getPath().segmentCount());
796 // String pkg = ProjectPrefUtil.packageName(pkgPath);
797 // if (pkg == null) return null;
798 // element = root.getPackageFragment(pkg);
802 // case IJavaElement.COMPILATION_UNIT:
803 // case IJavaElement.CLASS_FILE:
804 // // find the element that encloses the resource
805 // this.popUntilPrefixOf(path);
807 // if (this.currentElement == null) {
808 // element = rootInfo == null ? JavaCore.create(resource) :
809 // JavaModelManager.create(resource, rootInfo.project);
811 // // find the package
812 // IPackageFragment pkgFragment = null;
813 // switch (this.currentElement.getElementType()) {
814 // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
815 // IPackageFragmentRoot root = (IPackageFragmentRoot)this.currentElement;
816 // IPath rootPath = root.getPath();
817 // IPath pkgPath = path.removeLastSegments(1);
819 // ProjectPrefUtil.packageName(pkgPath.removeFirstSegments(rootPath.segmentCount()));
820 // if (pkgName != null) {
821 // pkgFragment = root.getPackageFragment(pkgName);
824 // case IJavaElement.PACKAGE_FRAGMENT:
825 // Openable pkg = (Openable)this.currentElement;
826 // if (pkg.getPath().equals(path.removeLastSegments(1))) {
827 // pkgFragment = (IPackageFragment)pkg;
828 // } // else case of package x which is a prefix of x.y
830 // case IJavaElement.COMPILATION_UNIT:
831 // case IJavaElement.CLASS_FILE:
832 // pkgFragment = (IPackageFragment)this.currentElement.getParent();
835 // if (pkgFragment == null) {
836 // element = rootInfo == null ? JavaCore.create(resource) :
837 // JavaModelManager.create(resource, rootInfo.project);
839 // if (elementType == IJavaElement.COMPILATION_UNIT) {
840 // // create compilation unit handle
841 // // fileName validation has been done in elementType(IResourceDelta, int,
843 // String fileName = path.lastSegment();
844 // element = pkgFragment.getCompilationUnit(fileName);
846 // // create class file handle
847 // // fileName validation has been done in elementType(IResourceDelta, int,
849 // String fileName = path.lastSegment();
850 // element = pkgFragment.getClassFile(fileName);
856 // if (element == null) {
859 // this.currentElement = (Openable)element;
860 // return this.currentElement;
864 * Note that the project is about to be deleted.
866 // public void deleting(IProject project) {
869 // // discard indexing jobs that belong to this project so that the project
871 // // deleted without interferences from the index manager
872 // this.indexManager.discardJobs(project.getName());
874 // JavaProject javaProject = (JavaProject)JavaCore.create(project);
876 // // remember roots of this project
877 // if (this.removedRoots == null) {
878 // this.removedRoots = new HashMap();
880 // if (javaProject.isOpen()) {
881 // this.removedRoots.put(javaProject,
882 // javaProject.getPackageFragmentRoots());
884 // // compute roots without opening project
885 // this.removedRoots.put(
887 // javaProject.computePackageFragmentRoots(
888 // javaProject.getResolvedClasspath(true),
892 // javaProject.close();
894 // // workaround for bug 15168 circular errors not reported
895 // if (this.manager.javaProjectsCache == null) {
896 // this.manager.javaProjectsCache =
897 // this.manager.getJavaModel().getJavaProjects();
899 // this.removeFromParentInfo(javaProject);
901 // } catch (JavaModelException e) {
904 // this.addDependentProjects(project.getFullPath(), this.projectsToUpdate);
908 * Processing for an element that has been added:
910 * <li>If the element is a project, do nothing, and do not process
911 * children, as when a project is created it does not yet have any natures -
912 * specifically a java nature.
913 * <li>If the elemet is not a project, process it as added (see
914 * <code>basicElementAdded</code>.
916 * Delta argument could be null if processing an external JAR change
918 // protected void elementAdded(Openable element, IResourceDelta delta,
919 // RootInfo rootInfo) {
920 // int elementType = element.getElementType();
922 // if (elementType == IJavaElement.JAVA_PROJECT) {
923 // // project add is handled by JavaProject.configure() because
924 // // when a project is created, it does not yet have a java nature
925 // if (delta != null &&
926 // JavaProject.hasJavaNature((IProject)delta.getResource())) {
927 // addToParentInfo(element);
928 // if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
929 // Openable movedFromElement =
930 // (Openable)element.getJavaModel().getJavaProject(delta.getMovedFromPath().lastSegment());
931 // currentDelta().movedTo(element, movedFromElement);
933 // currentDelta().added(element);
935 // this.projectsToUpdate.add(element);
936 // this.updateRoots(element.getPath(), delta);
937 // this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
940 // addToParentInfo(element);
942 // // Force the element to be closed as it might have been opened
943 // // before the resource modification came in and it might have a new child
944 // // For example, in an IWorkspaceRunnable:
945 // // 1. create a package fragment p using a java model operation
946 // // 2. open package p
947 // // 3. add file X.java in folder p
948 // // When the resource delta comes in, only the addition of p is notified,
949 // // but the package p is already opened, thus its children are not
951 // // and it appears empty.
954 // if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_FROM) != 0)
956 // IPath movedFromPath = delta.getMovedFromPath();
957 // IResource res = delta.getResource();
958 // IResource movedFromRes;
959 // if (res instanceof IFile) {
960 // movedFromRes = res.getWorkspace().getRoot().getFile(movedFromPath);
962 // movedFromRes = res.getWorkspace().getRoot().getFolder(movedFromPath);
965 // // find the element type of the moved from element
966 // RootInfo movedFromInfo = this.enclosingRootInfo(movedFromPath,
967 // IResourceDelta.REMOVED);
968 // int movedFromType =
971 // IResourceDelta.REMOVED,
972 // element.getParent().getElementType(),
975 // // reset current element as it might be inside a nested root
976 // (popUntilPrefixOf() may use the outer root)
977 // this.currentElement = null;
979 // // create the moved from element
980 // Openable movedFromElement =
981 // elementType != IJavaElement.JAVA_PROJECT && movedFromType ==
982 // IJavaElement.JAVA_PROJECT ?
983 // null : // outside classpath
984 // this.createElement(movedFromRes, movedFromType, movedFromInfo);
985 // if (movedFromElement == null) {
986 // // moved from outside classpath
987 // currentDelta().added(element);
989 // currentDelta().movedTo(element, movedFromElement);
992 // currentDelta().added(element);
995 // switch (elementType) {
996 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
997 // // when a root is added, and is on the classpath, the project must be
999 // JavaProject project = (JavaProject) element.getJavaProject();
1000 // this.projectsToUpdate.add(project);
1001 // this.projectsForDependentNamelookupRefresh.add(project);
1004 // case IJavaElement.PACKAGE_FRAGMENT :
1005 // // get rid of namelookup since it holds onto obsolete cached info
1006 // project = (JavaProject) element.getJavaProject();
1008 // project.getJavaProjectElementInfo().setNameLookup(null);
1009 // this.projectsForDependentNamelookupRefresh.add(project);
1010 // } catch (JavaModelException e) {
1012 // // add subpackages
1013 // if (delta != null){
1014 // PackageFragmentRoot root = element.getPackageFragmentRoot();
1015 // String name = element.getElementName();
1016 // IResourceDelta[] children = delta.getAffectedChildren();
1017 // for (int i = 0, length = children.length; i < length; i++) {
1018 // IResourceDelta child = children[i];
1019 // IResource resource = child.getResource();
1020 // if (resource instanceof IFolder) {
1021 // String folderName = resource.getName();
1022 // if (ProjectPrefUtil.isValidFolderNameForPackage(folderName)) {
1023 // String subpkgName =
1024 // name.length() == 0 ?
1026 // name + "." + folderName; //$NON-NLS-1$
1027 // Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
1028 // this.updateIndex(subpkg, child);
1029 // this.elementAdded(subpkg, child, rootInfo);
1039 * Generic processing for a removed element:
1041 * <li>Close the element, removing its structure from the cache
1042 * <li>Remove the element from its parent's cache of children
1043 * <li>Add a REMOVED entry in the delta
1045 * Delta argument could be null if processing an external JAR change
1047 // protected void elementRemoved(Openable element, IResourceDelta delta,
1048 // RootInfo rootInfo) {
1050 // if (element.isOpen()) {
1053 // removeFromParentInfo(element);
1054 // int elementType = element.getElementType();
1055 // if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
1056 // IPath movedToPath = delta.getMovedToPath();
1057 // IResource res = delta.getResource();
1058 // IResource movedToRes;
1059 // switch (res.getType()) {
1060 // case IResource.PROJECT:
1062 // res.getWorkspace().getRoot().getProject(movedToPath.lastSegment());
1064 // case IResource.FOLDER:
1065 // movedToRes = res.getWorkspace().getRoot().getFolder(movedToPath);
1067 // case IResource.FILE:
1068 // movedToRes = res.getWorkspace().getRoot().getFile(movedToPath);
1074 // // find the element type of the moved from element
1075 // RootInfo movedToInfo = this.enclosingRootInfo(movedToPath,
1076 // IResourceDelta.ADDED);
1077 // int movedToType =
1078 // this.elementType(
1080 // IResourceDelta.ADDED,
1081 // element.getParent().getElementType(),
1084 // // reset current element as it might be inside a nested root
1085 // (popUntilPrefixOf() may use the outer root)
1086 // this.currentElement = null;
1088 // // create the moved To element
1089 // Openable movedToElement =
1090 // elementType != IJavaElement.JAVA_PROJECT && movedToType ==
1091 // IJavaElement.JAVA_PROJECT ?
1092 // null : // outside classpath
1093 // this.createElement(movedToRes, movedToType, movedToInfo);
1094 // if (movedToElement == null) {
1095 // // moved outside classpath
1096 // currentDelta().removed(element);
1098 // currentDelta().movedFrom(element, movedToElement);
1101 // currentDelta().removed(element);
1104 // switch (elementType) {
1105 // case IJavaElement.JAVA_MODEL :
1106 // this.indexManager.reset();
1108 // case IJavaElement.JAVA_PROJECT :
1109 // this.manager.removePerProjectInfo(
1110 // (JavaProject) element);
1111 // this.updateRoots(element.getPath(), delta);
1112 // this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
1114 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
1115 // JavaProject project = (JavaProject) element.getJavaProject();
1116 // this.projectsToUpdate.add(project);
1117 // this.projectsForDependentNamelookupRefresh.add(project);
1119 // case IJavaElement.PACKAGE_FRAGMENT :
1120 // //1G1TW2T - get rid of namelookup since it holds onto obsolete cached
1122 // project = (JavaProject) element.getJavaProject();
1124 // project.getJavaProjectElementInfo().setNameLookup(null);
1125 // this.projectsForDependentNamelookupRefresh.add(project);
1126 // } catch (JavaModelException e) {
1128 // // remove subpackages
1129 // if (delta != null){
1130 // PackageFragmentRoot root = element.getPackageFragmentRoot();
1131 // String name = element.getElementName();
1132 // IResourceDelta[] children = delta.getAffectedChildren();
1133 // for (int i = 0, length = children.length; i < length; i++) {
1134 // IResourceDelta child = children[i];
1135 // IResource resource = child.getResource();
1136 // if (resource instanceof IFolder) {
1137 // String folderName = resource.getName();
1138 // if (ProjectPrefUtil.isValidFolderNameForPackage(folderName)) {
1139 // String subpkgName =
1140 // name.length() == 0 ?
1142 // name + "." + folderName; //$NON-NLS-1$
1143 // Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
1144 // this.updateIndex(subpkg, child);
1145 // this.elementRemoved(subpkg, child, rootInfo);
1154 * Returns the type of the java element the given delta matches to. Returns
1155 * NON_JAVA_RESOURCE if unknown (e.g. a non-java resource or excluded .java
1158 // private int elementType(IResource res, int kind, int parentType, RootInfo
1160 // switch (parentType) {
1161 // case IJavaElement.JAVA_MODEL:
1162 // // case of a movedTo or movedFrom project (other cases are handled in
1163 // processResourceDelta(...)
1164 // return IJavaElement.JAVA_PROJECT;
1165 // case NON_JAVA_RESOURCE:
1166 // case IJavaElement.JAVA_PROJECT:
1167 // if (rootInfo == null) {
1168 // rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
1170 // if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
1171 // return IJavaElement.PACKAGE_FRAGMENT_ROOT;
1173 // return NON_JAVA_RESOURCE; // not yet in a package fragment root or root
1174 // of another project
1176 // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
1177 // case IJavaElement.PACKAGE_FRAGMENT:
1178 // if (rootInfo == null) {
1179 // rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
1181 // if (rootInfo == null || ProjectPrefUtil.isExcluded(res,
1182 // rootInfo.exclusionPatterns)) {
1183 // return NON_JAVA_RESOURCE;
1185 // if (res instanceof IFolder) {
1186 // if (ProjectPrefUtil.isValidFolderNameForPackage(res.getName())) {
1187 // return IJavaElement.PACKAGE_FRAGMENT;
1189 // return NON_JAVA_RESOURCE;
1192 // String fileName = res.getName();
1193 // if (ProjectPrefUtil.isValidCompilationUnitName(fileName)) {
1194 // return IJavaElement.COMPILATION_UNIT;
1195 // } else if (ProjectPrefUtil.isValidClassFileName(fileName)) {
1196 // return IJavaElement.CLASS_FILE;
1197 // } else if (this.rootInfo(res.getFullPath(), kind) != null) {
1198 // // case of proj=src=bin and resource is a jar file on the classpath
1199 // return IJavaElement.PACKAGE_FRAGMENT_ROOT;
1201 // return NON_JAVA_RESOURCE;
1205 // return NON_JAVA_RESOURCE;
1209 * Answer a combination of the lastModified stamp and the size. Used for
1210 * detecting external JAR changes
1212 // public static long getTimeStamp(File file) {
1213 // return file.lastModified() + file.length();
1216 // public void initializeRoots() {
1217 // // remember roots infos as old roots infos
1218 // this.oldRoots = this.roots == null ? new HashMap() : this.roots;
1219 // this.oldOtherRoots = this.otherRoots == null ? new HashMap()
1220 // : this.otherRoots;
1222 // // recompute root infos only if necessary
1223 // if (!rootsAreStale)
1226 // this.roots = new HashMap();
1227 // this.otherRoots = new HashMap();
1228 // this.sourceAttachments = new HashMap();
1230 // IJavaModel model = this.manager.getJavaModel();
1231 // IJavaProject[] projects;
1233 // projects = model.getJavaProjects();
1234 // } catch (JavaModelException e) {
1235 // // nothing can be done
1238 // for (int i = 0, length = projects.length; i < length; i++) {
1239 // IJavaProject project = projects[i];
1240 // IClasspathEntry[] classpath;
1242 // classpath = project.getResolvedClasspath(true);
1243 // } catch (JavaModelException e) {
1244 // // continue with next project
1247 // for (int j = 0, classpathLength = classpath.length; j < classpathLength; j++) {
1248 // IClasspathEntry entry = classpath[j];
1249 // if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT)
1253 // IPath path = entry.getPath();
1254 // if (this.roots.get(path) == null) {
1255 // this.roots.put(path, new RootInfo(project, path,
1256 // ((ClasspathEntry) entry)
1257 // .fullExclusionPatternChars()));
1259 // ArrayList rootList = (ArrayList) this.otherRoots.get(path);
1260 // if (rootList == null) {
1261 // rootList = new ArrayList();
1262 // this.otherRoots.put(path, rootList);
1264 // rootList.add(new RootInfo(project, path,
1265 // ((ClasspathEntry) entry)
1266 // .fullExclusionPatternChars()));
1269 // // source attachment path
1270 // if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY)
1272 // QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID,
1273 // "sourceattachment: " + path.toOSString()); //$NON-NLS-1$;
1274 // String propertyString = null;
1276 // propertyString = ResourcesPlugin.getWorkspace().getRoot()
1277 // .getPersistentProperty(qName);
1278 // } catch (CoreException e) {
1281 // IPath sourceAttachmentPath;
1282 // // if (propertyString != null) {
1284 // // propertyString.lastIndexOf(JarPackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER);
1285 // // sourceAttachmentPath = (index < 0) ? new Path(propertyString)
1286 // // : new Path(propertyString.substring(0, index));
1288 // sourceAttachmentPath = entry.getSourceAttachmentPath();
1290 // if (sourceAttachmentPath != null) {
1291 // this.sourceAttachments.put(sourceAttachmentPath, path);
1295 // this.rootsAreStale = false;
1299 * Returns whether a given delta contains some information relevant to the
1300 * JavaModel, in particular it will not consider SYNC or MARKER only deltas.
1302 public boolean isAffectedBy(IResourceDelta rootDelta) {
1303 // if (rootDelta == null) System.out.println("NULL DELTA");
1304 // long start = System.currentTimeMillis();
1305 if (rootDelta != null) {
1306 // use local exception to quickly escape from delta traversal
1307 class FoundRelevantDeltaException extends RuntimeException {
1312 private static final long serialVersionUID = -7732598607464929404L;
1315 rootDelta.accept(new IResourceDeltaVisitor() {
1316 public boolean visit(IResourceDelta delta)
1317 throws CoreException {
1318 switch (delta.getKind()) {
1319 case IResourceDelta.ADDED:
1320 case IResourceDelta.REMOVED:
1321 throw new FoundRelevantDeltaException();
1322 case IResourceDelta.CHANGED:
1323 // if any flag is set but SYNC or MARKER, this delta
1324 // should be considered
1325 if (delta.getAffectedChildren().length == 0 // only
1330 && (delta.getFlags() & ~(IResourceDelta.SYNC | IResourceDelta.MARKERS)) != 0) {
1331 throw new FoundRelevantDeltaException();
1337 } catch (FoundRelevantDeltaException e) {
1338 // System.out.println("RELEVANT DELTA detected in: "+
1339 // (System.currentTimeMillis() - start));
1341 } catch (CoreException e) { // ignore delta if not able to traverse
1344 // System.out.println("IGNORE SYNC DELTA took: "+
1345 // (System.currentTimeMillis() - start));
1350 * Returns whether the given resource is in one of the given output folders
1351 * and if it is filtered out from this output folder.
1353 // private boolean isResFilteredFromOutput(OutputsInfo info, IResource res,
1354 // int elementType) {
1355 // if (info != null) {
1356 // IPath resPath = res.getFullPath();
1357 // for (int i = 0; i < info.outputCount; i++) {
1358 // if (info.paths[i].isPrefixOf(resPath)) {
1359 // if (info.traverseModes[i] != IGNORE) {
1360 // // case of bin=src
1361 // if (info.traverseModes[i] == SOURCE
1362 // && elementType == IJavaElement.CLASS_FILE) {
1365 // // case of .class file under project and no source
1368 // if (elementType == IJavaElement.JAVA_PROJECT
1369 // && res instanceof IFile
1370 // && PHPFileUtil.isPHPFile((IFile) res)) {
1384 * Merges all awaiting deltas.
1386 private IJavaElementDelta mergeDeltas(Collection deltas) {
1387 if (deltas.size() == 0)
1389 if (deltas.size() == 1)
1390 return (IJavaElementDelta) deltas.iterator().next();
1394 .println("MERGING " + deltas.size() + " DELTAS [" + Thread.currentThread() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1397 Iterator iterator = deltas.iterator();
1398 JavaElementDelta rootDelta = new JavaElementDelta(
1399 this.manager.javaModel);
1400 boolean insertedTree = false;
1401 while (iterator.hasNext()) {
1402 JavaElementDelta delta = (JavaElementDelta) iterator.next();
1404 System.out.println(delta.toString());
1406 IJavaElement element = delta.getElement();
1407 if (this.manager.javaModel.equals(element)) {
1408 IJavaElementDelta[] children = delta.getAffectedChildren();
1409 for (int j = 0; j < children.length; j++) {
1410 JavaElementDelta projectDelta = (JavaElementDelta) children[j];
1411 rootDelta.insertDeltaTree(projectDelta.getElement(),
1413 insertedTree = true;
1415 IResourceDelta[] resourceDeltas = delta.getResourceDeltas();
1416 if (resourceDeltas != null) {
1417 for (int i = 0, length = resourceDeltas.length; i < length; i++) {
1418 rootDelta.addResourceDelta(resourceDeltas[i]);
1419 insertedTree = true;
1423 rootDelta.insertDeltaTree(element, delta);
1424 insertedTree = true;
1433 * Check whether the updated file is affecting some of the properties of a
1434 * given project (like its classpath persisted as a file). Also force
1435 * classpath problems to be refresh if not running in autobuild mode. NOTE:
1436 * It can induce resource changes, and cannot be called during POST_CHANGE
1440 // public void performPreBuildCheck(
1441 // IResourceDelta delta,
1442 // IJavaElement parent) {
1444 // IResource resource = delta.getResource();
1445 // IJavaElement element = null;
1446 // boolean processChildren = false;
1448 // switch (resource.getType()) {
1450 // case IResource.ROOT :
1451 // if (delta.getKind() == IResourceDelta.CHANGED) {
1452 // element = JavaCore.create(resource);
1453 // processChildren = true;
1456 // case IResource.PROJECT :
1457 // int kind = delta.getKind();
1459 // case IResourceDelta.CHANGED:
1460 // // do not visit non-java projects (see bug 16140 Non-java project gets
1462 // IProject project = (IProject)resource;
1463 // if (JavaProject.hasJavaNature(project)) {
1464 // element = JavaCore.create(resource);
1465 // processChildren = true;
1467 // (JavaModelManager.getJavaModelManager().getJavaModel().findJavaProject(project)
1469 // // project had the java nature
1470 // this.rootsAreStale = true;
1472 // // remove classpath cache so that initializeRoots() will not consider the
1473 // project has a classpath
1474 // this.manager.removePerProjectInfo((JavaProject)JavaCore.create(project));
1477 // case IResourceDelta.ADDED:
1478 // this.rootsAreStale = true;
1480 // case IResourceDelta.REMOVED:
1481 // // remove classpath cache so that initializeRoots() will not consider the
1482 // project has a classpath
1483 // this.manager.removePerProjectInfo((JavaProject)JavaCore.create(resource));
1485 // this.rootsAreStale = true;
1489 // case IResource.FILE :
1490 // if (parent.getElementType() == IJavaElement.JAVA_PROJECT) {
1491 // IFile file = (IFile) resource;
1492 // JavaProject project = (JavaProject) parent;
1494 // /* check classpath file change */
1495 // if (file.getName().equals(JavaProject.CLASSPATH_FILENAME)) {
1496 // reconcileClasspathFileUpdate(delta, file, project);
1497 // this.rootsAreStale = true;
1500 // // /* check custom preference file change */
1501 // // if (file.getName().equals(JavaProject.PREF_FILENAME)) {
1502 // // reconcilePreferenceFileUpdate(delta, file, project);
1508 // if (processChildren) {
1509 // IResourceDelta[] children = delta.getAffectedChildren();
1510 // for (int i = 0; i < children.length; i++) {
1511 // performPreBuildCheck(children[i], element);
1515 // private void popUntilPrefixOf(IPath path) {
1516 // while (this.currentElement != null) {
1517 // IPath currentElementPath = null;
1518 // if (this.currentElement instanceof IPackageFragmentRoot) {
1519 // currentElementPath =
1520 // ((IPackageFragmentRoot)this.currentElement).getPath();
1522 // IResource currentElementResource = this.currentElement.getResource();
1523 // if (currentElementResource != null) {
1524 // currentElementPath = currentElementResource.getFullPath();
1527 // if (currentElementPath != null) {
1528 // if (this.currentElement instanceof IPackageFragment
1529 // && this.currentElement.getElementName().length() == 0
1530 // && currentElementPath.segmentCount() != path.segmentCount()-1) {
1531 // // default package and path is not a direct child
1532 // this.currentElement = (Openable)this.currentElement.getParent();
1534 // if (currentElementPath.isPrefixOf(path)) {
1538 // this.currentElement = (Openable)this.currentElement.getParent();
1542 * Converts a <code>IResourceDelta</code> rooted in a
1543 * <code>Workspace</code> into the corresponding set of
1544 * <code>IJavaElementDelta</code>, rooted in the relevant
1545 * <code>JavaModel</code>s.
1549 * Update the JavaModel according to a .classpath file change. The file can
1550 * have changed as a result of a previous call to
1551 * JavaProject#setRawClasspath or as a result of some user update (through
1554 // void reconcileClasspathFileUpdate(IResourceDelta delta, IFile file,
1555 // JavaProject project) {
1557 // switch (delta.getKind()) {
1558 // case IResourceDelta.REMOVED : // recreate one based on in-memory
1561 // JavaModelManager.PerProjectInfo info =
1562 // JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
1563 // if (info.classpath != null) { // if there is an in-memory classpath
1564 // project.saveClasspath(info.classpath, info.outputLocation);
1566 // } catch (JavaModelException e) {
1567 // if (project.getProject().isAccessible()) {
1568 // ProjectPrefUtil.log(e, "Could not save classpath for "+
1569 // project.getPath()); //$NON-NLS-1$
1573 // case IResourceDelta.CHANGED :
1574 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0 // only consider
1576 // && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move
1577 // and overide scenario (see
1578 // http://dev.eclipse.org/bugs/show_bug.cgi?id=21420)
1580 // case IResourceDelta.ADDED :
1581 // // check if any actual difference
1582 // project.flushClasspathProblemMarkers(false, true);
1583 // boolean wasSuccessful = false; // flag recording if .classpath file
1584 // change got reflected
1586 // // force to (re)read the property file
1587 // IClasspathEntry[] fileEntries = project.readClasspathFile(true/*create
1588 // markers*/, false/*don't log problems*/);
1589 // if (fileEntries == null)
1590 // break; // could not read, ignore
1591 // JavaModelManager.PerProjectInfo info =
1592 // JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
1593 // if (info.classpath != null) { // if there is an in-memory classpath
1594 // if (project.isClasspathEqualsTo(info.classpath, info.outputLocation,
1596 // wasSuccessful = true;
1601 // // will force an update of the classpath/output location based on the
1603 // // extract out the output location
1604 // IPath outputLocation = null;
1605 // if (fileEntries != null && fileEntries.length > 0) {
1606 // IClasspathEntry entry = fileEntries[fileEntries.length - 1];
1607 // if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
1608 // outputLocation = entry.getPath();
1609 // IClasspathEntry[] copy = new IClasspathEntry[fileEntries.length - 1];
1610 // System.arraycopy(fileEntries, 0, copy, 0, copy.length);
1611 // fileEntries = copy;
1614 // // restore output location
1615 // if (outputLocation == null) {
1616 // outputLocation = SetClasspathOperation.ReuseOutputLocation;
1617 // // clean mode will also default to reusing current one
1619 // project.setRawClasspath(
1623 // true, // canChangeResource
1624 // project.getResolvedClasspath(true), // ignoreUnresolvedVariable
1625 // true, // needValidation
1626 // false); // no need to save
1628 // // if reach that far, the classpath file change got absorbed
1629 // wasSuccessful = true;
1630 // } catch (RuntimeException e) {
1631 // // setRawClasspath might fire a delta, and a listener may throw an
1633 // if (project.getProject().isAccessible()) {
1634 // ProjectPrefUtil.log(e, "Could not set classpath for "+
1635 // project.getPath()); //$NON-NLS-1$
1638 // } catch (JavaModelException e) { // CP failed validation
1639 // if (project.getProject().isAccessible()) {
1640 // if (e.getJavaModelStatus().getException() instanceof CoreException) {
1641 // // happens if the .classpath could not be written to disk
1642 // project.createClasspathProblemMarker(new JavaModelStatus(
1643 // IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1644 // ProjectPrefUtil.bind("classpath.couldNotWriteClasspathFile",
1645 // project.getElementName(), e.getMessage()))); //$NON-NLS-1$
1647 // project.createClasspathProblemMarker(new JavaModelStatus(
1648 // IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1649 // ProjectPrefUtil.bind("classpath.invalidClasspathInClasspathFile",
1650 // project.getElementName(), e.getMessage()))); //$NON-NLS-1$
1655 // if (!wasSuccessful) {
1657 // project.setRawClasspath0(JavaProject.INVALID_CLASSPATH);
1658 // project.updatePackageFragmentRoots();
1659 // } catch (JavaModelException e) {
1666 * Update the JavaModel according to a .jprefs file change. The file can
1667 * have changed as a result of a previous call to JavaProject#setOptions or
1668 * as a result of some user update (through repository) Unused until
1669 * preference file get shared (.jpref)
1671 // void reconcilePreferenceFileUpdate(IResourceDelta delta, IFile file,
1672 // JavaProject project) {
1674 // switch (delta.getKind()) {
1675 // case IResourceDelta.REMOVED : // flush project custom settings
1676 // project.setOptions(null);
1678 // case IResourceDelta.CHANGED :
1679 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0 // only consider
1681 // && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move
1682 // and overide scenario
1684 // identityCheck : { // check if any actual difference
1685 // // force to (re)read the property file
1686 // Preferences filePreferences = project.loadPreferences();
1687 // if (filePreferences == null){
1688 // project.setOptions(null); // should have got removed delta.
1691 // Preferences projectPreferences = project.getPreferences();
1692 // if (projectPreferences == null) return; // not a Java project
1694 // // compare preferences set to their default
1695 // String[] defaultProjectPropertyNames =
1696 // projectPreferences.defaultPropertyNames();
1697 // String[] defaultFilePropertyNames =
1698 // filePreferences.defaultPropertyNames();
1699 // if (defaultProjectPropertyNames.length ==
1700 // defaultFilePropertyNames.length) {
1701 // for (int i = 0; i < defaultProjectPropertyNames.length; i++){
1702 // String propertyName = defaultProjectPropertyNames[i];
1704 // (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1705 // break identityCheck;
1708 // } else break identityCheck;
1710 // // compare custom preferences not set to their default
1711 // String[] projectPropertyNames = projectPreferences.propertyNames();
1712 // String[] filePropertyNames = filePreferences.propertyNames();
1713 // if (projectPropertyNames.length == filePropertyNames.length) {
1714 // for (int i = 0; i < projectPropertyNames.length; i++){
1715 // String propertyName = projectPropertyNames[i];
1717 // (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1718 // break identityCheck;
1721 // } else break identityCheck;
1723 // // identical - do nothing
1726 // case IResourceDelta.ADDED :
1727 // // not identical, create delta and reset cached preferences
1728 // project.setPreferences(null);
1730 // //fCurrentDelta.changed(project, IJavaElementDelta.F_OPTIONS_CHANGED);
1734 * Registers the given delta with this delta processor.
1736 public void registerJavaModelDelta(IJavaElementDelta delta) {
1737 this.javaModelDeltas.add(delta);
1741 * Removes the given element from its parents cache of children. If the
1742 * element does not have a parent, or the parent is not currently open, this
1745 protected void removeFromParentInfo(Openable child) {
1747 Openable parent = (Openable) child.getParent();
1748 if (parent != null && parent.isOpen()) {
1750 JavaElementInfo info = (JavaElementInfo) parent
1752 info.removeChild(child);
1753 } catch (JavaModelException e) {
1754 // do nothing - we already checked if open
1760 * Notification that some resource changes have happened on the platform,
1761 * and that the Java Model should update any required internal structures
1762 * such that its elements remain consistent. Translates
1763 * <code>IResourceDeltas</code> into <code>IJavaElementDeltas</code>.
1765 * @see IResourceDelta
1768 public void resourceChanged(IResourceChangeEvent event) {
1769 if (event.getSource() instanceof IWorkspace) {
1770 int eventType = this.overridenEventType == -1 ? event.getType()
1771 : this.overridenEventType;
1772 IResource resource = event.getResource();
1773 IResourceDelta delta = event.getDelta();
1775 switch (eventType) {
1776 case IResourceChangeEvent.PRE_DELETE:
1778 if (resource.getType() == IResource.PROJECT
1779 && ((IProject) resource)
1780 .hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
1782 deleting((IProject) resource);
1784 } catch (CoreException e) {
1785 // project doesn't exist or is not open: ignore
1789 case IResourceChangeEvent.POST_CHANGE:
1790 if (isAffectedBy(delta)) { // avoid populating for SYNC or
1795 // checkProjectsBeingAddedOrRemoved(delta);
1796 // if (this.refreshedElements != null) {
1797 // createExternalArchiveDelta(null);
1799 IJavaElementDelta translatedDelta = processResourceDelta(delta);
1800 if (translatedDelta != null) {
1801 registerJavaModelDelta(translatedDelta);
1806 // notifyTypeHierarchies(this.state.elementChangedListeners,
1807 // this.state.elementChangedListenerCount);
1808 fire(null, ElementChangedEvent.POST_CHANGE);
1810 // workaround for bug 15168 circular errors not reported
1811 this.state.modelProjectsCache = null;
1812 this.removedRoots = null;
1817 case IResourceChangeEvent.PRE_BUILD:
1818 DeltaProcessingState.ProjectUpdateInfo[] updates = this.state
1819 .removeAllProjectUpdates();
1820 if (updates != null) {
1821 for (int i = 0, length = updates.length; i < length; i++) {
1823 updates[i].updateProjectReferencesIfNecessary();
1824 } catch (JavaModelException e) {
1829 // this.processPostChange = false;
1830 if (isAffectedBy(delta)) { // avoid populating for SYNC or
1832 // updateClasspathMarkers(delta);
1833 PHPBuilder.buildStarting();
1835 // does not fire any deltas
1838 case IResourceChangeEvent.POST_BUILD:
1839 PHPBuilder.buildFinished();
1843 // // jsurfer TODO compare 3.0 sources
1844 // if (event.getSource() instanceof IWorkspace) {
1845 // int eventType = this.overridenEventType == -1 ? event.getType() :
1846 // this.overridenEventType;
1847 // IResource resource = event.getResource();
1848 // IResourceDelta delta = event.getDelta();
1850 // switch(eventType){
1851 // case IResourceChangeEvent.PRE_DELETE :
1853 // if(resource.getType() == IResource.PROJECT
1854 // && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
1855 // // TODO jsurfer temp-del
1856 // // this.deleting((IProject)resource);
1858 // } catch(CoreException e){
1862 // case IResourceChangeEvent.PRE_BUILD :
1863 // // TODO jsurfer temp-del
1864 // // if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER
1866 // // this.checkProjectsBeingAddedOrRemoved(delta);
1868 // // // update the classpath related markers
1869 // // this.updateClasspathMarkers();
1871 // // // the following will close project if affected by the property
1874 // // // don't fire classpath change deltas right away, but batch them
1875 // // this.manager.stopDeltas();
1876 // // this.performPreBuildCheck(delta, null);
1878 // // this.manager.startDeltas();
1881 // // only fire already computed deltas (resource ones will be processed
1882 // in post change only)
1883 // this.manager.fire(null, ElementChangedEvent.PRE_AUTO_BUILD);
1886 // case IResourceChangeEvent.POST_BUILD :
1887 // // TODO jsurfer temp-del
1888 // // JavaBuilder.finishedBuilding(event);
1891 // case IResourceChangeEvent.POST_CHANGE :
1892 // // TODO jsurfer temp-del
1893 // // if (isAffectedBy(delta)) {
1895 // // if (this.refreshedElements != null) {
1897 // // createExternalArchiveDelta(null);
1898 // // } catch (JavaModelException e) {
1899 // // e.printStackTrace();
1902 // // IJavaElementDelta translatedDelta =
1903 // this.processResourceDelta(delta);
1904 // // if (translatedDelta != null) {
1905 // // this.manager.registerJavaModelDelta(translatedDelta);
1907 // // this.manager.fire(null, ElementChangedEvent.POST_CHANGE);
1909 // // // workaround for bug 15168 circular errors not reported
1910 // // this.manager.javaProjectsCache = null;
1911 // // this.removedRoots = null;
1919 * Turns the firing mode to on. That is, deltas that are/have been
1920 * registered will be fired.
1922 private void startDeltas() {
1923 this.isFiring = true;
1927 * Turns the firing mode to off. That is, deltas that are/have been
1928 * registered will not be fired until deltas are started again.
1930 private void stopDeltas() {
1931 this.isFiring = false;
1935 * Note that the project is about to be deleted.
1937 private void deleting(IProject project) {
1940 // discard indexing jobs that belong to this project so that the
1942 // deleted without interferences from the index manager
1943 // this.manager.indexManager.discardJobs(project.getName());
1945 JavaProject javaProject = (JavaProject) JavaCore.create(project);
1947 // remember roots of this project
1948 if (this.removedRoots == null) {
1949 this.removedRoots = new HashMap();
1951 if (javaProject.isOpen()) {
1952 this.removedRoots.put(javaProject, javaProject
1953 .getPackageFragmentRoots());
1955 // compute roots without opening project
1956 // this.removedRoots.put(
1958 // javaProject.computePackageFragmentRoots(
1959 // javaProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/,
1960 // false/*don't generateMarkerOnError*/, false/*don't
1961 // returnResolutionInProgress*/),
1965 javaProject.close();
1967 // workaround for bug 15168 circular errors not reported
1968 if (this.state.modelProjectsCache == null) {
1969 this.state.modelProjectsCache = this.manager.getJavaModel()
1972 this.removeFromParentInfo(javaProject);
1974 } catch (JavaModelException e) {
1975 // java project doesn't exist: ignore
1980 * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code>
1981 * into the corresponding set of <code>IJavaElementDelta</code>, rooted
1982 * in the relevant <code>JavaModel</code>s.
1984 private IJavaElementDelta processResourceDelta(IResourceDelta changes) {
1987 IJavaModel model = this.manager.getJavaModel();
1988 if (!model.isOpen()) {
1989 // force opening of java model so that java element delta are
1993 } catch (JavaModelException e) {
1995 e.printStackTrace();
2000 this.state.initializeRoots();
2001 this.currentElement = null;
2003 // get the workspace delta, and start processing there.
2004 IResourceDelta[] deltas = changes.getAffectedChildren();
2005 for (int i = 0; i < deltas.length; i++) {
2006 IResourceDelta delta = deltas[i];
2007 IResource res = delta.getResource();
2009 // find out the element type
2010 // RootInfo rootInfo = null;
2012 IProject proj = (IProject) res;
2013 boolean wasJavaProject = this.manager.getJavaModel()
2014 .findJavaProject(proj) != null;
2015 boolean isJavaProject = JavaProject.hasJavaNature(proj);
2016 if (!wasJavaProject && !isJavaProject) {
2017 elementType = NON_JAVA_RESOURCE;
2019 // rootInfo = this.enclosingRootInfo(res.getFullPath(),
2020 // delta.getKind());
2021 // if (rootInfo != null &&
2022 // rootInfo.isRootOfProject(res.getFullPath())) {
2023 // elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT;
2025 elementType = IJavaElement.JAVA_PROJECT;
2030 // this.traverseDelta(delta, elementType, rootInfo, null);
2032 if (elementType == NON_JAVA_RESOURCE
2033 || (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { // project
2041 // add child as non java resource
2042 nonJavaResourcesChanged((JavaModel) model, delta);
2043 } catch (JavaModelException e) {
2044 // java model could not be opened
2049 // refreshPackageFragmentRoots();
2050 // resetProjectCaches();
2052 return this.currentDelta;
2054 this.currentDelta = null;
2055 // this.rootsToRefresh.clear();
2056 // this.projectCachesToReset.clear();
2061 * Converts an <code>IResourceDelta</code> and its children into the
2062 * corresponding <code>IJavaElementDelta</code>s.
2064 // private void traverseDelta(
2065 // IResourceDelta delta,
2067 // RootInfo rootInfo,
2068 // OutputsInfo outputsInfo) {
2070 // IResource res = delta.getResource();
2072 // // set stack of elements
2073 // if (this.currentElement == null && rootInfo != null) {
2074 // // this.currentElement = rootInfo.project;
2077 // // process current delta
2078 // boolean processChildren = true;
2079 // if (res instanceof IProject) {
2080 // processChildren =
2081 // this.updateCurrentDeltaAndIndex(
2083 // elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ?
2084 // IJavaElement.JAVA_PROJECT : // case of prj=src
2087 // } else if (rootInfo != null) {
2088 // processChildren = this.updateCurrentDeltaAndIndex(delta, elementType,
2091 // // not yet inside a package fragment root
2092 // processChildren = true;
2095 // // get the project's output locations and traverse mode
2096 // if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
2098 // // process children if needed
2099 // if (processChildren) {
2100 // IResourceDelta[] children = delta.getAffectedChildren();
2101 // boolean oneChildOnClasspath = false;
2102 // int length = children.length;
2103 // IResourceDelta[] orphanChildren = null;
2104 // Openable parent = null;
2105 // boolean isValidParent = true;
2106 // for (int i = 0; i < length; i++) {
2107 // IResourceDelta child = children[i];
2108 // IResource childRes = child.getResource();
2110 // // check source attachment change
2111 // this.checkSourceAttachmentChange(child, childRes);
2113 // // find out whether the child is a package fragment root of the current
2115 // IPath childPath = childRes.getFullPath();
2116 // int childKind = child.getKind();
2117 // RootInfo childRootInfo = this.rootInfo(childPath, childKind);
2118 // if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
2119 // // package fragment root of another project (dealt with later)
2120 // childRootInfo = null;
2123 // // compute child type
2125 // this.elementType(
2129 // rootInfo == null ? childRootInfo : rootInfo
2132 // // is childRes in the output folder and is it filtered out ?
2133 // boolean isResFilteredFromOutput =
2134 // this.isResFilteredFromOutput(outputsInfo, childRes, childType);
2136 // boolean isNestedRoot = rootInfo != null && childRootInfo != null;
2137 // if (!isResFilteredFromOutput
2138 // && !isNestedRoot) { // do not treat as non-java rsc if nested root
2140 // this.traverseDelta(child, childType, rootInfo == null ? childRootInfo :
2141 // rootInfo, outputsInfo); // traverse delta for child in the same project
2143 // if (childType == NON_JAVA_RESOURCE) {
2144 // if (rootInfo != null) { // if inside a package fragment root
2145 // if (!isValidParent) continue;
2146 // if (parent == null) {
2147 // // find the parent of the non-java resource to attach to
2148 // if (this.currentElement == null
2149 // || !rootInfo.project.equals(this.currentElement.getJavaProject())) { //
2150 // note if currentElement is the IJavaModel, getJavaProject() is null
2151 // // force the currentProject to be used
2152 // this.currentElement = rootInfo.project;
2154 // if (elementType == IJavaElement.JAVA_PROJECT
2155 // || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT
2156 // && res instanceof IProject)) {
2157 // // NB: attach non-java resource to project (not to its package fragment
2159 // parent = rootInfo.project;
2161 // parent = this.createElement(res, elementType, rootInfo);
2163 // if (parent == null) {
2164 // isValidParent = false;
2168 // // add child as non java resource
2170 // nonJavaResourcesChanged(parent, child);
2171 // } catch (JavaModelException e) {
2175 // // the non-java resource (or its parent folder) will be attached to the
2177 // if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
2178 // orphanChildren[i] = child;
2181 // oneChildOnClasspath = true;
2184 // oneChildOnClasspath = true; // to avoid reporting child delta as non-java
2188 // // if child is a nested root
2189 // // or if it is not a package fragment root of the current project
2190 // // but it is a package fragment root of another project, traverse delta
2193 // || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath,
2194 // childKind)) != null)) {
2195 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT,
2196 // childRootInfo, null); // binary output of childRootInfo.project cannot be
2200 // // if the child is a package fragment root of one or several other
2202 // ArrayList rootList;
2203 // if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) {
2204 // Iterator iterator = rootList.iterator();
2205 // while (iterator.hasNext()) {
2206 // childRootInfo = (RootInfo) iterator.next();
2207 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT,
2208 // childRootInfo, null); // binary output of childRootInfo.project cannot be
2213 // if (orphanChildren != null
2214 // && (oneChildOnClasspath // orphan children are siblings of a package
2216 // || res instanceof IProject)) { // non-java resource directly under a
2219 // // attach orphan children
2220 // IProject rscProject = res.getProject();
2221 // JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
2222 // if (adoptiveProject != null
2223 // && JavaProject.hasJavaNature(rscProject)) { // delta iff Java project
2225 // for (int i = 0; i < length; i++) {
2226 // if (orphanChildren[i] != null) {
2228 // nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
2229 // } catch (JavaModelException e) {
2235 // } // else resource delta will be added by parent
2236 // } // else resource delta will be added by parent
2238 private void notifyListeners(IJavaElementDelta deltaToNotify,
2239 int eventType, IElementChangedListener[] listeners,
2240 int[] listenerMask, int listenerCount) {
2241 final ElementChangedEvent extraEvent = new ElementChangedEvent(
2242 deltaToNotify, eventType);
2243 for (int i = 0; i < listenerCount; i++) {
2244 if ((listenerMask[i] & eventType) != 0) {
2245 final IElementChangedListener listener = listeners[i];
2249 .print("Listener #" + (i + 1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
2250 start = System.currentTimeMillis();
2252 // wrap callbacks with Safe runnable for subsequent listeners to
2253 // be called when some are causing grief
2254 SafeRunner.run(new ISafeRunnable() {
2255 public void handleException(Throwable exception) {
2258 "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
2261 public void run() throws Exception {
2262 listener.elementChanged(extraEvent);
2267 .println(" -> " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
2273 // private void notifyTypeHierarchies(IElementChangedListener[] listeners,
2274 // int listenerCount) {
2275 // for (int i= 0; i < listenerCount; i++) {
2276 // final IElementChangedListener listener = listeners[i];
2277 // if (!(listener instanceof TypeHierarchy)) continue;
2279 // // wrap callbacks with Safe runnable for subsequent listeners to be
2280 // called when some are causing grief
2281 // Platform.run(new ISafeRunnable() {
2282 // public void handleException(Throwable exception) {
2283 // ProjectPrefUtil.log(exception, "Exception occurred in listener of Java
2284 // element change notification"); //$NON-NLS-1$
2286 // public void run() throws Exception {
2287 // TypeHierarchy typeHierarchy = (TypeHierarchy)listener;
2288 // if (typeHierarchy.hasFineGrainChanges()) {
2289 // // case of changes in primary working copies
2290 // typeHierarchy.needsRefresh = true;
2291 // typeHierarchy.fireChange();
2298 * Generic processing for elements with changed contents:<ul> <li>The
2299 * element is closed such that any subsequent accesses will re-open the
2300 * element reflecting its new structure. <li>An entry is made in the delta
2301 * reporting a content change (K_CHANGE with F_CONTENT flag set). </ul>
2303 private void nonJavaResourcesChanged(Openable element, IResourceDelta delta)
2304 throws JavaModelException {
2306 // reset non-java resources if element was open
2307 if (element.isOpen()) {
2308 JavaElementInfo info = (JavaElementInfo) element.getElementInfo();
2309 switch (element.getElementType()) {
2310 case IJavaElement.JAVA_MODEL:
2311 ((JavaModelInfo) info).nonJavaResources = null;
2312 currentDelta().addResourceDelta(delta);
2314 case IJavaElement.JAVA_PROJECT:
2315 ((JavaProjectElementInfo) info).setNonJavaResources(null);
2317 // if a package fragment root is the project, clear it too
2318 JavaProject project = (JavaProject) element;
2319 PackageFragmentRoot projectRoot = (PackageFragmentRoot) project
2320 .getPackageFragmentRoot(project.getProject());
2321 if (projectRoot.isOpen()) {
2322 ((PackageFragmentRootInfo) projectRoot.getElementInfo())
2323 .setNonJavaResources(null);
2326 case IJavaElement.PACKAGE_FRAGMENT:
2327 ((PackageFragmentInfo) info).setNonJavaResources(null);
2329 case IJavaElement.PACKAGE_FRAGMENT_ROOT:
2330 ((PackageFragmentRootInfo) info).setNonJavaResources(null);
2334 JavaElementDelta current = currentDelta();
2335 JavaElementDelta elementDelta = current.find(element);
2336 if (elementDelta == null) {
2337 // don't use find after creating the delta as it can be null (see
2338 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=63434)
2339 elementDelta = current
2340 .changed(element, IJavaElementDelta.F_CONTENT);
2342 elementDelta.addResourceDelta(delta);
2346 * Flushes all deltas without firing them.
2348 public void flush() {
2349 this.javaModelDeltas = new ArrayList();
2353 * Finds the root info this path is included in. Returns null if not found.
2355 // RootInfo enclosingRootInfo(IPath path, int kind) {
2356 // while (path != null && path.segmentCount() > 0) {
2357 // RootInfo rootInfo = this.rootInfo(path, kind);
2358 // if (rootInfo != null)
2360 // path = path.removeLastSegments(1);
2366 * Fire Java Model delta, flushing them after the fact after post_change
2367 * notification. If the firing mode has been turned off, this has no effect.
2369 public void fire(IJavaElementDelta customDelta, int eventType) {
2375 .println("-----------------------------------------------------------------------------------------------------------------------");//$NON-NLS-1$
2378 IJavaElementDelta deltaToNotify;
2379 if (customDelta == null) {
2380 deltaToNotify = this.mergeDeltas(this.javaModelDeltas);
2382 deltaToNotify = customDelta;
2385 // Refresh internal scopes
2386 // if (deltaToNotify != null) {
2387 // Iterator scopes = this.manager.searchScopes.keySet().iterator();
2388 // while (scopes.hasNext()) {
2389 // AbstractSearchScope scope = (AbstractSearchScope)scopes.next();
2390 // scope.processDelta(deltaToNotify);
2396 // Important: if any listener reacts to notification by updating the
2397 // listeners list or mask, these lists will
2398 // be duplicated, so it is necessary to remember original lists in a
2399 // variable (since field values may change under us)
2400 IElementChangedListener[] listeners = this.state.elementChangedListeners;
2401 int[] listenerMask = this.state.elementChangedListenerMasks;
2402 int listenerCount = this.state.elementChangedListenerCount;
2404 switch (eventType) {
2405 case DEFAULT_CHANGE_EVENT:
2406 firePostChangeDelta(deltaToNotify, listeners, listenerMask,
2408 fireReconcileDelta(listeners, listenerMask, listenerCount);
2410 case ElementChangedEvent.POST_CHANGE:
2411 firePostChangeDelta(deltaToNotify, listeners, listenerMask,
2413 fireReconcileDelta(listeners, listenerMask, listenerCount);
2418 private void firePostChangeDelta(IJavaElementDelta deltaToNotify,
2419 IElementChangedListener[] listeners, int[] listenerMask,
2420 int listenerCount) {
2422 // post change deltas
2425 .println("FIRING POST_CHANGE Delta [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
2427 .println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
2429 if (deltaToNotify != null) {
2430 // flush now so as to keep listener reactions to post their own
2431 // deltas for subsequent iteration
2434 notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE,
2435 listeners, listenerMask, listenerCount);
2439 private void fireReconcileDelta(IElementChangedListener[] listeners,
2440 int[] listenerMask, int listenerCount) {
2442 IJavaElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas
2446 .println("FIRING POST_RECONCILE Delta [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
2448 .println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
2450 if (deltaToNotify != null) {
2451 // flush now so as to keep listener reactions to post their own
2452 // deltas for subsequent iteration
2453 this.reconcileDeltas = new HashMap();
2455 notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE,
2456 listeners, listenerMask, listenerCount);
2461 * Returns the root info for the given path. Look in the old roots table if
2464 // RootInfo rootInfo(IPath path, int kind) {
2465 // if (kind == IResourceDelta.REMOVED) {
2466 // return (RootInfo) this.oldRoots.get(path);
2468 // return (RootInfo) this.roots.get(path);
2473 * Returns the other root infos for the given path. Look in the old other
2474 * roots table if kind is REMOVED.
2476 // ArrayList otherRootsInfo(IPath path, int kind) {
2477 // if (kind == IResourceDelta.REMOVED) {
2478 // return (ArrayList) this.oldOtherRoots.get(path);
2480 // return (ArrayList) this.otherRoots.get(path);
2485 * Converts an <code>IResourceDelta</code> and its children into the
2486 * corresponding <code>IJavaElementDelta</code>s. Return whether the
2487 * delta corresponds to a java element. If it is not a java element, it will
2488 * be added as a non-java resource by the sender of this method.
2490 // protected boolean traverseDelta(
2491 // IResourceDelta delta,
2493 // RootInfo rootInfo,
2494 // OutputsInfo outputsInfo) {
2496 // IResource res = delta.getResource();
2498 // // set stack of elements
2499 // if (this.currentElement == null && rootInfo != null) {
2500 // this.currentElement = (Openable)rootInfo.project;
2503 // // process current delta
2504 // boolean processChildren = true;
2505 // if (res instanceof IProject) {
2506 // processChildren =
2507 // this.updateCurrentDeltaAndIndex(
2509 // elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ?
2510 // IJavaElement.JAVA_PROJECT : // case of prj=src
2513 // } else if (rootInfo != null) {
2514 // processChildren = this.updateCurrentDeltaAndIndex(delta, elementType,
2517 // // not yet inside a package fragment root
2518 // processChildren = true;
2521 // // get the project's output locations and traverse mode
2522 // if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
2524 // // process children if needed
2525 // if (processChildren) {
2526 // IResourceDelta[] children = delta.getAffectedChildren();
2527 // boolean oneChildOnClasspath = false;
2528 // int length = children.length;
2529 // IResourceDelta[] orphanChildren = null;
2530 // Openable parent = null;
2531 // boolean isValidParent = true;
2532 // for (int i = 0; i < length; i++) {
2533 // IResourceDelta child = children[i];
2534 // IResource childRes = child.getResource();
2536 // // check source attachment change
2537 // this.checkSourceAttachmentChange(child, childRes);
2539 // // find out whether the child is a package fragment root of the current
2541 // IPath childPath = childRes.getFullPath();
2542 // int childKind = child.getKind();
2543 // RootInfo childRootInfo = this.rootInfo(childPath, childKind);
2544 // if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
2545 // // package fragment root of another project (dealt with later)
2546 // childRootInfo = null;
2549 // // compute child type
2551 // this.elementType(
2555 // rootInfo == null ? childRootInfo : rootInfo
2558 // // is childRes in the output folder and is it filtered out ?
2559 // boolean isResFilteredFromOutput =
2560 // this.isResFilteredFromOutput(outputsInfo, childRes, childType);
2562 // boolean isNestedRoot = rootInfo != null && childRootInfo != null;
2563 // if (!isResFilteredFromOutput
2564 // && !isNestedRoot) { // do not treat as non-java rsc if nested root
2565 // if (!this.traverseDelta(child, childType, rootInfo == null ?
2566 // childRootInfo : rootInfo, outputsInfo)) { // traverse delta for child in
2568 // // it is a non-java resource
2570 // if (rootInfo != null) { // if inside a package fragment root
2571 // if (!isValidParent) continue;
2572 // if (parent == null) {
2573 // // find the parent of the non-java resource to attach to
2574 // if (this.currentElement == null
2575 // || !this.currentElement.getJavaProject().equals(rootInfo.project)) {
2576 // // force the currentProject to be used
2577 // this.currentElement = (Openable)rootInfo.project;
2579 // if (elementType == IJavaElement.JAVA_PROJECT
2580 // || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT
2581 // && res instanceof IProject)) {
2582 // // NB: attach non-java resource to project (not to its package fragment
2584 // parent = (Openable)rootInfo.project;
2586 // parent = this.createElement(res, elementType, rootInfo);
2588 // if (parent == null) {
2589 // isValidParent = false;
2593 // // add child as non java resource
2594 // nonJavaResourcesChanged(parent, child);
2596 // // the non-java resource (or its parent folder) will be attached to the
2598 // if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
2599 // orphanChildren[i] = child;
2601 // } catch (JavaModelException e) {
2604 // oneChildOnClasspath = true;
2607 // oneChildOnClasspath = true; // to avoid reporting child delta as non-java
2611 // // if child is a nested root
2612 // // or if it is not a package fragment root of the current project
2613 // // but it is a package fragment root of another project, traverse delta
2616 // || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath,
2617 // childKind)) != null)) {
2618 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT,
2619 // childRootInfo, null); // binary output of childRootInfo.project cannot be
2621 // // NB: No need to check the return value as the child can only be on the
2625 // // if the child is a package fragment root of one or several other
2627 // ArrayList rootList;
2628 // if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) {
2629 // Iterator iterator = rootList.iterator();
2630 // while (iterator.hasNext()) {
2631 // childRootInfo = (RootInfo) iterator.next();
2632 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT,
2633 // childRootInfo, null); // binary output of childRootInfo.project cannot be
2638 // if (orphanChildren != null
2639 // && (oneChildOnClasspath // orphan children are siblings of a package
2641 // || res instanceof IProject)) { // non-java resource directly under a
2644 // // attach orphan children
2645 // IProject rscProject = res.getProject();
2646 // JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
2647 // if (adoptiveProject != null
2648 // && JavaProject.hasJavaNature(rscProject)) { // delta iff Java project
2650 // for (int i = 0; i < length; i++) {
2651 // if (orphanChildren[i] != null) {
2653 // nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
2654 // } catch (JavaModelException e) {
2659 // } // else resource delta will be added by parent
2660 // return elementType != NON_JAVA_RESOURCE; // TODO: (jerome) do we still
2661 // need to return? (check could be done by caller)
2663 // return elementType != NON_JAVA_RESOURCE;
2667 * Update the classpath markers and cycle markers for the projects to
2670 // void updateClasspathMarkers() {
2672 // if (!ResourcesPlugin.getWorkspace().isAutoBuilding()) {
2673 // Iterator iterator = this.projectsToUpdate.iterator();
2674 // while (iterator.hasNext()) {
2676 // JavaProject project = (JavaProject)iterator.next();
2678 // // force classpath marker refresh
2679 // project.getResolvedClasspath(
2680 // true, // ignoreUnresolvedEntry
2681 // true); // generateMarkerOnError
2683 // } catch (JavaModelException e) {
2687 // if (!this.projectsToUpdate.isEmpty()){
2689 // // update all cycle markers
2690 // JavaProject.updateAllCycleMarkers();
2691 // } catch (JavaModelException e) {
2695 // this.projectsToUpdate = new HashSet();
2699 * Update the current delta (ie. add/remove/change the given element) and
2700 * update the correponding index. Returns whether the children of the given
2701 * delta must be processed. @throws a JavaModelException if the delta
2702 * doesn't correspond to a java element of the given type.
2704 // private boolean updateCurrentDeltaAndIndex(IResourceDelta delta, int
2705 // elementType, RootInfo rootInfo) {
2706 // Openable element;
2707 // switch (delta.getKind()) {
2708 // case IResourceDelta.ADDED :
2709 // IResource deltaRes = delta.getResource();
2710 // element = this.createElement(deltaRes, elementType, rootInfo);
2711 // if (element == null) {
2712 // // resource might be containing shared roots (see bug 19058)
2713 // this.updateRoots(deltaRes.getFullPath(), delta);
2716 // this.updateIndex(element, delta);
2717 // this.elementAdded(element, delta, rootInfo);
2719 // case IResourceDelta.REMOVED :
2720 // deltaRes = delta.getResource();
2721 // element = this.createElement(deltaRes, elementType, rootInfo);
2722 // if (element == null) {
2723 // // resource might be containing shared roots (see bug 19058)
2724 // this.updateRoots(deltaRes.getFullPath(), delta);
2727 // this.updateIndex(element, delta);
2728 // this.elementRemoved(element, delta, rootInfo);
2730 // if (deltaRes.getType() == IResource.PROJECT){
2731 // // reset the corresponding project built state, since cannot reuse if
2733 // this.manager.setLastBuiltState((IProject)deltaRes, null /*no state*/);
2736 // case IResourceDelta.CHANGED :
2737 // int flags = delta.getFlags();
2738 // if ((flags & IResourceDelta.CONTENT) != 0) {
2739 // // content has changed
2740 // element = this.createElement(delta.getResource(), elementType, rootInfo);
2741 // if (element == null) return false;
2742 // this.updateIndex(element, delta);
2743 // this.contentChanged(element, delta);
2744 // } else if (elementType == IJavaElement.JAVA_PROJECT) {
2745 // if ((flags & IResourceDelta.OPEN) != 0) {
2746 // // project has been opened or closed
2747 // IProject res = (IProject)delta.getResource();
2748 // element = this.createElement(res, elementType, rootInfo);
2749 // if (element == null) {
2750 // // resource might be containing shared roots (see bug 19058)
2751 // this.updateRoots(res.getFullPath(), delta);
2754 // if (res.isOpen()) {
2755 // if (JavaProject.hasJavaNature(res)) {
2756 // this.elementAdded(element, delta, rootInfo);
2757 // this.indexManager.indexAll(res);
2760 // JavaModel javaModel = this.manager.getJavaModel();
2761 // boolean wasJavaProject = javaModel.findJavaProject(res) != null;
2762 // if (wasJavaProject) {
2763 // this.elementRemoved(element, delta, rootInfo);
2764 // this.indexManager.discardJobs(element.getElementName());
2765 // this.indexManager.removeIndexFamily(res.getFullPath());
2769 // return false; // when a project is open/closed don't process children
2771 // if ((flags & IResourceDelta.DESCRIPTION) != 0) {
2772 // IProject res = (IProject)delta.getResource();
2773 // JavaModel javaModel = this.manager.getJavaModel();
2774 // boolean wasJavaProject = javaModel.findJavaProject(res) != null;
2775 // boolean isJavaProject = JavaProject.hasJavaNature(res);
2776 // if (wasJavaProject != isJavaProject) {
2777 // // project's nature has been added or removed
2778 // element = this.createElement(res, elementType, rootInfo);
2779 // if (element == null) return false; // note its resources are still
2780 // visible as roots to other projects
2781 // if (isJavaProject) {
2782 // this.elementAdded(element, delta, rootInfo);
2783 // this.indexManager.indexAll(res);
2785 // this.elementRemoved(element, delta, rootInfo);
2786 // this.indexManager.discardJobs(element.getElementName());
2787 // this.indexManager.removeIndexFamily(res.getFullPath());
2788 // // reset the corresponding project built state, since cannot reuse if
2790 // this.manager.setLastBuiltState(res, null /*no state*/);
2792 // return false; // when a project's nature is added/removed don't process
2802 * Traverse the set of projects which have changed namespace, and refresh
2805 // public void updateDependentNamelookups() {
2806 // Iterator iterator;
2807 // // update namelookup of dependent projects
2808 // iterator = this.projectsForDependentNamelookupRefresh.iterator();
2809 // HashSet affectedDependents = new HashSet();
2810 // while (iterator.hasNext()) {
2811 // JavaProject project = (JavaProject)iterator.next();
2812 // addDependentProjects(project.getPath(), affectedDependents);
2814 // iterator = affectedDependents.iterator();
2815 // while (iterator.hasNext()) {
2816 // JavaProject project = (JavaProject) iterator.next();
2817 // if (project.isOpen()){
2819 // ((JavaProjectElementInfo)project.getElementInfo()).setNameLookup(null);
2820 // } catch (JavaModelException e) {
2825 // protected void updateIndex(Openable element, IResourceDelta delta) {
2827 // if (indexManager == null)
2830 // switch (element.getElementType()) {
2831 // case IJavaElement.JAVA_PROJECT :
2832 // switch (delta.getKind()) {
2833 // case IResourceDelta.ADDED :
2834 // this.indexManager.indexAll(element.getJavaProject().getProject());
2836 // case IResourceDelta.REMOVED :
2837 // this.indexManager.removeIndexFamily(element.getJavaProject().getProject().getFullPath());
2838 // // NB: Discarding index jobs belonging to this project was done during
2841 // // NB: Update of index if project is opened, closed, or its java nature
2842 // is added or removed
2843 // // is done in updateCurrentDeltaAndIndex
2846 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
2847 // if (element instanceof JarPackageFragmentRoot) {
2848 // JarPackageFragmentRoot root = (JarPackageFragmentRoot)element;
2849 // // index jar file only once (if the root is in its declaring project)
2850 // IPath jarPath = root.getPath();
2851 // switch (delta.getKind()) {
2852 // case IResourceDelta.ADDED:
2853 // // index the new jar
2854 // indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
2856 // case IResourceDelta.CHANGED:
2857 // // first remove the index so that it is forced to be re-indexed
2858 // indexManager.removeIndex(jarPath);
2859 // // then index the jar
2860 // indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
2862 // case IResourceDelta.REMOVED:
2863 // // the jar was physically removed: remove the index
2864 // this.indexManager.discardJobs(jarPath.toString());
2865 // this.indexManager.removeIndex(jarPath);
2870 // int kind = delta.getKind();
2871 // if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED) {
2872 // IPackageFragmentRoot root = (IPackageFragmentRoot)element;
2873 // this.updateRootIndex(root, root.getPackageFragment(""), delta);
2878 // // don't break as packages of the package fragment root can be indexed
2880 // case IJavaElement.PACKAGE_FRAGMENT :
2881 // switch (delta.getKind()) {
2882 // case IResourceDelta.ADDED:
2883 // case IResourceDelta.REMOVED:
2884 // IPackageFragment pkg = null;
2885 // if (element instanceof IPackageFragmentRoot) {
2886 // IPackageFragmentRoot root = (IPackageFragmentRoot)element;
2887 // pkg = root.getPackageFragment(""); //$NON-NLS-1$
2889 // pkg = (IPackageFragment)element;
2891 // IResourceDelta[] children = delta.getAffectedChildren();
2892 // for (int i = 0, length = children.length; i < length; i++) {
2893 // IResourceDelta child = children[i];
2894 // IResource resource = child.getResource();
2895 // if (resource instanceof IFile) {
2896 // String name = resource.getName();
2897 // if (ProjectPrefUtil.isJavaFileName(name)) {
2898 // Openable cu = (Openable)pkg.getCompilationUnit(name);
2899 // this.updateIndex(cu, child);
2900 // } else if (ProjectPrefUtil.isClassFileName(name)) {
2901 // Openable classFile = (Openable)pkg.getClassFile(name);
2902 // this.updateIndex(classFile, child);
2909 // case IJavaElement.CLASS_FILE :
2910 // IFile file = (IFile) delta.getResource();
2911 // IJavaProject project = element.getJavaProject();
2912 // IPath binaryFolderPath = element.getPackageFragmentRoot().getPath();
2913 // // if the class file is part of the binary output, it has been created by
2914 // // the java builder -> ignore
2916 // if (binaryFolderPath.equals(project.getOutputLocation())) {
2919 // } catch (JavaModelException e) {
2921 // switch (delta.getKind()) {
2922 // case IResourceDelta.CHANGED :
2923 // // no need to index if the content has not changed
2924 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
2926 // case IResourceDelta.ADDED :
2927 // indexManager.addBinary(file, binaryFolderPath);
2929 // case IResourceDelta.REMOVED :
2930 // indexManager.remove(file.getFullPath().toString(), binaryFolderPath);
2934 // case IJavaElement.COMPILATION_UNIT :
2935 // file = (IFile) delta.getResource();
2936 // switch (delta.getKind()) {
2937 // case IResourceDelta.CHANGED :
2938 // // no need to index if the content has not changed
2939 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
2941 // case IResourceDelta.ADDED :
2942 // indexManager.addSource(file,
2943 // file.getProject().getProject().getFullPath());
2945 // case IResourceDelta.REMOVED :
2946 // indexManager.remove(file.getFullPath().toString(),
2947 // file.getProject().getProject().getFullPath());
2953 * Upadtes the index of the given root (assuming it's an addition or a
2954 * removal). This is done recusively, pkg being the current package.
2956 // private void updateRootIndex(IPackageFragmentRoot root, IPackageFragment
2957 // pkg, IResourceDelta delta) {
2958 // this.updateIndex((Openable)pkg, delta);
2959 // IResourceDelta[] children = delta.getAffectedChildren();
2960 // String name = pkg.getElementName();
2961 // for (int i = 0, length = children.length; i < length; i++) {
2962 // IResourceDelta child = children[i];
2963 // IResource resource = child.getResource();
2964 // if (resource instanceof IFolder) {
2965 // String subpkgName =
2966 // name.length() == 0 ?
2967 // resource.getName() :
2968 // name + "." + resource.getName(); //$NON-NLS-1$
2969 // IPackageFragment subpkg = root.getPackageFragment(subpkgName);
2970 // this.updateRootIndex(root, subpkg, child);
2975 * Update the roots that are affected by the addition or the removal of the
2976 * given container resource.
2978 // private void updateRoots(IPath containerPath, IResourceDelta
2979 // containerDelta) {
2982 // if (containerDelta.getKind() == IResourceDelta.REMOVED) {
2983 // roots = this.oldRoots;
2984 // otherRoots = this.oldOtherRoots;
2986 // roots = this.roots;
2987 // otherRoots = this.otherRoots;
2989 // Iterator iterator = roots.keySet().iterator();
2990 // while (iterator.hasNext()) {
2991 // IPath path = (IPath)iterator.next();
2992 // if (containerPath.isPrefixOf(path) && !containerPath.equals(path)) {
2993 // IResourceDelta rootDelta =
2994 // containerDelta.findMember(path.removeFirstSegments(1));
2995 // if (rootDelta == null) continue;
2996 // RootInfo rootInfo = (RootInfo)roots.get(path);
2998 // if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider
2999 // roots that are not included in the container
3000 // this.updateCurrentDeltaAndIndex(rootDelta,
3001 // IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);
3004 // ArrayList rootList = (ArrayList)otherRoots.get(path);
3005 // if (rootList != null) {
3006 // Iterator otherProjects = rootList.iterator();
3007 // while (otherProjects.hasNext()) {
3008 // rootInfo = (RootInfo)otherProjects.next();
3009 // if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider
3010 // roots that are not included in the container
3011 // this.updateCurrentDeltaAndIndex(rootDelta,
3012 // IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);