Refactory: remove unused classes, imports, fields and methods.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / DeltaProcessor.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
12
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;
19 import java.util.Map;
20
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;
34
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;
50
51 /**
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).
56  */
57 public class DeltaProcessor implements IResourceChangeListener {
58
59         final static int IGNORE = 0;
60
61         final static int SOURCE = 1;
62
63         final static int BINARY = 2;
64
65         final static String EXTERNAL_JAR_ADDED = "external jar added"; //$NON-NLS-1$
66
67         final static String EXTERNAL_JAR_REMOVED = "external jar removed"; //$NON-NLS-1$
68
69         final static String EXTERNAL_JAR_CHANGED = "external jar changed"; //$NON-NLS-1$
70
71         final static String EXTERNAL_JAR_UNCHANGED = "external jar unchanged"; //$NON-NLS-1$
72
73         final static String INTERNAL_JAR_IGNORE = "internal jar ignore"; //$NON-NLS-1$
74
75         private final static int NON_JAVA_RESOURCE = -1;
76
77         public static boolean DEBUG = false;
78
79         public static boolean VERBOSE = false;
80
81         public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with
82                                                                                                                 // ElementChangedEvent
83                                                                                                                 // event masks
84
85         /**
86          * The <code>JavaElementDelta</code> corresponding to the
87          * <code>IResourceDelta</code> being translated.
88          */
89         protected JavaElementDelta currentDelta;
90
91         // protected IndexManager indexManager = new IndexManager();
92
93         /* A table from IPath (from a classpath entry) to RootInfo */
94         public Map roots;
95
96         /*
97          * A table from IPath (from a classpath entry) to ArrayList of RootInfo Used
98          * when an IPath corresponds to more than one root
99          */
100         Map otherRoots;
101
102         /* Whether the roots tables should be recomputed */
103         public boolean rootsAreStale = true;
104
105         /*
106          * A table from IPath (from a classpath entry) to RootInfo from the last
107          * time the delta processor was invoked.
108          */
109         public Map oldRoots;
110
111         /*
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
115          */
116         Map oldOtherRoots;
117
118         /*
119          * A table from IPath (a source attachment path from a classpath entry) to
120          * IPath (a root path)
121          */
122         Map sourceAttachments;
123
124         /*
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.
128          */
129         Openable currentElement;
130
131         /*
132          * Queue of deltas created explicily by the Java Model that have yet to be
133          * fired.
134          */
135         public ArrayList javaModelDeltas = new ArrayList();
136
137         /*
138          * Queue of reconcile deltas on working copies that have yet to be fired.
139          * This is a table form IWorkingCopy to IJavaElementDelta
140          */
141         public HashMap reconcileDeltas = new HashMap();
142
143         /*
144          * Turns delta firing on/off. By default it is on.
145          */
146         private boolean isFiring = true;
147
148         public HashMap externalTimeStamps = new HashMap();
149
150         public HashSet projectsToUpdate = new HashSet();
151
152         // list of root projects which namelookup caches need to be updated for
153         // dependents
154         // TODO: (jerome) is it needed? projectsToUpdate might be sufficient
155         public HashSet projectsForDependentNamelookupRefresh = new HashSet();
156
157         /*
158          * The global state of delta processing.
159          */
160         private DeltaProcessingState state;
161
162         /*
163          * The Java model manager
164          */
165         private JavaModelManager manager;
166
167         /*
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.
170          */
171         Map removedRoots;
172
173         /*
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.
176          */
177         HashSet refreshedElements;
178
179         class OutputsInfo {
180                 IPath[] paths;
181
182                 int[] traverseModes;
183
184                 int outputCount;
185
186                 OutputsInfo(IPath[] paths, int[] traverseModes, int outputCount) {
187                         this.paths = paths;
188                         this.traverseModes = traverseModes;
189                         this.outputCount = outputCount;
190                 }
191
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]) {
201                                 case BINARY:
202                                         buffer.append("BINARY"); //$NON-NLS-1$
203                                         break;
204                                 case IGNORE:
205                                         buffer.append("IGNORE"); //$NON-NLS-1$
206                                         break;
207                                 case SOURCE:
208                                         buffer.append("SOURCE"); //$NON-NLS-1$
209                                         break;
210                                 default:
211                                         buffer.append("<unknown>"); //$NON-NLS-1$
212                                 }
213                                 if (i + 1 < this.outputCount) {
214                                         buffer.append('\n');
215                                 }
216                         }
217                         return buffer.toString();
218                 }
219         }
220
221         class RootInfo {
222                 IJavaProject project;
223
224                 IPath rootPath;
225
226                 char[][] exclusionPatterns;
227
228                 RootInfo(IJavaProject project, IPath rootPath,
229                                 char[][] exclusionPatterns) {
230                         this.project = project;
231                         this.rootPath = rootPath;
232                         this.exclusionPatterns = exclusionPatterns;
233                 }
234
235                 boolean isRootOfProject(IPath path) {
236                         return this.rootPath.equals(path)
237                                         && this.project.getProject().getFullPath().isPrefixOf(path);
238                 }
239
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$
244                         } else {
245                                 buffer.append(this.project.getElementName());
246                         }
247                         buffer.append("\npath="); //$NON-NLS-1$
248                         if (this.rootPath == null) {
249                                 buffer.append("null"); //$NON-NLS-1$
250                         } else {
251                                 buffer.append(this.rootPath.toString());
252                         }
253                         buffer.append("\nexcluding="); //$NON-NLS-1$
254                         if (this.exclusionPatterns == null) {
255                                 buffer.append("null"); //$NON-NLS-1$
256                         } else {
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$
261                                         }
262                                 }
263                         }
264                         return buffer.toString();
265                 }
266         }
267
268         // DeltaProcessor(JavaModelManager manager) {
269         // this.manager = manager;
270         // }
271
272         /*
273          * Type of event that should be processed no matter what the real event type
274          * is.
275          */
276         public int overridenEventType = -1;
277
278         public DeltaProcessor(DeltaProcessingState state, JavaModelManager manager) {
279                 this.state = state;
280                 this.manager = manager;
281         }
282
283         /*
284          * Adds the dependents of the given project to the list of the projects to
285          * update.
286          */
287         // void addDependentProjects(IPath projectPath, HashSet result) {
288         // try {
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);
299         // }
300         // }
301         // }
302         // } catch (JavaModelException e) {
303         // }
304         // }
305         /*
306          * Adds the given element to the list of elements used as a scope for
307          * external jars refresh.
308          */
309         public void addForRefresh(IJavaElement element) {
310                 if (this.refreshedElements == null) {
311                         this.refreshedElements = new HashSet();
312                 }
313                 this.refreshedElements.add(element);
314         }
315
316         /*
317          * Adds the given project and its dependents to the list of the projects to
318          * update.
319          */
320 //      void addToProjectsToUpdateWithDependents(IProject project) {
321 //              this.projectsToUpdate.add(JavaCore.create(project));
322 //              // this.addDependentProjects(project.getFullPath(),
323 //              // this.projectsToUpdate);
324 //      }
325
326         /**
327          * Adds the given child handle to its parent's cache of children.
328          */
329 //      protected void addToParentInfo(Openable child) {
330 //
331 //              Openable parent = (Openable) child.getParent();
332 //              if (parent != null && parent.isOpen()) {
333 //                      try {
334 //                              JavaElementInfo info = (JavaElementInfo) parent
335 //                                              .getElementInfo();
336 //                              info.addChild(child);
337 //                      } catch (JavaModelException e) {
338 //                              // do nothing - we already checked if open
339 //                      }
340 //              }
341 //      }
342
343         /**
344          * Check all external archive (referenced by given roots, projects or model)
345          * status and issue a corresponding root delta. Also triggers index updates
346          */
347         // public void checkExternalArchiveChanges(IJavaElement[] refreshedElements,
348         // IProgressMonitor monitor) throws JavaModelException {
349         // try {
350         // for (int i = 0, length = refreshedElements.length; i < length; i++) {
351         // this.addForRefresh(refreshedElements[i]);
352         // }
353         // boolean hasDelta = this.createExternalArchiveDelta(monitor);
354         // if (monitor != null && monitor.isCanceled()) return;
355         // if (hasDelta){
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
365         // }
366         // if (this.currentDelta != null) { // if delta has not been fired while
367         // creating markers
368         // this.manager.fire(this.currentDelta,
369         // JavaModelManager.DEFAULT_CHANGE_EVENT);
370         // }
371         // }
372         // } finally {
373         // this.currentDelta = null;
374         // if (monitor != null) monitor.done();
375         // }
376         // }
377         /*
378          * Check if external archives have changed and create the corresponding
379          * deltas. Returns whether at least on delta was created.
380          */
381         // public boolean createExternalArchiveDelta(IProgressMonitor monitor)
382         // throws JavaModelException {
383         //              
384         // if (this.refreshedElements == null) return false;
385         //                      
386         // HashMap externalArchivesStatus = new HashMap();
387         // boolean hasDelta = false;
388         //              
389         // // find JARs to refresh
390         // HashSet archivePathsToRefresh = new HashSet();
391         // try {
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());
398         // break;
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
403         // break;
404         // }
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());
409         // }
410         // }
411         // break;
412         // case IJavaElement.JAVA_MODEL :
413         // IJavaProject[] projects =
414         // manager.getJavaModel().getOldJavaProjectsList();
415         // for (int j = 0, projectsLength = projects.length; j < projectsLength;
416         // j++){
417         // project = projects[j];
418         // if (!JavaProject.hasJavaNature(project.getProject())) {
419         // // project is not accessible or has lost its Java nature
420         // continue;
421         // }
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());
426         // }
427         // }
428         // }
429         // break;
430         // }
431         // }
432         // } finally {
433         // this.refreshedElements = null;
434         // }
435         //              
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++) {
441         //                      
442         // if (monitor != null && monitor.isCanceled()) break;
443         //                      
444         // IJavaProject project = projects[i];
445         // if (!JavaProject.hasJavaNature(project.getProject())) {
446         // // project is not accessible or has lost its Java nature
447         // continue;
448         // }
449         // IClasspathEntry[] entries = project.getResolvedClasspath(true);
450         // for (int j = 0; j < entries.length; j++){
451         // if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
452         //                                      
453         // IPath entryPath = entries[j].getPath();
454         //                                      
455         // if (!archivePathsToRefresh.contains(entryPath)) continue; // not supposed
456         // to be refreshed
457         //                                      
458         // String status = (String)externalArchivesStatus.get(entryPath);
459         // if (status == null){
460         //                                              
461         // // compute shared status
462         // Object targetLibrary = JavaModel.getTarget(wksRoot, entryPath, true);
463         //              
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);
470         // }
471         //              
472         // } else if (targetLibrary instanceof File){ // external JAR
473         //              
474         // File externalFile = (File)targetLibrary;
475         //                                                      
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){
480         //              
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);
486         //              
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());
494         // } else {
495         // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
496         // }
497         // } else {
498         // if (newTimeStamp == 0){ // jar still doesn't exist
499         // externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
500         // } else {
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());
505         // }
506         // }
507         // } else { // internal JAR
508         // externalArchivesStatus.put(entryPath, INTERNAL_JAR_IGNORE);
509         // }
510         // }
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());
517         // if (VERBOSE){
518         // System.out.println("- External JAR ADDED, affecting root:
519         // "+root.getElementName()); //$NON-NLS-1$
520         // }
521         // elementAdded(root, null, null);
522         // hasDelta = true;
523         // } else if (status == EXTERNAL_JAR_CHANGED) {
524         // PackageFragmentRoot root =
525         // (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
526         // if (VERBOSE){
527         // System.out.println("- External JAR CHANGED, affecting root:
528         // "+root.getElementName()); //$NON-NLS-1$
529         // }
530         // // reset the corresponding project built state, since the builder would
531         // miss this change
532         // this.manager.setLastBuiltState(project.getProject(), null /*no state*/);
533         // contentChanged(root, null);
534         // hasDelta = true;
535         // } else if (status == EXTERNAL_JAR_REMOVED) {
536         // PackageFragmentRoot root =
537         // (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
538         // if (VERBOSE){
539         // System.out.println("- External JAR REMOVED, affecting root:
540         // "+root.getElementName()); //$NON-NLS-1$
541         // }
542         // elementRemoved(root, null, null);
543         // hasDelta = true;
544         // }
545         // }
546         // }
547         // }
548         // }
549         // return hasDelta;
550         // }
551         JavaElementDelta currentDelta() {
552                 if (this.currentDelta == null) {
553                         this.currentDelta = new JavaElementDelta(this.manager
554                                         .getJavaModel());
555                 }
556                 return this.currentDelta;
557         }
558
559         /*
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.
565          */
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) {
572         // try {
573         // this.manager.javaProjectsCache =
574         // this.manager.getJavaModel().getJavaProjects();
575         // } catch (JavaModelException e) {
576         // }
577         // }
578         //                              
579         // IResourceDelta[] children = delta.getAffectedChildren();
580         // for (int i = 0, length = children.length; i < length; i++) {
581         // this.checkProjectsBeingAddedOrRemoved(children[i]);
582         // }
583         // break;
584         // case IResource.PROJECT :
585         // // NB: No need to check project's nature as if the project is not a java
586         // project:
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);
595         //                                      
596         // // workaround for bug 15168 circular errors not reported
597         // if (JavaProject.hasJavaNature(project)) {
598         // this.addToParentInfo((JavaProject)JavaCore.create(project));
599         // }
600         //
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);
606         //                                              
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));
611         // }
612         // } else {
613         // JavaProject javaProject =
614         // (JavaProject)this.manager.getJavaModel().findJavaProject(project);
615         // if (javaProject != null) {
616         // try {
617         // javaProject.close();
618         // } catch (JavaModelException e) {
619         // }
620         // this.removeFromParentInfo(javaProject);
621         // }
622         // }
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);
630         //
631         // // workaround for bug 15168 circular errors not reported
632         // if (isJavaProject) {
633         // this.addToParentInfo((JavaProject)JavaCore.create(project));
634         // } else {
635         // JavaProject javaProject = (JavaProject)JavaCore.create(project);
636         //                                                              
637         // // flush classpath markers
638         // javaProject.
639         // flushClasspathProblemMarkers(
640         // true, // flush cycle markers
641         // true //flush classpath format markers
642         // );
643         //                                                                      
644         // // remove problems and tasks created by the builder
645         // JavaBuilder.removeProblemsAndTasksFor(project);
646         //
647         // // close project
648         // try {
649         // javaProject.close();
650         // } catch (JavaModelException e) {
651         // }
652         // this.removeFromParentInfo(javaProject);
653         // }
654         // } else {
655         // // in case the project was removed then added then changed (see bug
656         // 19799)
657         // if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
658         // this.addToParentInfo((JavaProject)JavaCore.create(project));
659         // }
660         // }
661         // } else {
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));
666         // }
667         // }
668         // }
669         // break;
670         // }
671         // }
672         // private void checkSourceAttachmentChange(IResourceDelta delta, IResource
673         // res) {
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;
680         // try {
681         // // close the root so that source attachement cache is flushed
682         // root = projectOfRoot.findPackageFragmentRoot(rootPath);
683         // if (root != null) {
684         // root.close();
685         // }
686         // } catch (JavaModelException e) {
687         // }
688         // if (root == null) return;
689         // switch (delta.getKind()) {
690         // case IResourceDelta.ADDED:
691         // currentDelta().sourceAttached(root);
692         // break;
693         // case IResourceDelta.CHANGED:
694         // currentDelta().sourceDetached(root);
695         // currentDelta().sourceAttached(root);
696         // break;
697         // case IResourceDelta.REMOVED:
698         // currentDelta().sourceDetached(root);
699         // break;
700         // }
701         // }
702         // }
703         // }
704         /**
705          * Closes the given element, which removes it from the cache of open
706          * elements.
707          */
708         // protected static void close(Openable element) {
709         //
710         // try {
711         // element.close();
712         // } catch (JavaModelException e) {
713         // // do nothing
714         // }
715         // }
716         /**
717          * Generic processing for elements with changed contents:
718          * <ul>
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).
723          * </ul>
724          * Delta argument could be null if processing an external JAR change
725          */
726         // protected void contentChanged(Openable element, IResourceDelta delta) {
727         //
728         // close(element);
729         // int flags = IJavaElementDelta.F_CONTENT;
730         // if (element instanceof JarPackageFragmentRoot){
731         // flags |= IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED;
732         // }
733         // currentDelta().changed(element, flags);
734         // }
735         //      
736         /**
737          * Creates the openables corresponding to this resource. Returns null if
738          * none was found.
739          */
740         // protected Openable createElement(IResource resource, int elementType,
741         // RootInfo rootInfo) {
742         // if (resource == null) return null;
743         //              
744         // IPath path = resource.getFullPath();
745         // IJavaElement element = null;
746         // switch (elementType) {
747         //                      
748         // case IJavaElement.JAVA_PROJECT:
749         //                      
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){
754         //
755         // this.popUntilPrefixOf(path);
756         //                                      
757         // if (this.currentElement != null
758         // && this.currentElement.getElementType() == IJavaElement.JAVA_PROJECT
759         // && ((IJavaProject)this.currentElement).getProject().equals(resource)) {
760         // return this.currentElement;
761         // }
762         // if (rootInfo != null && rootInfo.project.getProject().equals(resource)){
763         // element = (Openable)rootInfo.project;
764         // break;
765         // }
766         // IProject proj = (IProject)resource;
767         // if (JavaProject.hasJavaNature(proj)) {
768         // element = JavaCore.create(proj);
769         // } else {
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);
773         // }
774         // }
775         // break;
776         // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
777         // element = rootInfo == null ? JavaCore.create(resource) :
778         // rootInfo.project.getPackageFragmentRoot(resource);
779         // break;
780         // case IJavaElement.PACKAGE_FRAGMENT:
781         // // find the element that encloses the resource
782         // this.popUntilPrefixOf(path);
783         //                              
784         // if (this.currentElement == null) {
785         // element = rootInfo == null ? JavaCore.create(resource) :
786         // JavaModelManager.create(resource, rootInfo.project);
787         // } else {
788         // // find the root
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);
799         // }
800         // }
801         // break;
802         // case IJavaElement.COMPILATION_UNIT:
803         // case IJavaElement.CLASS_FILE:
804         // // find the element that encloses the resource
805         // this.popUntilPrefixOf(path);
806         //                              
807         // if (this.currentElement == null) {
808         // element = rootInfo == null ? JavaCore.create(resource) :
809         // JavaModelManager.create(resource, rootInfo.project);
810         // } else {
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);
818         // String pkgName =
819         // ProjectPrefUtil.packageName(pkgPath.removeFirstSegments(rootPath.segmentCount()));
820         // if (pkgName != null) {
821         // pkgFragment = root.getPackageFragment(pkgName);
822         // }
823         // break;
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
829         // break;
830         // case IJavaElement.COMPILATION_UNIT:
831         // case IJavaElement.CLASS_FILE:
832         // pkgFragment = (IPackageFragment)this.currentElement.getParent();
833         // break;
834         // }
835         // if (pkgFragment == null) {
836         // element = rootInfo == null ? JavaCore.create(resource) :
837         // JavaModelManager.create(resource, rootInfo.project);
838         // } else {
839         // if (elementType == IJavaElement.COMPILATION_UNIT) {
840         // // create compilation unit handle
841         // // fileName validation has been done in elementType(IResourceDelta, int,
842         // boolean)
843         // String fileName = path.lastSegment();
844         // element = pkgFragment.getCompilationUnit(fileName);
845         // } else {
846         // // create class file handle
847         // // fileName validation has been done in elementType(IResourceDelta, int,
848         // boolean)
849         // String fileName = path.lastSegment();
850         // element = pkgFragment.getClassFile(fileName);
851         // }
852         // }
853         // }
854         // break;
855         // }
856         // if (element == null) {
857         // return null;
858         // } else {
859         // this.currentElement = (Openable)element;
860         // return this.currentElement;
861         // }
862         // }
863         /**
864          * Note that the project is about to be deleted.
865          */
866         // public void deleting(IProject project) {
867         //              
868         // try {
869         // // discard indexing jobs that belong to this project so that the project
870         // can be
871         // // deleted without interferences from the index manager
872         // this.indexManager.discardJobs(project.getName());
873         //
874         // JavaProject javaProject = (JavaProject)JavaCore.create(project);
875         //                      
876         // // remember roots of this project
877         // if (this.removedRoots == null) {
878         // this.removedRoots = new HashMap();
879         // }
880         // if (javaProject.isOpen()) {
881         // this.removedRoots.put(javaProject,
882         // javaProject.getPackageFragmentRoots());
883         // } else {
884         // // compute roots without opening project
885         // this.removedRoots.put(
886         // javaProject,
887         // javaProject.computePackageFragmentRoots(
888         // javaProject.getResolvedClasspath(true),
889         // false));
890         // }
891         //                      
892         // javaProject.close();
893         //
894         // // workaround for bug 15168 circular errors not reported
895         // if (this.manager.javaProjectsCache == null) {
896         // this.manager.javaProjectsCache =
897         // this.manager.getJavaModel().getJavaProjects();
898         // }
899         // this.removeFromParentInfo(javaProject);
900         //
901         // } catch (JavaModelException e) {
902         // }
903         //              
904         // this.addDependentProjects(project.getFullPath(), this.projectsToUpdate);
905         // }
906
907         /**
908          * Processing for an element that has been added:
909          * <ul>
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>.
915          * </ul>
916          * Delta argument could be null if processing an external JAR change
917          */
918         // protected void elementAdded(Openable element, IResourceDelta delta,
919         // RootInfo rootInfo) {
920         // int elementType = element.getElementType();
921         //              
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);
932         // } else {
933         // currentDelta().added(element);
934         // }
935         // this.projectsToUpdate.add(element);
936         // this.updateRoots(element.getPath(), delta);
937         // this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
938         // }
939         // } else {
940         // addToParentInfo(element);
941         //                      
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
950         // recomputed
951         // // and it appears empty.
952         // close(element);
953         //                      
954         // if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_FROM) != 0)
955         // {
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);
961         // } else {
962         // movedFromRes = res.getWorkspace().getRoot().getFolder(movedFromPath);
963         // }
964         //                              
965         // // find the element type of the moved from element
966         // RootInfo movedFromInfo = this.enclosingRootInfo(movedFromPath,
967         // IResourceDelta.REMOVED);
968         // int movedFromType =
969         // this.elementType(
970         // movedFromRes,
971         // IResourceDelta.REMOVED,
972         // element.getParent().getElementType(),
973         // movedFromInfo);
974         //                              
975         // // reset current element as it might be inside a nested root
976         // (popUntilPrefixOf() may use the outer root)
977         // this.currentElement = null;
978         //                      
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);
988         // } else {
989         // currentDelta().movedTo(element, movedFromElement);
990         // }
991         // } else {
992         // currentDelta().added(element);
993         // }
994         //                      
995         // switch (elementType) {
996         // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
997         // // when a root is added, and is on the classpath, the project must be
998         // updated
999         // JavaProject project = (JavaProject) element.getJavaProject();
1000         // this.projectsToUpdate.add(project);
1001         // this.projectsForDependentNamelookupRefresh.add(project);
1002         //                                      
1003         // break;
1004         // case IJavaElement.PACKAGE_FRAGMENT :
1005         // // get rid of namelookup since it holds onto obsolete cached info
1006         // project = (JavaProject) element.getJavaProject();
1007         // try {
1008         // project.getJavaProjectElementInfo().setNameLookup(null);
1009         // this.projectsForDependentNamelookupRefresh.add(project);
1010         // } catch (JavaModelException e) {
1011         // }
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 ?
1025         // folderName :
1026         // name + "." + folderName; //$NON-NLS-1$
1027         // Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
1028         // this.updateIndex(subpkg, child);
1029         // this.elementAdded(subpkg, child, rootInfo);
1030         // }
1031         // }
1032         // }
1033         // }
1034         // break;
1035         // }
1036         // }
1037         // }
1038         /**
1039          * Generic processing for a removed element:
1040          * <ul>
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
1044          * </ul>
1045          * Delta argument could be null if processing an external JAR change
1046          */
1047         // protected void elementRemoved(Openable element, IResourceDelta delta,
1048         // RootInfo rootInfo) {
1049         //              
1050         // if (element.isOpen()) {
1051         // close(element);
1052         // }
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:
1061         // movedToRes =
1062         // res.getWorkspace().getRoot().getProject(movedToPath.lastSegment());
1063         // break;
1064         // case IResource.FOLDER:
1065         // movedToRes = res.getWorkspace().getRoot().getFolder(movedToPath);
1066         // break;
1067         // case IResource.FILE:
1068         // movedToRes = res.getWorkspace().getRoot().getFile(movedToPath);
1069         // break;
1070         // default:
1071         // return;
1072         // }
1073         //
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(
1079         // movedToRes,
1080         // IResourceDelta.ADDED,
1081         // element.getParent().getElementType(),
1082         // movedToInfo);
1083         //
1084         // // reset current element as it might be inside a nested root
1085         // (popUntilPrefixOf() may use the outer root)
1086         // this.currentElement = null;
1087         //                      
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);
1097         // } else {
1098         // currentDelta().movedFrom(element, movedToElement);
1099         // }
1100         // } else {
1101         // currentDelta().removed(element);
1102         // }
1103         //
1104         // switch (elementType) {
1105         // case IJavaElement.JAVA_MODEL :
1106         // this.indexManager.reset();
1107         // break;
1108         // case IJavaElement.JAVA_PROJECT :
1109         // this.manager.removePerProjectInfo(
1110         // (JavaProject) element);
1111         // this.updateRoots(element.getPath(), delta);
1112         // this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
1113         // break;
1114         // case IJavaElement.PACKAGE_FRAGMENT_ROOT :
1115         // JavaProject project = (JavaProject) element.getJavaProject();
1116         // this.projectsToUpdate.add(project);
1117         // this.projectsForDependentNamelookupRefresh.add(project);
1118         // break;
1119         // case IJavaElement.PACKAGE_FRAGMENT :
1120         // //1G1TW2T - get rid of namelookup since it holds onto obsolete cached
1121         // info
1122         // project = (JavaProject) element.getJavaProject();
1123         // try {
1124         // project.getJavaProjectElementInfo().setNameLookup(null);
1125         // this.projectsForDependentNamelookupRefresh.add(project);
1126         // } catch (JavaModelException e) {
1127         // }
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 ?
1141         // folderName :
1142         // name + "." + folderName; //$NON-NLS-1$
1143         // Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
1144         // this.updateIndex(subpkg, child);
1145         // this.elementRemoved(subpkg, child, rootInfo);
1146         // }
1147         // }
1148         // }
1149         // }
1150         // break;
1151         // }
1152         // }
1153         /*
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
1156          * file)
1157          */
1158         // private int elementType(IResource res, int kind, int parentType, RootInfo
1159         // 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);
1169         // }
1170         // if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
1171         // return IJavaElement.PACKAGE_FRAGMENT_ROOT;
1172         // } else {
1173         // return NON_JAVA_RESOURCE; // not yet in a package fragment root or root
1174         // of another project
1175         // }
1176         // case IJavaElement.PACKAGE_FRAGMENT_ROOT:
1177         // case IJavaElement.PACKAGE_FRAGMENT:
1178         // if (rootInfo == null) {
1179         // rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
1180         // }
1181         // if (rootInfo == null || ProjectPrefUtil.isExcluded(res,
1182         // rootInfo.exclusionPatterns)) {
1183         // return NON_JAVA_RESOURCE;
1184         // }
1185         // if (res instanceof IFolder) {
1186         // if (ProjectPrefUtil.isValidFolderNameForPackage(res.getName())) {
1187         // return IJavaElement.PACKAGE_FRAGMENT;
1188         // } else {
1189         // return NON_JAVA_RESOURCE;
1190         // }
1191         // } else {
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;
1200         // } else {
1201         // return NON_JAVA_RESOURCE;
1202         // }
1203         // }
1204         // default:
1205         // return NON_JAVA_RESOURCE;
1206         // }
1207         // }
1208         /**
1209          * Answer a combination of the lastModified stamp and the size. Used for
1210          * detecting external JAR changes
1211          */
1212 //      public static long getTimeStamp(File file) {
1213 //              return file.lastModified() + file.length();
1214 //      }
1215
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;
1221 //
1222 //              // recompute root infos only if necessary
1223 //              if (!rootsAreStale)
1224 //                      return;
1225 //
1226 //              this.roots = new HashMap();
1227 //              this.otherRoots = new HashMap();
1228 //              this.sourceAttachments = new HashMap();
1229 //
1230 //              IJavaModel model = this.manager.getJavaModel();
1231 //              IJavaProject[] projects;
1232 //              try {
1233 //                      projects = model.getJavaProjects();
1234 //              } catch (JavaModelException e) {
1235 //                      // nothing can be done
1236 //                      return;
1237 //              }
1238 //              for (int i = 0, length = projects.length; i < length; i++) {
1239 //                      IJavaProject project = projects[i];
1240 //                      IClasspathEntry[] classpath;
1241 //                      try {
1242 //                              classpath = project.getResolvedClasspath(true);
1243 //                      } catch (JavaModelException e) {
1244 //                              // continue with next project
1245 //                              continue;
1246 //                      }
1247 //                      for (int j = 0, classpathLength = classpath.length; j < classpathLength; j++) {
1248 //                              IClasspathEntry entry = classpath[j];
1249 //                              if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT)
1250 //                                      continue;
1251 //
1252 //                              // root path
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()));
1258 //                              } else {
1259 //                                      ArrayList rootList = (ArrayList) this.otherRoots.get(path);
1260 //                                      if (rootList == null) {
1261 //                                              rootList = new ArrayList();
1262 //                                              this.otherRoots.put(path, rootList);
1263 //                                      }
1264 //                                      rootList.add(new RootInfo(project, path,
1265 //                                                      ((ClasspathEntry) entry)
1266 //                                                                      .fullExclusionPatternChars()));
1267 //                              }
1268 //
1269 //                              // source attachment path
1270 //                              if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY)
1271 //                                      continue;
1272 //                              QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID,
1273 //                                              "sourceattachment: " + path.toOSString()); //$NON-NLS-1$;
1274 //                              String propertyString = null;
1275 //                              try {
1276 //                                      propertyString = ResourcesPlugin.getWorkspace().getRoot()
1277 //                                                      .getPersistentProperty(qName);
1278 //                              } catch (CoreException e) {
1279 //                                      continue;
1280 //                              }
1281 //                              IPath sourceAttachmentPath;
1282 //                              // if (propertyString != null) {
1283 //                              // int index=
1284 //                              // propertyString.lastIndexOf(JarPackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER);
1285 //                              // sourceAttachmentPath = (index < 0) ? new Path(propertyString)
1286 //                              // : new Path(propertyString.substring(0, index));
1287 //                              // } else {
1288 //                              sourceAttachmentPath = entry.getSourceAttachmentPath();
1289 //                              // }
1290 //                              if (sourceAttachmentPath != null) {
1291 //                                      this.sourceAttachments.put(sourceAttachmentPath, path);
1292 //                              }
1293 //                      }
1294 //              }
1295 //              this.rootsAreStale = false;
1296 //      }
1297
1298         /*
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.
1301          */
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 {
1308
1309                                 /**
1310                                  * 
1311                                  */
1312                                 private static final long serialVersionUID = -7732598607464929404L;
1313                         }
1314                         try {
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
1326                                                                                                                                                 // check
1327                                                                                                                                                 // leaf
1328                                                                                                                                                 // delta
1329                                                                                                                                                 // nodes
1330                                                                         && (delta.getFlags() & ~(IResourceDelta.SYNC | IResourceDelta.MARKERS)) != 0) {
1331                                                                 throw new FoundRelevantDeltaException();
1332                                                         }
1333                                                 }
1334                                                 return true;
1335                                         }
1336                                 });
1337                         } catch (FoundRelevantDeltaException e) {
1338                                 // System.out.println("RELEVANT DELTA detected in: "+
1339                                 // (System.currentTimeMillis() - start));
1340                                 return true;
1341                         } catch (CoreException e) { // ignore delta if not able to traverse
1342                         }
1343                 }
1344                 // System.out.println("IGNORE SYNC DELTA took: "+
1345                 // (System.currentTimeMillis() - start));
1346                 return false;
1347         }
1348
1349         /*
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.
1352          */
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) {
1363 //                                                      return true;
1364 //                                              } else {
1365 //                                                      // case of .class file under project and no source
1366 //                                                      // folder
1367 //                                                      // proj=bin
1368 //                                                      if (elementType == IJavaElement.JAVA_PROJECT
1369 //                                                                      && res instanceof IFile
1370 //                                                                      && PHPFileUtil.isPHPFile((IFile) res)) {
1371 //                                                              return true;
1372 //                                                      }
1373 //                                              }
1374 //                                      } else {
1375 //                                              return true;
1376 //                                      }
1377 //                              }
1378 //                      }
1379 //              }
1380 //              return false;
1381 //      }
1382
1383         /*
1384          * Merges all awaiting deltas.
1385          */
1386         private IJavaElementDelta mergeDeltas(Collection deltas) {
1387                 if (deltas.size() == 0)
1388                         return null;
1389                 if (deltas.size() == 1)
1390                         return (IJavaElementDelta) deltas.iterator().next();
1391
1392                 if (VERBOSE) {
1393                         System.out
1394                                         .println("MERGING " + deltas.size() + " DELTAS [" + Thread.currentThread() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1395                 }
1396
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();
1403                         if (VERBOSE) {
1404                                 System.out.println(delta.toString());
1405                         }
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(),
1412                                                         projectDelta);
1413                                         insertedTree = true;
1414                                 }
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;
1420                                         }
1421                                 }
1422                         } else {
1423                                 rootDelta.insertDeltaTree(element, delta);
1424                                 insertedTree = true;
1425                         }
1426                 }
1427                 if (insertedTree)
1428                         return rootDelta;
1429                 return null;
1430         }
1431
1432         /**
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
1437          * notification.
1438          * 
1439          */
1440         // public void performPreBuildCheck(
1441         // IResourceDelta delta,
1442         // IJavaElement parent) {
1443         //      
1444         // IResource resource = delta.getResource();
1445         // IJavaElement element = null;
1446         // boolean processChildren = false;
1447         //      
1448         // switch (resource.getType()) {
1449         //      
1450         // case IResource.ROOT :
1451         // if (delta.getKind() == IResourceDelta.CHANGED) {
1452         // element = JavaCore.create(resource);
1453         // processChildren = true;
1454         // }
1455         // break;
1456         // case IResource.PROJECT :
1457         // int kind = delta.getKind();
1458         // switch (kind) {
1459         // case IResourceDelta.CHANGED:
1460         // // do not visit non-java projects (see bug 16140 Non-java project gets
1461         // .classpath)
1462         // IProject project = (IProject)resource;
1463         // if (JavaProject.hasJavaNature(project)) {
1464         // element = JavaCore.create(resource);
1465         // processChildren = true;
1466         // } else if
1467         // (JavaModelManager.getJavaModelManager().getJavaModel().findJavaProject(project)
1468         // != null) {
1469         // // project had the java nature
1470         // this.rootsAreStale = true;
1471         //
1472         // // remove classpath cache so that initializeRoots() will not consider the
1473         // project has a classpath
1474         // this.manager.removePerProjectInfo((JavaProject)JavaCore.create(project));
1475         // }
1476         // break;
1477         // case IResourceDelta.ADDED:
1478         // this.rootsAreStale = true;
1479         // break;
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));
1484         //                                              
1485         // this.rootsAreStale = true;
1486         // break;
1487         // }
1488         // break;
1489         // case IResource.FILE :
1490         // if (parent.getElementType() == IJavaElement.JAVA_PROJECT) {
1491         // IFile file = (IFile) resource;
1492         // JavaProject project = (JavaProject) parent;
1493         //      
1494         // /* check classpath file change */
1495         // if (file.getName().equals(JavaProject.CLASSPATH_FILENAME)) {
1496         // reconcileClasspathFileUpdate(delta, file, project);
1497         // this.rootsAreStale = true;
1498         // break;
1499         // }
1500         // // /* check custom preference file change */
1501         // // if (file.getName().equals(JavaProject.PREF_FILENAME)) {
1502         // // reconcilePreferenceFileUpdate(delta, file, project);
1503         // // break;
1504         // // }
1505         // }
1506         // break;
1507         // }
1508         // if (processChildren) {
1509         // IResourceDelta[] children = delta.getAffectedChildren();
1510         // for (int i = 0; i < children.length; i++) {
1511         // performPreBuildCheck(children[i], element);
1512         // }
1513         // }
1514         // }
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();
1521         // } else {
1522         // IResource currentElementResource = this.currentElement.getResource();
1523         // if (currentElementResource != null) {
1524         // currentElementPath = currentElementResource.getFullPath();
1525         // }
1526         // }
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();
1533         // }
1534         // if (currentElementPath.isPrefixOf(path)) {
1535         // return;
1536         // }
1537         // }
1538         // this.currentElement = (Openable)this.currentElement.getParent();
1539         // }
1540         // }
1541         /**
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.
1546          */
1547
1548         /**
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
1552          * repository)
1553          */
1554         // void reconcileClasspathFileUpdate(IResourceDelta delta, IFile file,
1555         // JavaProject project) {
1556         //                      
1557         // switch (delta.getKind()) {
1558         // case IResourceDelta.REMOVED : // recreate one based on in-memory
1559         // classpath
1560         // try {
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);
1565         // }
1566         // } catch (JavaModelException e) {
1567         // if (project.getProject().isAccessible()) {
1568         // ProjectPrefUtil.log(e, "Could not save classpath for "+
1569         // project.getPath()); //$NON-NLS-1$
1570         // }
1571         // }
1572         // break;
1573         // case IResourceDelta.CHANGED :
1574         // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0 // only consider
1575         // content change
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)
1579         // break;
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
1585         // try {
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,
1595         // fileEntries)) {
1596         // wasSuccessful = true;
1597         // break;
1598         // }
1599         // }
1600         //              
1601         // // will force an update of the classpath/output location based on the
1602         // file information
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;
1612         // }
1613         // }
1614         // // restore output location
1615         // if (outputLocation == null) {
1616         // outputLocation = SetClasspathOperation.ReuseOutputLocation;
1617         // // clean mode will also default to reusing current one
1618         // }
1619         // project.setRawClasspath(
1620         // fileEntries,
1621         // outputLocation,
1622         // null, // monitor
1623         // true, // canChangeResource
1624         // project.getResolvedClasspath(true), // ignoreUnresolvedVariable
1625         // true, // needValidation
1626         // false); // no need to save
1627         //                                      
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
1632         // exception
1633         // if (project.getProject().isAccessible()) {
1634         // ProjectPrefUtil.log(e, "Could not set classpath for "+
1635         // project.getPath()); //$NON-NLS-1$
1636         // }
1637         // break;
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$
1646         // } else {
1647         // project.createClasspathProblemMarker(new JavaModelStatus(
1648         // IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1649         // ProjectPrefUtil.bind("classpath.invalidClasspathInClasspathFile",
1650         // project.getElementName(), e.getMessage()))); //$NON-NLS-1$
1651         // }
1652         // }
1653         // break;
1654         // } finally {
1655         // if (!wasSuccessful) {
1656         // try {
1657         // project.setRawClasspath0(JavaProject.INVALID_CLASSPATH);
1658         // project.updatePackageFragmentRoots();
1659         // } catch (JavaModelException e) {
1660         // }
1661         // }
1662         // }
1663         // }
1664         // }
1665         /**
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)
1670          */
1671         // void reconcilePreferenceFileUpdate(IResourceDelta delta, IFile file,
1672         // JavaProject project) {
1673         //                      
1674         // switch (delta.getKind()) {
1675         // case IResourceDelta.REMOVED : // flush project custom settings
1676         // project.setOptions(null);
1677         // return;
1678         // case IResourceDelta.CHANGED :
1679         // if ((delta.getFlags() & IResourceDelta.CONTENT) == 0 // only consider
1680         // content change
1681         // && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move
1682         // and overide scenario
1683         // break;
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.
1689         // return;
1690         // }
1691         // Preferences projectPreferences = project.getPreferences();
1692         // if (projectPreferences == null) return; // not a Java project
1693         //                                              
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];
1703         // if
1704         // (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1705         // break identityCheck;
1706         // }
1707         // }
1708         // } else break identityCheck;
1709         //
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];
1716         // if
1717         // (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1718         // break identityCheck;
1719         // }
1720         // }
1721         // } else break identityCheck;
1722         //                                      
1723         // // identical - do nothing
1724         // return;
1725         // }
1726         // case IResourceDelta.ADDED :
1727         // // not identical, create delta and reset cached preferences
1728         // project.setPreferences(null);
1729         // // create delta
1730         // //fCurrentDelta.changed(project, IJavaElementDelta.F_OPTIONS_CHANGED);
1731         // }
1732         // }
1733         /*
1734          * Registers the given delta with this delta processor.
1735          */
1736         public void registerJavaModelDelta(IJavaElementDelta delta) {
1737                 this.javaModelDeltas.add(delta);
1738         }
1739
1740         /**
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
1743          * has no effect.
1744          */
1745         protected void removeFromParentInfo(Openable child) {
1746
1747                 Openable parent = (Openable) child.getParent();
1748                 if (parent != null && parent.isOpen()) {
1749                         try {
1750                                 JavaElementInfo info = (JavaElementInfo) parent
1751                                                 .getElementInfo();
1752                                 info.removeChild(child);
1753                         } catch (JavaModelException e) {
1754                                 // do nothing - we already checked if open
1755                         }
1756                 }
1757         }
1758
1759         /**
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>.
1764          * 
1765          * @see IResourceDelta
1766          * @see IResource
1767          */
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();
1774
1775                         switch (eventType) {
1776                         case IResourceChangeEvent.PRE_DELETE:
1777                                 try {
1778                                         if (resource.getType() == IResource.PROJECT
1779                                                         && ((IProject) resource)
1780                                                                         .hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
1781
1782                                                 deleting((IProject) resource);
1783                                         }
1784                                 } catch (CoreException e) {
1785                                         // project doesn't exist or is not open: ignore
1786                                 }
1787                                 return;
1788
1789                         case IResourceChangeEvent.POST_CHANGE:
1790                                 if (isAffectedBy(delta)) { // avoid populating for SYNC or
1791                                                                                         // MARKER deltas
1792                                         try {
1793                                                 try {
1794                                                         stopDeltas();
1795                                                         // checkProjectsBeingAddedOrRemoved(delta);
1796                                                         // if (this.refreshedElements != null) {
1797                                                         // createExternalArchiveDelta(null);
1798                                                         // }
1799                                                         IJavaElementDelta translatedDelta = processResourceDelta(delta);
1800                                                         if (translatedDelta != null) {
1801                                                                 registerJavaModelDelta(translatedDelta);
1802                                                         }
1803                                                 } finally {
1804                                                         startDeltas();
1805                                                 }
1806                                                 // notifyTypeHierarchies(this.state.elementChangedListeners,
1807                                                 // this.state.elementChangedListenerCount);
1808                                                 fire(null, ElementChangedEvent.POST_CHANGE);
1809                                         } finally {
1810                                                 // workaround for bug 15168 circular errors not reported
1811                                                 this.state.modelProjectsCache = null;
1812                                                 this.removedRoots = null;
1813                                         }
1814                                 }
1815                                 return;
1816
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++) {
1822                                                 try {
1823                                                         updates[i].updateProjectReferencesIfNecessary();
1824                                                 } catch (JavaModelException e) {
1825                                                         // do nothing
1826                                                 }
1827                                         }
1828                                 }
1829                                 // this.processPostChange = false;
1830                                 if (isAffectedBy(delta)) { // avoid populating for SYNC or
1831                                                                                         // MARKER deltas
1832                                 // updateClasspathMarkers(delta);
1833                                         PHPBuilder.buildStarting();
1834                                 }
1835                                 // does not fire any deltas
1836                                 return;
1837
1838                         case IResourceChangeEvent.POST_BUILD:
1839                                 PHPBuilder.buildFinished();
1840                                 return;
1841                         }
1842                 }
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();
1849                 //                      
1850                 // switch(eventType){
1851                 // case IResourceChangeEvent.PRE_DELETE :
1852                 // try {
1853                 // if(resource.getType() == IResource.PROJECT
1854                 // && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
1855                 // // TODO jsurfer temp-del
1856                 // // this.deleting((IProject)resource);
1857                 // }
1858                 // } catch(CoreException e){
1859                 // }
1860                 // return;
1861                 //                                      
1862                 // case IResourceChangeEvent.PRE_BUILD :
1863                 // // TODO jsurfer temp-del
1864                 // // if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER
1865                 // deltas
1866                 // // this.checkProjectsBeingAddedOrRemoved(delta);
1867                 // //
1868                 // // // update the classpath related markers
1869                 // // this.updateClasspathMarkers();
1870                 // //
1871                 // // // the following will close project if affected by the property
1872                 // file change
1873                 // // try {
1874                 // // // don't fire classpath change deltas right away, but batch them
1875                 // // this.manager.stopDeltas();
1876                 // // this.performPreBuildCheck(delta, null);
1877                 // // } finally {
1878                 // // this.manager.startDeltas();
1879                 // // }
1880                 // // }
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);
1884                 // break;
1885                 //
1886                 // case IResourceChangeEvent.POST_BUILD :
1887                 // // TODO jsurfer temp-del
1888                 // // JavaBuilder.finishedBuilding(event);
1889                 // break;
1890                 //                                      
1891                 // case IResourceChangeEvent.POST_CHANGE :
1892                 // // TODO jsurfer temp-del
1893                 // // if (isAffectedBy(delta)) {
1894                 // // try {
1895                 // // if (this.refreshedElements != null) {
1896                 // // try {
1897                 // // createExternalArchiveDelta(null);
1898                 // // } catch (JavaModelException e) {
1899                 // // e.printStackTrace();
1900                 // // }
1901                 // // }
1902                 // // IJavaElementDelta translatedDelta =
1903                 // this.processResourceDelta(delta);
1904                 // // if (translatedDelta != null) {
1905                 // // this.manager.registerJavaModelDelta(translatedDelta);
1906                 // // }
1907                 // // this.manager.fire(null, ElementChangedEvent.POST_CHANGE);
1908                 // // } finally {
1909                 // // // workaround for bug 15168 circular errors not reported
1910                 // // this.manager.javaProjectsCache = null;
1911                 // // this.removedRoots = null;
1912                 // // }
1913                 // // }
1914                 // }
1915                 // }
1916         }
1917
1918         /*
1919          * Turns the firing mode to on. That is, deltas that are/have been
1920          * registered will be fired.
1921          */
1922         private void startDeltas() {
1923                 this.isFiring = true;
1924         }
1925
1926         /*
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.
1929          */
1930         private void stopDeltas() {
1931                 this.isFiring = false;
1932         }
1933
1934         /*
1935          * Note that the project is about to be deleted.
1936          */
1937         private void deleting(IProject project) {
1938
1939                 try {
1940                         // discard indexing jobs that belong to this project so that the
1941                         // project can be
1942                         // deleted without interferences from the index manager
1943                         // this.manager.indexManager.discardJobs(project.getName());
1944
1945                         JavaProject javaProject = (JavaProject) JavaCore.create(project);
1946
1947                         // remember roots of this project
1948                         if (this.removedRoots == null) {
1949                                 this.removedRoots = new HashMap();
1950                         }
1951                         if (javaProject.isOpen()) {
1952                                 this.removedRoots.put(javaProject, javaProject
1953                                                 .getPackageFragmentRoots());
1954                         } else {
1955                                 // compute roots without opening project
1956                                 // this.removedRoots.put(
1957                                 // javaProject,
1958                                 // javaProject.computePackageFragmentRoots(
1959                                 // javaProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/,
1960                                 // false/*don't generateMarkerOnError*/, false/*don't
1961                                 // returnResolutionInProgress*/),
1962                                 // false));
1963                         }
1964
1965                         javaProject.close();
1966
1967                         // workaround for bug 15168 circular errors not reported
1968                         if (this.state.modelProjectsCache == null) {
1969                                 this.state.modelProjectsCache = this.manager.getJavaModel()
1970                                                 .getJavaProjects();
1971                         }
1972                         this.removeFromParentInfo(javaProject);
1973
1974                 } catch (JavaModelException e) {
1975                         // java project doesn't exist: ignore
1976                 }
1977         }
1978
1979         /*
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.
1983          */
1984         private IJavaElementDelta processResourceDelta(IResourceDelta changes) {
1985
1986                 try {
1987                         IJavaModel model = this.manager.getJavaModel();
1988                         if (!model.isOpen()) {
1989                                 // force opening of java model so that java element delta are
1990                                 // reported
1991                                 try {
1992                                         model.open(null);
1993                                 } catch (JavaModelException e) {
1994                                         if (VERBOSE) {
1995                                                 e.printStackTrace();
1996                                         }
1997                                         return null;
1998                                 }
1999                         }
2000                         this.state.initializeRoots();
2001                         this.currentElement = null;
2002
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();
2008
2009                                 // find out the element type
2010                                 // RootInfo rootInfo = null;
2011                                 int elementType;
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;
2018                                 } else {
2019                                         // rootInfo = this.enclosingRootInfo(res.getFullPath(),
2020                                         // delta.getKind());
2021                                         // if (rootInfo != null &&
2022                                         // rootInfo.isRootOfProject(res.getFullPath())) {
2023                                         // elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT;
2024                                         // } else {
2025                                         elementType = IJavaElement.JAVA_PROJECT;
2026                                         // }
2027                                 }
2028
2029                                 // traverse delta
2030                                 // this.traverseDelta(delta, elementType, rootInfo, null);
2031
2032                                 if (elementType == NON_JAVA_RESOURCE
2033                                                 || (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { // project
2034                                                                                                                                                                                                                                 // has
2035                                                                                                                                                                                                                                 // changed
2036                                                                                                                                                                                                                                 // nature
2037                                                                                                                                                                                                                                 // (description
2038                                                                                                                                                                                                                                 // or
2039                                                                                                                                                                                                                                 // open/closed)
2040                                         try {
2041                                                 // add child as non java resource
2042                                                 nonJavaResourcesChanged((JavaModel) model, delta);
2043                                         } catch (JavaModelException e) {
2044                                                 // java model could not be opened
2045                                         }
2046                                 }
2047
2048                         }
2049                         // refreshPackageFragmentRoots();
2050                         // resetProjectCaches();
2051
2052                         return this.currentDelta;
2053                 } finally {
2054                         this.currentDelta = null;
2055                         // this.rootsToRefresh.clear();
2056                         // this.projectCachesToReset.clear();
2057                 }
2058         }
2059
2060         /*
2061          * Converts an <code>IResourceDelta</code> and its children into the
2062          * corresponding <code>IJavaElementDelta</code>s.
2063          */
2064         // private void traverseDelta(
2065         // IResourceDelta delta,
2066         // int elementType,
2067         // RootInfo rootInfo,
2068         // OutputsInfo outputsInfo) {
2069         //                      
2070         // IResource res = delta.getResource();
2071         //      
2072         // // set stack of elements
2073         // if (this.currentElement == null && rootInfo != null) {
2074         // // this.currentElement = rootInfo.project;
2075         // }
2076         //              
2077         // // process current delta
2078         // boolean processChildren = true;
2079         // if (res instanceof IProject) {
2080         // processChildren =
2081         // this.updateCurrentDeltaAndIndex(
2082         // delta,
2083         // elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ?
2084         // IJavaElement.JAVA_PROJECT : // case of prj=src
2085         // elementType,
2086         // rootInfo);
2087         // } else if (rootInfo != null) {
2088         // processChildren = this.updateCurrentDeltaAndIndex(delta, elementType,
2089         // rootInfo);
2090         // } else {
2091         // // not yet inside a package fragment root
2092         // processChildren = true;
2093         // }
2094         //              
2095         // // get the project's output locations and traverse mode
2096         // if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
2097         //      
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();
2109         //      
2110         // // check source attachment change
2111         // this.checkSourceAttachmentChange(child, childRes);
2112         //                              
2113         // // find out whether the child is a package fragment root of the current
2114         // project
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;
2121         // }
2122         //                              
2123         // // compute child type
2124         // int childType =
2125         // this.elementType(
2126         // childRes,
2127         // childKind,
2128         // elementType,
2129         // rootInfo == null ? childRootInfo : rootInfo
2130         // );
2131         //                                              
2132         // // is childRes in the output folder and is it filtered out ?
2133         // boolean isResFilteredFromOutput =
2134         // this.isResFilteredFromOutput(outputsInfo, childRes, childType);
2135         //
2136         // boolean isNestedRoot = rootInfo != null && childRootInfo != null;
2137         // if (!isResFilteredFromOutput
2138         // && !isNestedRoot) { // do not treat as non-java rsc if nested root
2139         //
2140         // this.traverseDelta(child, childType, rootInfo == null ? childRootInfo :
2141         // rootInfo, outputsInfo); // traverse delta for child in the same project
2142         //
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;
2153         // }
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
2158         // root)
2159         // parent = rootInfo.project;
2160         // } else {
2161         // parent = this.createElement(res, elementType, rootInfo);
2162         // }
2163         // if (parent == null) {
2164         // isValidParent = false;
2165         // continue;
2166         // }
2167         // }
2168         // // add child as non java resource
2169         // try {
2170         // nonJavaResourcesChanged(parent, child);
2171         // } catch (JavaModelException e) {
2172         // // ignore
2173         // }
2174         // } else {
2175         // // the non-java resource (or its parent folder) will be attached to the
2176         // java project
2177         // if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
2178         // orphanChildren[i] = child;
2179         // }
2180         // } else {
2181         // oneChildOnClasspath = true;
2182         // }
2183         // } else {
2184         // oneChildOnClasspath = true; // to avoid reporting child delta as non-java
2185         // resource delta
2186         // }
2187         //                                                              
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
2191         // too
2192         // if (isNestedRoot
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
2197         // this root
2198         // }
2199         //      
2200         // // if the child is a package fragment root of one or several other
2201         // projects
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
2209         // this root
2210         // }
2211         // }
2212         // }
2213         // if (orphanChildren != null
2214         // && (oneChildOnClasspath // orphan children are siblings of a package
2215         // fragment root
2216         // || res instanceof IProject)) { // non-java resource directly under a
2217         // project
2218         //                                              
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
2224         // (18698)
2225         // for (int i = 0; i < length; i++) {
2226         // if (orphanChildren[i] != null) {
2227         // try {
2228         // nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
2229         // } catch (JavaModelException e) {
2230         // // ignore
2231         // }
2232         // }
2233         // }
2234         // }
2235         // } // else resource delta will be added by parent
2236         // } // else resource delta will be added by parent
2237         // }
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];
2246                                 long start = -1;
2247                                 if (VERBOSE) {
2248                                         System.out
2249                                                         .print("Listener #" + (i + 1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
2250                                         start = System.currentTimeMillis();
2251                                 }
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) {
2256                                                 Util
2257                                                                 .log(exception,
2258                                                                                 "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
2259                                         }
2260
2261                                         public void run() throws Exception {
2262                                                 listener.elementChanged(extraEvent);
2263                                         }
2264                                 });
2265                                 if (VERBOSE) {
2266                                         System.out
2267                                                         .println(" -> " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
2268                                 }
2269                         }
2270                 }
2271         }
2272
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;
2278         //
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$
2285         // }
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();
2292         // }
2293         // }
2294         // });
2295         // }
2296         // }
2297         /*
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>
2302          */
2303         private void nonJavaResourcesChanged(Openable element, IResourceDelta delta)
2304                         throws JavaModelException {
2305
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);
2313                                 return;
2314                         case IJavaElement.JAVA_PROJECT:
2315                                 ((JavaProjectElementInfo) info).setNonJavaResources(null);
2316
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);
2324                                 }
2325                                 break;
2326                         case IJavaElement.PACKAGE_FRAGMENT:
2327                                 ((PackageFragmentInfo) info).setNonJavaResources(null);
2328                                 break;
2329                         case IJavaElement.PACKAGE_FRAGMENT_ROOT:
2330                                 ((PackageFragmentRootInfo) info).setNonJavaResources(null);
2331                         }
2332                 }
2333
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);
2341                 }
2342                 elementDelta.addResourceDelta(delta);
2343         }
2344
2345         /*
2346          * Flushes all deltas without firing them.
2347          */
2348         public void flush() {
2349                 this.javaModelDeltas = new ArrayList();
2350         }
2351
2352         /*
2353          * Finds the root info this path is included in. Returns null if not found.
2354          */
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)
2359 //                              return rootInfo;
2360 //                      path = path.removeLastSegments(1);
2361 //              }
2362 //              return null;
2363 //      }
2364
2365         /*
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.
2368          */
2369         public void fire(IJavaElementDelta customDelta, int eventType) {
2370                 if (!this.isFiring)
2371                         return;
2372
2373                 if (DEBUG) {
2374                         System.out
2375                                         .println("-----------------------------------------------------------------------------------------------------------------------");//$NON-NLS-1$
2376                 }
2377
2378                 IJavaElementDelta deltaToNotify;
2379                 if (customDelta == null) {
2380                         deltaToNotify = this.mergeDeltas(this.javaModelDeltas);
2381                 } else {
2382                         deltaToNotify = customDelta;
2383                 }
2384
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);
2391                 // }
2392                 // }
2393
2394                 // Notification
2395
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;
2403
2404                 switch (eventType) {
2405                 case DEFAULT_CHANGE_EVENT:
2406                         firePostChangeDelta(deltaToNotify, listeners, listenerMask,
2407                                         listenerCount);
2408                         fireReconcileDelta(listeners, listenerMask, listenerCount);
2409                         break;
2410                 case ElementChangedEvent.POST_CHANGE:
2411                         firePostChangeDelta(deltaToNotify, listeners, listenerMask,
2412                                         listenerCount);
2413                         fireReconcileDelta(listeners, listenerMask, listenerCount);
2414                         break;
2415                 }
2416         }
2417
2418         private void firePostChangeDelta(IJavaElementDelta deltaToNotify,
2419                         IElementChangedListener[] listeners, int[] listenerMask,
2420                         int listenerCount) {
2421
2422                 // post change deltas
2423                 if (DEBUG) {
2424                         System.out
2425                                         .println("FIRING POST_CHANGE Delta [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
2426                         System.out
2427                                         .println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
2428                 }
2429                 if (deltaToNotify != null) {
2430                         // flush now so as to keep listener reactions to post their own
2431                         // deltas for subsequent iteration
2432                         this.flush();
2433
2434                         notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE,
2435                                         listeners, listenerMask, listenerCount);
2436                 }
2437         }
2438
2439         private void fireReconcileDelta(IElementChangedListener[] listeners,
2440                         int[] listenerMask, int listenerCount) {
2441
2442                 IJavaElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas
2443                                 .values());
2444                 if (DEBUG) {
2445                         System.out
2446                                         .println("FIRING POST_RECONCILE Delta [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
2447                         System.out
2448                                         .println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
2449                 }
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();
2454
2455                         notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE,
2456                                         listeners, listenerMask, listenerCount);
2457                 }
2458         }
2459
2460         /*
2461          * Returns the root info for the given path. Look in the old roots table if
2462          * kind is REMOVED.
2463          */
2464 //      RootInfo rootInfo(IPath path, int kind) {
2465 //              if (kind == IResourceDelta.REMOVED) {
2466 //                      return (RootInfo) this.oldRoots.get(path);
2467 //              } else {
2468 //                      return (RootInfo) this.roots.get(path);
2469 //              }
2470 //      }
2471
2472         /*
2473          * Returns the other root infos for the given path. Look in the old other
2474          * roots table if kind is REMOVED.
2475          */
2476 //      ArrayList otherRootsInfo(IPath path, int kind) {
2477 //              if (kind == IResourceDelta.REMOVED) {
2478 //                      return (ArrayList) this.oldOtherRoots.get(path);
2479 //              } else {
2480 //                      return (ArrayList) this.otherRoots.get(path);
2481 //              }
2482 //      }
2483
2484         /**
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.
2489          */
2490         // protected boolean traverseDelta(
2491         // IResourceDelta delta,
2492         // int elementType,
2493         // RootInfo rootInfo,
2494         // OutputsInfo outputsInfo) {
2495         //                      
2496         // IResource res = delta.getResource();
2497         //      
2498         // // set stack of elements
2499         // if (this.currentElement == null && rootInfo != null) {
2500         // this.currentElement = (Openable)rootInfo.project;
2501         // }
2502         //              
2503         // // process current delta
2504         // boolean processChildren = true;
2505         // if (res instanceof IProject) {
2506         // processChildren =
2507         // this.updateCurrentDeltaAndIndex(
2508         // delta,
2509         // elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ?
2510         // IJavaElement.JAVA_PROJECT : // case of prj=src
2511         // elementType,
2512         // rootInfo);
2513         // } else if (rootInfo != null) {
2514         // processChildren = this.updateCurrentDeltaAndIndex(delta, elementType,
2515         // rootInfo);
2516         // } else {
2517         // // not yet inside a package fragment root
2518         // processChildren = true;
2519         // }
2520         //              
2521         // // get the project's output locations and traverse mode
2522         // if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
2523         //      
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();
2535         //      
2536         // // check source attachment change
2537         // this.checkSourceAttachmentChange(child, childRes);
2538         //                              
2539         // // find out whether the child is a package fragment root of the current
2540         // project
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;
2547         // }
2548         //                              
2549         // // compute child type
2550         // int childType =
2551         // this.elementType(
2552         // childRes,
2553         // childKind,
2554         // elementType,
2555         // rootInfo == null ? childRootInfo : rootInfo
2556         // );
2557         //                                              
2558         // // is childRes in the output folder and is it filtered out ?
2559         // boolean isResFilteredFromOutput =
2560         // this.isResFilteredFromOutput(outputsInfo, childRes, childType);
2561         //
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
2567         // the same project
2568         // // it is a non-java resource
2569         // try {
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;
2578         // }
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
2583         // root)
2584         // parent = (Openable)rootInfo.project;
2585         // } else {
2586         // parent = this.createElement(res, elementType, rootInfo);
2587         // }
2588         // if (parent == null) {
2589         // isValidParent = false;
2590         // continue;
2591         // }
2592         // }
2593         // // add child as non java resource
2594         // nonJavaResourcesChanged(parent, child);
2595         // } else {
2596         // // the non-java resource (or its parent folder) will be attached to the
2597         // java project
2598         // if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
2599         // orphanChildren[i] = child;
2600         // }
2601         // } catch (JavaModelException e) {
2602         // }
2603         // } else {
2604         // oneChildOnClasspath = true;
2605         // }
2606         // } else {
2607         // oneChildOnClasspath = true; // to avoid reporting child delta as non-java
2608         // resource delta
2609         // }
2610         //                                                              
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
2614         // too
2615         // if (isNestedRoot
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
2620         // this root
2621         // // NB: No need to check the return value as the child can only be on the
2622         // classpath
2623         // }
2624         //      
2625         // // if the child is a package fragment root of one or several other
2626         // projects
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
2634         // this root
2635         // }
2636         // }
2637         // }
2638         // if (orphanChildren != null
2639         // && (oneChildOnClasspath // orphan children are siblings of a package
2640         // fragment root
2641         // || res instanceof IProject)) { // non-java resource directly under a
2642         // project
2643         //                                              
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
2649         // (18698)
2650         // for (int i = 0; i < length; i++) {
2651         // if (orphanChildren[i] != null) {
2652         // try {
2653         // nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
2654         // } catch (JavaModelException e) {
2655         // }
2656         // }
2657         // }
2658         // }
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)
2662         // } else {
2663         // return elementType != NON_JAVA_RESOURCE;
2664         // }
2665         // }
2666         /**
2667          * Update the classpath markers and cycle markers for the projects to
2668          * update.
2669          */
2670         // void updateClasspathMarkers() {
2671         // try {
2672         // if (!ResourcesPlugin.getWorkspace().isAutoBuilding()) {
2673         // Iterator iterator = this.projectsToUpdate.iterator();
2674         // while (iterator.hasNext()) {
2675         // try {
2676         // JavaProject project = (JavaProject)iterator.next();
2677         //                                              
2678         // // force classpath marker refresh
2679         // project.getResolvedClasspath(
2680         // true, // ignoreUnresolvedEntry
2681         // true); // generateMarkerOnError
2682         //                                              
2683         // } catch (JavaModelException e) {
2684         // }
2685         // }
2686         // }
2687         // if (!this.projectsToUpdate.isEmpty()){
2688         // try {
2689         // // update all cycle markers
2690         // JavaProject.updateAllCycleMarkers();
2691         // } catch (JavaModelException e) {
2692         // }
2693         // }
2694         // } finally {
2695         // this.projectsToUpdate = new HashSet();
2696         // }
2697         // }
2698         /*
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.
2703          */
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);
2714         // return false;
2715         // }
2716         // this.updateIndex(element, delta);
2717         // this.elementAdded(element, delta, rootInfo);
2718         // return false;
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);
2725         // return false;
2726         // }
2727         // this.updateIndex(element, delta);
2728         // this.elementRemoved(element, delta, rootInfo);
2729         //      
2730         // if (deltaRes.getType() == IResource.PROJECT){
2731         // // reset the corresponding project built state, since cannot reuse if
2732         // added back
2733         // this.manager.setLastBuiltState((IProject)deltaRes, null /*no state*/);
2734         // }
2735         // return false;
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);
2752         // return false;
2753         // }
2754         // if (res.isOpen()) {
2755         // if (JavaProject.hasJavaNature(res)) {
2756         // this.elementAdded(element, delta, rootInfo);
2757         // this.indexManager.indexAll(res);
2758         // }
2759         // } else {
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());
2766         //                                                              
2767         // }
2768         // }
2769         // return false; // when a project is open/closed don't process children
2770         // }
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);
2784         // } else {
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
2789         // added back
2790         // this.manager.setLastBuiltState(res, null /*no state*/);
2791         // }
2792         // return false; // when a project's nature is added/removed don't process
2793         // children
2794         // }
2795         // }
2796         // }
2797         // return true;
2798         // }
2799         // return true;
2800         // }
2801         /**
2802          * Traverse the set of projects which have changed namespace, and refresh
2803          * their dependents
2804          */
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);
2813         // }
2814         // iterator = affectedDependents.iterator();
2815         // while (iterator.hasNext()) {
2816         // JavaProject project = (JavaProject) iterator.next();
2817         // if (project.isOpen()){
2818         // try {
2819         // ((JavaProjectElementInfo)project.getElementInfo()).setNameLookup(null);
2820         // } catch (JavaModelException e) {
2821         // }
2822         // }
2823         // }
2824         // }
2825         // protected void updateIndex(Openable element, IResourceDelta delta) {
2826         //
2827         // if (indexManager == null)
2828         // return;
2829         //
2830         // switch (element.getElementType()) {
2831         // case IJavaElement.JAVA_PROJECT :
2832         // switch (delta.getKind()) {
2833         // case IResourceDelta.ADDED :
2834         // this.indexManager.indexAll(element.getJavaProject().getProject());
2835         // break;
2836         // case IResourceDelta.REMOVED :
2837         // this.indexManager.removeIndexFamily(element.getJavaProject().getProject().getFullPath());
2838         // // NB: Discarding index jobs belonging to this project was done during
2839         // PRE_DELETE
2840         // break;
2841         // // NB: Update of index if project is opened, closed, or its java nature
2842         // is added or removed
2843         // // is done in updateCurrentDeltaAndIndex
2844         // }
2845         // break;
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());
2855         // break;
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());
2861         // break;
2862         // case IResourceDelta.REMOVED:
2863         // // the jar was physically removed: remove the index
2864         // this.indexManager.discardJobs(jarPath.toString());
2865         // this.indexManager.removeIndex(jarPath);
2866         // break;
2867         // }
2868         // break;
2869         // } else {
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);
2874         // //$NON-NLS-1$
2875         // break;
2876         // }
2877         // }
2878         // // don't break as packages of the package fragment root can be indexed
2879         // below
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$
2888         // } else {
2889         // pkg = (IPackageFragment)element;
2890         // }
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);
2903         // }
2904         // }
2905         // }
2906         // break;
2907         // }
2908         // break;
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
2915         // try {
2916         // if (binaryFolderPath.equals(project.getOutputLocation())) {
2917         // break;
2918         // }
2919         // } catch (JavaModelException e) {
2920         // }
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)
2925         // break;
2926         // case IResourceDelta.ADDED :
2927         // indexManager.addBinary(file, binaryFolderPath);
2928         // break;
2929         // case IResourceDelta.REMOVED :
2930         // indexManager.remove(file.getFullPath().toString(), binaryFolderPath);
2931         // break;
2932         // }
2933         // break;
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)
2940         // break;
2941         // case IResourceDelta.ADDED :
2942         // indexManager.addSource(file,
2943         // file.getProject().getProject().getFullPath());
2944         // break;
2945         // case IResourceDelta.REMOVED :
2946         // indexManager.remove(file.getFullPath().toString(),
2947         // file.getProject().getProject().getFullPath());
2948         // break;
2949         // }
2950         // }
2951         // }
2952         /**
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.
2955          */
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);
2971         // }
2972         // }
2973         // }
2974         /*
2975          * Update the roots that are affected by the addition or the removal of the
2976          * given container resource.
2977          */
2978         // private void updateRoots(IPath containerPath, IResourceDelta
2979         // containerDelta) {
2980         // Map roots;
2981         // Map otherRoots;
2982         // if (containerDelta.getKind() == IResourceDelta.REMOVED) {
2983         // roots = this.oldRoots;
2984         // otherRoots = this.oldOtherRoots;
2985         // } else {
2986         // roots = this.roots;
2987         // otherRoots = this.otherRoots;
2988         // }
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);
2997         //
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);
3002         // }
3003         //                      
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);
3013         // }
3014         // }
3015         // }
3016         // }
3017         // }
3018         // }
3019 }