package org.eclipse.jdt.internal.launching;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.IRuntimeClasspathEntryResolver;
import org.eclipse.jdt.launching.IRuntimeClasspathEntryResolver2;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.LibraryLocation;
public class JRERuntimeClasspathEntryResolver implements IRuntimeClasspathEntryResolver2 {
private static IAccessRule[] EMPTY_RULES = new IAccessRule[0];
@Override
public IRuntimeClasspathEntry[] resolveRuntimeClasspathEntry(IRuntimeClasspathEntry entry, ILaunchConfiguration configuration) throws CoreException {
IVMInstall jre = null;
if (entry.getType() == IRuntimeClasspathEntry.CONTAINER && entry.getPath().segmentCount() > 1) {
jre = JREContainerInitializer.resolveVM(entry.getPath());
} else {
jre = JavaRuntime.computeVMInstall(configuration);
}
if (jre == null) {
return new IRuntimeClasspathEntry[0];
}
return resolveLibraryLocations(jre, entry.getClasspathProperty());
}
@Override
public IRuntimeClasspathEntry[] resolveRuntimeClasspathEntry(IRuntimeClasspathEntry entry, IJavaProject project) throws CoreException {
IVMInstall jre = null;
if (entry.getType() == IRuntimeClasspathEntry.CONTAINER && entry.getPath().segmentCount() > 1) {
jre = JREContainerInitializer.resolveVM(entry.getPath());
} else {
jre = JavaRuntime.getVMInstall(project);
}
if (jre == null) {
return new IRuntimeClasspathEntry[0];
}
return resolveLibraryLocations(jre, entry.getClasspathProperty());
}
protected IRuntimeClasspathEntry[] resolveLibraryLocations(IVMInstall vm, int kind) {
LibraryLocation[] libs = vm.getLibraryLocations();
LibraryLocation[] defaultLibs = vm.getVMInstallType().getDefaultLibraryLocations(vm.getInstallLocation());
boolean overrideJavadoc = false;
if (libs == null) {
libs = defaultLibs;
overrideJavadoc = true;
} else if (!isSameArchives(libs, defaultLibs)) {
kind = IRuntimeClasspathEntry.BOOTSTRAP_CLASSES;
}
if (kind == IRuntimeClasspathEntry.BOOTSTRAP_CLASSES) {
File vmInstallLocation= vm.getInstallLocation();
if (vmInstallLocation != null) {
LibraryInfo libraryInfo= LaunchingPlugin.getLibraryInfo(vmInstallLocation.getAbsolutePath());
if (libraryInfo != null) {
String[] extensionDirsArray = libraryInfo.getExtensionDirs();
Set<String> extensionDirsSet = new HashSet<>();
for (int i = 0; i < extensionDirsArray.length; i++) {
extensionDirsSet.add(extensionDirsArray[i]);
}
List<IRuntimeClasspathEntry> resolvedEntries = new ArrayList<>(libs.length);
for (int i = 0; i < libs.length; i++) {
LibraryLocation location = libs[i];
IPath libraryPath = location.getSystemLibraryPath();
String dir = libraryPath.toFile().getParent();
if (!extensionDirsSet.contains(dir)) {
resolvedEntries.add(resolveLibraryLocation(vm, location, kind, overrideJavadoc));
}
}
return resolvedEntries.toArray(new IRuntimeClasspathEntry[resolvedEntries.size()]);
}
}
}
List<IRuntimeClasspathEntry> resolvedEntries = new ArrayList<>(libs.length);
for (int i = 0; i < libs.length; i++) {
IPath systemLibraryPath = libs[i].getSystemLibraryPath();
if (systemLibraryPath.toFile().exists()) {
resolvedEntries.add(resolveLibraryLocation(vm, libs[i], kind, overrideJavadoc));
}
}
return resolvedEntries.toArray(new IRuntimeClasspathEntry[resolvedEntries.size()]);
}
public static boolean isSameArchives(LibraryLocation[] libs, LibraryLocation[] defaultLibs) {
if (libs.length != defaultLibs.length) {
return false;
}
IPath dpath = null, lpath = null;
for (int i = 0; i < defaultLibs.length; i++) {
dpath = defaultLibs[i].getSystemLibraryPath();
lpath = libs[i].getSystemLibraryPath();
if(Platform.getOS().equals(Platform.OS_WIN32)) {
if (!dpath.removeTrailingSeparator().toOSString().equalsIgnoreCase(lpath.removeTrailingSeparator().toOSString())) {
return false;
}
} else if (!dpath.equals(lpath)) {
return false;
}
}
return true;
}
@Override
public IVMInstall resolveVMInstall(IClasspathEntry entry) {
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_VARIABLE:
if (entry.getPath().segment(0).equals(JavaRuntime.JRELIB_VARIABLE)) {
return JavaRuntime.getDefaultVMInstall();
}
break;
case IClasspathEntry.CPE_CONTAINER:
if (entry.getPath().segment(0).equals(JavaRuntime.JRE_CONTAINER)) {
return JREContainerInitializer.resolveVM(entry.getPath());
}
break;
default:
break;
}
return null;
}
@Override
public boolean isVMInstallReference(IClasspathEntry entry) {
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_VARIABLE:
if (entry.getPath().segment(0).equals(JavaRuntime.JRELIB_VARIABLE)) {
return true;
}
break;
case IClasspathEntry.CPE_CONTAINER:
if (entry.getPath().segment(0).equals(JavaRuntime.JRE_CONTAINER)) {
return true;
}
break;
default:
break;
}
return false;
}
private IRuntimeClasspathEntry resolveLibraryLocation(IVMInstall vm, LibraryLocation location, int kind, boolean overrideJavaDoc) {
IPath libraryPath = location.getSystemLibraryPath();
URL javadocLocation = location.getJavadocLocation();
if (overrideJavaDoc && javadocLocation == null) {
javadocLocation = vm.getJavadocLocation();
}
IClasspathAttribute[] attributes = null;
if (javadocLocation == null) {
attributes = new IClasspathAttribute[0];
} else {
attributes = new IClasspathAttribute[]{JavaCore.newClasspathAttribute(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, javadocLocation.toExternalForm())};
}
IClasspathEntry cpe = JavaCore.newLibraryEntry(libraryPath, location.getSystemLibraryPath(), location.getPackageRootPath(), EMPTY_RULES, attributes, false);
IRuntimeClasspathEntry resolved = new RuntimeClasspathEntry(cpe);
resolved.setClasspathProperty(kind);
IPath sourcePath = location.getSystemLibrarySourcePath();
if (sourcePath != null && !sourcePath.isEmpty()) {
resolved.setSourceAttachmentPath(sourcePath);
resolved.setSourceAttachmentRootPath(location.getPackageRootPath());
}
return resolved;
}
}