📄 abstractinterpretermanager.java
字号:
/*
* Created on May 17, 2005
*
* @author Fabio Zadrozny
*/
package org.python.pydev.ui.interpreters;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.python.copiedfromeclipsesrc.JDTNotAvailableException;
import org.python.pydev.core.ExtensionHelper;
import org.python.pydev.core.IInterpreterManager;
import org.python.pydev.core.IModule;
import org.python.pydev.core.IPythonNature;
import org.python.pydev.core.IToken;
import org.python.pydev.core.Tuple;
import org.python.pydev.editor.codecompletion.revisited.SystemModulesManager;
import org.python.pydev.plugin.PydevPlugin;
import org.python.pydev.plugin.nature.PythonNature;
import org.python.pydev.ui.NotConfiguredInterpreterException;
import org.python.pydev.ui.pythonpathconf.InterpreterInfo;
/**
* Does not write directly in INTERPRETER_PATH, just loads from it and works with it.
*
* @author Fabio Zadrozny
*/
public abstract class AbstractInterpreterManager implements IInterpreterManager {
/**
* This is the cache, that points from an interpreter to its information.
*/
private Map<String, InterpreterInfo> exeToInfo = new HashMap<String, InterpreterInfo>();
private Preferences prefs;
private String[] interpretersFromPersistedString;
//caches that are filled at runtime -------------------------------------------------------------------------------
/**
* This is used to keep the builtin completions
*/
protected transient IToken[] builtinCompletions;
/**
* This is used to keep the builtin module
*/
protected transient IModule builtinMod;
public void setBuiltinCompletions(IToken[] comps) {
this.builtinCompletions = comps;
}
public IToken[] getBuiltinCompletions() {
return builtinCompletions;
}
public IModule getBuiltinMod() {
return builtinMod;
}
public void setBuiltinMod(IModule mod) {
this.builtinMod = mod;
}
/**
* Constructor
*/
@SuppressWarnings("unchecked")
public AbstractInterpreterManager(Preferences prefs) {
this.prefs = prefs;
prefs.setDefault(getPreferenceName(), "");
List<IInterpreterObserver> participants = ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_INTERPRETER_OBSERVER);
for (IInterpreterObserver observer : participants) {
observer.notifyInterpreterManagerRecreated(this);
}
prefs.addPropertyChangeListener(new Preferences.IPropertyChangeListener(){
public void propertyChange(PropertyChangeEvent event) {
clearCaches();
}
});
}
public void clearCaches() {
builtinMod = null;
builtinCompletions = null;
interpretersFromPersistedString = null;
}
/**
* @return the preference name where the options for this interpreter manager should be stored
*/
protected abstract String getPreferenceName();
/**
* @throws NotConfiguredInterpreterException
* @see org.python.pydev.core.IInterpreterManager#getDefaultInterpreter()
*/
public String getDefaultInterpreter() throws NotConfiguredInterpreterException {
String[] interpreters = getInterpreters();
if(interpreters.length > 0){
String interpreter = interpreters[0];
if(interpreter == null){
throw new NotConfiguredInterpreterException("The configured interpreter is null, some error happened getting it.\n" +getNotConfiguredInterpreterMsg());
}
return interpreter;
}else{
throw new NotConfiguredInterpreterException(this.getClass().getName()+":"+getNotConfiguredInterpreterMsg());
}
}
public void clearAllBut(List<String> allButTheseInterpreters) {
synchronized(exeToInfo){
ArrayList<String> toRemove = new ArrayList<String>();
for (String interpreter : exeToInfo.keySet()) {
if(!allButTheseInterpreters.contains(interpreter)){
toRemove.add(interpreter);
}
}
//we do not want to remove it while we are iterating...
for (Object object : toRemove) {
exeToInfo.remove(object);
}
}
}
/**
* @return a message to show to the user when there is no configured interpreter
*/
protected abstract String getNotConfiguredInterpreterMsg();
/**
* @see org.python.pydev.core.IInterpreterManager#getInterpreters()
*/
public String[] getInterpreters() {
if(interpretersFromPersistedString == null){
interpretersFromPersistedString = getInterpretersFromPersistedString(getPersistedString());
}
return interpretersFromPersistedString;
}
/**
* @see org.python.pydev.core.IInterpreterManager#hasInfoOnInterpreter(java.lang.String)
*/
public boolean hasInfoOnInterpreter(String interpreter) {
if(interpreter == null){
InterpreterInfo info = (InterpreterInfo) exeToInfo.get(getDefaultInterpreter());
return info != null;
}
interpreter = interpreter.toLowerCase();
String[] interpreters = getInterpreters();
for (String str : interpreters) {
if(str.toLowerCase().equals(interpreter)){
return true;
}
}
return false;
}
/**
* @see org.python.pydev.core.IInterpreterManager#getDefaultInterpreterInfo(org.eclipse.core.runtime.IProgressMonitor)
*/
public InterpreterInfo getDefaultInterpreterInfo(IProgressMonitor monitor) {
String interpreter = getDefaultInterpreter();
return getInterpreterInfo(interpreter, monitor);
}
/**
* Given an executable, should create the interpreter info that corresponds to it
*
* @param executable the executable that should be used to create the info
* @param monitor a monitor to keep track of the info
*
* @return the interpreter info for the executable
* @throws CoreException
* @throws JDTNotAvailableException
*/
public abstract Tuple<InterpreterInfo,String> createInterpreterInfo(String executable, IProgressMonitor monitor) throws CoreException, JDTNotAvailableException;
/**
* Creates the interpreter info from the output. Checks for errors.
*/
protected static InterpreterInfo createInfoFromOutput(IProgressMonitor monitor, Tuple<String, String> outTup) {
if(outTup.o1 == null || outTup.o1.trim().length() == 0){
throw new RuntimeException(
"No output was in the standard output when trying to create the interpreter info.\n" +
"The error output contains:>>"+outTup.o2+"<<");
}
InterpreterInfo info = InterpreterInfo.fromString(outTup.o1);
return info;
}
/**
* @see org.python.pydev.core.IInterpreterManager#getInterpreterInfo(java.lang.String)
*/
public InterpreterInfo getInterpreterInfo(String executable, IProgressMonitor monitor) {
synchronized(lock){
InterpreterInfo info = (InterpreterInfo) exeToInfo.get(executable);
if(info == null){
monitor.worked(5);
//ok, we have to get the info from the executable (and let's cache results for future use)...
Tuple<InterpreterInfo,String> tup = null;
try {
tup = createInterpreterInfo(executable, monitor);
if(tup == null){
//cancelled (in the dialog that asks the user to choose the valid paths)
return null;
}
info = tup.o1;
} catch (RuntimeException e) {
PydevPlugin.log(e);
throw e;
} catch (Exception e) {
PydevPlugin.log(e);
throw new RuntimeException(e);
}
if(info.executableOrJar != null && info.executableOrJar.trim().length() > 0){
exeToInfo.put(info.executableOrJar, info);
}else{ //it is null or empty
final String title = "Invalid interpreter:"+executable;
final String msg = "Unable to get information on interpreter!";
String reasonCreation = "The interpreter (or jar): '"+executable+"' is not valid - info.executable found: "+info.executableOrJar+"\n";
if(tup != null){
reasonCreation += "The standard output gotten from the executed shell was: >>"+tup.o2+"<<";
}
final String reason = reasonCreation;
try {
final Display disp = Display.getDefault();
disp.asyncExec(new Runnable(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -