1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.HashSet;
19 import net.sourceforge.phpdt.core.ElementChangedEvent;
20 import net.sourceforge.phpdt.core.IClasspathEntry;
21 import net.sourceforge.phpdt.core.IJavaElement;
22 import net.sourceforge.phpdt.core.IJavaModel;
23 import net.sourceforge.phpdt.core.IJavaProject;
24 import net.sourceforge.phpdt.core.JavaModelException;
25 import net.sourceforge.phpdt.core.JavaCore;
26 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
27 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
29 import org.eclipse.core.resources.IFile;
30 import org.eclipse.core.resources.IProject;
31 import org.eclipse.core.resources.IResource;
32 import org.eclipse.core.resources.IResourceChangeEvent;
33 import org.eclipse.core.resources.IResourceChangeListener;
34 import org.eclipse.core.resources.IResourceDelta;
35 import org.eclipse.core.resources.IResourceDeltaVisitor;
36 import org.eclipse.core.resources.IWorkspace;
37 import org.eclipse.core.resources.ResourcesPlugin;
38 import org.eclipse.core.runtime.CoreException;
39 import org.eclipse.core.runtime.IPath;
40 import org.eclipse.core.runtime.QualifiedName;
44 * This class is used by <code>JavaModelManager</code> to convert
45 * <code>IResourceDelta</code>s into <code>IJavaElementDelta</code>s.
46 * It also does some processing on the <code>JavaElement</code>s involved
47 * (e.g. closing them or updating classpaths).
49 public class DeltaProcessor implements IResourceChangeListener {
51 final static int IGNORE = 0;
52 final static int SOURCE = 1;
53 final static int BINARY = 2;
55 final static String EXTERNAL_JAR_ADDED = "external jar added"; //$NON-NLS-1$
56 final static String EXTERNAL_JAR_REMOVED = "external jar removed"; //$NON-NLS-1$
57 final static String EXTERNAL_JAR_CHANGED = "external jar changed"; //$NON-NLS-1$
58 final static String EXTERNAL_JAR_UNCHANGED = "external jar unchanged"; //$NON-NLS-1$
59 final static String INTERNAL_JAR_IGNORE = "internal jar ignore"; //$NON-NLS-1$
61 final static int NON_JAVA_RESOURCE = -1;
64 * The <code>JavaElementDelta</code> corresponding to the <code>IResourceDelta</code> being translated.
66 protected JavaElementDelta currentDelta;
68 // protected IndexManager indexManager = new IndexManager();
70 /* A table from IPath (from a classpath entry) to RootInfo */
73 /* A table from IPath (from a classpath entry) to ArrayList of RootInfo
74 * Used when an IPath corresponds to more than one root */
77 /* Whether the roots tables should be recomputed */
78 public boolean rootsAreStale = true;
80 /* A table from IPath (from a classpath entry) to RootInfo
81 * from the last time the delta processor was invoked. */
84 /* A table from IPath (from a classpath entry) to ArrayList of RootInfo
85 * from the last time the delta processor was invoked.
86 * Used when an IPath corresponds to more than one root */
89 /* A table from IPath (a source attachment path from a classpath entry) to IPath (a root path) */
90 Map sourceAttachments;
92 /* The java element that was last created (see createElement(IResource)).
93 * This is used as a stack of java elements (using getParent() to pop it, and
94 * using the various get*(...) to push it. */
95 Openable currentElement;
97 public HashMap externalTimeStamps = new HashMap();
98 public HashSet projectsToUpdate = new HashSet();
99 // list of root projects which namelookup caches need to be updated for dependents
100 // TODO: (jerome) is it needed? projectsToUpdate might be sufficient
101 public HashSet projectsForDependentNamelookupRefresh = new HashSet();
103 JavaModelManager manager;
105 /* A table from IJavaProject to an array of IPackageFragmentRoot.
106 * This table contains the pkg fragment roots of the project that are being deleted.
111 * A list of IJavaElement used as a scope for external archives refresh during POST_CHANGE.
112 * This is null if no refresh is needed.
114 HashSet refreshedElements;
115 public static boolean VERBOSE = false;
121 OutputsInfo(IPath[] paths, int[] traverseModes, int outputCount) {
123 this.traverseModes = traverseModes;
124 this.outputCount = outputCount;
126 public String toString() {
127 if (this.paths == null) return "<none>"; //$NON-NLS-1$
128 StringBuffer buffer = new StringBuffer();
129 for (int i = 0; i < this.outputCount; i++) {
130 buffer.append("path="); //$NON-NLS-1$
131 buffer.append(this.paths[i].toString());
132 buffer.append("\n->traverse="); //$NON-NLS-1$
133 switch (this.traverseModes[i]) {
135 buffer.append("BINARY"); //$NON-NLS-1$
138 buffer.append("IGNORE"); //$NON-NLS-1$
141 buffer.append("SOURCE"); //$NON-NLS-1$
144 buffer.append("<unknown>"); //$NON-NLS-1$
146 if (i+1 < this.outputCount) {
150 return buffer.toString();
154 IJavaProject project;
156 char[][] exclusionPatterns;
157 RootInfo(IJavaProject project, IPath rootPath, char[][] exclusionPatterns) {
158 this.project = project;
159 this.rootPath = rootPath;
160 this.exclusionPatterns = exclusionPatterns;
162 boolean isRootOfProject(IPath path) {
163 return this.rootPath.equals(path) && this.project.getProject().getFullPath().isPrefixOf(path);
165 public String toString() {
166 StringBuffer buffer = new StringBuffer("project="); //$NON-NLS-1$
167 if (this.project == null) {
168 buffer.append("null"); //$NON-NLS-1$
170 buffer.append(this.project.getElementName());
172 buffer.append("\npath="); //$NON-NLS-1$
173 if (this.rootPath == null) {
174 buffer.append("null"); //$NON-NLS-1$
176 buffer.append(this.rootPath.toString());
178 buffer.append("\nexcluding="); //$NON-NLS-1$
179 if (this.exclusionPatterns == null) {
180 buffer.append("null"); //$NON-NLS-1$
182 for (int i = 0, length = this.exclusionPatterns.length; i < length; i++) {
183 buffer.append(new String(this.exclusionPatterns[i]));
185 buffer.append("|"); //$NON-NLS-1$
189 return buffer.toString();
193 DeltaProcessor(JavaModelManager manager) {
194 this.manager = manager;
198 * Adds the dependents of the given project to the list of the projects
201 // void addDependentProjects(IPath projectPath, HashSet result) {
203 // IJavaProject[] projects = this.manager.getJavaModel().getJavaProjects();
204 // for (int i = 0, length = projects.length; i < length; i++) {
205 // IJavaProject project = projects[i];
206 // IClasspathEntry[] classpath = ((JavaProject)project).getExpandedClasspath(true);
207 // for (int j = 0, length2 = classpath.length; j < length2; j++) {
208 // IClasspathEntry entry = classpath[j];
209 // if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT
210 // && entry.getPath().equals(projectPath)) {
211 // result.add(project);
215 // } catch (JavaModelException e) {
219 * Adds the given element to the list of elements used as a scope for external jars refresh.
221 public void addForRefresh(IJavaElement element) {
222 if (this.refreshedElements == null) {
223 this.refreshedElements = new HashSet();
225 this.refreshedElements.add(element);
228 * Adds the given project and its dependents to the list of the projects
231 void addToProjectsToUpdateWithDependents(IProject project) {
232 this.projectsToUpdate.add(JavaCore.create(project));
233 // this.addDependentProjects(project.getFullPath(), this.projectsToUpdate);
237 * Adds the given child handle to its parent's cache of children.
239 protected void addToParentInfo(Openable child) {
241 Openable parent = (Openable) child.getParent();
242 if (parent != null && parent.isOpen()) {
244 JavaElementInfo info = (JavaElementInfo)parent.getElementInfo();
245 info.addChild(child);
246 } catch (JavaModelException e) {
247 // do nothing - we already checked if open
253 * Check all external archive (referenced by given roots, projects or model) status and issue a corresponding root delta.
254 * Also triggers index updates
256 // public void checkExternalArchiveChanges(IJavaElement[] refreshedElements, IProgressMonitor monitor) throws JavaModelException {
258 // for (int i = 0, length = refreshedElements.length; i < length; i++) {
259 // this.addForRefresh(refreshedElements[i]);
261 // boolean hasDelta = this.createExternalArchiveDelta(monitor);
262 // if (monitor != null && monitor.isCanceled()) return;
264 // // force classpath marker refresh of affected projects
265 // JavaModel.flushExternalFileCache();
266 // IJavaElementDelta[] projectDeltas = this.currentDelta.getAffectedChildren();
267 // for (int i = 0, length = projectDeltas.length; i < length; i++) {
268 // IJavaElementDelta delta = projectDeltas[i];
269 // ((JavaProject)delta.getElement()).getResolvedClasspath(
270 // true, // ignoreUnresolvedEntry
271 // true); // generateMarkerOnError
273 // if (this.currentDelta != null) { // if delta has not been fired while creating markers
274 // this.manager.fire(this.currentDelta, JavaModelManager.DEFAULT_CHANGE_EVENT);
278 // this.currentDelta = null;
279 // if (monitor != null) monitor.done();
283 * Check if external archives have changed and create the corresponding deltas.
284 * Returns whether at least on delta was created.
286 // public boolean createExternalArchiveDelta(IProgressMonitor monitor) throws JavaModelException {
288 // if (this.refreshedElements == null) return false;
290 // HashMap externalArchivesStatus = new HashMap();
291 // boolean hasDelta = false;
293 // // find JARs to refresh
294 // HashSet archivePathsToRefresh = new HashSet();
296 // Iterator iterator = this.refreshedElements.iterator();
297 // while (iterator.hasNext()) {
298 // IJavaElement element = (IJavaElement)iterator.next();
299 // switch(element.getElementType()){
300 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
301 // archivePathsToRefresh.add(element.getPath());
303 // case IJavaElement.JAVA_PROJECT :
304 // IJavaProject project = (IJavaProject) element;
305 // if (!JavaProject.hasJavaNature(project.getProject())) {
306 // // project is not accessible or has lost its Java nature
309 // IClasspathEntry[] classpath = project.getResolvedClasspath(true);
310 // for (int j = 0, cpLength = classpath.length; j < cpLength; j++){
311 // if (classpath[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
312 // archivePathsToRefresh.add(classpath[j].getPath());
316 // case IJavaElement.JAVA_MODEL :
317 // IJavaProject[] projects = manager.getJavaModel().getOldJavaProjectsList();
318 // for (int j = 0, projectsLength = projects.length; j < projectsLength; j++){
319 // project = projects[j];
320 // if (!JavaProject.hasJavaNature(project.getProject())) {
321 // // project is not accessible or has lost its Java nature
324 // classpath = project.getResolvedClasspath(true);
325 // for (int k = 0, cpLength = classpath.length; k < cpLength; k++){
326 // if (classpath[k].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
327 // archivePathsToRefresh.add(classpath[k].getPath());
335 // this.refreshedElements = null;
338 // // perform refresh
339 // IJavaProject[] projects = manager.getJavaModel().getOldJavaProjectsList();
340 // IWorkspaceRoot wksRoot = ResourcesPlugin.getWorkspace().getRoot();
341 // for (int i = 0, length = projects.length; i < length; i++) {
343 // if (monitor != null && monitor.isCanceled()) break;
345 // IJavaProject project = projects[i];
346 // if (!JavaProject.hasJavaNature(project.getProject())) {
347 // // project is not accessible or has lost its Java nature
350 // IClasspathEntry[] entries = project.getResolvedClasspath(true);
351 // for (int j = 0; j < entries.length; j++){
352 // if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
354 // IPath entryPath = entries[j].getPath();
356 // if (!archivePathsToRefresh.contains(entryPath)) continue; // not supposed to be refreshed
358 // String status = (String)externalArchivesStatus.get(entryPath);
359 // if (status == null){
361 // // compute shared status
362 // Object targetLibrary = JavaModel.getTarget(wksRoot, entryPath, true);
364 // if (targetLibrary == null){ // missing JAR
365 // if (this.externalTimeStamps.containsKey(entryPath)){
366 // this.externalTimeStamps.remove(entryPath);
367 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
368 // // the jar was physically removed: remove the index
369 // indexManager.removeIndex(entryPath);
372 // } else if (targetLibrary instanceof File){ // external JAR
374 // File externalFile = (File)targetLibrary;
376 // // check timestamp to figure if JAR has changed in some way
377 // Long oldTimestamp =(Long) this.externalTimeStamps.get(entryPath);
378 // long newTimeStamp = getTimeStamp(externalFile);
379 // if (oldTimestamp != null){
381 // if (newTimeStamp == 0){ // file doesn't exist
382 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
383 // this.externalTimeStamps.remove(entryPath);
384 // // remove the index
385 // indexManager.removeIndex(entryPath);
387 // } else if (oldTimestamp.longValue() != newTimeStamp){
388 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_CHANGED);
389 // this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
390 // // first remove the index so that it is forced to be re-indexed
391 // indexManager.removeIndex(entryPath);
392 // // then index the jar
393 // indexManager.indexLibrary(entryPath, project.getProject());
395 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
398 // if (newTimeStamp == 0){ // jar still doesn't exist
399 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
401 // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_ADDED);
402 // this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
403 // // index the new jar
404 // indexManager.indexLibrary(entryPath, project.getProject());
407 // } else { // internal JAR
408 // externalArchivesStatus.put(entryPath, INTERNAL_JAR_IGNORE);
411 // // according to computed status, generate a delta
412 // status = (String)externalArchivesStatus.get(entryPath);
413 // if (status != null){
414 // if (status == EXTERNAL_JAR_ADDED){
415 // PackageFragmentRoot root = (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
417 // System.out.println("- External JAR ADDED, affecting root: "+root.getElementName()); //$NON-NLS-1$
419 // elementAdded(root, null, null);
421 // } else if (status == EXTERNAL_JAR_CHANGED) {
422 // PackageFragmentRoot root = (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
424 // System.out.println("- External JAR CHANGED, affecting root: "+root.getElementName()); //$NON-NLS-1$
426 // // reset the corresponding project built state, since the builder would miss this change
427 // this.manager.setLastBuiltState(project.getProject(), null /*no state*/);
428 // contentChanged(root, null);
430 // } else if (status == EXTERNAL_JAR_REMOVED) {
431 // PackageFragmentRoot root = (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
433 // System.out.println("- External JAR REMOVED, affecting root: "+root.getElementName()); //$NON-NLS-1$
435 // elementRemoved(root, null, null);
444 JavaElementDelta currentDelta() {
445 if (this.currentDelta == null) {
446 this.currentDelta = new JavaElementDelta(this.manager.getJavaModel());
448 return this.currentDelta;
452 * Process the given delta and look for projects being added, opened, closed or
453 * with a java nature being added or removed.
454 * Note that projects being deleted are checked in deleting(IProject).
455 * In all cases, add the project's dependents to the list of projects to update
456 * so that the classpath related markers can be updated.
458 // public void checkProjectsBeingAddedOrRemoved(IResourceDelta delta) {
459 // IResource resource = delta.getResource();
460 // switch (resource.getType()) {
461 // case IResource.ROOT :
462 // // workaround for bug 15168 circular errors not reported
463 // if (this.manager.javaProjectsCache == null) {
465 // this.manager.javaProjectsCache = this.manager.getJavaModel().getJavaProjects();
466 // } catch (JavaModelException e) {
470 // IResourceDelta[] children = delta.getAffectedChildren();
471 // for (int i = 0, length = children.length; i < length; i++) {
472 // this.checkProjectsBeingAddedOrRemoved(children[i]);
475 // case IResource.PROJECT :
476 // // NB: No need to check project's nature as if the project is not a java project:
477 // // - if the project is added or changed this is a noop for projectsBeingDeleted
478 // // - if the project is closed, it has already lost its java nature
479 // int deltaKind = delta.getKind();
480 // if (deltaKind == IResourceDelta.ADDED) {
481 // // remember project and its dependents
482 // IProject project = (IProject)resource;
483 // this.addToProjectsToUpdateWithDependents(project);
485 // // workaround for bug 15168 circular errors not reported
486 // if (JavaProject.hasJavaNature(project)) {
487 // this.addToParentInfo((JavaProject)JavaCore.create(project));
490 // } else if (deltaKind == IResourceDelta.CHANGED) {
491 // IProject project = (IProject)resource;
492 // if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
493 // // project opened or closed: remember project and its dependents
494 // this.addToProjectsToUpdateWithDependents(project);
496 // // workaround for bug 15168 circular errors not reported
497 // if (project.isOpen()) {
498 // if (JavaProject.hasJavaNature(project)) {
499 // this.addToParentInfo((JavaProject)JavaCore.create(project));
502 // JavaProject javaProject = (JavaProject)this.manager.getJavaModel().findJavaProject(project);
503 // if (javaProject != null) {
505 // javaProject.close();
506 // } catch (JavaModelException e) {
508 // this.removeFromParentInfo(javaProject);
511 // } else if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) {
512 // boolean wasJavaProject = this.manager.getJavaModel().findJavaProject(project) != null;
513 // boolean isJavaProject = JavaProject.hasJavaNature(project);
514 // if (wasJavaProject != isJavaProject) {
515 // // java nature added or removed: remember project and its dependents
516 // this.addToProjectsToUpdateWithDependents(project);
518 // // workaround for bug 15168 circular errors not reported
519 // if (isJavaProject) {
520 // this.addToParentInfo((JavaProject)JavaCore.create(project));
522 // JavaProject javaProject = (JavaProject)JavaCore.create(project);
524 // // flush classpath markers
526 // flushClasspathProblemMarkers(
527 // true, // flush cycle markers
528 // true //flush classpath format markers
531 // // remove problems and tasks created by the builder
532 // JavaBuilder.removeProblemsAndTasksFor(project);
536 // javaProject.close();
537 // } catch (JavaModelException e) {
539 // this.removeFromParentInfo(javaProject);
542 // // in case the project was removed then added then changed (see bug 19799)
543 // if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
544 // this.addToParentInfo((JavaProject)JavaCore.create(project));
548 // // workaround for bug 15168 circular errors not reported
549 // // in case the project was removed then added then changed
550 // if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
551 // this.addToParentInfo((JavaProject)JavaCore.create(project));
559 // private void checkSourceAttachmentChange(IResourceDelta delta, IResource res) {
560 // IPath rootPath = (IPath)this.sourceAttachments.get(res.getFullPath());
561 // if (rootPath != null) {
562 // RootInfo rootInfo = this.rootInfo(rootPath, delta.getKind());
563 // if (rootInfo != null) {
564 // IJavaProject projectOfRoot = rootInfo.project;
565 // IPackageFragmentRoot root = null;
567 // // close the root so that source attachement cache is flushed
568 // root = projectOfRoot.findPackageFragmentRoot(rootPath);
569 // if (root != null) {
572 // } catch (JavaModelException e) {
574 // if (root == null) return;
575 // switch (delta.getKind()) {
576 // case IResourceDelta.ADDED:
577 // currentDelta().sourceAttached(root);
579 // case IResourceDelta.CHANGED:
580 // currentDelta().sourceDetached(root);
581 // currentDelta().sourceAttached(root);
583 // case IResourceDelta.REMOVED:
584 // currentDelta().sourceDetached(root);
592 * Closes the given element, which removes it from the cache of open elements.
594 // protected static void close(Openable element) {
598 // } catch (JavaModelException e) {
603 * Generic processing for elements with changed contents:<ul>
604 * <li>The element is closed such that any subsequent accesses will re-open
605 * the element reflecting its new structure.
606 * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
608 * Delta argument could be null if processing an external JAR change
610 // protected void contentChanged(Openable element, IResourceDelta delta) {
613 // int flags = IJavaElementDelta.F_CONTENT;
614 // if (element instanceof JarPackageFragmentRoot){
615 // flags |= IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED;
617 // currentDelta().changed(element, flags);
621 * Creates the openables corresponding to this resource.
622 * Returns null if none was found.
624 // protected Openable createElement(IResource resource, int elementType, RootInfo rootInfo) {
625 // if (resource == null) return null;
627 // IPath path = resource.getFullPath();
628 // IJavaElement element = null;
629 // switch (elementType) {
631 // case IJavaElement.JAVA_PROJECT:
633 // // note that non-java resources rooted at the project level will also enter this code with
634 // // an elementType JAVA_PROJECT (see #elementType(...)).
635 // if (resource instanceof IProject){
637 // this.popUntilPrefixOf(path);
639 // if (this.currentElement != null
640 // && this.currentElement.getElementType() == IJavaElement.JAVA_PROJECT
641 // && ((IJavaProject)this.currentElement).getProject().equals(resource)) {
642 // return this.currentElement;
644 // if (rootInfo != null && rootInfo.project.getProject().equals(resource)){
645 // element = (Openable)rootInfo.project;
648 // IProject proj = (IProject)resource;
649 // if (JavaProject.hasJavaNature(proj)) {
650 // element = JavaCore.create(proj);
652 // // java project may have been been closed or removed (look for
653 // // element amongst old java project s list).
654 // element = (Openable) manager.getJavaModel().findJavaProject(proj);
658 // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
659 // element = rootInfo == null ? JavaCore.create(resource) : rootInfo.project.getPackageFragmentRoot(resource);
661 // case IJavaElement.PACKAGE_FRAGMENT:
662 // // find the element that encloses the resource
663 // this.popUntilPrefixOf(path);
665 // if (this.currentElement == null) {
666 // element = rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
669 // IPackageFragmentRoot root = this.currentElement.getPackageFragmentRoot();
670 // if (root == null) {
671 // element = rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
672 // } else if (((JavaProject)root.getJavaProject()).contains(resource)) {
673 // // create package handle
674 // IPath pkgPath = path.removeFirstSegments(root.getPath().segmentCount());
675 // String pkg = Util.packageName(pkgPath);
676 // if (pkg == null) return null;
677 // element = root.getPackageFragment(pkg);
681 // case IJavaElement.COMPILATION_UNIT:
682 // case IJavaElement.CLASS_FILE:
683 // // find the element that encloses the resource
684 // this.popUntilPrefixOf(path);
686 // if (this.currentElement == null) {
687 // element = rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
689 // // find the package
690 // IPackageFragment pkgFragment = null;
691 // switch (this.currentElement.getElementType()) {
692 // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
693 // IPackageFragmentRoot root = (IPackageFragmentRoot)this.currentElement;
694 // IPath rootPath = root.getPath();
695 // IPath pkgPath = path.removeLastSegments(1);
696 // String pkgName = Util.packageName(pkgPath.removeFirstSegments(rootPath.segmentCount()));
697 // if (pkgName != null) {
698 // pkgFragment = root.getPackageFragment(pkgName);
701 // case IJavaElement.PACKAGE_FRAGMENT:
702 // Openable pkg = (Openable)this.currentElement;
703 // if (pkg.getPath().equals(path.removeLastSegments(1))) {
704 // pkgFragment = (IPackageFragment)pkg;
705 // } // else case of package x which is a prefix of x.y
707 // case IJavaElement.COMPILATION_UNIT:
708 // case IJavaElement.CLASS_FILE:
709 // pkgFragment = (IPackageFragment)this.currentElement.getParent();
712 // if (pkgFragment == null) {
713 // element = rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
715 // if (elementType == IJavaElement.COMPILATION_UNIT) {
716 // // create compilation unit handle
717 // // fileName validation has been done in elementType(IResourceDelta, int, boolean)
718 // String fileName = path.lastSegment();
719 // element = pkgFragment.getCompilationUnit(fileName);
721 // // create class file handle
722 // // fileName validation has been done in elementType(IResourceDelta, int, boolean)
723 // String fileName = path.lastSegment();
724 // element = pkgFragment.getClassFile(fileName);
730 // if (element == null) {
733 // this.currentElement = (Openable)element;
734 // return this.currentElement;
738 * Note that the project is about to be deleted.
740 // public void deleting(IProject project) {
743 // // discard indexing jobs that belong to this project so that the project can be
744 // // deleted without interferences from the index manager
745 // this.indexManager.discardJobs(project.getName());
747 // JavaProject javaProject = (JavaProject)JavaCore.create(project);
749 // // remember roots of this project
750 // if (this.removedRoots == null) {
751 // this.removedRoots = new HashMap();
753 // if (javaProject.isOpen()) {
754 // this.removedRoots.put(javaProject, javaProject.getPackageFragmentRoots());
756 // // compute roots without opening project
757 // this.removedRoots.put(
759 // javaProject.computePackageFragmentRoots(
760 // javaProject.getResolvedClasspath(true),
764 // javaProject.close();
766 // // workaround for bug 15168 circular errors not reported
767 // if (this.manager.javaProjectsCache == null) {
768 // this.manager.javaProjectsCache = this.manager.getJavaModel().getJavaProjects();
770 // this.removeFromParentInfo(javaProject);
772 // } catch (JavaModelException e) {
775 // this.addDependentProjects(project.getFullPath(), this.projectsToUpdate);
780 * Processing for an element that has been added:<ul>
781 * <li>If the element is a project, do nothing, and do not process
782 * children, as when a project is created it does not yet have any
783 * natures - specifically a java nature.
784 * <li>If the elemet is not a project, process it as added (see
785 * <code>basicElementAdded</code>.
787 * Delta argument could be null if processing an external JAR change
789 // protected void elementAdded(Openable element, IResourceDelta delta, RootInfo rootInfo) {
790 // int elementType = element.getElementType();
792 // if (elementType == IJavaElement.JAVA_PROJECT) {
793 // // project add is handled by JavaProject.configure() because
794 // // when a project is created, it does not yet have a java nature
795 // if (delta != null && JavaProject.hasJavaNature((IProject)delta.getResource())) {
796 // addToParentInfo(element);
797 // if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
798 // Openable movedFromElement = (Openable)element.getJavaModel().getJavaProject(delta.getMovedFromPath().lastSegment());
799 // currentDelta().movedTo(element, movedFromElement);
801 // currentDelta().added(element);
803 // this.projectsToUpdate.add(element);
804 // this.updateRoots(element.getPath(), delta);
805 // this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
808 // addToParentInfo(element);
810 // // Force the element to be closed as it might have been opened
811 // // before the resource modification came in and it might have a new child
812 // // For example, in an IWorkspaceRunnable:
813 // // 1. create a package fragment p using a java model operation
814 // // 2. open package p
815 // // 3. add file X.java in folder p
816 // // When the resource delta comes in, only the addition of p is notified,
817 // // but the package p is already opened, thus its children are not recomputed
818 // // and it appears empty.
821 // if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
822 // IPath movedFromPath = delta.getMovedFromPath();
823 // IResource res = delta.getResource();
824 // IResource movedFromRes;
825 // if (res instanceof IFile) {
826 // movedFromRes = res.getWorkspace().getRoot().getFile(movedFromPath);
828 // movedFromRes = res.getWorkspace().getRoot().getFolder(movedFromPath);
831 // // find the element type of the moved from element
832 // RootInfo movedFromInfo = this.enclosingRootInfo(movedFromPath, IResourceDelta.REMOVED);
833 // int movedFromType =
836 // IResourceDelta.REMOVED,
837 // element.getParent().getElementType(),
840 // // reset current element as it might be inside a nested root (popUntilPrefixOf() may use the outer root)
841 // this.currentElement = null;
843 // // create the moved from element
844 // Openable movedFromElement =
845 // elementType != IJavaElement.JAVA_PROJECT && movedFromType == IJavaElement.JAVA_PROJECT ?
846 // null : // outside classpath
847 // this.createElement(movedFromRes, movedFromType, movedFromInfo);
848 // if (movedFromElement == null) {
849 // // moved from outside classpath
850 // currentDelta().added(element);
852 // currentDelta().movedTo(element, movedFromElement);
855 // currentDelta().added(element);
858 // switch (elementType) {
859 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
860 // // when a root is added, and is on the classpath, the project must be updated
861 // JavaProject project = (JavaProject) element.getJavaProject();
862 // this.projectsToUpdate.add(project);
863 // this.projectsForDependentNamelookupRefresh.add(project);
866 // case IJavaElement.PACKAGE_FRAGMENT :
867 // // get rid of namelookup since it holds onto obsolete cached info
868 // project = (JavaProject) element.getJavaProject();
870 // project.getJavaProjectElementInfo().setNameLookup(null);
871 // this.projectsForDependentNamelookupRefresh.add(project);
872 // } catch (JavaModelException e) {
874 // // add subpackages
875 // if (delta != null){
876 // PackageFragmentRoot root = element.getPackageFragmentRoot();
877 // String name = element.getElementName();
878 // IResourceDelta[] children = delta.getAffectedChildren();
879 // for (int i = 0, length = children.length; i < length; i++) {
880 // IResourceDelta child = children[i];
881 // IResource resource = child.getResource();
882 // if (resource instanceof IFolder) {
883 // String folderName = resource.getName();
884 // if (Util.isValidFolderNameForPackage(folderName)) {
885 // String subpkgName =
886 // name.length() == 0 ?
888 // name + "." + folderName; //$NON-NLS-1$
889 // Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
890 // this.updateIndex(subpkg, child);
891 // this.elementAdded(subpkg, child, rootInfo);
902 * Generic processing for a removed element:<ul>
903 * <li>Close the element, removing its structure from the cache
904 * <li>Remove the element from its parent's cache of children
905 * <li>Add a REMOVED entry in the delta
907 * Delta argument could be null if processing an external JAR change
909 // protected void elementRemoved(Openable element, IResourceDelta delta, RootInfo rootInfo) {
911 // if (element.isOpen()) {
914 // removeFromParentInfo(element);
915 // int elementType = element.getElementType();
916 // if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
917 // IPath movedToPath = delta.getMovedToPath();
918 // IResource res = delta.getResource();
919 // IResource movedToRes;
920 // switch (res.getType()) {
921 // case IResource.PROJECT:
922 // movedToRes = res.getWorkspace().getRoot().getProject(movedToPath.lastSegment());
924 // case IResource.FOLDER:
925 // movedToRes = res.getWorkspace().getRoot().getFolder(movedToPath);
927 // case IResource.FILE:
928 // movedToRes = res.getWorkspace().getRoot().getFile(movedToPath);
934 // // find the element type of the moved from element
935 // RootInfo movedToInfo = this.enclosingRootInfo(movedToPath, IResourceDelta.ADDED);
939 // IResourceDelta.ADDED,
940 // element.getParent().getElementType(),
943 // // reset current element as it might be inside a nested root (popUntilPrefixOf() may use the outer root)
944 // this.currentElement = null;
946 // // create the moved To element
947 // Openable movedToElement =
948 // elementType != IJavaElement.JAVA_PROJECT && movedToType == IJavaElement.JAVA_PROJECT ?
949 // null : // outside classpath
950 // this.createElement(movedToRes, movedToType, movedToInfo);
951 // if (movedToElement == null) {
952 // // moved outside classpath
953 // currentDelta().removed(element);
955 // currentDelta().movedFrom(element, movedToElement);
958 // currentDelta().removed(element);
961 // switch (elementType) {
962 // case IJavaElement.JAVA_MODEL :
963 // this.indexManager.reset();
965 // case IJavaElement.JAVA_PROJECT :
966 // this.manager.removePerProjectInfo(
967 // (JavaProject) element);
968 // this.updateRoots(element.getPath(), delta);
969 // this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
971 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
972 // JavaProject project = (JavaProject) element.getJavaProject();
973 // this.projectsToUpdate.add(project);
974 // this.projectsForDependentNamelookupRefresh.add(project);
976 // case IJavaElement.PACKAGE_FRAGMENT :
977 // //1G1TW2T - get rid of namelookup since it holds onto obsolete cached info
978 // project = (JavaProject) element.getJavaProject();
980 // project.getJavaProjectElementInfo().setNameLookup(null);
981 // this.projectsForDependentNamelookupRefresh.add(project);
982 // } catch (JavaModelException e) {
984 // // remove subpackages
985 // if (delta != null){
986 // PackageFragmentRoot root = element.getPackageFragmentRoot();
987 // String name = element.getElementName();
988 // IResourceDelta[] children = delta.getAffectedChildren();
989 // for (int i = 0, length = children.length; i < length; i++) {
990 // IResourceDelta child = children[i];
991 // IResource resource = child.getResource();
992 // if (resource instanceof IFolder) {
993 // String folderName = resource.getName();
994 // if (Util.isValidFolderNameForPackage(folderName)) {
995 // String subpkgName =
996 // name.length() == 0 ?
998 // name + "." + folderName; //$NON-NLS-1$
999 // Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
1000 // this.updateIndex(subpkg, child);
1001 // this.elementRemoved(subpkg, child, rootInfo);
1011 * Returns the type of the java element the given delta matches to.
1012 * Returns NON_JAVA_RESOURCE if unknown (e.g. a non-java resource or excluded .java file)
1014 // private int elementType(IResource res, int kind, int parentType, RootInfo rootInfo) {
1015 // switch (parentType) {
1016 // case IJavaElement.JAVA_MODEL:
1017 // // case of a movedTo or movedFrom project (other cases are handled in processResourceDelta(...)
1018 // return IJavaElement.JAVA_PROJECT;
1019 // case NON_JAVA_RESOURCE:
1020 // case IJavaElement.JAVA_PROJECT:
1021 // if (rootInfo == null) {
1022 // rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
1024 // if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
1025 // return IJavaElement.PACKAGE_FRAGMENT_ROOT;
1027 // return NON_JAVA_RESOURCE; // not yet in a package fragment root or root of another project
1029 // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
1030 // case IJavaElement.PACKAGE_FRAGMENT:
1031 // if (rootInfo == null) {
1032 // rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
1034 // if (rootInfo == null || Util.isExcluded(res, rootInfo.exclusionPatterns)) {
1035 // return NON_JAVA_RESOURCE;
1037 // if (res instanceof IFolder) {
1038 // if (Util.isValidFolderNameForPackage(res.getName())) {
1039 // return IJavaElement.PACKAGE_FRAGMENT;
1041 // return NON_JAVA_RESOURCE;
1044 // String fileName = res.getName();
1045 // if (Util.isValidCompilationUnitName(fileName)) {
1046 // return IJavaElement.COMPILATION_UNIT;
1047 // } else if (Util.isValidClassFileName(fileName)) {
1048 // return IJavaElement.CLASS_FILE;
1049 // } else if (this.rootInfo(res.getFullPath(), kind) != null) {
1050 // // case of proj=src=bin and resource is a jar file on the classpath
1051 // return IJavaElement.PACKAGE_FRAGMENT_ROOT;
1053 // return NON_JAVA_RESOURCE;
1057 // return NON_JAVA_RESOURCE;
1062 * Answer a combination of the lastModified stamp and the size.
1063 * Used for detecting external JAR changes
1065 public static long getTimeStamp(File file) {
1066 return file.lastModified() + file.length();
1069 public void initializeRoots() {
1070 // remember roots infos as old roots infos
1071 this.oldRoots = this.roots == null ? new HashMap() : this.roots;
1072 this.oldOtherRoots = this.otherRoots == null ? new HashMap() : this.otherRoots;
1074 // recompute root infos only if necessary
1075 if (!rootsAreStale) return;
1077 this.roots = new HashMap();
1078 this.otherRoots = new HashMap();
1079 this.sourceAttachments = new HashMap();
1081 IJavaModel model = this.manager.getJavaModel();
1082 IJavaProject[] projects;
1084 projects = model.getJavaProjects();
1085 } catch (JavaModelException e) {
1086 // nothing can be done
1089 for (int i = 0, length = projects.length; i < length; i++) {
1090 IJavaProject project = projects[i];
1091 IClasspathEntry[] classpath;
1093 classpath = project.getResolvedClasspath(true);
1094 } catch (JavaModelException e) {
1095 // continue with next project
1098 for (int j= 0, classpathLength = classpath.length; j < classpathLength; j++) {
1099 IClasspathEntry entry = classpath[j];
1100 if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue;
1103 IPath path = entry.getPath();
1104 if (this.roots.get(path) == null) {
1105 this.roots.put(path, new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars()));
1107 ArrayList rootList = (ArrayList)this.otherRoots.get(path);
1108 if (rootList == null) {
1109 rootList = new ArrayList();
1110 this.otherRoots.put(path, rootList);
1112 rootList.add(new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars()));
1115 // source attachment path
1116 if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) continue;
1117 QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "sourceattachment: " + path.toOSString()); //$NON-NLS-1$;
1118 String propertyString = null;
1120 propertyString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
1121 } catch (CoreException e) {
1124 IPath sourceAttachmentPath;
1125 // if (propertyString != null) {
1126 // int index= propertyString.lastIndexOf(JarPackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER);
1127 // sourceAttachmentPath = (index < 0) ? new Path(propertyString) : new Path(propertyString.substring(0, index));
1129 sourceAttachmentPath = entry.getSourceAttachmentPath();
1131 if (sourceAttachmentPath != null) {
1132 this.sourceAttachments.put(sourceAttachmentPath, path);
1136 this.rootsAreStale = false;
1140 * Returns whether a given delta contains some information relevant to the JavaModel,
1141 * in particular it will not consider SYNC or MARKER only deltas.
1143 public boolean isAffectedBy(IResourceDelta rootDelta){
1144 //if (rootDelta == null) System.out.println("NULL DELTA");
1145 //long start = System.currentTimeMillis();
1146 if (rootDelta != null) {
1147 // use local exception to quickly escape from delta traversal
1148 class FoundRelevantDeltaException extends RuntimeException {}
1150 rootDelta.accept(new IResourceDeltaVisitor() {
1151 public boolean visit(IResourceDelta delta) throws CoreException {
1152 switch (delta.getKind()){
1153 case IResourceDelta.ADDED :
1154 case IResourceDelta.REMOVED :
1155 throw new FoundRelevantDeltaException();
1156 case IResourceDelta.CHANGED :
1157 // if any flag is set but SYNC or MARKER, this delta should be considered
1158 if (delta.getAffectedChildren().length == 0 // only check leaf delta nodes
1159 && (delta.getFlags() & ~(IResourceDelta.SYNC | IResourceDelta.MARKERS)) != 0) {
1160 throw new FoundRelevantDeltaException();
1166 } catch(FoundRelevantDeltaException e) {
1167 //System.out.println("RELEVANT DELTA detected in: "+ (System.currentTimeMillis() - start));
1169 } catch(CoreException e) { // ignore delta if not able to traverse
1172 //System.out.println("IGNORE SYNC DELTA took: "+ (System.currentTimeMillis() - start));
1177 * Returns whether the given resource is in one of the given output folders and if
1178 * it is filtered out from this output folder.
1180 private boolean isResFilteredFromOutput(OutputsInfo info, IResource res, int elementType) {
1182 IPath resPath = res.getFullPath();
1183 for (int i = 0; i < info.outputCount; i++) {
1184 if (info.paths[i].isPrefixOf(resPath)) {
1185 if (info.traverseModes[i] != IGNORE) {
1187 if (info.traverseModes[i] == SOURCE && elementType == IJavaElement.CLASS_FILE) {
1190 // case of .class file under project and no source folder
1192 if (elementType == IJavaElement.JAVA_PROJECT
1193 && res instanceof IFile
1194 && PHPFileUtil.isPHPFile((IFile)res)) {
1208 * Generic processing for elements with changed contents:<ul>
1209 * <li>The element is closed such that any subsequent accesses will re-open
1210 * the element reflecting its new structure.
1211 * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
1214 // protected void nonJavaResourcesChanged(Openable element, IResourceDelta delta)
1215 // throws JavaModelException {
1217 // // reset non-java resources if element was open
1218 // if (element.isOpen()) {
1219 // JavaElementInfo info = (JavaElementInfo)element.getElementInfo();
1220 // switch (element.getElementType()) {
1221 // case IJavaElement.JAVA_MODEL :
1222 // ((JavaModelInfo) info).nonJavaResources = null;
1223 // currentDelta().addResourceDelta(delta);
1225 // case IJavaElement.JAVA_PROJECT :
1226 // ((JavaProjectElementInfo) info).setNonJavaResources(null);
1228 // // if a package fragment root is the project, clear it too
1229 // JavaProject project = (JavaProject) element;
1230 // PackageFragmentRoot projectRoot =
1231 // (PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject());
1232 // if (projectRoot.isOpen()) {
1233 // ((PackageFragmentRootInfo) projectRoot.getElementInfo()).setNonJavaResources(
1237 // case IJavaElement.PACKAGE_FRAGMENT :
1238 // ((PackageFragmentInfo) info).setNonJavaResources(null);
1240 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
1241 // ((PackageFragmentRootInfo) info).setNonJavaResources(null);
1245 // JavaElementDelta elementDelta = currentDelta().find(element);
1246 // if (elementDelta == null) {
1247 // currentDelta().changed(element, IJavaElementDelta.F_CONTENT);
1248 // elementDelta = currentDelta().find(element);
1250 // elementDelta.addResourceDelta(delta);
1252 // private OutputsInfo outputsInfo(RootInfo rootInfo, IResource res) {
1254 // IJavaProject proj =
1255 // rootInfo == null ?
1256 // (IJavaProject)this.createElement(res.getProject(), IJavaElement.JAVA_PROJECT, null) :
1257 // rootInfo.project;
1258 // if (proj != null) {
1259 // IPath projectOutput = proj.getOutputLocation();
1260 // int traverseMode = IGNORE;
1261 // if (proj.getProject().getFullPath().equals(projectOutput)){ // case of proj==bin==src
1262 // return new OutputsInfo(new IPath[] {projectOutput}, new int[] {SOURCE}, 1);
1264 // IClasspathEntry[] classpath = proj.getResolvedClasspath(true);
1265 // IPath[] outputs = new IPath[classpath.length+1];
1266 // int[] traverseModes = new int[classpath.length+1];
1267 // int outputCount = 1;
1268 // outputs[0] = projectOutput;
1269 // traverseModes[0] = traverseMode;
1270 // for (int i = 0, length = classpath.length; i < length; i++) {
1271 // IClasspathEntry entry = classpath[i];
1272 // IPath entryPath = entry.getPath();
1273 // IPath output = entry.getOutputLocation();
1274 // if (output != null) {
1275 // outputs[outputCount] = output;
1276 // // check case of src==bin
1277 // if (entryPath.equals(output)) {
1278 // traverseModes[outputCount++] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY;
1280 // traverseModes[outputCount++] = IGNORE;
1284 // // check case of src==bin
1285 // if (entryPath.equals(projectOutput)) {
1286 // traverseModes[0] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY;
1289 // return new OutputsInfo(outputs, traverseModes, outputCount);
1292 // } catch (JavaModelException e) {
1298 * Check whether the updated file is affecting some of the properties of a given project (like
1299 * its classpath persisted as a file).
1300 * Also force classpath problems to be refresh if not running in autobuild mode.
1301 * NOTE: It can induce resource changes, and cannot be called during POST_CHANGE notification.
1304 // public void performPreBuildCheck(
1305 // IResourceDelta delta,
1306 // IJavaElement parent) {
1308 // IResource resource = delta.getResource();
1309 // IJavaElement element = null;
1310 // boolean processChildren = false;
1312 // switch (resource.getType()) {
1314 // case IResource.ROOT :
1315 // if (delta.getKind() == IResourceDelta.CHANGED) {
1316 // element = JavaCore.create(resource);
1317 // processChildren = true;
1320 // case IResource.PROJECT :
1321 // int kind = delta.getKind();
1323 // case IResourceDelta.CHANGED:
1324 // // do not visit non-java projects (see bug 16140 Non-java project gets .classpath)
1325 // IProject project = (IProject)resource;
1326 // if (JavaProject.hasJavaNature(project)) {
1327 // element = JavaCore.create(resource);
1328 // processChildren = true;
1329 // } else if (JavaModelManager.getJavaModelManager().getJavaModel().findJavaProject(project) != null) {
1330 // // project had the java nature
1331 // this.rootsAreStale = true;
1333 // // remove classpath cache so that initializeRoots() will not consider the project has a classpath
1334 // this.manager.removePerProjectInfo((JavaProject)JavaCore.create(project));
1337 // case IResourceDelta.ADDED:
1338 // this.rootsAreStale = true;
1340 // case IResourceDelta.REMOVED:
1341 // // remove classpath cache so that initializeRoots() will not consider the project has a classpath
1342 // this.manager.removePerProjectInfo((JavaProject)JavaCore.create(resource));
1344 // this.rootsAreStale = true;
1348 // case IResource.FILE :
1349 // if (parent.getElementType() == IJavaElement.JAVA_PROJECT) {
1350 // IFile file = (IFile) resource;
1351 // JavaProject project = (JavaProject) parent;
1353 // /* check classpath file change */
1354 // if (file.getName().equals(JavaProject.CLASSPATH_FILENAME)) {
1355 // reconcileClasspathFileUpdate(delta, file, project);
1356 // this.rootsAreStale = true;
1359 //// /* check custom preference file change */
1360 //// if (file.getName().equals(JavaProject.PREF_FILENAME)) {
1361 //// reconcilePreferenceFileUpdate(delta, file, project);
1367 // if (processChildren) {
1368 // IResourceDelta[] children = delta.getAffectedChildren();
1369 // for (int i = 0; i < children.length; i++) {
1370 // performPreBuildCheck(children[i], element);
1375 // private void popUntilPrefixOf(IPath path) {
1376 // while (this.currentElement != null) {
1377 // IPath currentElementPath = null;
1378 // if (this.currentElement instanceof IPackageFragmentRoot) {
1379 // currentElementPath = ((IPackageFragmentRoot)this.currentElement).getPath();
1381 // IResource currentElementResource = this.currentElement.getResource();
1382 // if (currentElementResource != null) {
1383 // currentElementPath = currentElementResource.getFullPath();
1386 // if (currentElementPath != null) {
1387 // if (this.currentElement instanceof IPackageFragment
1388 // && this.currentElement.getElementName().length() == 0
1389 // && currentElementPath.segmentCount() != path.segmentCount()-1) {
1390 // // default package and path is not a direct child
1391 // this.currentElement = (Openable)this.currentElement.getParent();
1393 // if (currentElementPath.isPrefixOf(path)) {
1397 // this.currentElement = (Openable)this.currentElement.getParent();
1402 * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into
1403 * the corresponding set of <code>IJavaElementDelta</code>, rooted in the
1404 * relevant <code>JavaModel</code>s.
1406 // public IJavaElementDelta processResourceDelta(IResourceDelta changes) {
1409 // IJavaModel model = this.manager.getJavaModel();
1410 // if (!model.isOpen()) {
1411 // // force opening of java model so that java element delta are reported
1413 // model.open(null);
1414 // } catch (JavaModelException e) {
1416 // e.printStackTrace();
1421 // this.initializeRoots();
1422 // this.currentElement = null;
1424 // // get the workspace delta, and start processing there.
1425 // IResourceDelta[] deltas = changes.getAffectedChildren();
1426 // for (int i = 0; i < deltas.length; i++) {
1427 // IResourceDelta delta = deltas[i];
1428 // IResource res = delta.getResource();
1430 // // find out the element type
1431 // RootInfo rootInfo = null;
1433 // IProject proj = (IProject)res;
1434 // boolean wasJavaProject = this.manager.getJavaModel().findJavaProject(proj) != null;
1435 // boolean isJavaProject = JavaProject.hasJavaNature(proj);
1436 // if (!wasJavaProject && !isJavaProject) {
1437 // elementType = NON_JAVA_RESOURCE;
1439 // rootInfo = this.enclosingRootInfo(res.getFullPath(), delta.getKind());
1440 // if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
1441 // elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT;
1443 // elementType = IJavaElement.JAVA_PROJECT;
1447 // // traverse delta
1448 // if (!this.traverseDelta(delta, elementType, rootInfo, null)
1449 // || (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { // project has changed nature (description or open/closed)
1451 // // add child as non java resource
1452 // nonJavaResourcesChanged((JavaModel)model, delta);
1453 // } catch (JavaModelException e) {
1459 // // update package fragment roots of projects that were affected
1460 // Iterator iterator = this.projectsToUpdate.iterator();
1461 // while (iterator.hasNext()) {
1462 // JavaProject project = (JavaProject)iterator.next();
1463 // project.updatePackageFragmentRoots();
1466 // updateDependentNamelookups();
1468 // return this.currentDelta;
1470 // this.currentDelta = null;
1471 // this.projectsToUpdate.clear();
1472 // this.projectsForDependentNamelookupRefresh.clear();
1477 * Update the JavaModel according to a .classpath file change. The file can have changed as a result of a previous
1478 * call to JavaProject#setRawClasspath or as a result of some user update (through repository)
1480 // void reconcileClasspathFileUpdate(IResourceDelta delta, IFile file, JavaProject project) {
1482 // switch (delta.getKind()) {
1483 // case IResourceDelta.REMOVED : // recreate one based on in-memory classpath
1485 // JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
1486 // if (info.classpath != null) { // if there is an in-memory classpath
1487 // project.saveClasspath(info.classpath, info.outputLocation);
1489 // } catch (JavaModelException e) {
1490 // if (project.getProject().isAccessible()) {
1491 // Util.log(e, "Could not save classpath for "+ project.getPath()); //$NON-NLS-1$
1495 // case IResourceDelta.CHANGED :
1496 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0 // only consider content change
1497 // && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move and overide scenario (see http://dev.eclipse.org/bugs/show_bug.cgi?id=21420)
1499 // case IResourceDelta.ADDED :
1500 // // check if any actual difference
1501 // project.flushClasspathProblemMarkers(false, true);
1502 // boolean wasSuccessful = false; // flag recording if .classpath file change got reflected
1504 // // force to (re)read the property file
1505 // IClasspathEntry[] fileEntries = project.readClasspathFile(true/*create markers*/, false/*don't log problems*/);
1506 // if (fileEntries == null)
1507 // break; // could not read, ignore
1508 // JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
1509 // if (info.classpath != null) { // if there is an in-memory classpath
1510 // if (project.isClasspathEqualsTo(info.classpath, info.outputLocation, fileEntries)) {
1511 // wasSuccessful = true;
1516 // // will force an update of the classpath/output location based on the file information
1517 // // extract out the output location
1518 // IPath outputLocation = null;
1519 // if (fileEntries != null && fileEntries.length > 0) {
1520 // IClasspathEntry entry = fileEntries[fileEntries.length - 1];
1521 // if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
1522 // outputLocation = entry.getPath();
1523 // IClasspathEntry[] copy = new IClasspathEntry[fileEntries.length - 1];
1524 // System.arraycopy(fileEntries, 0, copy, 0, copy.length);
1525 // fileEntries = copy;
1528 // // restore output location
1529 // if (outputLocation == null) {
1530 // outputLocation = SetClasspathOperation.ReuseOutputLocation;
1531 // // clean mode will also default to reusing current one
1533 // project.setRawClasspath(
1537 // true, // canChangeResource
1538 // project.getResolvedClasspath(true), // ignoreUnresolvedVariable
1539 // true, // needValidation
1540 // false); // no need to save
1542 // // if reach that far, the classpath file change got absorbed
1543 // wasSuccessful = true;
1544 // } catch (RuntimeException e) {
1545 // // setRawClasspath might fire a delta, and a listener may throw an exception
1546 // if (project.getProject().isAccessible()) {
1547 // Util.log(e, "Could not set classpath for "+ project.getPath()); //$NON-NLS-1$
1550 // } catch (JavaModelException e) { // CP failed validation
1551 // if (project.getProject().isAccessible()) {
1552 // if (e.getJavaModelStatus().getException() instanceof CoreException) {
1553 // // happens if the .classpath could not be written to disk
1554 // project.createClasspathProblemMarker(new JavaModelStatus(
1555 // IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1556 // Util.bind("classpath.couldNotWriteClasspathFile", project.getElementName(), e.getMessage()))); //$NON-NLS-1$
1558 // project.createClasspathProblemMarker(new JavaModelStatus(
1559 // IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1560 // Util.bind("classpath.invalidClasspathInClasspathFile", project.getElementName(), e.getMessage()))); //$NON-NLS-1$
1565 // if (!wasSuccessful) {
1567 // project.setRawClasspath0(JavaProject.INVALID_CLASSPATH);
1568 // project.updatePackageFragmentRoots();
1569 // } catch (JavaModelException e) {
1577 * Update the JavaModel according to a .jprefs file change. The file can have changed as a result of a previous
1578 * call to JavaProject#setOptions or as a result of some user update (through repository)
1579 * Unused until preference file get shared (.jpref)
1581 // void reconcilePreferenceFileUpdate(IResourceDelta delta, IFile file, JavaProject project) {
1583 // switch (delta.getKind()) {
1584 // case IResourceDelta.REMOVED : // flush project custom settings
1585 // project.setOptions(null);
1587 // case IResourceDelta.CHANGED :
1588 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0 // only consider content change
1589 // && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move and overide scenario
1591 // identityCheck : { // check if any actual difference
1592 // // force to (re)read the property file
1593 // Preferences filePreferences = project.loadPreferences();
1594 // if (filePreferences == null){
1595 // project.setOptions(null); // should have got removed delta.
1598 // Preferences projectPreferences = project.getPreferences();
1599 // if (projectPreferences == null) return; // not a Java project
1601 // // compare preferences set to their default
1602 // String[] defaultProjectPropertyNames = projectPreferences.defaultPropertyNames();
1603 // String[] defaultFilePropertyNames = filePreferences.defaultPropertyNames();
1604 // if (defaultProjectPropertyNames.length == defaultFilePropertyNames.length) {
1605 // for (int i = 0; i < defaultProjectPropertyNames.length; i++){
1606 // String propertyName = defaultProjectPropertyNames[i];
1607 // if (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1608 // break identityCheck;
1611 // } else break identityCheck;
1613 // // compare custom preferences not set to their default
1614 // String[] projectPropertyNames = projectPreferences.propertyNames();
1615 // String[] filePropertyNames = filePreferences.propertyNames();
1616 // if (projectPropertyNames.length == filePropertyNames.length) {
1617 // for (int i = 0; i < projectPropertyNames.length; i++){
1618 // String propertyName = projectPropertyNames[i];
1619 // if (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1620 // break identityCheck;
1623 // } else break identityCheck;
1625 // // identical - do nothing
1628 // case IResourceDelta.ADDED :
1629 // // not identical, create delta and reset cached preferences
1630 // project.setPreferences(null);
1632 // //fCurrentDelta.changed(project, IJavaElementDelta.F_OPTIONS_CHANGED);
1637 * Removes the given element from its parents cache of children. If the
1638 * element does not have a parent, or the parent is not currently open,
1639 * this has no effect.
1641 protected void removeFromParentInfo(Openable child) {
1643 Openable parent = (Openable) child.getParent();
1644 if (parent != null && parent.isOpen()) {
1646 JavaElementInfo info = (JavaElementInfo)parent.getElementInfo();
1647 info.removeChild(child);
1648 } catch (JavaModelException e) {
1649 // do nothing - we already checked if open
1654 * Notification that some resource changes have happened
1655 * on the platform, and that the Java Model should update any required
1656 * internal structures such that its elements remain consistent.
1657 * Translates <code>IResourceDeltas</code> into <code>IJavaElementDeltas</code>.
1659 * @see IResourceDelta
1662 public void resourceChanged(IResourceChangeEvent event) {
1664 if (event.getSource() instanceof IWorkspace) {
1665 IResource resource = event.getResource();
1666 IResourceDelta delta = event.getDelta();
1668 switch(event.getType()){
1669 case IResourceChangeEvent.PRE_DELETE :
1671 if(resource.getType() == IResource.PROJECT
1672 && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
1673 // TODO khartlage temp-del
1674 // this.deleting((IProject)resource);
1676 } catch(CoreException e){
1680 case IResourceChangeEvent.PRE_AUTO_BUILD :
1681 // TODO khartlage temp-del
1682 // if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER deltas
1683 // this.checkProjectsBeingAddedOrRemoved(delta);
1685 // // update the classpath related markers
1686 // this.updateClasspathMarkers();
1688 // // the following will close project if affected by the property file change
1690 // // don't fire classpath change deltas right away, but batch them
1691 // this.manager.stopDeltas();
1692 // this.performPreBuildCheck(delta, null);
1694 // this.manager.startDeltas();
1697 // only fire already computed deltas (resource ones will be processed in post change only)
1698 this.manager.fire(null, ElementChangedEvent.PRE_AUTO_BUILD);
1701 case IResourceChangeEvent.POST_AUTO_BUILD :
1702 // TODO khartlage temp-del
1703 // JavaBuilder.finishedBuilding(event);
1706 case IResourceChangeEvent.POST_CHANGE :
1707 // TODO khartlage temp-del
1708 // if (isAffectedBy(delta)) {
1710 // if (this.refreshedElements != null) {
1712 // createExternalArchiveDelta(null);
1713 // } catch (JavaModelException e) {
1714 // e.printStackTrace();
1717 // IJavaElementDelta translatedDelta = this.processResourceDelta(delta);
1718 // if (translatedDelta != null) {
1719 // this.manager.registerJavaModelDelta(translatedDelta);
1721 // this.manager.fire(null, ElementChangedEvent.POST_CHANGE);
1723 // // workaround for bug 15168 circular errors not reported
1724 // this.manager.javaProjectsCache = null;
1725 // this.removedRoots = null;
1732 * Finds the root info this path is included in.
1733 * Returns null if not found.
1735 RootInfo enclosingRootInfo(IPath path, int kind) {
1736 while (path != null && path.segmentCount() > 0) {
1737 RootInfo rootInfo = this.rootInfo(path, kind);
1738 if (rootInfo != null) return rootInfo;
1739 path = path.removeLastSegments(1);
1744 * Returns the root info for the given path. Look in the old roots table if kind is REMOVED.
1746 RootInfo rootInfo(IPath path, int kind) {
1747 if (kind == IResourceDelta.REMOVED) {
1748 return (RootInfo)this.oldRoots.get(path);
1750 return (RootInfo)this.roots.get(path);
1754 * Returns the other root infos for the given path. Look in the old other roots table if kind is REMOVED.
1756 ArrayList otherRootsInfo(IPath path, int kind) {
1757 if (kind == IResourceDelta.REMOVED) {
1758 return (ArrayList)this.oldOtherRoots.get(path);
1760 return (ArrayList)this.otherRoots.get(path);
1765 * Converts an <code>IResourceDelta</code> and its children into
1766 * the corresponding <code>IJavaElementDelta</code>s.
1767 * Return whether the delta corresponds to a java element.
1768 * If it is not a java element, it will be added as a non-java
1769 * resource by the sender of this method.
1771 // protected boolean traverseDelta(
1772 // IResourceDelta delta,
1774 // RootInfo rootInfo,
1775 // OutputsInfo outputsInfo) {
1777 // IResource res = delta.getResource();
1779 // // set stack of elements
1780 // if (this.currentElement == null && rootInfo != null) {
1781 // this.currentElement = (Openable)rootInfo.project;
1784 // // process current delta
1785 // boolean processChildren = true;
1786 // if (res instanceof IProject) {
1787 // processChildren =
1788 // this.updateCurrentDeltaAndIndex(
1790 // elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ?
1791 // IJavaElement.JAVA_PROJECT : // case of prj=src
1794 // } else if (rootInfo != null) {
1795 // processChildren = this.updateCurrentDeltaAndIndex(delta, elementType, rootInfo);
1797 // // not yet inside a package fragment root
1798 // processChildren = true;
1801 // // get the project's output locations and traverse mode
1802 // if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
1804 // // process children if needed
1805 // if (processChildren) {
1806 // IResourceDelta[] children = delta.getAffectedChildren();
1807 // boolean oneChildOnClasspath = false;
1808 // int length = children.length;
1809 // IResourceDelta[] orphanChildren = null;
1810 // Openable parent = null;
1811 // boolean isValidParent = true;
1812 // for (int i = 0; i < length; i++) {
1813 // IResourceDelta child = children[i];
1814 // IResource childRes = child.getResource();
1816 // // check source attachment change
1817 // this.checkSourceAttachmentChange(child, childRes);
1819 // // find out whether the child is a package fragment root of the current project
1820 // IPath childPath = childRes.getFullPath();
1821 // int childKind = child.getKind();
1822 // RootInfo childRootInfo = this.rootInfo(childPath, childKind);
1823 // if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
1824 // // package fragment root of another project (dealt with later)
1825 // childRootInfo = null;
1828 // // compute child type
1830 // this.elementType(
1834 // rootInfo == null ? childRootInfo : rootInfo
1837 // // is childRes in the output folder and is it filtered out ?
1838 // boolean isResFilteredFromOutput = this.isResFilteredFromOutput(outputsInfo, childRes, childType);
1840 // boolean isNestedRoot = rootInfo != null && childRootInfo != null;
1841 // if (!isResFilteredFromOutput
1842 // && !isNestedRoot) { // do not treat as non-java rsc if nested root
1843 // if (!this.traverseDelta(child, childType, rootInfo == null ? childRootInfo : rootInfo, outputsInfo)) { // traverse delta for child in the same project
1844 // // it is a non-java resource
1846 // if (rootInfo != null) { // if inside a package fragment root
1847 // if (!isValidParent) continue;
1848 // if (parent == null) {
1849 // // find the parent of the non-java resource to attach to
1850 // if (this.currentElement == null
1851 // || !this.currentElement.getJavaProject().equals(rootInfo.project)) {
1852 // // force the currentProject to be used
1853 // this.currentElement = (Openable)rootInfo.project;
1855 // if (elementType == IJavaElement.JAVA_PROJECT
1856 // || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT
1857 // && res instanceof IProject)) {
1858 // // NB: attach non-java resource to project (not to its package fragment root)
1859 // parent = (Openable)rootInfo.project;
1861 // parent = this.createElement(res, elementType, rootInfo);
1863 // if (parent == null) {
1864 // isValidParent = false;
1868 // // add child as non java resource
1869 // nonJavaResourcesChanged(parent, child);
1871 // // the non-java resource (or its parent folder) will be attached to the java project
1872 // if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
1873 // orphanChildren[i] = child;
1875 // } catch (JavaModelException e) {
1878 // oneChildOnClasspath = true;
1881 // oneChildOnClasspath = true; // to avoid reporting child delta as non-java resource delta
1884 // // if child is a nested root
1885 // // or if it is not a package fragment root of the current project
1886 // // but it is a package fragment root of another project, traverse delta too
1888 // || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath, childKind)) != null)) {
1889 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
1890 // // NB: No need to check the return value as the child can only be on the classpath
1893 // // if the child is a package fragment root of one or several other projects
1894 // ArrayList rootList;
1895 // if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) {
1896 // Iterator iterator = rootList.iterator();
1897 // while (iterator.hasNext()) {
1898 // childRootInfo = (RootInfo) iterator.next();
1899 // this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
1903 // if (orphanChildren != null
1904 // && (oneChildOnClasspath // orphan children are siblings of a package fragment root
1905 // || res instanceof IProject)) { // non-java resource directly under a project
1907 // // attach orphan children
1908 // IProject rscProject = res.getProject();
1909 // JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
1910 // if (adoptiveProject != null
1911 // && JavaProject.hasJavaNature(rscProject)) { // delta iff Java project (18698)
1912 // for (int i = 0; i < length; i++) {
1913 // if (orphanChildren[i] != null) {
1915 // nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
1916 // } catch (JavaModelException e) {
1921 // } // else resource delta will be added by parent
1922 // return elementType != NON_JAVA_RESOURCE; // TODO: (jerome) do we still need to return? (check could be done by caller)
1924 // return elementType != NON_JAVA_RESOURCE;
1929 * Update the classpath markers and cycle markers for the projects to update.
1931 // void updateClasspathMarkers() {
1933 // if (!ResourcesPlugin.getWorkspace().isAutoBuilding()) {
1934 // Iterator iterator = this.projectsToUpdate.iterator();
1935 // while (iterator.hasNext()) {
1937 // JavaProject project = (JavaProject)iterator.next();
1939 // // force classpath marker refresh
1940 // project.getResolvedClasspath(
1941 // true, // ignoreUnresolvedEntry
1942 // true); // generateMarkerOnError
1944 // } catch (JavaModelException e) {
1948 // if (!this.projectsToUpdate.isEmpty()){
1950 // // update all cycle markers
1951 // JavaProject.updateAllCycleMarkers();
1952 // } catch (JavaModelException e) {
1956 // this.projectsToUpdate = new HashSet();
1961 * Update the current delta (ie. add/remove/change the given element) and update the correponding index.
1962 * Returns whether the children of the given delta must be processed.
1963 * @throws a JavaModelException if the delta doesn't correspond to a java element of the given type.
1965 // private boolean updateCurrentDeltaAndIndex(IResourceDelta delta, int elementType, RootInfo rootInfo) {
1966 // Openable element;
1967 // switch (delta.getKind()) {
1968 // case IResourceDelta.ADDED :
1969 // IResource deltaRes = delta.getResource();
1970 // element = this.createElement(deltaRes, elementType, rootInfo);
1971 // if (element == null) {
1972 // // resource might be containing shared roots (see bug 19058)
1973 // this.updateRoots(deltaRes.getFullPath(), delta);
1976 // this.updateIndex(element, delta);
1977 // this.elementAdded(element, delta, rootInfo);
1979 // case IResourceDelta.REMOVED :
1980 // deltaRes = delta.getResource();
1981 // element = this.createElement(deltaRes, elementType, rootInfo);
1982 // if (element == null) {
1983 // // resource might be containing shared roots (see bug 19058)
1984 // this.updateRoots(deltaRes.getFullPath(), delta);
1987 // this.updateIndex(element, delta);
1988 // this.elementRemoved(element, delta, rootInfo);
1990 // if (deltaRes.getType() == IResource.PROJECT){
1991 // // reset the corresponding project built state, since cannot reuse if added back
1992 // this.manager.setLastBuiltState((IProject)deltaRes, null /*no state*/);
1995 // case IResourceDelta.CHANGED :
1996 // int flags = delta.getFlags();
1997 // if ((flags & IResourceDelta.CONTENT) != 0) {
1998 // // content has changed
1999 // element = this.createElement(delta.getResource(), elementType, rootInfo);
2000 // if (element == null) return false;
2001 // this.updateIndex(element, delta);
2002 // this.contentChanged(element, delta);
2003 // } else if (elementType == IJavaElement.JAVA_PROJECT) {
2004 // if ((flags & IResourceDelta.OPEN) != 0) {
2005 // // project has been opened or closed
2006 // IProject res = (IProject)delta.getResource();
2007 // element = this.createElement(res, elementType, rootInfo);
2008 // if (element == null) {
2009 // // resource might be containing shared roots (see bug 19058)
2010 // this.updateRoots(res.getFullPath(), delta);
2013 // if (res.isOpen()) {
2014 // if (JavaProject.hasJavaNature(res)) {
2015 // this.elementAdded(element, delta, rootInfo);
2016 // this.indexManager.indexAll(res);
2019 // JavaModel javaModel = this.manager.getJavaModel();
2020 // boolean wasJavaProject = javaModel.findJavaProject(res) != null;
2021 // if (wasJavaProject) {
2022 // this.elementRemoved(element, delta, rootInfo);
2023 // this.indexManager.discardJobs(element.getElementName());
2024 // this.indexManager.removeIndexFamily(res.getFullPath());
2028 // return false; // when a project is open/closed don't process children
2030 // if ((flags & IResourceDelta.DESCRIPTION) != 0) {
2031 // IProject res = (IProject)delta.getResource();
2032 // JavaModel javaModel = this.manager.getJavaModel();
2033 // boolean wasJavaProject = javaModel.findJavaProject(res) != null;
2034 // boolean isJavaProject = JavaProject.hasJavaNature(res);
2035 // if (wasJavaProject != isJavaProject) {
2036 // // project's nature has been added or removed
2037 // element = this.createElement(res, elementType, rootInfo);
2038 // if (element == null) return false; // note its resources are still visible as roots to other projects
2039 // if (isJavaProject) {
2040 // this.elementAdded(element, delta, rootInfo);
2041 // this.indexManager.indexAll(res);
2043 // this.elementRemoved(element, delta, rootInfo);
2044 // this.indexManager.discardJobs(element.getElementName());
2045 // this.indexManager.removeIndexFamily(res.getFullPath());
2046 // // reset the corresponding project built state, since cannot reuse if added back
2047 // this.manager.setLastBuiltState(res, null /*no state*/);
2049 // return false; // when a project's nature is added/removed don't process children
2059 * Traverse the set of projects which have changed namespace, and refresh their dependents
2061 // public void updateDependentNamelookups() {
2062 // Iterator iterator;
2063 // // update namelookup of dependent projects
2064 // iterator = this.projectsForDependentNamelookupRefresh.iterator();
2065 // HashSet affectedDependents = new HashSet();
2066 // while (iterator.hasNext()) {
2067 // JavaProject project = (JavaProject)iterator.next();
2068 // addDependentProjects(project.getPath(), affectedDependents);
2070 // iterator = affectedDependents.iterator();
2071 // while (iterator.hasNext()) {
2072 // JavaProject project = (JavaProject) iterator.next();
2073 // if (project.isOpen()){
2075 // ((JavaProjectElementInfo)project.getElementInfo()).setNameLookup(null);
2076 // } catch (JavaModelException e) {
2082 //protected void updateIndex(Openable element, IResourceDelta delta) {
2084 // if (indexManager == null)
2087 // switch (element.getElementType()) {
2088 // case IJavaElement.JAVA_PROJECT :
2089 // switch (delta.getKind()) {
2090 // case IResourceDelta.ADDED :
2091 // this.indexManager.indexAll(element.getJavaProject().getProject());
2093 // case IResourceDelta.REMOVED :
2094 // this.indexManager.removeIndexFamily(element.getJavaProject().getProject().getFullPath());
2095 // // NB: Discarding index jobs belonging to this project was done during PRE_DELETE
2097 // // NB: Update of index if project is opened, closed, or its java nature is added or removed
2098 // // is done in updateCurrentDeltaAndIndex
2101 // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
2102 // if (element instanceof JarPackageFragmentRoot) {
2103 // JarPackageFragmentRoot root = (JarPackageFragmentRoot)element;
2104 // // index jar file only once (if the root is in its declaring project)
2105 // IPath jarPath = root.getPath();
2106 // switch (delta.getKind()) {
2107 // case IResourceDelta.ADDED:
2108 // // index the new jar
2109 // indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
2111 // case IResourceDelta.CHANGED:
2112 // // first remove the index so that it is forced to be re-indexed
2113 // indexManager.removeIndex(jarPath);
2114 // // then index the jar
2115 // indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
2117 // case IResourceDelta.REMOVED:
2118 // // the jar was physically removed: remove the index
2119 // this.indexManager.discardJobs(jarPath.toString());
2120 // this.indexManager.removeIndex(jarPath);
2125 // int kind = delta.getKind();
2126 // if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED) {
2127 // IPackageFragmentRoot root = (IPackageFragmentRoot)element;
2128 // this.updateRootIndex(root, root.getPackageFragment(""), delta); //$NON-NLS-1$
2132 // // don't break as packages of the package fragment root can be indexed below
2133 // case IJavaElement.PACKAGE_FRAGMENT :
2134 // switch (delta.getKind()) {
2135 // case IResourceDelta.ADDED:
2136 // case IResourceDelta.REMOVED:
2137 // IPackageFragment pkg = null;
2138 // if (element instanceof IPackageFragmentRoot) {
2139 // IPackageFragmentRoot root = (IPackageFragmentRoot)element;
2140 // pkg = root.getPackageFragment(""); //$NON-NLS-1$
2142 // pkg = (IPackageFragment)element;
2144 // IResourceDelta[] children = delta.getAffectedChildren();
2145 // for (int i = 0, length = children.length; i < length; i++) {
2146 // IResourceDelta child = children[i];
2147 // IResource resource = child.getResource();
2148 // if (resource instanceof IFile) {
2149 // String name = resource.getName();
2150 // if (Util.isJavaFileName(name)) {
2151 // Openable cu = (Openable)pkg.getCompilationUnit(name);
2152 // this.updateIndex(cu, child);
2153 // } else if (Util.isClassFileName(name)) {
2154 // Openable classFile = (Openable)pkg.getClassFile(name);
2155 // this.updateIndex(classFile, child);
2162 // case IJavaElement.CLASS_FILE :
2163 // IFile file = (IFile) delta.getResource();
2164 // IJavaProject project = element.getJavaProject();
2165 // IPath binaryFolderPath = element.getPackageFragmentRoot().getPath();
2166 // // if the class file is part of the binary output, it has been created by
2167 // // the java builder -> ignore
2169 // if (binaryFolderPath.equals(project.getOutputLocation())) {
2172 // } catch (JavaModelException e) {
2174 // switch (delta.getKind()) {
2175 // case IResourceDelta.CHANGED :
2176 // // no need to index if the content has not changed
2177 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
2179 // case IResourceDelta.ADDED :
2180 // indexManager.addBinary(file, binaryFolderPath);
2182 // case IResourceDelta.REMOVED :
2183 // indexManager.remove(file.getFullPath().toString(), binaryFolderPath);
2187 // case IJavaElement.COMPILATION_UNIT :
2188 // file = (IFile) delta.getResource();
2189 // switch (delta.getKind()) {
2190 // case IResourceDelta.CHANGED :
2191 // // no need to index if the content has not changed
2192 // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
2194 // case IResourceDelta.ADDED :
2195 // indexManager.addSource(file, file.getProject().getProject().getFullPath());
2197 // case IResourceDelta.REMOVED :
2198 // indexManager.remove(file.getFullPath().toString(), file.getProject().getProject().getFullPath());
2204 * Upadtes the index of the given root (assuming it's an addition or a removal).
2205 * This is done recusively, pkg being the current package.
2207 //private void updateRootIndex(IPackageFragmentRoot root, IPackageFragment pkg, IResourceDelta delta) {
2208 // this.updateIndex((Openable)pkg, delta);
2209 // IResourceDelta[] children = delta.getAffectedChildren();
2210 // String name = pkg.getElementName();
2211 // for (int i = 0, length = children.length; i < length; i++) {
2212 // IResourceDelta child = children[i];
2213 // IResource resource = child.getResource();
2214 // if (resource instanceof IFolder) {
2215 // String subpkgName =
2216 // name.length() == 0 ?
2217 // resource.getName() :
2218 // name + "." + resource.getName(); //$NON-NLS-1$
2219 // IPackageFragment subpkg = root.getPackageFragment(subpkgName);
2220 // this.updateRootIndex(root, subpkg, child);
2225 * Update the roots that are affected by the addition or the removal of the given container resource.
2227 //private void updateRoots(IPath containerPath, IResourceDelta containerDelta) {
2230 // if (containerDelta.getKind() == IResourceDelta.REMOVED) {
2231 // roots = this.oldRoots;
2232 // otherRoots = this.oldOtherRoots;
2234 // roots = this.roots;
2235 // otherRoots = this.otherRoots;
2237 // Iterator iterator = roots.keySet().iterator();
2238 // while (iterator.hasNext()) {
2239 // IPath path = (IPath)iterator.next();
2240 // if (containerPath.isPrefixOf(path) && !containerPath.equals(path)) {
2241 // IResourceDelta rootDelta = containerDelta.findMember(path.removeFirstSegments(1));
2242 // if (rootDelta == null) continue;
2243 // RootInfo rootInfo = (RootInfo)roots.get(path);
2245 // if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider roots that are not included in the container
2246 // this.updateCurrentDeltaAndIndex(rootDelta, IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);
2249 // ArrayList rootList = (ArrayList)otherRoots.get(path);
2250 // if (rootList != null) {
2251 // Iterator otherProjects = rootList.iterator();
2252 // while (otherProjects.hasNext()) {
2253 // rootInfo = (RootInfo)otherProjects.next();
2254 // if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider roots that are not included in the container
2255 // this.updateCurrentDeltaAndIndex(rootDelta, IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);