package org.eclipse.jdt.internal.core; | |
/* | |
* (c) Copyright IBM Corp. 2000, 2001. | |
* All Rights Reserved. | |
*/ | |
import org.eclipse.core.resources.*; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IPath; | |
import org.eclipse.core.runtime.Path; | |
import org.eclipse.core.runtime.QualifiedName; | |
import org.eclipse.jdt.core.IClasspathEntry; | |
import org.eclipse.jdt.core.IJavaElement; | |
import org.eclipse.jdt.core.IJavaElementDelta; | |
import org.eclipse.jdt.core.IJavaProject; | |
import org.eclipse.jdt.core.IPackageFragment; | |
import org.eclipse.jdt.core.IPackageFragmentRoot; | |
import org.eclipse.jdt.core.JavaCore; | |
import org.eclipse.jdt.core.JavaModelException; | |
import org.eclipse.jdt.internal.core.search.indexing.*; | |
import java.io.IOException; | |
import java.util.Enumeration; | |
import java.util.Hashtable; | |
import java.util.Vector; | |
/** | |
* This class is used by <code>JavaModelManager</code> to convert | |
* <code>IResourceDelta</code>s into <code>IJavaElementDelta</code>s. | |
* It also does some processing on the <code>JavaElement</code>s involved | |
* (e.g. closing them or updating classpaths). | |
*/ | |
public class DeltaProcessor { | |
/** | |
* The <code>JavaElementDelta</code> corresponding to the <code>IResourceDelta</code> being translated. | |
*/ | |
protected JavaElementDelta fCurrentDelta; | |
/** | |
* JavaProjects that need classpaths updated when resource delta | |
* translation is complete. | |
*/ | |
protected Hashtable fJavaProjectsToUpdate = null; | |
/** | |
* Flag can be set to avoid processing children of current element | |
*/ | |
protected boolean fProcessChildren = true; | |
protected IndexManager indexManager = | |
JavaModelManager.ENABLE_INDEXING ? new IndexManager() : null; | |
/** | |
* Adds the given child handle to its parent's cache of children. | |
*/ | |
protected void addToParentInfo(Openable child) { | |
Openable parent = (Openable) child.getParent(); | |
if (parent != null && parent.isOpen()) { | |
try { | |
JavaElementInfo info = parent.getElementInfo(); | |
info.addChild(child); | |
} catch (JavaModelException e) { | |
// do nothing - we already checked if open | |
} | |
} | |
} | |
/** | |
* Generic processing for an element that has been added:<ul> | |
* <li>The element is added to its parent's cache of children | |
* <li>The element is closed (to ensure consistency) | |
* <li>An entry is made in the delta reporting it as added (ADDED). | |
* </ul> | |
* <p> | |
* If the element is an archive, and it has just been added, it may not be specified | |
* on the project's classpath. In this case, the new element is not added as a child | |
* of its parent (since only package fragment roots on the classpath are considered to | |
* be children of a project). | |
*/ | |
protected void basicElementAdded(Openable element, IResourceDelta delta) { | |
if (isOpen(delta.getResource())) { | |
boolean onClasspath = isOnClasspath(element); | |
// only add as a child if it is on the classpath | |
if (onClasspath) { | |
addToParentInfo(element); | |
switch (element.getElementType()) { | |
case IJavaElement.PACKAGE_FRAGMENT_ROOT : | |
// when a root is added, and is on the classpath, the project must be updated | |
JavaProject project = (JavaProject) element.getJavaProject(); | |
updateProject(project); | |
//1G1TW2T - get rid of namelookup since it holds onto obsolete cached info | |
try { | |
project.getJavaProjectElementInfo().setNameLookup(null); | |
} catch (JavaModelException e) { | |
} | |
break; | |
case IJavaElement.PACKAGE_FRAGMENT : | |
//1G1TW2T - get rid of namelookup since it holds onto obsolete cached info | |
project = (JavaProject) element.getJavaProject(); | |
try { | |
project.getJavaProjectElementInfo().setNameLookup(null); | |
} catch (JavaModelException e) { | |
} | |
break; | |
} | |
} | |
close(element); | |
fCurrentDelta.added(element); | |
} | |
} | |
/** | |
* Check whether the updated file is affecting some of the properties of a given project (like | |
* its classpath persisted as a file). | |
* | |
*/ | |
public static void checkProjectPropertyFileUpdate( | |
IResourceDelta delta, | |
IJavaElement parent) { | |
IResource resource = delta.getResource(); | |
IJavaElement element = JavaCore.create(resource); | |
boolean processChildren = false; | |
switch (resource.getType()) { | |
case IResource.ROOT : | |
processChildren = true; | |
break; | |
case IResource.PROJECT : | |
try { | |
if (((IProject) resource).hasNature(JavaCore.NATURE_ID)) { | |
processChildren = true; | |
} | |
} catch (CoreException e) { | |
} | |
break; | |
case IResource.FILE : | |
if (parent.getElementType() == IJavaElement.JAVA_PROJECT) { | |
IFile file = (IFile) resource; | |
JavaProject project = (JavaProject) parent; | |
/* check classpath property file change */ | |
QualifiedName classpathProp; | |
if (file.getName().equals( | |
project.computeSharedPropertyFileName( | |
classpathProp = project.getClasspathPropertyName()))) { | |
switch (delta.getKind()) { | |
case IResourceDelta.REMOVED : // recreate one based on in-memory path | |
try { | |
project.saveClasspath(); | |
} catch (JavaModelException e) { | |
} | |
break; | |
case IResourceDelta.CHANGED : | |
if ((delta.getFlags() & IResourceDelta.CONTENT) == 0) | |
break; // only consider content change | |
case IResourceDelta.ADDED : | |
// check if any actual difference | |
IPath oldOutputLocation = null; | |
try { | |
oldOutputLocation = project.getOutputLocation(); | |
// force to (re)read the property file | |
String fileClasspathString = project.getSharedProperty(classpathProp); | |
if (fileClasspathString == null) | |
break; // did not find the file | |
IClasspathEntry[] fileEntries = project.readPaths(fileClasspathString); | |
if (fileEntries == null) | |
break; // could not read, ignore | |
if (project.isClasspathEqualsTo(fileEntries)) | |
break; | |
// will force an update of the classpath/output location based on the file information | |
// extract out the output location | |
IPath outputLocation = null; | |
if (fileEntries != null && fileEntries.length > 0) { | |
IClasspathEntry entry = fileEntries[fileEntries.length - 1]; | |
if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { | |
outputLocation = entry.getPath(); | |
IClasspathEntry[] copy = new IClasspathEntry[fileEntries.length - 1]; | |
System.arraycopy(fileEntries, 0, copy, 0, copy.length); | |
fileEntries = copy; | |
} | |
} | |
// restore output location | |
if (outputLocation != null) { | |
project.setOutputLocation0(outputLocation); | |
} | |
try { | |
project.setRawClasspath(fileEntries, null, false); | |
} catch (JavaModelException e) { // undo output location change | |
project.setOutputLocation0(oldOutputLocation); | |
} | |
} catch (IOException e) { | |
break; | |
} catch (RuntimeException e) { | |
break; | |
} catch (CoreException e) { | |
break; | |
} | |
} | |
} | |
} | |
break; | |
} | |
if (processChildren) { | |
IResourceDelta[] children = delta.getAffectedChildren(); | |
for (int i = 0; i < children.length; i++) { | |
checkProjectPropertyFileUpdate(children[i], element); | |
} | |
} | |
} | |
/** | |
* Clears the caches related to classpath updates. | |
*/ | |
protected void clearState() { | |
fJavaProjectsToUpdate = null; | |
} | |
/** | |
* Closes the given element, which removes it from the cache of open elements. | |
*/ | |
protected static void close(Openable element) { | |
try { | |
element.close(); | |
} catch (JavaModelException e) { | |
// do nothing | |
} | |
} | |
/** | |
* Traverse an existing delta and close the affected compilation units. | |
*/ | |
protected void closeAffectedElements(IResourceDelta delta) { | |
Openable element = (Openable) JavaCore.create(delta.getResource()); | |
boolean processChildren = true; | |
if (element != null) { | |
int flags = delta.getFlags(); | |
switch (element.getElementType()) { | |
case IJavaElement.CLASS_FILE : | |
case IJavaElement.COMPILATION_UNIT : | |
processChildren = false; | |
switch (delta.getKind()) { | |
case IResourceDelta.ADDED : | |
break; | |
case IResourceDelta.CHANGED : | |
if ((flags & IResourceDelta.CONTENT) != 0) { | |
try { | |
element.close(); | |
} catch (JavaModelException e) { | |
} | |
} | |
break; | |
case IResourceDelta.REMOVED : | |
try { | |
element.close(); | |
} catch (JavaModelException e) { | |
} | |
} | |
} | |
} | |
if (processChildren) { | |
IResourceDelta[] children = delta.getAffectedChildren(); | |
for (int i = 0; i < children.length; i++) { | |
closeAffectedElements(children[i]); | |
} | |
} | |
} | |
/** | |
* Generic processing for elements with changed contents:<ul> | |
* <li>The element is closed such that any subsequent accesses will re-open | |
* the element reflecting its new structure. | |
* <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set). | |
* </ul> | |
*/ | |
protected void contentChanged(Openable element, IResourceDelta delta) { | |
close(element); | |
fCurrentDelta.changed(element, IJavaElementDelta.F_CONTENT); | |
} | |
/** | |
* Creates the openables corresponding to this resource. | |
* Returns null if none was found. | |
* In general, there is only one openable corresponding to a resource, | |
* except for jar and zip files that can correspond to one or more | |
* JarPackageFragmentRoots. | |
*/ | |
protected Openable[] createElements(IResource resource) { | |
if (resource == null) | |
return null; | |
String extension = resource.getFileExtension(); | |
extension = extension == null ? null : extension.toLowerCase(); | |
if ("jar".equals(extension) //$NON-NLS-1$ | |
|| "zip".equals(extension)) { //$NON-NLS-1$ | |
IJavaProject[] projects = null; | |
try { | |
projects = | |
JavaModelManager.getJavaModel(resource.getWorkspace()).getJavaProjects(); | |
} catch (JavaModelException e) { | |
return null; | |
} | |
Vector jars = new Vector(); | |
for (int i = 0, length = projects.length; i < length; i++) { | |
IJavaProject project = projects[i]; | |
// Create a jar package fragment root only if on the classpath | |
IPath resourcePath = resource.getFullPath(); | |
try { | |
IClasspathEntry[] entries = ((JavaProject) project).getExpandedClasspath(true); | |
for (int j = 0, length2 = entries.length; j < length2; j++) { | |
IClasspathEntry entry = entries[j]; | |
IPath rootPath = entry.getPath(); | |
if (rootPath.equals(resourcePath)) { | |
jars.add(project.getPackageFragmentRoot((IFile) resource)); | |
} | |
} | |
} catch (JavaModelException e) { | |
} | |
} | |
int size = jars.size(); | |
if (size == 0) | |
return null; | |
Openable[] result = new Openable[size]; | |
jars.copyInto(result); | |
return result; | |
} else { | |
Openable element = (Openable) JavaCore.create(resource); | |
if (element == null) { | |
return null; | |
} else { | |
return new Openable[] { element }; | |
} | |
} | |
} | |
/** | |
* Processing for an element that has been added:<ul> | |
* <li>If the element is a project, do nothing, and do not process | |
* children, as when a project is created it does not yet have any | |
* natures - specifically a java nature. | |
* <li>If the elemet is not a project, process it as added (see | |
* <code>basicElementAdded</code>. | |
* </ul> | |
*/ | |
protected void elementAdded(Openable element, IResourceDelta delta) { | |
if (element.getElementType() == IJavaElement.JAVA_PROJECT) { | |
// project add is handled by JavaProject.configure() because | |
// when a project is created, it does not yet have a java nature | |
if (hasJavaNature(delta.getResource())) { | |
basicElementAdded(element, delta); | |
} | |
fProcessChildren = false; | |
return; | |
} else { | |
basicElementAdded(element, delta); | |
} | |
} | |
/** | |
* Processing for the closing of an element - there are two cases:<ul> | |
* <li>when a project is closed (in the platform sense), the | |
* JavaModel reports this as if the JavaProject has been removed. | |
* <li>otherwise, the JavaModel reports this | |
* as a the element being closed (CHANGED + F_CLOSED). | |
* </ul> | |
* <p>In both cases, the children of the element are not processed. When | |
* a resource is closed, the platform reports all children as removed. This | |
* would effectively delete the classpath if we processed children. | |
*/ | |
protected void elementClosed(Openable element, IResourceDelta delta) { | |
if (element.getElementType() == IJavaElement.JAVA_PROJECT) { | |
// treat project closing as removal | |
elementRemoved(element, delta); | |
} else { | |
removeFromParentInfo(element); | |
close(element); | |
fCurrentDelta.closed(element); | |
} | |
// do not process any children | |
fProcessChildren = false; | |
} | |
/** | |
* Processing for the opening of an element - there are two cases:<ul> | |
* <li>when a project is opened (in the platform sense), the | |
* JavaModel reports this as if the JavaProject has been added. | |
* <li>otherwise, the JavaModel reports this | |
* as a the element being opened (CHANGED + F_CLOSED). | |
* </ul> | |
*/ | |
protected void elementOpened(Openable element, IResourceDelta delta) { | |
if (element.getElementType() == IJavaElement.JAVA_PROJECT) { | |
// treat project opening as addition | |
if (hasJavaNature(delta.getResource())) { | |
basicElementAdded(element, delta); | |
} | |
} else { | |
addToParentInfo(element); | |
fCurrentDelta.opened(element); | |
} | |
} | |
/** | |
* Generic processing for a removed element:<ul> | |
* <li>Close the element, removing its structure from the cache | |
* <li>Remove the element from its parent's cache of children | |
* <li>Add a REMOVED entry in the delta | |
* </ul> | |
*/ | |
protected void elementRemoved(Openable element, IResourceDelta delta) { | |
close(element); | |
removeFromParentInfo(element); | |
fCurrentDelta.removed(element); | |
switch (element.getElementType()) { | |
case IJavaElement.JAVA_PROJECT : | |
JavaModelManager.getJavaModelManager().removePerProjectInfo( | |
(JavaProject) element); | |
break; | |
case IJavaElement.PACKAGE_FRAGMENT_ROOT : | |
if (isOnClasspath(element)) { | |
updateProject(element.getJavaProject()); // to trigger deltas | |
JavaProject project = (JavaProject) element.getJavaProject(); | |
try { | |
project.getJavaProjectElementInfo().setNameLookup(null); | |
} catch (JavaModelException e) { | |
} | |
} | |
break; | |
case IJavaElement.PACKAGE_FRAGMENT : | |
//1G1TW2T - get rid of namelookup since it holds onto obsolete cached info | |
if (isOnClasspath(element)) { | |
JavaProject project = (JavaProject) element.getJavaProject(); | |
try { | |
project.getJavaProjectElementInfo().setNameLookup(null); | |
} catch (JavaModelException e) { | |
} | |
} | |
break; | |
case IJavaElement.JAVA_MODEL : | |
element.getJavaModelManager().getIndexManager().reset(); | |
element.getJavaModelManager().fModelInfo = null; | |
break; | |
} | |
} | |
/** | |
* Filters the generated <code>JavaElementDelta</code>s to remove those | |
* which should not be fired (because they don't represent a real change | |
* in the Java Model). | |
*/ | |
protected IJavaElementDelta[] filterRealDeltas(IJavaElementDelta[] deltas) { | |
IJavaElementDelta[] realDeltas = new IJavaElementDelta[deltas.length]; | |
int index = 0; | |
for (int i = 0; i < deltas.length; i++) { | |
IJavaElementDelta delta = deltas[i]; | |
if (delta == null) { | |
continue; | |
} | |
if (delta.getAffectedChildren().length > 0 | |
|| delta.getKind() != IJavaElementDelta.CHANGED | |
|| delta.getFlags() == IJavaElementDelta.F_CLOSED | |
|| delta.getFlags() == IJavaElementDelta.F_OPENED) { | |
realDeltas[index++] = delta; | |
} | |
} | |
IJavaElementDelta[] result = new IJavaElementDelta[index]; | |
if (result.length > 0) { | |
System.arraycopy(realDeltas, 0, result, 0, result.length); | |
} | |
return result; | |
} | |
/** | |
* Returns true if the given resource is contained in an open project | |
* with a java nature, otherwise false. | |
*/ | |
protected boolean hasJavaNature(IResource resource) { | |
// ensure the project has a java nature (if open) | |
IProject project = resource.getProject(); | |
if (project.isOpen()) { | |
try { | |
return project.hasNature(JavaCore.NATURE_ID); | |
} catch (CoreException e) { | |
// do nothing | |
} | |
} | |
return false; | |
} | |
/** | |
* Returns true if on of the following holds, otherwise false:<ul> | |
* <li>the given element is a package fragment root and is specified | |
* on its project's classpath | |
* <li>the given element is not a package fragment root | |
* </ul> | |
*/ | |
protected boolean isOnClasspath(IJavaElement element) { | |
if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) { | |
IPackageFragmentRoot root = (IPackageFragmentRoot) element; | |
JavaProject jp = (JavaProject) element.getJavaProject(); | |
try { | |
return jp.getClasspathEntryFor(root.getPath()) != null; | |
} catch (JavaModelException e) { | |
return false; | |
} | |
} else { | |
return true; | |
} | |
} | |
/** | |
* Returns true if the given resource is considered open (in the | |
* platform sense), otherwise false. | |
*/ | |
protected boolean isOpen(IResource resource) { | |
IProject project = resource.getProject(); | |
if (project == null) { | |
return true; // workspace is always open | |
} else { | |
return project.isOpen(); | |
} | |
} | |
/** | |
* Creates and returns a new classpath entry of the same kind as the | |
* old entry, but with the new specified path. | |
*/ | |
protected IClasspathEntry newClasspathEntry( | |
IJavaProject project, | |
IClasspathEntry oldEntry, | |
IPath to) { | |
IClasspathEntry newEntry = null; | |
switch (oldEntry.getEntryKind()) { | |
case IClasspathEntry.CPE_LIBRARY : | |
newEntry = | |
JavaCore.newLibraryEntry( | |
to, | |
oldEntry.getSourceAttachmentPath(), | |
oldEntry.getSourceAttachmentRootPath(), | |
oldEntry.isExported()); | |
break; | |
case IClasspathEntry.CPE_PROJECT : | |
newEntry = JavaCore.newProjectEntry(to, oldEntry.isExported()); | |
break; | |
case IClasspathEntry.CPE_SOURCE : | |
newEntry = JavaCore.newSourceEntry(to); | |
break; | |
} | |
return newEntry; | |
} | |
/** | |
* Generic processing for elements with changed contents:<ul> | |
* <li>The element is closed such that any subsequent accesses will re-open | |
* the element reflecting its new structure. | |
* <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set). | |
* </ul> | |
*/ | |
protected void nonJavaResourcesChanged(Openable element, IResourceDelta delta) | |
throws JavaModelException { | |
JavaElementInfo info = element.getElementInfo(); | |
switch (element.getElementType()) { | |
case IJavaElement.JAVA_PROJECT : | |
IResource resource = delta.getResource(); | |
((JavaProjectElementInfo) info).setNonJavaResources(null); | |
// if a package fragment root is the project, clear it too | |
PackageFragmentRoot projectRoot = | |
(PackageFragmentRoot) ((JavaProject) element).getPackageFragmentRoot( | |
new Path(IPackageFragment.DEFAULT_PACKAGE_NAME)); | |
if (projectRoot.isOpen()) { | |
((PackageFragmentRootInfo) projectRoot.getElementInfo()).setNonJavaResources( | |
null); | |
} | |
if (delta | |
.getResource() | |
.getFullPath() | |
.equals(((JavaProject) element).getOutputLocation())) { | |
fProcessChildren = false; | |
return; | |
} | |
break; | |
case IJavaElement.PACKAGE_FRAGMENT : | |
((PackageFragmentInfo) info).setNonJavaResources(null); | |
break; | |
case IJavaElement.PACKAGE_FRAGMENT_ROOT : | |
((PackageFragmentRootInfo) info).setNonJavaResources(null); | |
}; | |
JavaElementDelta elementDelta = fCurrentDelta.find(element); | |
if (elementDelta == null) { | |
fCurrentDelta.changed(element, IJavaElementDelta.F_CONTENT); | |
elementDelta = fCurrentDelta.find(element); | |
} | |
elementDelta.addResourceDelta(delta); | |
} | |
/** | |
* Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into | |
* the corresponding set of <code>IJavaElementDelta</code>, rooted in the | |
* relevant <code>JavaModel</code>s. | |
*/ | |
public IJavaElementDelta[] processResourceDelta(IResourceDelta changes) { | |
// clear state | |
clearState(); | |
// get the workspace delta, and start processing there. | |
IResourceDelta[] deltas = changes.getAffectedChildren(); | |
IJavaElementDelta[] translatedDeltas = new JavaElementDelta[deltas.length]; | |
for (int i = 0; i < deltas.length; i++) { | |
IResourceDelta delta = deltas[i]; | |
JavaModel model = | |
JavaModelManager.getJavaModel(delta.getResource().getWorkspace()); | |
if (model != null) { | |
fCurrentDelta = new JavaElementDelta(model); | |
traverseDelta(delta, model); // traverse delta | |
translatedDeltas[i] = fCurrentDelta; | |
} | |
} | |
// update classpaths | |
updateClasspaths(false); | |
// clear state | |
clearState(); | |
return filterRealDeltas(translatedDeltas); | |
} | |
/** | |
* Removes the given element from its parents cache of children. If the | |
* element does not have a parent, or the parent is not currently open, | |
* this has no effect. | |
*/ | |
protected void removeFromParentInfo(Openable child) { | |
Openable parent = (Openable) child.getParent(); | |
if (parent != null && parent.isOpen()) { | |
try { | |
JavaElementInfo info = parent.getElementInfo(); | |
info.removeChild(child); | |
} catch (JavaModelException e) { | |
// do nothing - we already checked if open | |
} | |
} | |
} | |
/** | |
* Reset the non-java resources collection for package fragment roots of the | |
* corresponding project. | |
*/ | |
protected void resetNonJavaResourcesForPackageFragmentRoots(JavaProject project) | |
throws JavaModelException { | |
IPackageFragmentRoot[] roots = project.getAllPackageFragmentRoots(); | |
if (roots == null) | |
return; | |
for (int i = 0, max = roots.length; i < max; i++) { | |
IPackageFragmentRoot root = roots[i]; | |
IResource res = root.getUnderlyingResource(); | |
if (res != null) { | |
((PackageFragmentRoot) root).resetNonJavaResources(); | |
} | |
} | |
} | |
/** | |
* Converts an <code>IResourceDelta</code> and its children into | |
* the corresponding <code>IJavaElementDelta</code>s. | |
*/ | |
protected void traverseDelta(IResourceDelta delta, Openable parentElement) { | |
Openable[] elements = this.createElements(delta.getResource()); | |
Openable element = null; | |
int flags = delta.getFlags(); | |
fProcessChildren = true; | |
if (elements != null) { | |
for (int i = 0, length = elements.length; i < length; i++) { | |
element = elements[i]; | |
IResource res = delta.getResource(); | |
updateIndex(element, delta); | |
switch (delta.getKind()) { | |
case IResourceDelta.ADDED : | |
PackageFragmentRoot pkgRoot; | |
if (res.getType() == IResource.FILE | |
&& parentElement != null | |
&& !parentElement.equals(element.getParent()) | |
&& ((pkgRoot = element.getPackageFragmentRoot()) == null | |
|| !isOnClasspath(pkgRoot))) { | |
try { // fake compilation/class file scenario (see JavaCore.createCompilationUnitFrom & createClassFileFrom | |
nonJavaResourcesChanged(parentElement, delta); | |
break; | |
} catch (JavaModelException e) { | |
} | |
} | |
elementAdded(element, delta); | |
break; | |
case IResourceDelta.REMOVED : | |
if (res.getType() == IResource.FILE | |
&& parentElement != null | |
&& !parentElement.equals(element.getParent()) | |
&& ((pkgRoot = element.getPackageFragmentRoot()) == null | |
|| !isOnClasspath(pkgRoot))) { | |
try { // fake compilation/class file scenario (see JavaCore.createCompilationUnitFrom & createClassFileFrom | |
nonJavaResourcesChanged(parentElement, delta); | |
break; | |
} catch (JavaModelException e) { | |
} | |
} | |
elementRemoved(element, delta); | |
break; | |
case IResourceDelta.CHANGED : | |
if ((flags & IResourceDelta.CONTENT) != 0) { | |
contentChanged(element, delta); | |
break; | |
} | |
if ((flags & IResourceDelta.OPEN) != 0) { | |
res = delta.getResource(); | |
if (isOpen(res)) { | |
elementOpened(element, delta); | |
} else { | |
elementClosed(element, delta); | |
} | |
break; | |
} | |
break; | |
} | |
} | |
} else { | |
try { | |
if (parentElement != null && delta.getResource() != null) { | |
switch (delta.getResource().getType()) { | |
case IResource.FILE : | |
case IResource.FOLDER : | |
nonJavaResourcesChanged(parentElement, delta); | |
} | |
} | |
} catch (JavaModelException e) { | |
// do nothing | |
} | |
} | |
if (fProcessChildren) { | |
IResourceDelta[] children = delta.getAffectedChildren(); | |
for (int i = 0; i < children.length; i++) { | |
traverseDelta(children[i], element); | |
} | |
} | |
} | |
/** | |
* Updates the classpath of each project requiring update. This refreshes | |
* the cached info in each project's namelookup facility, and persists | |
* classpaths. | |
*/ | |
protected void updateClasspaths(boolean saveClasspath) { | |
if (fJavaProjectsToUpdate != null) { | |
Enumeration projects = fJavaProjectsToUpdate.elements(); | |
while (projects.hasMoreElements()) { | |
JavaProject project = (JavaProject) projects.nextElement(); | |
try { | |
project.updateClassPath(); | |
if (saveClasspath) | |
project.saveClasspath(); | |
} catch (JavaModelException e) { | |
} | |
} | |
} | |
} | |
protected void updateIndex(Openable element, IResourceDelta delta) { | |
if (indexManager == null) | |
return; | |
switch (element.getElementType()) { | |
case IJavaElement.JAVA_PROJECT : | |
switch (delta.getKind()) { | |
case IResourceDelta.ADDED : | |
case IResourceDelta.OPEN : | |
indexManager.indexAll((IProject) delta.getResource()); | |
break; | |
} | |
break; | |
case IJavaElement.CLASS_FILE : | |
IFile file = (IFile) delta.getResource(); | |
IJavaProject project = element.getJavaProject(); | |
IResource binaryFolder; | |
try { | |
binaryFolder = element.getPackageFragmentRoot().getUnderlyingResource(); | |
// if the class file is part of the binary output, it has been created by | |
// the java builder -> ignore | |
if (binaryFolder.getFullPath().equals(project.getOutputLocation())) { | |
break; | |
} | |
} catch (JavaModelException e) { | |
break; | |
} | |
switch (delta.getKind()) { | |
case IResourceDelta.CHANGED : | |
// no need to index if the content has not changed | |
if ((delta.getFlags() & IResourceDelta.CONTENT) == 0) | |
break; | |
case IResourceDelta.ADDED : | |
if (file.isLocal(IResource.DEPTH_ZERO)) | |
indexManager.add(file, binaryFolder); | |
break; | |
case IResourceDelta.REMOVED : | |
indexManager.remove(file.getFullPath().toString(), binaryFolder); | |
break; | |
} | |
break; | |
case IJavaElement.COMPILATION_UNIT : | |
file = (IFile) delta.getResource(); | |
switch (delta.getKind()) { | |
case IResourceDelta.CHANGED : | |
// no need to index if the content has not changed | |
if ((delta.getFlags() & IResourceDelta.CONTENT) == 0) | |
break; | |
case IResourceDelta.ADDED : | |
if (file.isLocal(IResource.DEPTH_ZERO)) | |
indexManager.add(file, file.getProject()); | |
break; | |
case IResourceDelta.REMOVED : | |
indexManager.remove(file.getFullPath().toString(), file.getProject()); | |
break; | |
} | |
} | |
} | |
/** | |
* Adds the given project to the cache of projects requiring classpath | |
* updates when delta translation is complete. | |
*/ | |
protected void updateProject(IJavaProject project) { | |
if (fJavaProjectsToUpdate == null) { | |
fJavaProjectsToUpdate = new Hashtable(2); | |
} | |
fJavaProjectsToUpdate.put(project, project); | |
} | |
} |