package org.eclipse.jdt.internal.core.search;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
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.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.core.DeltaProcessor;
import org.eclipse.jdt.internal.core.DeltaProcessor.RootInfo;
import org.eclipse.jdt.internal.core.ExternalFoldersManager;
import org.eclipse.jdt.internal.core.JavaModel;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.util.Util;
public class JavaWorkspaceScope extends AbstractJavaSearchScope {
private IPath[] enclosingPaths = null;
public JavaWorkspaceScope() {
}
@Override
public boolean encloses(IJavaElement element) {
return true;
}
@Override
public boolean encloses(String resourcePathString) {
return true;
}
@Override
public IPath[] enclosingProjectsAndJars() {
IPath[] result = this.enclosingPaths;
if (result != null) {
return result;
}
long start = BasicSearchEngine.VERBOSE ? System.currentTimeMillis() : -1;
try {
IJavaProject[] projects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
Set<IPath> paths = new LinkedHashSet<>(projects.length * 2);
for (int i = 0, length = projects.length; i < length; i++) {
JavaProject javaProject = (JavaProject) projects[i];
IPath projectPath = javaProject.getProject().getFullPath();
paths.add(projectPath);
}
for (int i = 0, length = projects.length; i < length; i++) {
JavaProject javaProject = (JavaProject) projects[i];
IClasspathEntry[] entries = javaProject.getResolvedClasspath();
for (int j = 0, eLength = entries.length; j < eLength; j++) {
IClasspathEntry entry = entries[j];
if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
IPath path = entry.getPath();
Object target = JavaModel.getTarget(path, false);
if (target instanceof IFolder)
path = ((IFolder) target).getFullPath();
paths.add(entry.getPath());
}
}
}
result = new IPath[paths.size()];
paths.toArray(result);
return this.enclosingPaths = result;
} catch (JavaModelException e) {
Util.log(e, "Exception while computing workspace scope's enclosing projects and jars");
return new IPath[0];
} finally {
if (BasicSearchEngine.VERBOSE) {
long time = System.currentTimeMillis() - start;
int length = result == null ? 0 : result.length;
Util.verbose("JavaWorkspaceScope.enclosingProjectsAndJars: "+length+" paths computed in "+time+"ms.");
}
}
}
@Override
public boolean equals(Object o) {
return o == this;
}
@Override
public AccessRuleSet getAccessRuleSet(String relativePath, String containerPath) {
return null;
}
@Override
public int hashCode() {
return JavaWorkspaceScope.class.hashCode();
}
@Override
public IPackageFragmentRoot packageFragmentRoot(String resourcePathString, int jarSeparatorIndex, String jarPath) {
Map<IPath, RootInfo> rootInfos = JavaModelManager.getDeltaState().roots;
DeltaProcessor.RootInfo rootInfo = null;
if (jarPath != null) {
IPath path = new Path(jarPath);
rootInfo = rootInfos.get(path);
} else {
IPath path = new Path(resourcePathString);
if (ExternalFoldersManager.isInternalPathForExternalFolder(path)) {
IResource resource = JavaModel.getWorkspaceTarget(path.uptoSegment(2));
if (resource != null)
rootInfo = rootInfos.get(resource.getLocation());
} else {
rootInfo = rootInfos.get(path);
while (rootInfo == null && path.segmentCount() > 0) {
path = path.removeLastSegments(1);
rootInfo = rootInfos.get(path);
}
}
}
if (rootInfo == null)
return null;
return rootInfo.getPackageFragmentRoot(null);
}
@Override
public void processDelta(IJavaElementDelta delta, int eventType) {
if (this.enclosingPaths == null) return;
IJavaElement element = delta.getElement();
switch (element.getElementType()) {
case IJavaElement.JAVA_MODEL:
IJavaElementDelta[] children = delta.getAffectedChildren();
for (int i = 0, length = children.length; i < length; i++) {
IJavaElementDelta child = children[i];
processDelta(child, eventType);
}
break;
case IJavaElement.JAVA_PROJECT:
int kind = delta.getKind();
switch (kind) {
case IJavaElementDelta.ADDED:
case IJavaElementDelta.REMOVED:
this.enclosingPaths = null;
break;
case IJavaElementDelta.CHANGED:
int flags = delta.getFlags();
if ((flags & IJavaElementDelta.F_CLOSED) != 0
|| (flags & IJavaElementDelta.F_OPENED) != 0) {
this.enclosingPaths = null;
} else {
children = delta.getAffectedChildren();
for (int i = 0, length = children.length; i < length; i++) {
IJavaElementDelta child = children[i];
processDelta(child, eventType);
}
}
break;
}
break;
case IJavaElement.PACKAGE_FRAGMENT_ROOT:
kind = delta.getKind();
switch (kind) {
case IJavaElementDelta.ADDED:
case IJavaElementDelta.REMOVED:
this.enclosingPaths = null;
break;
case IJavaElementDelta.CHANGED:
int flags = delta.getFlags();
if ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) > 0
|| (flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) > 0) {
this.enclosingPaths = null;
}
break;
}
break;
}
}
@Override
public String toString() {
StringBuffer result = new StringBuffer("JavaWorkspaceScope on ");
IPath[] paths = enclosingProjectsAndJars();
int length = paths == null ? 0 : paths.length;
if (length == 0) {
result.append("[empty scope]");
} else {
result.append("[");
for (int i = 0; i < length; i++) {
result.append("\n\t");
result.append(paths[i]);
}
result.append("\n]");
}
return result.toString();
}
}