blob: c18aea39c1c4c7b1d4ca038cf7fbe400bbf56415 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.dltk.internal.launching;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.DLTKLanguageManager;
import org.eclipse.dltk.core.IBuildpathAttribute;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.launching.AbstractScriptLaunchConfigurationDelegate;
import org.eclipse.dltk.launching.IInterpreterInstall;
import org.eclipse.dltk.launching.IRuntimeBuildpathEntry;
import org.eclipse.dltk.launching.IRuntimeBuildpathEntryResolver;
import org.eclipse.dltk.launching.IRuntimeBuildpathEntryResolver2;
import org.eclipse.dltk.launching.LibraryLocation;
import org.eclipse.dltk.launching.ScriptLaunchConfigurationConstants;
import org.eclipse.dltk.launching.ScriptRuntime;
/**
* Resolves INTERPRETER_CONTAINER
*/
public class InterpreterRuntimeBuildpathEntryResolver
implements IRuntimeBuildpathEntryResolver2 {
/**
* @see IRuntimeBuildpathEntryResolver#resolveRuntimeBuildpathEntry(IRuntimeBuildpathEntry,
* ILaunchConfiguration)
*/
@Override
public IRuntimeBuildpathEntry[] resolveRuntimeBuildpathEntry(
IRuntimeBuildpathEntry entry, ILaunchConfiguration configuration)
throws CoreException {
String nature = configuration.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_SCRIPT_NATURE,
(String) null);
IScriptProject project = AbstractScriptLaunchConfigurationDelegate
.getScriptProject(configuration);
IEnvironment environment = EnvironmentManager.getEnvironment(project);
IInterpreterInstall interpreterEnvironment = null;
if (entry.getType() == IRuntimeBuildpathEntry.CONTAINER
&& entry.getPath().segmentCount() > 1) {
// a specific Interpreter
interpreterEnvironment = InterpreterContainerInitializer
.resolveInterpreter(nature, environment.getId(),
entry.getPath());
} else {
// default Interpreter for config
interpreterEnvironment = ScriptRuntime
.computeInterpreterInstall(configuration);
}
if (interpreterEnvironment == null) {
// cannot resolve InterpreterEnvironment
return new IRuntimeBuildpathEntry[0];
}
return resolveLibraryLocations(interpreterEnvironment,
entry.getBuildpathProperty());
}
private String getNatureFromProject(IScriptProject project) {
return DLTKLanguageManager.getLanguageToolkit(project).getNatureId();
}
private String getEnvironmentFromProject(IScriptProject project) {
return EnvironmentManager.getEnvironment(project).getId();
}
/**
* @see IRuntimeBuildpathEntryResolver#resolveRuntimeBuildpathEntry(IRuntimeBuildpathEntry,
* IScriptProject)
*/
@Override
public IRuntimeBuildpathEntry[] resolveRuntimeBuildpathEntry(
IRuntimeBuildpathEntry entry, IScriptProject project)
throws CoreException {
IInterpreterInstall interpreterEnvironment = null;
if (entry.getType() == IRuntimeBuildpathEntry.CONTAINER
&& entry.getPath().segmentCount() > 1) {
// a specific Interpreter
interpreterEnvironment = InterpreterContainerInitializer
.resolveInterpreter(getNatureFromProject(project),
getEnvironmentFromProject(project),
entry.getPath());
} else {
// default Interpreter for project
interpreterEnvironment = ScriptRuntime
.getInterpreterInstall(project);
}
if (interpreterEnvironment == null) {
// cannot resolve InterpreterEnvironment
return new IRuntimeBuildpathEntry[0];
}
return resolveLibraryLocations(interpreterEnvironment,
entry.getBuildpathProperty());
}
/**
* Resolves library locations for the given Interpreter install
*/
protected IRuntimeBuildpathEntry[] resolveLibraryLocations(
IInterpreterInstall interpreter, int kind) {
LibraryLocation[] libs = interpreter.getLibraryLocations();
LibraryLocation[] defaultLibs = interpreter.getInterpreterInstallType()
.getDefaultLibraryLocations(interpreter.getInstallLocation(),
interpreter.getEnvironmentVariables(), null);
if (libs == null) {
// default system libs
libs = defaultLibs;
} else if (!isSamePaths(libs, defaultLibs)) {
// determine if bootpath should be explicit
kind = IRuntimeBuildpathEntry.BOOTSTRAP_ENTRY;
}
List<IRuntimeBuildpathEntry> resolvedEntries = new ArrayList<>(
libs.length);
final IEnvironment environment = interpreter.getEnvironment();
for (int i = 0; i < libs.length; i++) {
IPath systemLibraryPath = libs[i].getLibraryPath();
if (!contains(defaultLibs, systemLibraryPath)) {
final boolean exists;
if (environment != null) {
final IFileHandle fileHandle = EnvironmentPathUtils
.getFile(environment, systemLibraryPath);
if (fileHandle != null) {
exists = fileHandle.exists();
} else {
exists = true;
}
} else {
exists = systemLibraryPath.toFile().exists();
}
if (exists) {
resolvedEntries.add(
resolveLibraryLocation(interpreter, libs[i], kind));
}
}
}
return resolvedEntries
.toArray(new IRuntimeBuildpathEntry[resolvedEntries.size()]);
}
/**
* @param libs
* @param path
* @return
*/
private static boolean contains(LibraryLocation[] libs, IPath path) {
final IPathEquality compare = PathEqualityUtils.getInstance();
for (int i = 0; i < libs.length; ++i) {
if (compare.equals(path, libs[i].getLibraryPath())) {
return true;
}
}
return false;
}
public static boolean isSamePaths(LibraryLocation[] libs,
LibraryLocation[] defaultLibs) {
final int length = defaultLibs.length;
if (libs.length != length) {
return false;
}
if (length != 0) {
// TODO paths could be remote...
final IPathEquality compare = PathEqualityUtils.getInstance();
for (int i = 0; i < length; i++) {
IPath dpath = defaultLibs[i].getLibraryPath();
IPath lpath = libs[i].getLibraryPath();
if (!compare.equals(dpath, lpath)) {
return false;
}
}
}
return true;
}
/**
* Return whether the given list of libraries refer to the same archives in
* the same order. Only considers the binary archive (not source or javadoc
* locations).
*
* @param libs
* @param defaultLibs
* @return whether the given list of libraries refer to the same archives in
* the same order
*/
public static boolean isSameArchives(LibraryLocation[] libs,
LibraryLocation[] defaultLibs) {
if (libs.length != defaultLibs.length) {
return false;
}
for (int i = 0; i < defaultLibs.length; i++) {
LibraryLocation def = defaultLibs[i];
LibraryLocation lib = libs[i];
if (!def.getLibraryPath().equals(lib.getLibraryPath())) {
return false;
}
}
return true;
}
/**
* @see IRuntimeBuildpathEntryResolver#resolveInterpreterInstall(IBuildpathEntry)
*/
@Override
public IInterpreterInstall resolveInterpreterInstall(String lang,
String environment, IBuildpathEntry entry) {
if (entry.getEntryKind() == IBuildpathEntry.BPE_CONTAINER)
if (entry.getPath().segment(0)
.equals(ScriptRuntime.INTERPRETER_CONTAINER)) {
try {
return InterpreterContainerInitializer.resolveInterpreter(
lang, environment, entry.getPath());
} catch (CoreException e) {
return null;
}
}
return null;
}
@Override
public boolean isInterpreterInstallReference(String lang,
String environment, IBuildpathEntry entry) {
if (entry.getEntryKind() == IBuildpathEntry.BPE_CONTAINER)
if (entry.getPath().segment(0)
.equals(ScriptRuntime.INTERPRETER_CONTAINER)) {
return true;
}
return false;
}
/**
* Returns a runtime buildpath entry for the given library in the specified
* Interpreter.
*
* @param Interpreter
* @param location
* @param kind
* @return runtime buildpath entry
*
*/
private IRuntimeBuildpathEntry resolveLibraryLocation(
IInterpreterInstall Interpreter, LibraryLocation location,
int kind) {
IPath libraryPath = location.getLibraryPath();
IBuildpathAttribute[] attributes = new IBuildpathAttribute[0];
IBuildpathEntry bpe = DLTKCore.newLibraryEntry(libraryPath,
IBuildpathEntry.NO_ACCESS_RULES, attributes, false, false);
IRuntimeBuildpathEntry resolved = new RuntimeBuildpathEntry(bpe);
resolved.setBuildpathProperty(kind);
return resolved;
}
}